class JsAjaxWizard
Public Class Methods
new(html='', debug: false)
click to toggle source
# File lib/jsajax_wizard.rb, line 45 def initialize(html='', debug: false) @html, @debug = RXFHelper.read(html).first, debug @requests = [] # search for AJAX placeholders scan_requests(@html) end
Public Instance Methods
add_request(server: '', element: {}, trigger: nil, target_element: {}, target_eval: false)
click to toggle source
# File lib/jsajax_wizard.rb, line 55 def add_request(server: '', element: {}, trigger: nil, target_element: {}, target_eval: false) type = element.any? ? [:element, element] : [:trigger, trigger] @requests << [server, type, target_element, target_eval ] end
to_html()
click to toggle source
# File lib/jsajax_wizard.rb, line 61 def to_html() html = @html.empty? ? build_html : @html puts 'html: ' + html.inspect if @debug doc = Rexle.new(html) puts 'doc.xml: ' + doc.xml(pretty: true) if @debug add_events(doc) js = build_js(doc) doc.root.element('body').add(Rexle.new(js)) doc.xml end
Private Instance Methods
add_element_function(element, i, server, target, target_eval)
click to toggle source
# File lib/jsajax_wizard.rb, line 78 def add_element_function(element, i, server, target, target_eval) puts ('element: ' + element.inspect).debug if @debug puts '::' + [element, i, server, target, target_eval].inspect if @debug a = [] a << if element.is_a?(Hash) then if element[:type] == 'text' then if element[:event].to_sym == :on_enter then " function ajaxCall#{i+1}(keyCode, e) { if (keyCode==13){ ajaxRequest('#{server}' + e.value, ajaxResponse#{i+1}) } } " else " function ajaxCall#{i+1}(e) { ajaxRequest('#{server}' + e.value, ajaxResponse#{i+1}) } " end elsif element[:type] == 'timer' " setInterval( function() { ajaxRequest('#{server}', ajaxResponse#{i+1}) }, #{element[:interval]}); " else " function ajaxCall#{i+1}() { ajaxRequest('#{server}', ajaxResponse#{i+1}) } " end else " function ajaxCall#{i+1}(s) { ajaxRequest('#{server}' + escape(s), ajaxResponse#{i+1}) } " end a << " function ajaxResponse#{i+1}(xhttp) { " if target.is_a?(Hash) and target[:id] then a << " document.getElementById('#{target[:id]}')" + ".innerHTML = xhttp.responseText;" end if target_eval then a << " eval(xhttp.responseText);" end a << " } " a.join end
add_events(doc)
click to toggle source
# File lib/jsajax_wizard.rb, line 156 def add_events(doc) @requests.each.with_index do |x,i| puts ('request x: ' + x.inspect).debug if @debug method(('modify_' + x[1].first.to_s).to_sym).call(x[1].last, doc, i) end doc end
build_elements()
click to toggle source
# File lib/jsajax_wizard.rb, line 169 def build_elements() html = @requests.map.with_index do |x,i| raw_e, e2 = x[1..-1] e = raw_e.last # e = element e.g. {type: 'button', event: 'onclick'} # e2 = target_element: {id: '', property: :innerHTML} a = if e[:type].to_s == 'button' then ["<button type='button''>Change Content</button>"] elsif e[:type].to_s == 'text' then ["<input type='text'/>"] else [''] end a << "<div id='%s'></div>" % [e2[:id]] if e2.is_a? Hash a.join("\n") end r = html.join("\n") puts 'r: ' + r.inspect if @debug r end
build_html()
click to toggle source
# File lib/jsajax_wizard.rb, line 203 def build_html() RexleBuilder.build do |xml| xml.html do xml.head do xml.meta name: "viewport", content: \ "width=device-width, initial-scale=1" xml.style "\nbody {font-family: Arial;}\n\n" end xml.body build_elements end end end
build_js(doc)
click to toggle source
# File lib/jsajax_wizard.rb, line 218 def build_js(doc) ajax=<<EOF function ajaxRequest(url, cFunction) { var xhttp; xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { cFunction(this); } }; xhttp.open("GET", url, true); xhttp.send(); } EOF funcs_defined = @requests.map.with_index do |x,i| puts ('x: ' + x.inspect).debug if @debug server, raw_type, target, target_eval = x if raw_type.first == :trigger then modify_trigger_function(raw_type.last, i, server, doc) end add_element_function(raw_type.last, i, server, target, target_eval) end s = "\n\n" + ajax + "\n\n" + funcs_defined.join "\n <script>\n%s\n </script>\n" % s end
modify_element(element, doc, i)
click to toggle source
# File lib/jsajax_wizard.rb, line 253 def modify_element(element, doc, i) selector = if element[:id] then '#' + element[:id] elsif element[:type] "*[@type='%s']" % element[:type] end if @debug then puts ("selector: %s" % selector.inspect).debug puts 'doc: ' + doc.xml(pretty: true).inspect end e = doc.at_css(selector) puts ('e: ' + e.inspect).debug if @debug return unless e puts ('e: ' + e.inspect).debug if @debug func = 'ajaxCall' + (i+1).to_s event = e.attributes[:type] == 'button' ? func + '()' : func + '(this)' puts ('element: ' + element.inspect).debug if @debug key = if element[:event] then if element[:event].to_sym == :on_enter then event = func + '(event.keyCode, this)' :onkeyup else element[:event].to_sym end else e.attributes[:type] == 'button' ? :onclick : :onkeyup end e.attributes[key] = event end
modify_trigger(element, doc, i)
click to toggle source
# File lib/jsajax_wizard.rb, line 292 def modify_trigger(element, doc, i) end
modify_trigger_function(trigger, i, server, doc)
click to toggle source
# File lib/jsajax_wizard.rb, line 295 def modify_trigger_function(trigger, i, server, doc) doc.root.xpath('//script').each do |script| puts 'script: ' + script.inspect s = script.text.to_s script.text = s.sub(/#{trigger} = function\(\) {[^}]+/) {|x| a = x.lines indent = a[1][/\s+/] a[0..-2].join + indent + "ajaxCall#{i+1}(event.results[0][0]." + "transcript);\n" + a[-1] } end end
scan_requests(html)
click to toggle source
find the ajax requests
# File lib/jsajax_wizard.rb, line 314 def scan_requests(html) a = html.scan(/\$\[([^\]]+)?\]\(([^\)]+)/) a.each do |var, url| #== fetch the trigger element details tag = html[/<[^<]+\$\[([^\]]+)?\]\(#{url}[^\>]+>/] element_name = tag[/(?<=<)\w+/] event = tag[/(\w+)=["']\$\[([^\]]+)?\]\(#{url}/,1] # is there an id? id = tag[/(?<=id=["'])[^"']+/] h2 = if id then {id: id} else {type: element_name.to_sym } end element = h2.merge(event: event) if var.nil? then add_request(server: url, element: element, target_eval: true) next end #== fetch the target element details tag2 = html[/<[^<]+>\$#{var}</] # is there an id? target_id = tag2[/(?<=id=["'])[^"']+/] inner_html = tag2 =~ />\$#{var}</ property = if inner_html then html.sub!(/>\$#{var}</,'> <') :innerHTML end target_element = {id: target_id, property: property} add_request(server: url, element: element, target_element: target_element) end end