Class: Dommy::NamedNodeMap

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/dommy/attr.rb

Overview

‘Element.attributes` returns this. Iterable, `.length`, `.item(i)`, `.getNamedItem(name)`, `.removeNamedItem(name)`, `.setNamedItem(attr)`, plus property-style access (`attributes.id`, `attributes.class`).

NamedNodeMap is live — it re-reads the element’s Nokogiri attributes on every access so DOM mutations are reflected.

Constant Summary collapse

JS_METHOD_NAMES =

Methods routed through js_call (keep in sync with its when-arms).

%w[item getNamedItem setNamedItem removeNamedItem].freeze

Instance Method Summary collapse

Constructor Details

#initialize(element) ⇒ NamedNodeMap

Returns a new instance of NamedNodeMap.



113
114
115
# File 'lib/dommy/attr.rb', line 113

def initialize(element)
  @element = element
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



203
204
205
206
# File 'lib/dommy/attr.rb', line 203

def method_missing(name, *args)
  attr = get_named_item(name)
  attr || super
end

Instance Method Details

#[](key) ⇒ Object

Property-style access — ‘el.attributes.id`, `el.attributes`.



161
162
163
164
165
166
167
168
# File 'lib/dommy/attr.rb', line 161

def [](key)
  case key
  when Integer
    item(key)
  else
    get_named_item(key)
  end
end

#__js_call__(method, args) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/dommy/attr.rb', line 190

def __js_call__(method, args)
  case method
  when "item"
    item(args[0])
  when "getNamedItem"
    get_named_item(args[0])
  when "setNamedItem"
    set_named_item(args[0])
  when "removeNamedItem"
    remove_named_item(args[0])
  end
end

#__js_get__(key) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/dommy/attr.rb', line 170

def __js_get__(key)
  case key
  when "length"
    length
  else
    # Numeric key = item(i); string key = named item
    if key.is_a?(Integer) || key.to_s.match?(/\A\d+\z/)
      item(key.to_i)
    else
      get_named_item(key)
    end
  end
end

#__js_method_names__Object



186
187
188
# File 'lib/dommy/attr.rb', line 186

def __js_method_names__
  JS_METHOD_NAMES
end

#each(&blk) ⇒ Object



154
155
156
157
158
# File 'lib/dommy/attr.rb', line 154

def each(&blk)
  @element.__dommy_backend_node__.attribute_nodes.each do |a|
    yield Attr.new(a.name, owner: @element)
  end
end

#get_named_item(name) ⇒ Object



128
129
130
131
132
133
# File 'lib/dommy/attr.rb', line 128

def get_named_item(name)
  key = name.to_s.downcase
  return nil unless @element.__dommy_backend_node__.key?(key)

  Attr.new(key, owner: @element)
end

#item(index) ⇒ Object



123
124
125
126
# File 'lib/dommy/attr.rb', line 123

def item(index)
  name = @element.__dommy_backend_node__.attribute_nodes[index.to_i]&.name
  name && Attr.new(name, owner: @element)
end

#lengthObject Also known as: size



117
118
119
# File 'lib/dommy/attr.rb', line 117

def length
  @element.__dommy_backend_node__.attribute_nodes.size
end

#remove_named_item(name) ⇒ Object



145
146
147
148
149
150
151
152
# File 'lib/dommy/attr.rb', line 145

def remove_named_item(name)
  key = name.to_s.downcase
  return nil unless @element.__dommy_backend_node__.key?(key)

  attr = Attr.new(key, owner: nil, value: @element.__dommy_backend_node__[key].to_s)
  @element.remove_attribute(key)
  attr
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


208
209
210
# File 'lib/dommy/attr.rb', line 208

def respond_to_missing?(name, include_private = false)
  @element.__dommy_backend_node__.key?(name.to_s.downcase) || super
end

#set_named_item(attr) ⇒ Object



135
136
137
138
139
140
141
142
143
# File 'lib/dommy/attr.rb', line 135

def set_named_item(attr)
  return nil unless attr.is_a?(Attr)

  key = attr.name
  val = attr.value
  attr.__internal_attach__(@element)
  @element.set_attribute(key, val)
  attr
end