Module: Dommy::Backend::Nokolexbor

Defined in:
lib/dommy/backend/nokolexbor_adapter.rb

Overview

Nokolexbor (Lexbor-based) backend. 3-7× faster CSS selectors, 6× faster HTML5 parsing. HTML-only — XML namespaces are not tracked, so SVG detection falls back to ancestor walking.

Defined Under Namespace

Classes: SvgNamespace

Constant Summary collapse

Element =

Class references for ‘is_a?` / type-checking.

::Nokolexbor::Element
Document =
::Nokolexbor::Document
Text =
::Nokolexbor::Text
Comment =
::Nokolexbor::Comment
DocumentFragment =
::Nokolexbor::DocumentFragment
Node =
::Nokolexbor::Node
SVG_NAMESPACE =
SvgNamespace.new.freeze

Class Method Summary collapse

Class Method Details

.add_namespace_definition(_node, _prefix, _href) ⇒ Object



62
63
64
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 62

def add_namespace_definition(_node, _prefix, _href)
  # No-op: Nokolexbor doesn't support XML namespaces.
end

.attribute_nodes(node) ⇒ Object



99
100
101
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 99

def attribute_nodes(node)
  node.attribute_nodes
end

.attribute_ns_info(attr_node) ⇒ Object



89
90
91
92
93
94
95
96
97
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 89

def attribute_ns_info(attr_node)
  {
    namespace_uri: nil,
    prefix: nil,
    local_name: attr_node.name,
    qualified_name: attr_node.name,
    value: attr_node.value,
  }
end

.create_comment(content, doc) ⇒ Object



48
49
50
51
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 48

def create_comment(content, doc)
  # Nokolexbor's argument order is (content, doc).
  ::Nokolexbor::Comment.new(content, doc)
end

.create_element(name, doc) ⇒ Object



40
41
42
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 40

def create_element(name, doc)
  ::Nokolexbor::Node.new(name, doc)
end

.create_text(content, doc) ⇒ Object



44
45
46
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 44

def create_text(content, doc)
  ::Nokolexbor::Text.new(content, doc)
end

.fragment(html, owner_doc:) ⇒ Object



36
37
38
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 36

def fragment(html, owner_doc:)
  ::Nokolexbor::DocumentFragment.parse(html.to_s)
end

.get_attribute_ns(node, _namespace, local_name) ⇒ Object

—– Namespaced attributes (degraded) —– Nokolexbor has no namespace model, so *AttributeNS collapses to the qualified name in the null namespace. Fine for HTML (all attributes are null-namespace); foreign-content (SVG/MathML) fidelity is lost.



71
72
73
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 71

def get_attribute_ns(node, _namespace, local_name)
  node[local_name.to_s]
end

.has_attribute_ns?(node, _namespace, local_name) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 75

def has_attribute_ns?(node, _namespace, local_name)
  node.key?(local_name.to_s)
end

.in_svg_subtree?(node) ⇒ Boolean

Internal helper — visible to allow testing.

Returns:

  • (Boolean)


104
105
106
107
108
109
110
111
112
113
114
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 104

def in_svg_subtree?(node)
  return true if node.name.to_s.downcase == "svg"

  current = node.parent
  while current
    return true if current.respond_to?(:name) && current.name.to_s.downcase == "svg"
    current = current.respond_to?(:parent) ? current.parent : nil
  end

  false
end

.namespace_of(node) ⇒ Object

Nokolexbor doesn’t track XML namespaces. We synthesize one for SVG by walking ancestors — necessary so ‘element_class_for` routes SVG tags to their specialized classes.



56
57
58
59
60
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 56

def namespace_of(node)
  return nil unless node.respond_to?(:name)

  in_svg_subtree?(node) ? SVG_NAMESPACE : nil
end

.parse(html) ⇒ Object



32
33
34
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 32

def parse(html)
  ::Nokolexbor.parse(html.to_s)
end

.remove_attribute_ns(node, _namespace, local_name) ⇒ Object



84
85
86
87
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 84

def remove_attribute_ns(node, _namespace, local_name)
  node.remove_attribute(local_name.to_s) if node.key?(local_name.to_s)
  nil
end

.set_attribute_ns(node, _namespace, _prefix, _local_name, qualified_name, value) ⇒ Object



79
80
81
82
# File 'lib/dommy/backend/nokolexbor_adapter.rb', line 79

def set_attribute_ns(node, _namespace, _prefix, _local_name, qualified_name, value)
  node[qualified_name] = value.to_s
  value.to_s
end