Class: Dommy::Internal::TemplateContentRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/dommy/internal/template_content_registry.rb

Overview

Manages <template> element content fragments. When HTML contains <template>X</template>, the inner content X is detached and stored in a separate DocumentFragment, accessed via the element’s ‘content` property (per HTML spec).

Keeping these fragments off-document is what makes template content invisible to querySelector, getElementById, etc., on the main tree.

Instance Method Summary collapse

Constructor Details

#initialize(document) ⇒ TemplateContentRegistry

Returns a new instance of TemplateContentRegistry.



13
14
15
16
17
# File 'lib/dommy/internal/template_content_registry.rb', line 13

def initialize(document)
  @document = document
  # template_node.object_id → Nokogiri fragment
  @fragments = {}
end

Instance Method Details

#attach(template_element, html) ⇒ Object

Parse HTML into a fragment and attach it as the template’s content. Drops any pre-existing direct children of the template element.



21
22
23
24
25
26
# File 'lib/dommy/internal/template_content_registry.rb', line 21

def attach(template_element, html)
  template_element.__node__.children.each(&:unlink)
  fragment = @document.nokogiri_doc.fragment(html.to_s)
  @fragments[template_element.__node__.object_id] = fragment
  fragment
end

#fragment_for(template_element) ⇒ Object

Get the wrapped Fragment for a template element, seeding from the template’s current children if not previously migrated.



30
31
32
33
34
# File 'lib/dommy/internal/template_content_registry.rb', line 30

def fragment_for(template_element)
  fragment = @fragments[template_element.__node__.object_id]
  fragment ||= seed(template_element)
  @document.wrap_node(fragment)
end

#has_content?(nokogiri_node) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/dommy/internal/template_content_registry.rb', line 49

def has_content?(nokogiri_node)
  @fragments.key?(nokogiri_node.object_id)
end

#inner_html_of(template_element) ⇒ Object



42
43
44
45
46
47
# File 'lib/dommy/internal/template_content_registry.rb', line 42

def inner_html_of(template_element)
  fragment = @fragments[template_element.__node__.object_id]
  return "" unless fragment

  fragment.children.map(&:to_html).join
end

#migrate_descendants(root) ⇒ Object

Walk a Nokogiri subtree, finding <template> elements whose children are still direct (not yet migrated to a fragment), and migrate each one. Called after innerHTML / fragment-parsing to keep template content out of the main tree.



63
64
65
66
67
68
69
70
71
# File 'lib/dommy/internal/template_content_registry.rb', line 63

def migrate_descendants(root)
  targets = []
  targets << root if template_needing_migration?(root)
  root.traverse do |node|
    targets << node if template_needing_migration?(node)
  end

  targets.uniq.each { |t| migrate_one(t) }
end

#raw_fragment_for(nokogiri_node) ⇒ Object

Raw (Nokogiri) fragment lookup by Nokogiri node — used by internal traversal to skip template-content sub-trees.



38
39
40
# File 'lib/dommy/internal/template_content_registry.rb', line 38

def raw_fragment_for(nokogiri_node)
  @fragments[nokogiri_node.object_id]
end

#store(template_node, fragment) ⇒ Object

Direct register — called after manual fragment construction (e.g., when seeding from existing template children).



55
56
57
# File 'lib/dommy/internal/template_content_registry.rb', line 55

def store(template_node, fragment)
  @fragments[template_node.object_id] = fragment
end