Class: DomTemplate

Inherits:
Object show all
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.

Instance Method Summary collapse

Methods included from CommentSearchers

#build_from_html, #find_by_comment

Constructor Details

#initialize(page, template_name) ⇒ DomTemplate

Returns a new instance of DomTemplate.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/volt/page/targets/dom_template.rb', line 11

def initialize(page, template_name)
  template = page.templates[template_name]

  if template
    html = template['html']
    @bindings = template['bindings']
  else
    html = "<div>-- &lt; missing template #{template_name.inspect.gsub('<', '&lt;').gsub('>', '&gt;')} &gt; --</div>"
    @bindings = {}
  end

  @nodes = build_from_html(html)

  track_binding_anchors
end

Instance Method Details

#make_newObject

Returns the dom nodes and bindings



28
29
30
31
32
33
34
# File 'lib/volt/page/targets/dom_template.rb', line 28

def make_new
  bindings = update_binding_anchors!

  new_nodes = `self.nodes.cloneNode(true)`

  return [new_nodes, bindings]
end

#track_binding_anchorsObject

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
      %x{
        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!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
# File 'lib/volt/page/targets/dom_template.rb', line 63

def update_binding_anchors!
  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

      %x{
        start_comment.textContent = " $" + new_name + " ";
        end_comment.textContent = " $/" + new_name + " ";
      }

      new_bindings[new_name] = @bindings[name]
    end
  end

  return new_bindings
end