class Volt::DomTemplate
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.
Public Class Methods
new(volt_app, template_name)
click to toggle source
# File lib/volt/page/targets/dom_template.rb, line 12 def initialize(volt_app, template_name) template = volt_app.templates[template_name] if template html = template['html'] @bindings = template['bindings'] else html = "<div>-- < missing view or tag at #{template_name.inspect}, make sure it's component is included in dependencies.rb > --</div>" @bindings = {} end @nodes = build_from_html(html) track_binding_anchors end
Public Instance Methods
make_new()
click to toggle source
Returns the dom nodes and bindings
# 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()
click to toggle source
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.
# 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)
click to toggle source
Takes the binding_anchors and updates them with new numbers (comments and id's) then returns the bindings updated to the new numbers.
# 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