dommy 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +213 -0
- data/lib/dommy/attr.rb +200 -0
- data/lib/dommy/blob.rb +182 -0
- data/lib/dommy/bridge.rb +141 -0
- data/lib/dommy/css.rb +283 -0
- data/lib/dommy/custom_elements.rb +125 -0
- data/lib/dommy/data_transfer.rb +98 -0
- data/lib/dommy/document.rb +674 -0
- data/lib/dommy/dom_exception.rb +258 -0
- data/lib/dommy/dom_parser.rb +88 -0
- data/lib/dommy/element.rb +1975 -0
- data/lib/dommy/event.rb +589 -0
- data/lib/dommy/fetch.rb +241 -0
- data/lib/dommy/form_data.rb +208 -0
- data/lib/dommy/html_collection.rb +207 -0
- data/lib/dommy/html_elements.rb +4455 -0
- data/lib/dommy/internal/cookie_jar.rb +27 -0
- data/lib/dommy/internal/dom_matching.rb +141 -0
- data/lib/dommy/internal/mutation_coordinator.rb +172 -0
- data/lib/dommy/internal/node_traversal.rb +36 -0
- data/lib/dommy/internal/node_wrapper_cache.rb +179 -0
- data/lib/dommy/internal/observer_manager.rb +31 -0
- data/lib/dommy/internal/observer_matcher.rb +31 -0
- data/lib/dommy/internal/scope_resolution.rb +27 -0
- data/lib/dommy/internal/shadow_root_registry.rb +35 -0
- data/lib/dommy/internal/template_content_registry.rb +97 -0
- data/lib/dommy/minitest/assertions.rb +105 -0
- data/lib/dommy/minitest.rb +17 -0
- data/lib/dommy/navigator.rb +271 -0
- data/lib/dommy/node.rb +218 -0
- data/lib/dommy/observer.rb +199 -0
- data/lib/dommy/parser.rb +29 -0
- data/lib/dommy/promise.rb +199 -0
- data/lib/dommy/router.rb +275 -0
- data/lib/dommy/rspec/capy_style_matchers.rb +356 -0
- data/lib/dommy/rspec/matchers.rb +230 -0
- data/lib/dommy/rspec.rb +18 -0
- data/lib/dommy/scheduler.rb +135 -0
- data/lib/dommy/shadow_root.rb +255 -0
- data/lib/dommy/storage.rb +112 -0
- data/lib/dommy/test_helpers.rb +78 -0
- data/lib/dommy/tree_walker.rb +425 -0
- data/lib/dommy/url.rb +479 -0
- data/lib/dommy/version.rb +5 -0
- data/lib/dommy/world.rb +209 -0
- data/lib/dommy.rb +119 -0
- metadata +110 -0
data/lib/dommy.rb
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "nokogiri"
|
|
4
|
+
require "set"
|
|
5
|
+
|
|
6
|
+
require_relative "dommy/version"
|
|
7
|
+
require_relative "dommy/dom_exception"
|
|
8
|
+
require_relative "dommy/node"
|
|
9
|
+
require_relative "dommy/html_collection"
|
|
10
|
+
require_relative "dommy/event"
|
|
11
|
+
require_relative "dommy/scheduler"
|
|
12
|
+
require_relative "dommy/observer"
|
|
13
|
+
require_relative "dommy/promise"
|
|
14
|
+
require_relative "dommy/blob"
|
|
15
|
+
require_relative "dommy/data_transfer"
|
|
16
|
+
require_relative "dommy/bridge"
|
|
17
|
+
require_relative "dommy/storage"
|
|
18
|
+
require_relative "dommy/fetch"
|
|
19
|
+
require_relative "dommy/router"
|
|
20
|
+
require_relative "dommy/navigator"
|
|
21
|
+
require_relative "dommy/parser"
|
|
22
|
+
require_relative "dommy/attr"
|
|
23
|
+
require_relative "dommy/world"
|
|
24
|
+
require_relative "dommy/document"
|
|
25
|
+
require_relative "dommy/element"
|
|
26
|
+
require_relative "dommy/html_elements"
|
|
27
|
+
require_relative "dommy/shadow_root"
|
|
28
|
+
require_relative "dommy/custom_elements"
|
|
29
|
+
require_relative "dommy/tree_walker"
|
|
30
|
+
require_relative "dommy/url"
|
|
31
|
+
require_relative "dommy/form_data"
|
|
32
|
+
require_relative "dommy/dom_parser"
|
|
33
|
+
require_relative "dommy/css"
|
|
34
|
+
|
|
35
|
+
module Dommy
|
|
36
|
+
# Parse an HTML string and return a fresh `Window`.
|
|
37
|
+
#
|
|
38
|
+
# When the input starts with `<!doctype` or `<html>`, it is parsed as
|
|
39
|
+
# a full HTML document (preserving <head>, <title>, etc.). Otherwise
|
|
40
|
+
# the input is treated as a body fragment and inserted into a fresh
|
|
41
|
+
# document's <body>.
|
|
42
|
+
#
|
|
43
|
+
# The Window has no host (standalone CRuby usage); embedders that need
|
|
44
|
+
# bridge callbacks (e.g. a wasm host) pass a host instead.
|
|
45
|
+
def self.parse(html)
|
|
46
|
+
s = html.to_s
|
|
47
|
+
if s.match?(/\A\s*(<!doctype|<html\b)/i)
|
|
48
|
+
Window.new(nil, nokogiri_doc: Nokogiri::HTML5(s))
|
|
49
|
+
else
|
|
50
|
+
window = Window.new
|
|
51
|
+
window.document.body.inner_html = s
|
|
52
|
+
window
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Build a fresh, empty Window (no host). Equivalent to opening a
|
|
57
|
+
# blank document.
|
|
58
|
+
def self.new_window
|
|
59
|
+
Window.new
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# `structuredClone(value)` — deep clone for plain Ruby values and
|
|
63
|
+
# DOM nodes (via `cloneNode(true)`). Mirrors the JS structured-clone
|
|
64
|
+
# algorithm for the subset we support:
|
|
65
|
+
#
|
|
66
|
+
# - primitives (String / Numeric / Boolean / nil) → copied
|
|
67
|
+
# - Array / Hash / Set → deep-cloned
|
|
68
|
+
# - DOM nodes (anything responding to `clone_node`) → deep-cloned
|
|
69
|
+
# - cyclic structures → preserved
|
|
70
|
+
# - Proc / Method / Class / Module / IO → DataCloneError
|
|
71
|
+
#
|
|
72
|
+
# Symbols are passed through unchanged (Ruby has no `Symbol` clone
|
|
73
|
+
# concept; JS treats Symbols as DataCloneError, but Ruby code uses
|
|
74
|
+
# them as hash keys so this is the pragmatic choice).
|
|
75
|
+
def self.structured_clone(value, memo = {})
|
|
76
|
+
return memo[value.object_id] if memo.key?(value.object_id)
|
|
77
|
+
|
|
78
|
+
case value
|
|
79
|
+
when nil, true, false, Numeric, Symbol
|
|
80
|
+
value
|
|
81
|
+
when String
|
|
82
|
+
value.dup
|
|
83
|
+
when Array
|
|
84
|
+
arr = []
|
|
85
|
+
memo[value.object_id] = arr
|
|
86
|
+
value.each { |v| arr << structured_clone(v, memo) }
|
|
87
|
+
arr
|
|
88
|
+
when Hash
|
|
89
|
+
h = {}
|
|
90
|
+
memo[value.object_id] = h
|
|
91
|
+
value.each { |k, v| h[structured_clone(k, memo)] = structured_clone(v, memo) }
|
|
92
|
+
h
|
|
93
|
+
when Set
|
|
94
|
+
s = Set.new
|
|
95
|
+
memo[value.object_id] = s
|
|
96
|
+
value.each { |v| s << structured_clone(v, memo) }
|
|
97
|
+
s
|
|
98
|
+
when Time
|
|
99
|
+
value.dup
|
|
100
|
+
when Regexp
|
|
101
|
+
value.dup
|
|
102
|
+
when Proc, Method, UnboundMethod, IO, Class, Module
|
|
103
|
+
raise DOMException::DataCloneError, "#{value.class} cannot be cloned"
|
|
104
|
+
else
|
|
105
|
+
if value.respond_to?(:clone_node)
|
|
106
|
+
value.clone_node(true)
|
|
107
|
+
else
|
|
108
|
+
# Fallback: rely on the object's own `dup` (which handles
|
|
109
|
+
# custom classes the user might pass through).
|
|
110
|
+
value.dup
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# JS-style global alias for symmetry with `window.structuredClone(...)`.
|
|
117
|
+
def Dommy.structuredClone(value)
|
|
118
|
+
structured_clone(value)
|
|
119
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dommy
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.5.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- takahashim
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-05-21 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: nokogiri
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.15'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.15'
|
|
26
|
+
description: |
|
|
27
|
+
A pure-Ruby DOM polyfill on top of Nokogiri::HTML5, a Ruby-side
|
|
28
|
+
analogue to JavaScript DOM libraries like happy-dom and jsdom.
|
|
29
|
+
It exposes browser-like DOM semantics — events, MutationObserver,
|
|
30
|
+
Custom Elements, Shadow DOM, the File API (Blob / File / FormData /
|
|
31
|
+
DataTransfer), URL, Promise, timers, and Storage — without spinning
|
|
32
|
+
up a real browser.
|
|
33
|
+
|
|
34
|
+
Aimed at testing Ruby code that emits or consumes HTML. Includes
|
|
35
|
+
drop-in RSpec matchers and Minitest assertions.
|
|
36
|
+
email:
|
|
37
|
+
- takahashimm@gmail.com
|
|
38
|
+
executables: []
|
|
39
|
+
extensions: []
|
|
40
|
+
extra_rdoc_files: []
|
|
41
|
+
files:
|
|
42
|
+
- README.md
|
|
43
|
+
- lib/dommy.rb
|
|
44
|
+
- lib/dommy/attr.rb
|
|
45
|
+
- lib/dommy/blob.rb
|
|
46
|
+
- lib/dommy/bridge.rb
|
|
47
|
+
- lib/dommy/css.rb
|
|
48
|
+
- lib/dommy/custom_elements.rb
|
|
49
|
+
- lib/dommy/data_transfer.rb
|
|
50
|
+
- lib/dommy/document.rb
|
|
51
|
+
- lib/dommy/dom_exception.rb
|
|
52
|
+
- lib/dommy/dom_parser.rb
|
|
53
|
+
- lib/dommy/element.rb
|
|
54
|
+
- lib/dommy/event.rb
|
|
55
|
+
- lib/dommy/fetch.rb
|
|
56
|
+
- lib/dommy/form_data.rb
|
|
57
|
+
- lib/dommy/html_collection.rb
|
|
58
|
+
- lib/dommy/html_elements.rb
|
|
59
|
+
- lib/dommy/internal/cookie_jar.rb
|
|
60
|
+
- lib/dommy/internal/dom_matching.rb
|
|
61
|
+
- lib/dommy/internal/mutation_coordinator.rb
|
|
62
|
+
- lib/dommy/internal/node_traversal.rb
|
|
63
|
+
- lib/dommy/internal/node_wrapper_cache.rb
|
|
64
|
+
- lib/dommy/internal/observer_manager.rb
|
|
65
|
+
- lib/dommy/internal/observer_matcher.rb
|
|
66
|
+
- lib/dommy/internal/scope_resolution.rb
|
|
67
|
+
- lib/dommy/internal/shadow_root_registry.rb
|
|
68
|
+
- lib/dommy/internal/template_content_registry.rb
|
|
69
|
+
- lib/dommy/minitest.rb
|
|
70
|
+
- lib/dommy/minitest/assertions.rb
|
|
71
|
+
- lib/dommy/navigator.rb
|
|
72
|
+
- lib/dommy/node.rb
|
|
73
|
+
- lib/dommy/observer.rb
|
|
74
|
+
- lib/dommy/parser.rb
|
|
75
|
+
- lib/dommy/promise.rb
|
|
76
|
+
- lib/dommy/router.rb
|
|
77
|
+
- lib/dommy/rspec.rb
|
|
78
|
+
- lib/dommy/rspec/capy_style_matchers.rb
|
|
79
|
+
- lib/dommy/rspec/matchers.rb
|
|
80
|
+
- lib/dommy/scheduler.rb
|
|
81
|
+
- lib/dommy/shadow_root.rb
|
|
82
|
+
- lib/dommy/storage.rb
|
|
83
|
+
- lib/dommy/test_helpers.rb
|
|
84
|
+
- lib/dommy/tree_walker.rb
|
|
85
|
+
- lib/dommy/url.rb
|
|
86
|
+
- lib/dommy/version.rb
|
|
87
|
+
- lib/dommy/world.rb
|
|
88
|
+
homepage: https://github.com/takahashim/dommy
|
|
89
|
+
licenses:
|
|
90
|
+
- MIT
|
|
91
|
+
metadata:
|
|
92
|
+
homepage_uri: https://github.com/takahashim/dommy
|
|
93
|
+
rdoc_options: []
|
|
94
|
+
require_paths:
|
|
95
|
+
- lib
|
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
|
+
requirements:
|
|
98
|
+
- - ">="
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: '3.0'
|
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - ">="
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '0'
|
|
106
|
+
requirements: []
|
|
107
|
+
rubygems_version: 3.6.2
|
|
108
|
+
specification_version: 4
|
|
109
|
+
summary: happy-dom-style DOM polyfill in pure Ruby
|
|
110
|
+
test_files: []
|