Class: Volt::DomTemplate
- Includes:
- CommentSearchers
- Defined in:
- lib/volt/page/targets/dom_template.rb
Overview
A dom template is used to optimize going from a template name to dom nodes and bindings. It stores a copy of the template’s parsed dom nodes, then when a new instance is requested, it updates the dom markers (comments) for new binding numbers and returns a cloneNode’d version of the dom nodes and the bindings.
Constant Summary
Constants included from CommentSearchers
Instance Method Summary collapse
-
#initialize(page, template_name) ⇒ DomTemplate
constructor
A new instance of DomTemplate.
-
#make_new ⇒ Object
Returns the dom nodes and bindings.
-
#track_binding_anchors ⇒ Object
Finds each of the binding anchors in the temp dom, then stores a reference to them so they can be quickly updated without using xpath to find them again.
-
#update_binding_anchors!(nodes) ⇒ Object
Takes the binding_anchors and updates them with new numbers (comments and id’s) then returns the bindings updated to the new numbers.
Methods included from CommentSearchers
#build_from_html, #find_by_comment, #find_by_comment_without_xml
Constructor Details
#initialize(page, template_name) ⇒ DomTemplate
Returns a new instance of DomTemplate.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/volt/page/targets/dom_template.rb', line 12 def initialize(page, template_name) template = page.templates[template_name] if template html = template['html'] @bindings = template['bindings'] else html = "<div>-- < missing template #{template_name.inspect.gsub('<', '<').gsub('>', '>')} > --</div>" @bindings = {} end @nodes = build_from_html(html) track_binding_anchors end |
Instance Method Details
#make_new ⇒ Object
Returns the dom nodes and bindings
29 30 31 32 33 34 35 |
# File 'lib/volt/page/targets/dom_template.rb', line 29 def make_new bindings = update_binding_anchors!(`self.nodes`) new_nodes = `self.nodes.cloneNode(true)` [new_nodes, bindings] end |
#track_binding_anchors ⇒ Object
Finds each of the binding anchors in the temp dom, then stores a reference to them so they can be quickly updated without using xpath to find them again.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/volt/page/targets/dom_template.rb', line 39 def track_binding_anchors @binding_anchors = {} # Loop through the bindings, find in nodes. @bindings.each_pair do |name, binding| if name.is_a?(String) # Find the dom node for an attribute anchor node = nil ` node = self.nodes.querySelector('#' + name); ` @binding_anchors[name] = node else # Find the dom node for a comment anchor start_comment = find_by_comment("$#{name}", @nodes) end_comment = find_by_comment("$/#{name}", @nodes) @binding_anchors[name] = [start_comment, end_comment] end end end |
#update_binding_anchors!(nodes) ⇒ Object
Takes the binding_anchors and updates them with new numbers (comments and id’s) then returns the bindings updated to the new numbers.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/volt/page/targets/dom_template.rb', line 63 def update_binding_anchors!(nodes) new_bindings = {} @binding_anchors.each_pair do |name, anchors| new_name = @@binding_number @@binding_number += 1 if name.is_a?(String) if name[0..1] == 'id' # A generated id # update the id `anchors.setAttribute('id', 'id' + new_name);` new_bindings["id#{new_name}"] = @bindings[name] else # Assume a fixed id, should not be updated # TODO: Might want to check the page to see if a node # with this id already exists and raise if it does. # Copy from existing binding new_bindings[name] = @bindings[name] end else start_comment, end_comment = anchors ` if (start_comment.textContent) { // direct update start_comment.textContent = " $" + new_name + " "; end_comment.textContent = " $/" + new_name + " "; } else if (start_comment.innerText) { start_comment.innerText = " $" + new_name + " "; end_comment.innerText = " $/" + new_name + " "; } else { // phantomjs doesn't work with textContent, so we replace the nodes // and update the references start_comment.nodeValue = " $" + new_name + " "; end_comment.nodeValue = " $/" + new_name + " "; } ` # %x{ # start_comment.innerText = " $" + new_name + " "; # end_comment.innerText = " $/" + new_name + " "; # } new_bindings[new_name] = @bindings[name] end end new_bindings end |