Class: Dommy::HTMLCollection

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

Overview

‘HTMLCollection` — live, ordered set of Element nodes. Distinct from `NodeList` in two ways:

- Always element-only (Node types other than Element are skipped)
- Supports `namedItem(name)` lookup by `id` or `name` attribute

Live behavior: pass an evaluator block (called ‘&compute`) that returns the current element list on every access. Each query re-evaluates, so mutations to the parent tree are reflected immediately.

Intentionally NOT a subclass of Array; spec semantics demand ‘Array.isArray(html_collection) === false` in real browsers, and mirroring that here helps tests written against MDN behavior.

Direct Known Subclasses

HTMLOptionsCollection

Instance Method Summary collapse

Constructor Details

#initialize(&compute) ⇒ HTMLCollection

Returns a new instance of HTMLCollection.



21
22
23
# File 'lib/dommy/html_collection.rb', line 21

def initialize(&compute)
  @compute = compute
end

Instance Method Details

#[](key) ⇒ Object

‘[]` supports both integer index (`coll`, `coll`) and string name (`coll`). Negative indices are interpreted Ruby-style (offset from the end), even though the spec’s ‘item(i)` is positive-only.



59
60
61
62
63
64
65
66
67
68
# File 'lib/dommy/html_collection.rb', line 59

def [](key)
  case key
  when Integer
    to_a[key]
  when /\A-?\d+\z/
    to_a[key.to_i]
  else
    named_item(key)
  end
end

#__js_call__(method, args) ⇒ Object



102
103
104
105
106
107
108
109
# File 'lib/dommy/html_collection.rb', line 102

def __js_call__(method, args)
  case method
  when "item"
    item(args[0])
  when "namedItem"
    named_item(args[0])
  end
end

#__js_get__(key) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/dommy/html_collection.rb', line 86

def __js_get__(key)
  case key
  when "length"
    length
  when Integer
    item(key)
  else
    s = key.to_s
    if s.match?(/\A\d+\z/)
      item(s.to_i)
    else
      named_item(s) || (s == "length" ? length : nil)
    end
  end
end

#each(&blk) ⇒ Object



78
79
80
# File 'lib/dommy/html_collection.rb', line 78

def each(&blk)
  to_a.each(&blk)
end

#empty?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/dommy/html_collection.rb', line 31

def empty?
  to_a.empty?
end

#first(n = nil) ⇒ Object



70
71
72
# File 'lib/dommy/html_collection.rb', line 70

def first(n = nil)
  n.nil? ? to_a.first : to_a.first(n)
end

#item(index) ⇒ Object



35
36
37
38
39
40
# File 'lib/dommy/html_collection.rb', line 35

def item(index)
  i = index.to_i
  return nil if i < 0

  to_a[i]
end

#last(n = nil) ⇒ Object



74
75
76
# File 'lib/dommy/html_collection.rb', line 74

def last(n = nil)
  n.nil? ? to_a.last : to_a.last(n)
end

#lengthObject Also known as: size



25
26
27
# File 'lib/dommy/html_collection.rb', line 25

def length
  to_a.length
end

#named_item(name) ⇒ Object

‘namedItem(name)` returns the first element whose `id` or `name` attribute equals `name`. Returns nil if no match.



44
45
46
47
48
49
50
51
52
53
# File 'lib/dommy/html_collection.rb', line 44

def named_item(name)
  key = name.to_s
  return nil if key.empty?

  to_a.find do |el|
    next false unless el.respond_to?(:__node__)

    el.__node__["id"].to_s == key || el.__node__["name"].to_s == key
  end
end

#to_aObject



82
83
84
# File 'lib/dommy/html_collection.rb', line 82

def to_a
  @compute.call
end