Class: Dommy::Document
Overview
‘document` — the entry point for DOM construction and querying. Wrapper caching keeps DOM identity stable across repeated traversals (`body.children.parentElement`).
Constant Summary
collapse
- NAME_RE =
Spec-permitted name pattern (XML “Name” production restricted to ASCII for practicality). Used by ‘createElement` and `createAttribute` to validate the argument.
/\A[A-Za-z_][\w\-.:]*\z/.freeze
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::PROCESSING_INSTRUCTION_NODE, Node::TEXT_NODE
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#[](key) ⇒ Object
-
#[]=(key, value) ⇒ Object
-
#__event_parent__ ⇒ Object
-
#__js_call__(method, args) ⇒ Object
-
#__js_get__(key) ⇒ Object
-
#__js_set__(key, value) ⇒ Object
-
#__notify_attribute_changed__(element, name, old_value, new_value) ⇒ Object
-
#__notify_connected__(element) ⇒ Object
Lifecycle callback dispatchers.
-
#__notify_connected_subtree__(nk) ⇒ Object
-
#__notify_disconnected__(element) ⇒ Object
-
#__notify_disconnected_subtree__(nk) ⇒ Object
-
#__register_shadow_fragment__(fragment_node, shadow_root) ⇒ Object
ShadowRoot identity registry: map a Nokogiri DocumentFragment (the shadow tree’s backing node) to the wrapping ShadowRoot so slot assignment and event composition can walk from any inner node back to its shadow boundary.
-
#__reset_wrapper__(nokogiri_node) ⇒ Object
Clear the cached wrapper so the next ‘wrap_node` creates a new one.
-
#__set_active_element__(el) ⇒ Object
-
#__shadow_root_containing__(node) ⇒ Object
-
#__shadow_root_for_fragment__(fragment_node) ⇒ Object
-
#active_element ⇒ Object
Currently-focused element (or body if none).
-
#adopt_node(node) ⇒ Object
Move a node from another document into this one.
-
#attach_template_content(template_element, html) ⇒ Object
—– template content helpers (called from Element) —–.
-
#base_uri ⇒ Object
‘document.baseURI` — resolves the first `<base href>` (if any) relative to the document URL; otherwise just the document URL.
-
#child_element_count ⇒ Object
-
#children ⇒ Object
ParentNode mixin (operates on the document’s element children — in practice the ‘<html>` root).
-
#close ⇒ Object
-
#cookie ⇒ Object
-
#cookie=(value) ⇒ Object
-
#create_attribute(name) ⇒ Object
-
#create_attribute_ns(namespace_uri, qualified_name) ⇒ Object
-
#create_comment(text) ⇒ Object
-
#create_document_fragment ⇒ Object
-
#create_element(name) ⇒ Object
Delegate factory methods to NodeWrapperCache.
-
#create_element_ns(namespace_uri, qualified_name) ⇒ Object
-
#create_event(type_name) ⇒ Object
Legacy ‘document.createEvent(“EventName”)` factory.
-
#create_node_iterator(root, what_to_show = NodeFilter::SHOW_ALL, filter = nil) ⇒ Object
‘document.createNodeIterator(root, whatToShow?, filter?)` — flat depth-first iteration.
-
#create_text_node(text) ⇒ Object
-
#create_tree_walker(root, what_to_show = NodeFilter::SHOW_ALL, filter = nil) ⇒ Object
‘document.createTreeWalker(root, whatToShow?, filter?)` — stateful tree traversal with sibling/parent navigation.
-
#doctype ⇒ Object
Minimal DocumentType — represents the ‘<!doctype html>` line.
-
#document_element ⇒ Object
-
#domain ⇒ Object
‘document.domain` — host portion of the URL.
-
#element_from_point(_x, _y) ⇒ Object
-
#first_element_child ⇒ Object
-
#forms ⇒ Object
-
#get_element_by_id(id) ⇒ Object
-
#get_elements_by_class_name(name) ⇒ Object
-
#get_elements_by_name(name) ⇒ Object
-
#get_elements_by_tag_name(name) ⇒ Object
-
#get_selection ⇒ Object
-
#has_focus? ⇒ Boolean
(also: #has_focus)
Stubs for layout / focus / selection / execCommand APIs that don’t apply to a layout-less DOM.
-
#has_template_content?(nokogiri_node) ⇒ Boolean
-
#head ⇒ Object
-
#images ⇒ Object
-
#import_node(node, deep = false) ⇒ Object
Copy a node from another document into this one.
-
#initialize(host = nil, nokogiri_doc: nil, default_view: nil) ⇒ Document
constructor
A new instance of Document.
-
#last_element_child ⇒ Object
-
#links ⇒ Object
Live HTMLCollection helpers — each call re-queries the document so post-mutation reads reflect the current state.
-
#migrate_template_descendants(root) ⇒ Object
-
#notify_attribute_mutation(target_node:, attribute_name:, old_value:) ⇒ Object
-
#notify_character_data_mutation(target_node:, old_value:) ⇒ Object
-
#notify_child_list_mutation(target_node:, added_nodes:, removed_nodes:, previous_sibling: nil, next_sibling: nil) ⇒ Object
-
#open ⇒ Object
No-ops — real browsers reset the DOM on ‘open()` and flush pending writes on `close()`.
-
#query_command_supported(_command) ⇒ Object
-
#query_selector(selector) ⇒ Object
-
#query_selector_all(selector) ⇒ Object
-
#referrer ⇒ Object
‘document.referrer` — Dommy never has a referring page, so this is always empty.
-
#register_observer(observer) ⇒ Object
-
#scripts ⇒ Object
-
#template_content_fragment(template_element) ⇒ Object
-
#template_content_inner_html(template_element) ⇒ Object
-
#title ⇒ Object
—– Public Ruby API (snake_case) —–.
-
#title=(value) ⇒ Object
-
#unregister_observer(observer) ⇒ Object
-
#url ⇒ Object
(also: #document_uri)
‘document.URL` / `documentURI` — both return location.href in real browsers (legacy aliases of the same field).
-
#wrap_node(node) ⇒ Object
Delegate node wrapping to NodeWrapperCache.
-
#write(*args) ⇒ Object
‘document.write(html)` — legacy API.
#__deliver_event__, #add_event_listener, #dispatch_event, #invoke_listener, #remove_event_listener
Constructor Details
#initialize(host = nil, nokogiri_doc: nil, default_view: nil) ⇒ Document
Returns a new instance of Document.
Instance Attribute Details
#body ⇒ Object
Returns the value of attribute body.
47
48
49
|
# File 'lib/dommy/document.rb', line 47
def body
@body
end
|
#default_view ⇒ Object
Returns the value of attribute default_view.
48
49
50
|
# File 'lib/dommy/document.rb', line 48
def default_view
@default_view
end
|
#nokogiri_doc ⇒ Object
Returns the value of attribute nokogiri_doc.
47
48
49
|
# File 'lib/dommy/document.rb', line 47
def nokogiri_doc
@nokogiri_doc
end
|
Instance Method Details
#[](key) ⇒ Object
330
331
332
|
# File 'lib/dommy/document.rb', line 330
def [](key)
__js_get__(key.to_s)
end
|
#[]=(key, value) ⇒ Object
334
335
336
|
# File 'lib/dommy/document.rb', line 334
def []=(key, value)
__js_set__(key.to_s, value)
end
|
#__event_parent__ ⇒ Object
477
478
479
|
# File 'lib/dommy/document.rb', line 477
def __event_parent__
@default_view
end
|
#__js_call__(method, args) ⇒ Object
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
|
# File 'lib/dommy/document.rb', line 414
def __js_call__(method, args)
case method
when "createElement"
create_element(args[0])
when "createElementNS"
create_element_ns(args[0], args[1])
when "createTextNode"
create_text_node(args[0])
when "createComment"
(args[0])
when "createDocumentFragment"
create_document_fragment
when "querySelector"
query_selector(args[0])
when "querySelectorAll"
query_selector_all(args[0])
when "getElementById"
get_element_by_id(args[0])
when "getElementsByClassName"
get_elements_by_class_name(args[0])
when "getElementsByTagName"
get_elements_by_tag_name(args[0])
when "getElementsByName"
get_elements_by_name(args[0])
when "createAttribute"
create_attribute(args[0])
when "createAttributeNS"
create_attribute_ns(args[0], args[1])
when "createTreeWalker"
create_tree_walker(args[0], args[1] || NodeFilter::SHOW_ALL, args[2])
when "createNodeIterator"
create_node_iterator(args[0], args[1] || NodeFilter::SHOW_ALL, args[2])
when "createEvent"
create_event(args[0])
when "importNode"
import_node(args[0], args[1])
when "adoptNode"
adopt_node(args[0])
when "hasFocus"
has_focus?
when "getSelection"
get_selection
when "elementFromPoint"
element_from_point(args[0], args[1])
when "queryCommandSupported"
query_command_supported(args[0])
when "addEventListener"
add_event_listener(args[0], args[1], args[2])
when "removeEventListener"
remove_event_listener(args[0], args[1])
when "dispatchEvent"
dispatch_event(args[0])
when "write"
write(*args)
when "open"
open
when "close"
close
else
nil
end
end
|
#__js_get__(key) ⇒ Object
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
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
395
396
397
398
399
400
401
|
# File 'lib/dommy/document.rb', line 352
def __js_get__(key)
case key
when "body"
@body
when "head"
head
when "doctype"
doctype
when "defaultView"
@default_view
when "documentElement"
wrap_node(@nokogiri_doc.at_css("html"))
when "title"
read_title
when "cookie"
cookie
when "nodeType"
9
when "activeElement"
active_element
when "URL", "documentURI"
url
when "baseURI"
base_uri
when "domain"
domain
when "referrer"
referrer
when "links"
links
when "forms"
forms
when "scripts"
scripts
when "images"
images
when "children"
children
when "childElementCount"
child_element_count
when "firstElementChild"
first_element_child
when "lastElementChild"
last_element_child
when "nodeName"
"#document"
else
nil
end
end
|
#__js_set__(key, value) ⇒ Object
403
404
405
406
407
408
409
410
411
412
|
# File 'lib/dommy/document.rb', line 403
def __js_set__(key, value)
case key
when "title"
write_title(value.to_s)
when "cookie"
self.cookie = value.to_s
end
nil
end
|
#__notify_attribute_changed__(element, name, old_value, new_value) ⇒ Object
532
533
534
|
# File 'lib/dommy/document.rb', line 532
def __notify_attribute_changed__(element, name, old_value, new_value)
@mutation_coordinator.notify_attribute_changed(element, name, old_value, new_value)
end
|
#__notify_connected__(element) ⇒ Object
Lifecycle callback dispatchers. Errors raised inside user callbacks are swallowed so a single buggy custom element can’t break the whole mutation pipeline. Delegate to MutationCoordinator
516
517
518
|
# File 'lib/dommy/document.rb', line 516
def __notify_connected__(element)
@mutation_coordinator.notify_connected(element)
end
|
#__notify_connected_subtree__(nk) ⇒ Object
524
525
526
|
# File 'lib/dommy/document.rb', line 524
def __notify_connected_subtree__(nk)
@mutation_coordinator.notify_connected_subtree(nk)
end
|
#__notify_disconnected__(element) ⇒ Object
520
521
522
|
# File 'lib/dommy/document.rb', line 520
def __notify_disconnected__(element)
@mutation_coordinator.notify_disconnected(element)
end
|
#__notify_disconnected_subtree__(nk) ⇒ Object
528
529
530
|
# File 'lib/dommy/document.rb', line 528
def __notify_disconnected_subtree__(nk)
@mutation_coordinator.notify_disconnected_subtree(nk)
end
|
#__register_shadow_fragment__(fragment_node, shadow_root) ⇒ Object
ShadowRoot identity registry: map a Nokogiri DocumentFragment (the shadow tree’s backing node) to the wrapping ShadowRoot so slot assignment and event composition can walk from any inner node back to its shadow boundary. Delegate to ShadowRootRegistry
499
500
501
|
# File 'lib/dommy/document.rb', line 499
def __register_shadow_fragment__(fragment_node, shadow_root)
@shadow_registry.register(fragment_node, shadow_root)
end
|
#__reset_wrapper__(nokogiri_node) ⇒ Object
Clear the cached wrapper so the next ‘wrap_node` creates a new one. Used by `customElements.define` to upgrade nodes that were constructed before the registration landed.
489
490
491
|
# File 'lib/dommy/document.rb', line 489
def __reset_wrapper__(nokogiri_node)
@node_wrapper_cache.reset_wrapper(nokogiri_node)
end
|
#__set_active_element__(el) ⇒ Object
178
179
180
|
# File 'lib/dommy/document.rb', line 178
def __set_active_element__(el)
@active_element = el
end
|
#__shadow_root_containing__(node) ⇒ Object
507
508
509
|
# File 'lib/dommy/document.rb', line 507
def __shadow_root_containing__(node)
@shadow_registry.find_enclosing(node)
end
|
#__shadow_root_for_fragment__(fragment_node) ⇒ Object
503
504
505
|
# File 'lib/dommy/document.rb', line 503
def __shadow_root_for_fragment__(fragment_node)
@shadow_registry.find_for_fragment(fragment_node)
end
|
#active_element ⇒ Object
Currently-focused element (or body if none). Updated via ‘el.focus()` / `el.blur()`.
174
175
176
|
# File 'lib/dommy/document.rb', line 174
def active_element
@active_element || @body
end
|
#adopt_node(node) ⇒ Object
Move a node from another document into this one. The source node is detached from its previous owner and its ownerDocument becomes this. Returns the (possibly re-wrapped) node.
214
215
216
217
218
219
220
221
222
223
224
225
226
|
# File 'lib/dommy/document.rb', line 214
def adopt_node(node)
return nil unless node.respond_to?(:__node__)
src = node.__node__
src.unlink if src.parent
moved = if src.document == @nokogiri_doc
src
else
clone_into_doc(src, true)
end
wrap_node(moved)
end
|
#attach_template_content(template_element, html) ⇒ Object
—– template content helpers (called from Element) —–
604
605
606
|
# File 'lib/dommy/document.rb', line 604
def attach_template_content(template_element, html)
@template_content_registry.attach(template_element, html)
end
|
#base_uri ⇒ Object
‘document.baseURI` — resolves the first `<base href>` (if any) relative to the document URL; otherwise just the document URL. When `<base href>` is itself absolute, that wins. Browsers also ignore subsequent <base> elements; we mirror that.
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/dommy/document.rb', line 95
def base_uri
doc_url = url
base_el = @nokogiri_doc.at_css("base[href]")
return doc_url unless base_el
href = base_el["href"].to_s
return doc_url if href.empty?
begin
URI.join(doc_url.to_s.empty? ? "about:blank" : doc_url, href).to_s
rescue URI::InvalidURIError
doc_url
end
end
|
#child_element_count ⇒ Object
160
161
162
|
# File 'lib/dommy/document.rb', line 160
def child_element_count
children.size
end
|
#children ⇒ Object
ParentNode mixin (operates on the document’s element children —in practice the ‘<html>` root).
153
154
155
156
157
158
|
# File 'lib/dommy/document.rb', line 153
def children
HTMLCollection.new do
root = @nokogiri_doc.root
root ? [wrap_node(root)].compact : []
end
end
|
#close ⇒ Object
326
327
328
|
# File 'lib/dommy/document.rb', line 326
def close
nil
end
|
#cookie ⇒ Object
286
287
288
|
# File 'lib/dommy/document.rb', line 286
def cookie
@cookie_jar.to_cookie_string
end
|
#cookie=(value) ⇒ Object
290
291
292
293
|
# File 'lib/dommy/document.rb', line 290
def cookie=(value)
@cookie_jar.set_cookie(value)
nil
end
|
#create_attribute(name) ⇒ Object
Create a detached Attr. ‘setAttributeNode` attaches it to an element. Per spec, name must match the XML Name production —invalid names throw InvalidCharacterError.
185
186
187
|
# File 'lib/dommy/document.rb', line 185
def create_attribute(name)
@node_wrapper_cache.create_attribute(name)
end
|
#create_attribute_ns(namespace_uri, qualified_name) ⇒ Object
189
190
191
|
# File 'lib/dommy/document.rb', line 189
def create_attribute_ns(namespace_uri, qualified_name)
@node_wrapper_cache.create_attribute_ns(namespace_uri, qualified_name)
end
|
Create a Comment node. Wraps the Nokogiri comment so it flows through the same wrap_node identity machinery as Element / TextNode.
340
341
342
|
# File 'lib/dommy/document.rb', line 340
def (text)
@node_wrapper_cache.(text)
end
|
#create_document_fragment ⇒ Object
344
345
346
|
# File 'lib/dommy/document.rb', line 344
def create_document_fragment
@node_wrapper_cache.create_document_fragment
end
|
#create_element(name) ⇒ Object
Delegate factory methods to NodeWrapperCache
582
583
584
|
# File 'lib/dommy/document.rb', line 582
def create_element(name)
@node_wrapper_cache.create_element(name)
end
|
#create_element_ns(namespace_uri, qualified_name) ⇒ Object
295
296
297
|
# File 'lib/dommy/document.rb', line 295
def create_element_ns(namespace_uri, qualified_name)
@node_wrapper_cache.create_element_ns(namespace_uri, qualified_name)
end
|
#create_event(type_name) ⇒ Object
Legacy ‘document.createEvent(“EventName”)` factory. Returns an Event subclass instance whose init still has to be called (`event.initEvent(type, bubbles, cancelable)`). Matches the mapping happy-dom and linkedom use.
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'lib/dommy/document.rb', line 232
def create_event(type_name)
name = type_name.to_s
case name
when "Event", "Events", "HTMLEvents"
Event.new("")
when "CustomEvent"
CustomEvent.new("")
when "MouseEvent", "MouseEvents"
MouseEvent.new("")
when "KeyboardEvent", "KeyboardEvents"
KeyboardEvent.new("")
else
Event.new("")
end
end
|
#create_node_iterator(root, what_to_show = NodeFilter::SHOW_ALL, filter = nil) ⇒ Object
‘document.createNodeIterator(root, whatToShow?, filter?)` —flat depth-first iteration.
#create_text_node(text) ⇒ Object
586
587
588
|
# File 'lib/dommy/document.rb', line 586
def create_text_node(text)
@node_wrapper_cache.create_text_node(text)
end
|
#create_tree_walker(root, what_to_show = NodeFilter::SHOW_ALL, filter = nil) ⇒ Object
‘document.createTreeWalker(root, whatToShow?, filter?)` — stateful tree traversal with sibling/parent navigation. `filter` may be a Ruby Proc, a JS-bridge callable, or an object with `accept_node` / `acceptNode`.
#doctype ⇒ Object
Minimal DocumentType — represents the ‘<!doctype html>` line. Always present in HTML5 documents we parse, so we synthesize a stub object whose only useful field is `name`. Tests just need `nodeType == 10`.
280
281
282
|
# File 'lib/dommy/document.rb', line 280
def doctype
@doctype ||= DocumentType.new("html")
end
|
#document_element ⇒ Object
74
75
76
|
# File 'lib/dommy/document.rb', line 74
def document_element
wrap_node(@nokogiri_doc.at_css("html"))
end
|
#domain ⇒ Object
‘document.domain` — host portion of the URL. Real browsers restrict cross-origin reads of this; we just return the bare host.
112
113
114
115
116
117
|
# File 'lib/dommy/document.rb', line 112
def domain
view = @default_view
return "" unless view&.location
view.location.__js_get__("hostname").to_s
end
|
#element_from_point(_x, _y) ⇒ Object
262
263
264
|
# File 'lib/dommy/document.rb', line 262
def element_from_point(_x, _y)
nil
end
|
#first_element_child ⇒ Object
164
165
166
|
# File 'lib/dommy/document.rb', line 164
def first_element_child
wrap_node(@nokogiri_doc.root)
end
|
133
134
135
136
137
|
# File 'lib/dommy/document.rb', line 133
def forms
HTMLCollection.new do
@nokogiri_doc.css("form").map { |n| wrap_node(n) }.compact
end
end
|
#get_element_by_id(id) ⇒ Object
598
599
600
|
# File 'lib/dommy/document.rb', line 598
def get_element_by_id(id)
@node_wrapper_cache.get_element_by_id(id)
end
|
#get_elements_by_class_name(name) ⇒ Object
348
349
350
|
# File 'lib/dommy/document.rb', line 348
def get_elements_by_class_name(name)
@node_wrapper_cache.get_elements_by_class_name(name)
end
|
#get_elements_by_name(name) ⇒ Object
303
304
305
|
# File 'lib/dommy/document.rb', line 303
def get_elements_by_name(name)
@node_wrapper_cache.get_elements_by_name(name)
end
|
#get_elements_by_tag_name(name) ⇒ Object
299
300
301
|
# File 'lib/dommy/document.rb', line 299
def get_elements_by_tag_name(name)
@node_wrapper_cache.get_elements_by_tag_name(name)
end
|
#get_selection ⇒ Object
258
259
260
|
# File 'lib/dommy/document.rb', line 258
def get_selection
nil
end
|
#has_focus? ⇒ Boolean
Also known as:
has_focus
Stubs for layout / focus / selection / execCommand APIs that don’t apply to a layout-less DOM. They exist so callers don’t hit NoMethodError; semantics are documented as no-op.
252
253
254
|
# File 'lib/dommy/document.rb', line 252
def has_focus?
true
end
|
#has_template_content?(nokogiri_node) ⇒ Boolean
620
621
622
|
# File 'lib/dommy/document.rb', line 620
def has_template_content?(nokogiri_node)
@template_content_registry.has_content?(nokogiri_node)
end
|
#head ⇒ Object
78
79
80
|
# File 'lib/dommy/document.rb', line 78
def head
wrap_node(@nokogiri_doc.at_css("head"))
end
|
#images ⇒ Object
145
146
147
148
149
|
# File 'lib/dommy/document.rb', line 145
def images
HTMLCollection.new do
@nokogiri_doc.css("img").map { |n| wrap_node(n) }.compact
end
end
|
#import_node(node, deep = false) ⇒ Object
Copy a node from another document into this one. The returned wrapper is owned by ‘this`. Per spec, the source node is left in place. `deep: true` copies the entire subtree.
204
205
206
207
208
209
|
# File 'lib/dommy/document.rb', line 204
def import_node(node, deep = false)
return nil unless node.respond_to?(:__node__)
copy = clone_into_doc(node.__node__, deep)
wrap_node(copy)
end
|
#last_element_child ⇒ Object
168
169
170
|
# File 'lib/dommy/document.rb', line 168
def last_element_child
wrap_node(@nokogiri_doc.root)
end
|
#links ⇒ Object
Live HTMLCollection helpers — each call re-queries the document so post-mutation reads reflect the current state.
127
128
129
130
131
|
# File 'lib/dommy/document.rb', line 127
def links
HTMLCollection.new do
@nokogiri_doc.css("a[href], area[href]").map { |n| wrap_node(n) }.compact
end
end
|
#migrate_template_descendants(root) ⇒ Object
616
617
618
|
# File 'lib/dommy/document.rb', line 616
def migrate_template_descendants(root)
@template_content_registry.migrate_descendants(root)
end
|
#notify_attribute_mutation(target_node:, attribute_name:, old_value:) ⇒ Object
560
561
562
563
564
565
566
|
# File 'lib/dommy/document.rb', line 560
def notify_attribute_mutation(target_node:, attribute_name:, old_value:)
@mutation_coordinator.notify_attribute_mutation(
target_node: target_node,
attribute_name: attribute_name,
old_value: old_value
)
end
|
#notify_character_data_mutation(target_node:, old_value:) ⇒ Object
568
569
570
571
572
573
|
# File 'lib/dommy/document.rb', line 568
def notify_character_data_mutation(target_node:, old_value:)
@mutation_coordinator.notify_character_data_mutation(
target_node: target_node,
old_value: old_value
)
end
|
#notify_child_list_mutation(target_node:, added_nodes:, removed_nodes:, previous_sibling: nil, next_sibling: nil) ⇒ Object
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
|
# File 'lib/dommy/document.rb', line 544
def notify_child_list_mutation(
target_node:,
added_nodes:,
removed_nodes:,
previous_sibling: nil,
next_sibling: nil
)
@mutation_coordinator.notify_child_list_mutation(
target_node: target_node,
added_nodes: added_nodes,
removed_nodes: removed_nodes,
previous_sibling: previous_sibling,
next_sibling: next_sibling
)
end
|
#open ⇒ Object
No-ops — real browsers reset the DOM on ‘open()` and flush pending writes on `close()`. We don’t model the parse pipeline.
322
323
324
|
# File 'lib/dommy/document.rb', line 322
def open
nil
end
|
#query_command_supported(_command) ⇒ Object
266
267
268
|
# File 'lib/dommy/document.rb', line 266
def query_command_supported(_command)
false
end
|
#query_selector(selector) ⇒ Object
590
591
592
|
# File 'lib/dommy/document.rb', line 590
def query_selector(selector)
@node_wrapper_cache.query_selector(selector)
end
|
#query_selector_all(selector) ⇒ Object
594
595
596
|
# File 'lib/dommy/document.rb', line 594
def query_selector_all(selector)
@node_wrapper_cache.query_selector_all(selector)
end
|
#referrer ⇒ Object
‘document.referrer` — Dommy never has a referring page, so this is always empty.
121
122
123
|
# File 'lib/dommy/document.rb', line 121
def referrer
""
end
|
#register_observer(observer) ⇒ Object
536
537
538
|
# File 'lib/dommy/document.rb', line 536
def register_observer(observer)
@mutation_coordinator.register_observer(observer)
end
|
#scripts ⇒ Object
139
140
141
142
143
|
# File 'lib/dommy/document.rb', line 139
def scripts
HTMLCollection.new do
@nokogiri_doc.css("script").map { |n| wrap_node(n) }.compact
end
end
|
#template_content_fragment(template_element) ⇒ Object
608
609
610
|
# File 'lib/dommy/document.rb', line 608
def template_content_fragment(template_element)
@template_content_registry.fragment_for(template_element)
end
|
#template_content_inner_html(template_element) ⇒ Object
612
613
614
|
# File 'lib/dommy/document.rb', line 612
def template_content_inner_html(template_element)
@template_content_registry.inner_html_of(template_element)
end
|
#title ⇒ Object
—– Public Ruby API (snake_case) —–
66
67
68
|
# File 'lib/dommy/document.rb', line 66
def title
read_title
end
|
#title=(value) ⇒ Object
70
71
72
|
# File 'lib/dommy/document.rb', line 70
def title=(value)
write_title(value.to_s)
end
|
#unregister_observer(observer) ⇒ Object
540
541
542
|
# File 'lib/dommy/document.rb', line 540
def unregister_observer(observer)
@mutation_coordinator.unregister_observer(observer)
end
|
#url ⇒ Object
Also known as:
document_uri
‘document.URL` / `documentURI` — both return location.href in real browsers (legacy aliases of the same field).
84
85
86
87
|
# File 'lib/dommy/document.rb', line 84
def url
view = @default_view
view&.location ? view.location.href : ""
end
|
#wrap_node(node) ⇒ Object
Delegate node wrapping to NodeWrapperCache
482
483
484
|
# File 'lib/dommy/document.rb', line 482
def wrap_node(node)
@node_wrapper_cache.wrap(node)
end
|
#write(*args) ⇒ Object
‘document.write(html)` — legacy API. Appends parsed nodes to the body. Real browsers only re-stream the DOM during initial parse; this stub is enough for tests that fire write() during teardown.
310
311
312
313
314
315
316
317
318
|
# File 'lib/dommy/document.rb', line 310
def write(*args)
html = args.join
fragment = Parser.fragment(html, owner_doc: @nokogiri_doc)
removed = []
added = fragment.children.to_a
added.each { |node| @body.__node__.add_child(node) }
notify_child_list_mutation(target_node: @body.__node__, added_nodes: added, removed_nodes: removed)
nil
end
|