Class: Dommy::Attr
- Inherits:
-
Object
- Object
- Dommy::Attr
- Includes:
- Bridge::Methods, EventTarget, Node
- Defined in:
- lib/dommy/attr.rb
Overview
Attr — wraps an HTML attribute as a Node-like object. In real
DOM each attribute on an element is an Attr; el.getAttributeNode
returns the instance, attr.value = "x" mutates the element's
attribute, attr.ownerElement points back to the element.
We represent two states:
- "owned" — the Attr is attached to an Element. value reads/writes
go through the element's Makiri attribute slot.
- "detached" — created via `document.createAttribute(name)` but
not yet attached. Value is stored locally; `setAttributeNode`
transfers it to an element.
Constant Summary
Constants included from Node
Node::ATTRIBUTE_NODE, Node::CDATA_SECTION_NODE, Node::COMMENT_NODE, Node::DOCUMENT_FRAGMENT_NODE, Node::DOCUMENT_NODE, Node::DOCUMENT_POSITION_CONTAINED_BY, Node::DOCUMENT_POSITION_CONTAINS, Node::DOCUMENT_POSITION_DISCONNECTED, Node::DOCUMENT_POSITION_FOLLOWING, Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, Node::DOCUMENT_POSITION_PRECEDING, Node::DOCUMENT_TYPE_NODE, Node::ELEMENT_NODE, Node::HTML_NAMESPACE, Node::PROCESSING_INSTRUCTION_NODE, Node::TEXT_NODE, Node::XMLNS_NAMESPACE, Node::XML_NAMESPACE
Instance Attribute Summary collapse
-
#local_name ⇒ Object
readonly
Returns the value of attribute local_name.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#namespace_uri ⇒ Object
readonly
Returns the value of attribute namespace_uri.
-
#prefix ⇒ Object
readonly
Returns the value of attribute prefix.
Instance Method Summary collapse
-
#__internal_attach__(element) ⇒ Object
Internal: called by Element when the attr is being transferred to (or detached from) an Element.
- #__internal_detach__ ⇒ Object
- #__internal_event_parent__ ⇒ Object
- #__js_call__(method, args) ⇒ Object
- #__js_get__(key) ⇒ Object
- #__js_set__(key, val) ⇒ Object
-
#base_uri ⇒ Object
Node.baseURI — the node document's base URL.
-
#initialize(name, owner: nil, value: "", namespace_uri: nil, prefix: nil, local_name: nil, document: nil) ⇒ Attr
constructor
A new instance of Attr.
-
#owner_document ⇒ Object
Node.ownerDocument — the owner element's current document when attached (so it follows the element across adoptNode), else the creation document.
-
#owner_element ⇒ Object
The Element this attr is on, or nil if detached.
- #value ⇒ Object
- #value=(new_value) ⇒ Object
Methods included from Bridge::Methods
Methods included from EventTarget
#__dommy_dump_event_failure__, #__internal_deliver_event__, #__internal_process_event_handler_return__, #add_event_listener, capture_flag, #deliver_at, #dispatch_event, #event_name_from_on, #invoke_listener_isolated, js_truthy?, #on_handler, #remove_event_listener, #set_on_handler
Methods included from Node
#compare_document_position, #get_root_node, #is_default_namespace, #is_equal_node, #is_same_node, #lookup_namespace_uri, #lookup_prefix
Constructor Details
#initialize(name, owner: nil, value: "", namespace_uri: nil, prefix: nil, local_name: nil, document: nil) ⇒ Attr
Returns a new instance of Attr.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/dommy/attr.rb', line 25 def initialize(name, owner: nil, value: "", namespace_uri: nil, prefix: nil, local_name: nil, document: nil) qname = name.to_s @owner = owner # The node document (for baseURI/ownerDocument when detached from an # element). Owned attrs derive it from their owner instead. @document = document @detached_value = value.to_s if namespace_uri && !namespace_uri.to_s.empty? # Namespaced attributes preserve case and carry prefix / localName. @name = qname @namespace_uri = namespace_uri.to_s @prefix = prefix @local_name = (local_name || qname.split(":", 2).last).to_s else # Null-namespace attribute: use the qualified name verbatim. The casing is # already decided by the caller — the backend stores `setAttribute` names # lower-cased (HTML) but preserves `setAttributeNS("", "FOO")` as "FOO", # and `createAttribute` lower-cases up front — so re-downcasing here would # wrongly fold a case-preserved null-namespace attribute. @name = qname @namespace_uri = nil @prefix = nil @local_name = local_name ? local_name.to_s : @name end end |
Instance Attribute Details
#local_name ⇒ Object (readonly)
Returns the value of attribute local_name.
19 20 21 |
# File 'lib/dommy/attr.rb', line 19 def local_name @local_name end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
19 20 21 |
# File 'lib/dommy/attr.rb', line 19 def name @name end |
#namespace_uri ⇒ Object (readonly)
Returns the value of attribute namespace_uri.
19 20 21 |
# File 'lib/dommy/attr.rb', line 19 def namespace_uri @namespace_uri end |
#prefix ⇒ Object (readonly)
Returns the value of attribute prefix.
19 20 21 |
# File 'lib/dommy/attr.rb', line 19 def prefix @prefix end |
Instance Method Details
#__internal_attach__(element) ⇒ Object
Internal: called by Element when the attr is being transferred to (or detached from) an Element.
184 185 186 187 188 |
# File 'lib/dommy/attr.rb', line 184 def __internal_attach__(element) @owner = element @detached_value = "" nil end |
#__internal_detach__ ⇒ Object
190 191 192 193 194 195 |
# File 'lib/dommy/attr.rb', line 190 def __internal_detach__ cached = value @owner = nil @detached_value = cached nil end |
#__internal_event_parent__ ⇒ Object
21 22 23 |
# File 'lib/dommy/attr.rb', line 21 def __internal_event_parent__ nil end |
#__js_call__(method, args) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/dommy/attr.rb', line 147 def __js_call__(method, args) case method when "lookupNamespaceURI" lookup_namespace_uri(args[0]) when "lookupPrefix" lookup_prefix(args[0]) when "isDefaultNamespace" is_default_namespace(args[0]) when "cloneNode" Attr.new(@name, owner: nil, value: value, namespace_uri: @namespace_uri, prefix: @prefix, local_name: @local_name, document: @document || (@owner.respond_to?(:document) ? @owner.document : nil)) when "isSameNode" is_same_node(args[0]) when "getRootNode" get_root_node(args[0]) when "compareDocumentPosition" compare_document_position(args[0]) when "appendChild", "insertBefore" raise DOMException::HierarchyRequestError, "an Attr may not have children" when "removeChild", "replaceChild" raise DOMException::NotFoundError, "the node to be removed is not a child of this node" when "hasChildNodes" false when "normalize" nil when "addEventListener" add_event_listener(args[0], args[1], args[2]) when "removeEventListener" remove_event_listener(args[0], args[1], args[2]) when "dispatchEvent" dispatch_event(args[0]) end end |
#__js_get__(key) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/dommy/attr.rb', line 96 def __js_get__(key) case key when "name" @name when "value" value when "nodeName" @name when "nodeValue" value when "textContent" # Node.textContent for an Attr returns its value (WHATWG DOM). value when "ownerElement" @owner when "ownerDocument" owner_document when "localName" @local_name when "namespaceURI" @namespace_uri when "prefix" @prefix when "nodeType" 2 when "baseURI" base_uri when "specified" # Legacy/useless attribute — always true (WHATWG DOM). true else Bridge::ABSENT end end |
#__js_set__(key, val) ⇒ Object
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/dommy/attr.rb', line 131 def __js_set__(key, val) case key when "value", "nodeValue", "textContent" self.value = val else return Bridge::UNHANDLED end nil end |
#base_uri ⇒ Object
Node.baseURI — the node document's base URL. Derived from the owner element when attached, else the document the attr was created in.
58 59 60 61 62 |
# File 'lib/dommy/attr.rb', line 58 def base_uri return @owner.base_uri if @owner.respond_to?(:base_uri) @document&.base_uri end |
#owner_document ⇒ Object
Node.ownerDocument — the owner element's current document when attached (so it follows the element across adoptNode), else the creation document.
66 67 68 69 70 |
# File 'lib/dommy/attr.rb', line 66 def owner_document return @owner.document if @owner.respond_to?(:document) @document end |
#owner_element ⇒ Object
The Element this attr is on, or nil if detached.
52 53 54 |
# File 'lib/dommy/attr.rb', line 52 def owner_element @owner end |
#value ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/dommy/attr.rb', line 72 def value if @owner if @namespace_uri Backend.get_attribute_ns(@owner.__dommy_backend_node__, @namespace_uri, @local_name).to_s else @owner.__dommy_backend_node__[@name].to_s end else @detached_value end end |
#value=(new_value) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/dommy/attr.rb', line 84 def value=(new_value) if @owner if @namespace_uri @owner.set_attribute_ns(@namespace_uri, @name, new_value.to_s) else @owner.set_attribute(@name, new_value.to_s) end else @detached_value = new_value.to_s end end |