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.

Instance Method Summary collapse

Constructor Details

#initialize(element) ⇒ NamedNodeMap

Returns a new instance of NamedNodeMap.



107
108
109
# File 'lib/dommy/attr.rb', line 107

def initialize(element)
  @element = element
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



191
192
193
194
# File 'lib/dommy/attr.rb', line 191

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`.



155
156
157
158
159
160
161
162
# File 'lib/dommy/attr.rb', line 155

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

#__js_call__(method, args) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/dommy/attr.rb', line 178

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



164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/dommy/attr.rb', line 164

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

#each(&blk) ⇒ Object



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

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

#get_named_item(name) ⇒ Object



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

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

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

#item(index) ⇒ Object



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

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

#lengthObject Also known as: size



111
112
113
# File 'lib/dommy/attr.rb', line 111

def length
  @element.__node__.attribute_nodes.size
end

#remove_named_item(name) ⇒ Object



139
140
141
142
143
144
145
146
# File 'lib/dommy/attr.rb', line 139

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

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

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

Returns:

  • (Boolean)


196
197
198
# File 'lib/dommy/attr.rb', line 196

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

#set_named_item(attr) ⇒ Object



129
130
131
132
133
134
135
136
137
# File 'lib/dommy/attr.rb', line 129

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

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