Module: Dommy
- Defined in:
- lib/dommy/world.rb,
lib/dommy.rb,
lib/dommy/css.rb,
lib/dommy/url.rb,
lib/dommy/attr.rb,
lib/dommy/blob.rb,
lib/dommy/node.rb,
lib/dommy/event.rb,
lib/dommy/fetch.rb,
lib/dommy/bridge.rb,
lib/dommy/parser.rb,
lib/dommy/router.rb,
lib/dommy/element.rb,
lib/dommy/promise.rb,
lib/dommy/storage.rb,
lib/dommy/version.rb,
lib/dommy/document.rb,
lib/dommy/observer.rb,
lib/dommy/form_data.rb,
lib/dommy/navigator.rb,
lib/dommy/scheduler.rb,
lib/dommy/dom_parser.rb,
lib/dommy/shadow_root.rb,
lib/dommy/tree_walker.rb,
lib/dommy/test_helpers.rb,
lib/dommy/data_transfer.rb,
lib/dommy/dom_exception.rb,
lib/dommy/html_elements.rb,
lib/dommy/rspec/matchers.rb,
lib/dommy/custom_elements.rb,
lib/dommy/html_collection.rb,
lib/dommy/internal/cookie_jar.rb,
lib/dommy/minitest/assertions.rb,
lib/dommy/internal/dom_matching.rb,
lib/dommy/internal/node_traversal.rb,
lib/dommy/internal/observer_manager.rb,
lib/dommy/internal/observer_matcher.rb,
lib/dommy/internal/scope_resolution.rb,
lib/dommy/rspec/capy_style_matchers.rb,
lib/dommy/internal/node_wrapper_cache.rb,
lib/dommy/internal/mutation_coordinator.rb,
lib/dommy/internal/shadow_root_registry.rb,
lib/dommy/internal/template_content_registry.rb
Overview
Dommy — a happy-dom-style DOM polyfill in pure Ruby. Backbone is Nokogiri::HTML5 plus a small scheduler/event-loop layer.
Two views into the same objects:
- Public Ruby API (snake_case methods like `text_content`,
`append_child`) for CRuby users writing tests against rendered
HTML.
- `__js_get__` / `__js_set__` / `__js_call__` / `__js_new__`
bridge protocol for JS bridge embedders — dispatches into the
same underlying Ruby methods.
Defined Under Namespace
Modules: Bridge, EventTarget, Internal, Minitest, Node, NodeFilter, Parser, RSpec, TestHelpers, TreeTraversalCore Classes: AbortController, AbortSignal, Attr, Blob, CSSRule, CSSRuleList, CSSStyleSheet, CharacterDataNode, ClassList, Clipboard, CommentNode, CustomElementRegistry, CustomEvent, DOMException, DOMParser, DOMRect, DataTransfer, DatasetMap, Document, DocumentType, DragEvent, Element, ErrorValue, Event, FetchFn, File, FileList, FormData, Fragment, HTMLAnchorElement, HTMLAreaElement, HTMLAudioElement, HTMLBRElement, HTMLBaseElement, HTMLBodyElement, HTMLButtonElement, HTMLCollection, HTMLDataElement, HTMLDetailsElement, HTMLDialogElement, HTMLDivElement, HTMLElement, HTMLEmbedElement, HTMLFieldsetElement, HTMLFormElement, HTMLHRElement, HTMLHeadElement, HTMLHeadingElement, HTMLHtmlElement, HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLLIElement, HTMLLabelElement, HTMLLegendElement, HTMLLinkElement, HTMLMapElement, HTMLMediaElement, HTMLMetaElement, HTMLMeterElement, HTMLModElement, HTMLOListElement, HTMLObjectElement, HTMLOptGroupElement, HTMLOptionElement, HTMLOptionsCollection, HTMLOutputElement, HTMLParagraphElement, HTMLPictureElement, HTMLPreElement, HTMLProgressElement, HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLSlotElement, HTMLSourceElement, HTMLSpanElement, HTMLStyleElement, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement, HTMLTemplateElement, HTMLTextAreaElement, HTMLTimeElement, HTMLTitleElement, HTMLTrackElement, HTMLUListElement, HTMLVideoElement, Headers, History, KeyboardEvent, LiveNodeList, Location, MouseEvent, MutationObserver, MutationRecord, NamedNodeMap, Navigator, NodeIterator, NodeList, PermissionStatus, Permissions, PromiseValue, Response, Scheduler, ShadowRoot, StandaloneEventTarget, Storage, StyleDeclaration, TextNode, TreeWalker, URL, URLSearchParams, Url, ValidityState, Window, XMLSerializer
Constant Summary collapse
- VERSION =
"0.5.0"- HTML_ELEMENT_CLASSES =
Look up the subclass for a given HTML tag. Document#wrap_node consults this map; defaults to plain Element.
{ "a" => HTMLAnchorElement, "form" => HTMLFormElement, "input" => HTMLInputElement, "button" => HTMLButtonElement, "img" => HTMLImageElement, "script" => HTMLScriptElement, "link" => HTMLLinkElement, "select" => HTMLSelectElement, "option" => HTMLOptionElement, "optgroup" => HTMLOptGroupElement, "textarea" => HTMLTextAreaElement, "label" => HTMLLabelElement, "fieldset" => HTMLFieldsetElement, "output" => HTMLOutputElement, "legend" => HTMLLegendElement, "slot" => HTMLSlotElement, "table" => HTMLTableElement, "thead" => HTMLTableSectionElement, "tbody" => HTMLTableSectionElement, "tfoot" => HTMLTableSectionElement, "tr" => HTMLTableRowElement, "td" => HTMLTableCellElement, "th" => HTMLTableCellElement, "caption" => HTMLTableCaptionElement, "dialog" => HTMLDialogElement, "details" => HTMLDetailsElement, "meter" => HTMLMeterElement, "progress" => HTMLProgressElement, "template" => HTMLTemplateElement, "audio" => HTMLAudioElement, "video" => HTMLVideoElement, "source" => HTMLSourceElement, "track" => HTMLTrackElement, "iframe" => HTMLIFrameElement, "picture" => HTMLPictureElement, "ol" => HTMLOListElement, "ul" => HTMLUListElement, "li" => HTMLLIElement, "time" => HTMLTimeElement, "data" => HTMLDataElement, "area" => HTMLAreaElement, "map" => HTMLMapElement, "object" => HTMLObjectElement, "embed" => HTMLEmbedElement, "base" => HTMLBaseElement, "meta" => HTMLMetaElement, "style" => HTMLStyleElement, "title" => HTMLTitleElement, "q" => HTMLQuoteElement, "blockquote" => HTMLQuoteElement, "ins" => HTMLModElement, "del" => HTMLModElement, "div" => HTMLDivElement, "span" => HTMLSpanElement, "p" => HTMLParagraphElement, "h1" => HTMLHeadingElement, "h2" => HTMLHeadingElement, "h3" => HTMLHeadingElement, "h4" => HTMLHeadingElement, "h5" => HTMLHeadingElement, "h6" => HTMLHeadingElement, "br" => HTMLBRElement, "hr" => HTMLHRElement, "pre" => HTMLPreElement, "body" => HTMLBodyElement, "head" => HTMLHeadElement, "html" => HTMLHtmlElement }.freeze
Class Method Summary collapse
- .element_class_for(tag_name) ⇒ Object
-
.new_window ⇒ Object
Build a fresh, empty Window (no host).
-
.parse(html) ⇒ Object
Parse an HTML string and return a fresh ‘Window`.
-
.structured_clone(value, memo = {}) ⇒ Object
‘structuredClone(value)` — deep clone for plain Ruby values and DOM nodes (via `cloneNode(true)`).
-
.structuredClone(value) ⇒ Object
JS-style global alias for symmetry with ‘window.structuredClone(…)`.
Class Method Details
.element_class_for(tag_name) ⇒ Object
4452 4453 4454 |
# File 'lib/dommy/html_elements.rb', line 4452 def self.element_class_for(tag_name) HTML_ELEMENT_CLASSES[tag_name.to_s.downcase] || Element end |
.new_window ⇒ Object
Build a fresh, empty Window (no host). Equivalent to opening a blank document.
58 59 60 |
# File 'lib/dommy.rb', line 58 def self.new_window Window.new end |
.parse(html) ⇒ Object
Parse an HTML string and return a fresh ‘Window`.
When the input starts with ‘<!doctype` or `<html>`, it is parsed as a full HTML document (preserving <head>, <title>, etc.). Otherwise the input is treated as a body fragment and inserted into a fresh document’s <body>.
The Window has no host (standalone CRuby usage); embedders that need bridge callbacks (e.g. a wasm host) pass a host instead.
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/dommy.rb', line 45 def self.parse(html) s = html.to_s if s.match?(/\A\s*(<!doctype|<html\b)/i) Window.new(nil, nokogiri_doc: Nokogiri::HTML5(s)) else window = Window.new window.document.body.inner_html = s window end end |
.structured_clone(value, memo = {}) ⇒ Object
‘structuredClone(value)` — deep clone for plain Ruby values and DOM nodes (via `cloneNode(true)`). Mirrors the JS structured-clone algorithm for the subset we support:
- primitives (String / Numeric / Boolean / nil) → copied
- Array / Hash / Set → deep-cloned
- DOM nodes (anything responding to `clone_node`) → deep-cloned
- cyclic structures → preserved
- Proc / Method / Class / Module / IO → DataCloneError
Symbols are passed through unchanged (Ruby has no ‘Symbol` clone concept; JS treats Symbols as DataCloneError, but Ruby code uses them as hash keys so this is the pragmatic choice).
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/dommy.rb', line 75 def self.structured_clone(value, memo = {}) return memo[value.object_id] if memo.key?(value.object_id) case value when nil, true, false, Numeric, Symbol value when String value.dup when Array arr = [] memo[value.object_id] = arr value.each { |v| arr << structured_clone(v, memo) } arr when Hash h = {} memo[value.object_id] = h value.each { |k, v| h[structured_clone(k, memo)] = structured_clone(v, memo) } h when Set s = Set.new memo[value.object_id] = s value.each { |v| s << structured_clone(v, memo) } s when Time value.dup when Regexp value.dup when Proc, Method, UnboundMethod, IO, Class, Module raise DOMException::DataCloneError, "#{value.class} cannot be cloned" else if value.respond_to?(:clone_node) value.clone_node(true) else # Fallback: rely on the object's own `dup` (which handles # custom classes the user might pass through). value.dup end end end |
.structuredClone(value) ⇒ Object
JS-style global alias for symmetry with ‘window.structuredClone(…)`.
117 118 119 |
# File 'lib/dommy.rb', line 117 def Dommy.structuredClone(value) structured_clone(value) end |