Module: Dommy::Node
- Included in:
- Attr, CharacterDataNode, Document, DocumentType, Element, Fragment, ShadowRoot
- Defined in:
- lib/dommy/node.rb
Overview
Node — common base mixin. All node-like classes (Element,
TextNode, CommentNode, CharacterDataNode, Document, Fragment,
DocumentType, ShadowRoot) include this so el.is_a?(Dommy::Node)
works.
Real classes already define nodeType / nodeName / nodeValue
/ parentNode / isConnected / cloneNode independently; this
module is primarily an identity marker. Adding new shared methods
later is straightforward.
Constant Summary collapse
- ELEMENT_NODE =
Standardized nodeType constants — duplicated from Element so callers can refer to
Dommy::Node::ELEMENT_NODEwithout depending on a specific subclass. 1- ATTRIBUTE_NODE =
2- TEXT_NODE =
3- CDATA_SECTION_NODE =
4- PROCESSING_INSTRUCTION_NODE =
7- COMMENT_NODE =
8- DOCUMENT_NODE =
9- DOCUMENT_TYPE_NODE =
10- DOCUMENT_FRAGMENT_NODE =
11- DOCUMENT_POSITION_DISCONNECTED =
0x01- DOCUMENT_POSITION_PRECEDING =
0x02- DOCUMENT_POSITION_FOLLOWING =
0x04- DOCUMENT_POSITION_CONTAINS =
0x08- DOCUMENT_POSITION_CONTAINED_BY =
0x10- DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC =
0x20- HTML_NAMESPACE =
"http://www.w3.org/1999/xhtml"- XML_NAMESPACE =
"http://www.w3.org/XML/1998/namespace"- XMLNS_NAMESPACE =
"http://www.w3.org/2000/xmlns/"
Instance Method Summary collapse
-
#compare_document_position(other) ⇒ Object
Node.compareDocumentPosition(other) — a bitmask describing where
othersits relative to this node: 0 for the same node, CONTAINS/CONTAINED_BY for ancestor/descendant, PRECEDING/FOLLOWING for tree order, or DISCONNECTED (with a stable IMPLEMENTATION_SPECIFIC|PRECEDING) for unrelated nodes. -
#get_root_node(_options = nil) ⇒ Object
Node.getRootNode — the topmost ancestor of this node (the document, a ShadowRoot, a detached subtree root, or the node itself).
-
#is_default_namespace(namespace) ⇒ Object
Node.isDefaultNamespace(namespace) — true if
namespace(null/"" → null) is the default namespace in this node's scope. -
#is_equal_node(other) ⇒ Object
WHATWG Node.isEqualNode — deep structural equality (type-specific data plus equal, in-order, recursively-equal children).
-
#is_same_node(other) ⇒ Object
Node.isSameNode — strict reference identity (deprecated alias for
===). -
#lookup_namespace_uri(prefix) ⇒ Object
Node.lookupNamespaceURI(prefix) — WHATWG "locate a namespace": walk from the nearest enclosing element up its ancestors, matching the element's own namespace (by prefix) and its xmlns declarations.
-
#lookup_prefix(namespace) ⇒ Object
Node.lookupPrefix(namespace) — WHATWG "locate a prefix": a prefix bound to
namespacein this node's scope, or null.
Instance Method Details
#compare_document_position(other) ⇒ Object
Node.compareDocumentPosition(other) — a bitmask describing where other
sits relative to this node: 0 for the same node, CONTAINS/CONTAINED_BY for
ancestor/descendant, PRECEDING/FOLLOWING for tree order, or DISCONNECTED
(with a stable IMPLEMENTATION_SPECIFIC|PRECEDING) for unrelated nodes.
Generic over any node with a backing Nokogiri node.
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'lib/dommy/node.rb', line 316 def compare_document_position(other) return 0 if equal?(other) self_node = compare_backend_node(self) other_node = compare_backend_node(other) unless self_node && other_node return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING end self_ancestors = node_ancestor_chain(self_node) other_ancestors = node_ancestor_chain(other_node) common = self_ancestors.find { |a| other_ancestors.include?(a) } unless common return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING end return DOCUMENT_POSITION_CONTAINED_BY | DOCUMENT_POSITION_FOLLOWING if common == self_node return DOCUMENT_POSITION_CONTAINS | DOCUMENT_POSITION_PRECEDING if common == other_node self_branch = node_branch_under(common, self_ancestors) other_branch = node_branch_under(common, other_ancestors) common.children.each do |child| return DOCUMENT_POSITION_FOLLOWING if child == self_branch return DOCUMENT_POSITION_PRECEDING if child == other_branch end DOCUMENT_POSITION_DISCONNECTED end |
#get_root_node(_options = nil) ⇒ Object
Node.getRootNode — the topmost ancestor of this node (the document, a ShadowRoot, a detached subtree root, or the node itself). Generic default for any node backed by a Nokogiri node; classes with special roots (Element's shadow handling) override it.
348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/dommy/node.rb', line 348 def get_root_node( = nil) return self unless respond_to?(:__dommy_backend_node__) && instance_variable_defined?(:@document) node = __dommy_backend_node__ node = node.parent while node.respond_to?(:parent) && node.parent # The topmost node of an attached subtree is the Nokogiri document, which # has no element wrapper — map it to the Document. A detached node's root is # itself. return @document if @document && node.equal?(@document.backend_doc) (@document && @document.wrap_node(node)) || self end |
#is_default_namespace(namespace) ⇒ Object
Node.isDefaultNamespace(namespace) — true if namespace (null/"" → null) is
the default namespace in this node's scope.
420 421 422 423 424 |
# File 'lib/dommy/node.rb', line 420 def is_default_namespace(namespace) ns = namespace.nil? ? nil : namespace.to_s ns = nil if ns == "" lookup_namespace_uri(nil) == ns end |
#is_equal_node(other) ⇒ Object
WHATWG Node.isEqualNode — deep structural equality (type-specific data plus equal, in-order, recursively-equal children). Available on every node class that includes Node; the bridge routes "isEqualNode" here.
302 303 304 |
# File 'lib/dommy/node.rb', line 302 def is_equal_node(other) Internal::NodeEquality.equal?(self, other) end |
#is_same_node(other) ⇒ Object
Node.isSameNode — strict reference identity (deprecated alias for ===).
307 308 309 |
# File 'lib/dommy/node.rb', line 307 def is_same_node(other) equal?(other) end |
#lookup_namespace_uri(prefix) ⇒ Object
Node.lookupNamespaceURI(prefix) — WHATWG "locate a namespace": walk from the
nearest enclosing element up its ancestors, matching the element's own
namespace (by prefix) and its xmlns declarations. xml / xmlns are
implicitly bound. Non-element scopes (fragment, doctype, disconnected attr)
locate nothing.
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
# File 'lib/dommy/node.rb', line 370 def lookup_namespace_uri(prefix) wanted = namespace_prefix_arg(prefix) el = starting_namespace_element return nil unless el return XML_NAMESPACE if wanted == "xml" return XMLNS_NAMESPACE if wanted == "xmlns" each_namespace_ancestor(el) do |node| ns = node.namespace_uri return ns if ns && !ns.to_s.empty? && wrapper_prefix(node) == wanted node.attributes.each do |attr| next unless attr.namespace_uri == XMLNS_NAMESPACE ap = normalize_ns_prefix(attr.__js_get__("prefix")) value = attr.value.to_s if ap == "xmlns" && attr.local_name == wanted return value.empty? ? nil : value elsif ap.nil? && attr.local_name == "xmlns" && wanted.nil? return value.empty? ? nil : value end end end nil end |
#lookup_prefix(namespace) ⇒ Object
Node.lookupPrefix(namespace) — WHATWG "locate a prefix": a prefix bound to
namespace in this node's scope, or null.
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/dommy/node.rb', line 398 def lookup_prefix(namespace) ns = namespace.to_s return nil if ns.empty? el = starting_namespace_element return nil unless el each_namespace_ancestor(el) do |node| return wrapper_prefix(node) if node.namespace_uri == ns && wrapper_prefix(node) node.attributes.each do |attr| next unless attr.namespace_uri == XMLNS_NAMESPACE next unless normalize_ns_prefix(attr.__js_get__("prefix")) == "xmlns" return attr.local_name if attr.value.to_s == ns end end nil end |