opal-browser 0.2.0.beta1 → 0.3.2
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 +5 -5
- data/.github/workflows/build.yml +95 -0
- data/.gitignore +3 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +17 -3
- data/LICENSE +2 -1
- data/README.md +183 -52
- data/Rakefile +29 -1
- data/config.ru +20 -3
- data/docs/polyfills.md +24 -0
- data/examples/2048/Gemfile +6 -0
- data/examples/2048/README.md +13 -0
- data/examples/2048/app/application.rb +169 -0
- data/examples/2048/config.ru +9 -0
- data/examples/canvas/Gemfile +6 -0
- data/examples/canvas/README.md +9 -0
- data/examples/canvas/app/application.rb +55 -0
- data/examples/canvas/config.ru +9 -0
- data/examples/component/Gemfile +6 -0
- data/examples/component/README.md +10 -0
- data/examples/component/app/application.rb +66 -0
- data/examples/component/config.ru +9 -0
- data/examples/integrations/README.md +24 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/Gemfile +6 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/README.md +16 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/app/application.rb +6 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/config.ru +9 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/.gitignore +1 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/Gemfile +7 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/README.md +22 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/Rakefile +4 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/app/application.rb +6 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/app.rb +32 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/config.ru +3 -0
- data/examples/integrations/dynamic-roda-tilt/.gitignore +1 -0
- data/examples/integrations/dynamic-roda-tilt/Gemfile +8 -0
- data/examples/integrations/dynamic-roda-tilt/README.md +17 -0
- data/examples/integrations/dynamic-roda-tilt/Rakefile +6 -0
- data/examples/integrations/dynamic-roda-tilt/app/application.rb +6 -0
- data/examples/integrations/dynamic-roda-tilt/app.rb +50 -0
- data/examples/integrations/dynamic-roda-tilt/config.ru +3 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/Gemfile +7 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/README.md +16 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/app/application.rb +6 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/config.ru +29 -0
- data/examples/integrations/static-bash/.gitignore +2 -0
- data/examples/integrations/static-bash/Gemfile +3 -0
- data/examples/integrations/static-bash/README.md +8 -0
- data/examples/integrations/static-bash/app/application.rb +6 -0
- data/examples/integrations/static-bash/build.sh +4 -0
- data/examples/integrations/static-bash/index.html +10 -0
- data/examples/integrations/static-bash-opal-parser/.gitignore +3 -0
- data/examples/integrations/static-bash-opal-parser/Gemfile +3 -0
- data/examples/integrations/static-bash-opal-parser/README.md +10 -0
- data/examples/integrations/static-bash-opal-parser/build.sh +4 -0
- data/examples/integrations/static-bash-opal-parser/index.html +19 -0
- data/examples/integrations/static-rake/.gitignore +1 -0
- data/examples/integrations/static-rake/Gemfile +4 -0
- data/examples/integrations/static-rake/README.md +7 -0
- data/examples/integrations/static-rake/Rakefile +10 -0
- data/examples/integrations/static-rake/app/application.rb +6 -0
- data/examples/integrations/static-rake/index.html +9 -0
- data/examples/integrations/static-rake-guard/.gitignore +1 -0
- data/examples/integrations/static-rake-guard/Gemfile +6 -0
- data/examples/integrations/static-rake-guard/Guardfile +3 -0
- data/examples/integrations/static-rake-guard/README.md +10 -0
- data/examples/integrations/static-rake-guard/Rakefile +10 -0
- data/examples/integrations/static-rake-guard/app/application.rb +6 -0
- data/examples/integrations/static-rake-guard/index.html +9 -0
- data/examples/svg/.gitignore +1 -0
- data/examples/svg/Gemfile +4 -0
- data/examples/svg/README.md +7 -0
- data/examples/svg/Rakefile +10 -0
- data/examples/svg/app/application.rb +11 -0
- data/examples/svg/index.html +17 -0
- data/examples/svg/index.svg +6 -0
- data/index.html.erb +8 -6
- data/lib/opal-browser.rb +1 -0
- data/opal/browser/animation_frame.rb +26 -1
- data/opal/browser/audio/node.rb +121 -0
- data/opal/browser/audio/param_schedule.rb +43 -0
- data/opal/browser/audio.rb +66 -0
- data/opal/browser/blob.rb +94 -0
- data/opal/browser/canvas/data.rb +1 -11
- data/opal/browser/canvas/gradient.rb +1 -11
- data/opal/browser/canvas/style.rb +3 -11
- data/opal/browser/canvas/text.rb +1 -11
- data/opal/browser/canvas.rb +17 -13
- data/opal/browser/console.rb +3 -1
- data/opal/browser/cookies.rb +78 -42
- data/opal/browser/crypto.rb +79 -0
- data/opal/browser/css/declaration.rb +1 -1
- data/opal/browser/css/rule.rb +1 -1
- data/opal/browser/css/style_sheet.rb +2 -2
- data/opal/browser/css.rb +23 -7
- data/opal/browser/database/sql.rb +193 -0
- data/opal/browser/delay.rb +41 -7
- data/opal/browser/dom/attribute.rb +13 -12
- data/opal/browser/dom/builder.rb +31 -17
- data/opal/browser/dom/document.rb +174 -42
- data/opal/browser/dom/document_fragment.rb +18 -0
- data/opal/browser/dom/document_or_shadow_root.rb +19 -0
- data/opal/browser/dom/element/attributes.rb +111 -0
- data/opal/browser/dom/element/button.rb +31 -0
- data/opal/browser/dom/element/custom.rb +177 -0
- data/opal/browser/dom/element/data.rb +82 -0
- data/opal/browser/dom/element/editable.rb +47 -0
- data/opal/browser/dom/element/form.rb +38 -0
- data/opal/browser/dom/element/iframe.rb +37 -0
- data/opal/browser/dom/element/image.rb +2 -0
- data/opal/browser/dom/element/input.rb +48 -1
- data/opal/browser/dom/element/media.rb +17 -0
- data/opal/browser/dom/element/offset.rb +5 -0
- data/opal/browser/dom/element/position.rb +11 -2
- data/opal/browser/dom/element/scroll.rb +123 -24
- data/opal/browser/dom/element/select.rb +42 -0
- data/opal/browser/dom/element/size.rb +17 -0
- data/opal/browser/dom/element/template.rb +11 -0
- data/opal/browser/dom/element/textarea.rb +26 -0
- data/opal/browser/dom/element.rb +468 -238
- data/opal/browser/dom/mutation_observer.rb +4 -4
- data/opal/browser/dom/node.rb +142 -60
- data/opal/browser/dom/node_set.rb +73 -44
- data/opal/browser/dom/shadow_root.rb +12 -0
- data/opal/browser/dom/text.rb +2 -2
- data/opal/browser/dom.rb +40 -16
- data/opal/browser/effects.rb +180 -3
- data/opal/browser/event/all.rb +26 -0
- data/opal/browser/{dom/event → event}/animation.rb +4 -2
- data/opal/browser/{dom/event → event}/audio_processing.rb +4 -2
- data/opal/browser/{dom/event → event}/base.rb +98 -9
- data/opal/browser/{dom/event → event}/before_unload.rb +4 -2
- data/opal/browser/{dom/event → event}/clipboard.rb +11 -2
- data/opal/browser/{dom/event → event}/close.rb +4 -2
- data/opal/browser/{dom/event → event}/composition.rb +4 -2
- data/opal/browser/{dom/event → event}/custom.rb +3 -3
- data/opal/browser/event/data_transfer.rb +95 -0
- data/opal/browser/{dom/event → event}/device_light.rb +4 -2
- data/opal/browser/{dom/event → event}/device_motion.rb +4 -2
- data/opal/browser/{dom/event → event}/device_orientation.rb +4 -2
- data/opal/browser/{dom/event → event}/device_proximity.rb +4 -2
- data/opal/browser/{dom/event → event}/drag.rb +11 -7
- data/opal/browser/{dom/event → event}/focus.rb +4 -2
- data/opal/browser/{dom/event → event}/gamepad.rb +5 -3
- data/opal/browser/{dom/event → event}/hash_change.rb +4 -2
- data/opal/browser/{dom/event → event}/keyboard.rb +16 -3
- data/opal/browser/{dom/event → event}/message.rb +4 -2
- data/opal/browser/{dom/event → event}/mouse.rb +12 -8
- data/opal/browser/{dom/event → event}/page_transition.rb +4 -2
- data/opal/browser/{dom/event → event}/pop_state.rb +4 -2
- data/opal/browser/{dom/event → event}/progress.rb +4 -2
- data/opal/browser/{dom/event → event}/sensor.rb +4 -2
- data/opal/browser/{dom/event → event}/storage.rb +4 -2
- data/opal/browser/{dom/event → event}/touch.rb +4 -2
- data/opal/browser/{dom/event → event}/ui.rb +2 -2
- data/opal/browser/{dom/event → event}/wheel.rb +4 -2
- data/opal/browser/event.rb +163 -0
- data/opal/browser/event_source.rb +2 -2
- data/opal/browser/form_data.rb +225 -0
- data/opal/browser/history.rb +4 -8
- data/opal/browser/http/binary.rb +1 -0
- data/opal/browser/http/headers.rb +16 -2
- data/opal/browser/http/request.rb +46 -48
- data/opal/browser/http/response.rb +5 -1
- data/opal/browser/http.rb +25 -2
- data/opal/browser/immediate.rb +9 -5
- data/opal/browser/interval.rb +34 -11
- data/opal/browser/location.rb +7 -1
- data/opal/browser/navigator.rb +127 -7
- data/opal/browser/polyfill/visual_viewport.rb +216 -0
- data/opal/browser/screen.rb +3 -3
- data/opal/browser/setup/base.rb +6 -0
- data/opal/browser/setup/full.rb +13 -0
- data/opal/browser/setup/large.rb +17 -0
- data/opal/browser/setup/mini.rb +8 -0
- data/opal/browser/setup/traditional.rb +10 -0
- data/opal/browser/socket.rb +8 -4
- data/opal/browser/storage.rb +53 -35
- data/opal/browser/support.rb +72 -5
- data/opal/browser/utils.rb +94 -14
- data/opal/browser/version.rb +1 -1
- data/opal/browser/visual_viewport.rb +39 -0
- data/opal/browser/window/size.rb +31 -3
- data/opal/browser/window/view.rb +15 -0
- data/opal/browser/window.rb +46 -25
- data/opal/browser.rb +1 -10
- data/opal/opal-browser.rb +1 -0
- data/opal-browser.gemspec +3 -3
- data/spec/database/sql_spec.rb +139 -0
- data/spec/delay_spec.rb +41 -0
- data/spec/dom/attribute_spec.rb +49 -0
- data/spec/dom/builder_spec.rb +25 -8
- data/spec/dom/document_spec.rb +22 -0
- data/spec/dom/element/attributes_spec.rb +52 -0
- data/spec/dom/element/custom_spec.rb +106 -0
- data/spec/dom/element/subclass_spec.rb +144 -0
- data/spec/dom/element_spec.rb +181 -4
- data/spec/dom/mutation_observer_spec.rb +12 -8
- data/spec/dom/node_set_spec.rb +44 -0
- data/spec/dom/node_spec.rb +48 -0
- data/spec/dom_spec.rb +8 -0
- data/spec/event_source_spec.rb +15 -12
- data/spec/{dom/event_spec.rb → event_spec.rb} +44 -15
- data/spec/history_spec.rb +23 -19
- data/spec/http_spec.rb +19 -31
- data/spec/immediate_spec.rb +5 -4
- data/spec/interval_spec.rb +59 -0
- data/spec/native_cached_wrapper_spec.rb +46 -0
- data/spec/runner.rb +62 -69
- data/spec/socket_spec.rb +16 -12
- data/spec/spec_helper.rb +2 -5
- data/spec/spec_helper_promise.rb.erb +25 -0
- data/spec/storage_spec.rb +1 -1
- metadata +172 -50
- data/.travis.yml +0 -60
- data/opal/browser/dom/event.rb +0 -253
- data/opal/browser/http/parameters.rb +0 -8
- data/opal/browser/window/scroll.rb +0 -59
|
@@ -9,11 +9,11 @@ class MutationObserver
|
|
|
9
9
|
Browser.supports? :MutationObserver
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
include Native
|
|
12
|
+
include Native::Wrapper
|
|
13
13
|
|
|
14
14
|
# Encapsulates a recorded change.
|
|
15
15
|
class Record
|
|
16
|
-
include
|
|
16
|
+
include Browser::NativeCachedWrapper
|
|
17
17
|
|
|
18
18
|
# @!attribute [r] type
|
|
19
19
|
# @return [:attributes, :tree, :cdata] the type of the recorded change
|
|
@@ -49,7 +49,7 @@ class MutationObserver
|
|
|
49
49
|
[]
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
NodeSet
|
|
52
|
+
NodeSet[array]
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
# @!attribute [r] removed
|
|
@@ -61,7 +61,7 @@ class MutationObserver
|
|
|
61
61
|
[]
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
NodeSet
|
|
64
|
+
NodeSet[array]
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# @!attribute [r] target
|
data/opal/browser/dom/node.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Browser; module DOM
|
|
|
4
4
|
#
|
|
5
5
|
# @see https://developer.mozilla.org/en-US/docs/Web/API/Node
|
|
6
6
|
class Node
|
|
7
|
-
include
|
|
7
|
+
include Browser::NativeCachedWrapper
|
|
8
8
|
|
|
9
9
|
ELEMENT_NODE = 1
|
|
10
10
|
ATTRIBUTE_NODE = 2
|
|
@@ -38,20 +38,27 @@ class Node
|
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
def initialize(node)
|
|
42
|
+
raise ArgumentError, "Please ensure that #initialize of #{self.class} accepts one argument" unless node
|
|
43
|
+
super
|
|
44
|
+
end
|
|
45
|
+
|
|
41
46
|
# Return true of the other element is the same underlying DOM node.
|
|
42
47
|
#
|
|
43
48
|
# @return [Boolean]
|
|
44
49
|
def ==(other)
|
|
45
|
-
`#@native === #{Native.
|
|
50
|
+
`#@native === #{Native.convert(other)}`
|
|
46
51
|
end
|
|
47
52
|
|
|
48
|
-
#
|
|
53
|
+
# Initialize a new node after `#dup` or `#clone`.
|
|
49
54
|
#
|
|
50
|
-
#
|
|
55
|
+
# This method is not to be called directly. Use `Node#dup` or
|
|
56
|
+
# `Node#clone`.
|
|
51
57
|
#
|
|
52
|
-
#
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
# This method creates a deep detached clone of a DOM subtree to be used
|
|
59
|
+
# in the same document. The new node will have all events detached.
|
|
60
|
+
def initialize_copy(old)
|
|
61
|
+
set_native_reference `#{old.to_n}.cloneNode(true)`
|
|
55
62
|
end
|
|
56
63
|
|
|
57
64
|
# Append a child to the node.
|
|
@@ -65,36 +72,79 @@ class Node
|
|
|
65
72
|
#
|
|
66
73
|
# @return [self]
|
|
67
74
|
def <<(node)
|
|
68
|
-
if
|
|
75
|
+
if Opal.respond_to? node, :each
|
|
76
|
+
node.each { |n| self << n }
|
|
77
|
+
return self
|
|
78
|
+
elsif Opal.respond_to? node, :to_dom
|
|
79
|
+
node = node.to_dom(document)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
unless native?(node)
|
|
83
|
+
if String === node
|
|
84
|
+
node = `#@native.ownerDocument.createTextNode(node)`
|
|
85
|
+
else
|
|
86
|
+
node = Native.convert(node)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
`#@native.appendChild(node)`
|
|
91
|
+
|
|
92
|
+
self
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def >>(node)
|
|
96
|
+
if Opal.respond_to? node, :each
|
|
97
|
+
node.each { |n| self >> n }
|
|
98
|
+
return self
|
|
99
|
+
elsif Opal.respond_to? node, :to_dom
|
|
100
|
+
node = node.to_dom(document)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
unless native?(node)
|
|
104
|
+
if String === node
|
|
105
|
+
node = `#@native.ownerDocument.createTextNode(node)`
|
|
106
|
+
else
|
|
107
|
+
node = Native.convert(node)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if `#@native.firstChild == null`
|
|
69
112
|
`#@native.appendChild(node)`
|
|
70
|
-
elsif node.respond_to? :each
|
|
71
|
-
node.each { |n| add_child(n) }
|
|
72
|
-
elsif String === node
|
|
73
|
-
`#@native.appendChild(#@native.ownerDocument.createTextNode(node))`
|
|
74
113
|
else
|
|
75
|
-
`#@native.
|
|
114
|
+
`#@native.insertBefore(node, #@native.firstChild)`
|
|
76
115
|
end
|
|
77
116
|
|
|
78
117
|
self
|
|
79
118
|
end
|
|
80
119
|
|
|
81
|
-
|
|
120
|
+
def add_child(node = nil, &block)
|
|
121
|
+
unless node
|
|
122
|
+
node = DOM(&block)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
self << node
|
|
126
|
+
end
|
|
82
127
|
|
|
83
128
|
# Add the passed node after this one.
|
|
84
129
|
#
|
|
85
130
|
# When passing a {String} a text node will be created.
|
|
86
131
|
#
|
|
87
132
|
# @param node [String, Node, #to_n] the node to add
|
|
88
|
-
def add_next_sibling(node)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
133
|
+
def add_next_sibling(node = nil, &block)
|
|
134
|
+
unless node
|
|
135
|
+
node = DOM(&block)
|
|
136
|
+
end
|
|
137
|
+
node = node.to_dom(document) if Opal.respond_to? node, :to_dom
|
|
138
|
+
|
|
139
|
+
unless native?(node)
|
|
140
|
+
if String === node
|
|
141
|
+
node = `#@native.ownerDocument.createTextNode(node)`
|
|
142
|
+
else
|
|
143
|
+
node = Native.convert(node)
|
|
144
|
+
end
|
|
97
145
|
end
|
|
146
|
+
|
|
147
|
+
`#@native.parentNode.insertBefore(node, #@native.nextSibling)`
|
|
98
148
|
end
|
|
99
149
|
|
|
100
150
|
# Add the passed node before this one.
|
|
@@ -102,15 +152,21 @@ class Node
|
|
|
102
152
|
# When passing a {String} a text node will be created.
|
|
103
153
|
#
|
|
104
154
|
# @param node [String, Node, #to_n] the node to add
|
|
105
|
-
def add_previous_sibling(node)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
155
|
+
def add_previous_sibling(node = nil, &block)
|
|
156
|
+
unless node
|
|
157
|
+
node = DOM(&block)
|
|
158
|
+
end
|
|
159
|
+
node = node.to_dom(document) if Opal.respond_to? node, :to_dom
|
|
160
|
+
|
|
161
|
+
unless native?(node)
|
|
162
|
+
if String === node
|
|
163
|
+
node = `#@native.ownerDocument.createTextNode(node)`
|
|
164
|
+
else
|
|
165
|
+
node = Native.convert(node)
|
|
166
|
+
end
|
|
113
167
|
end
|
|
168
|
+
|
|
169
|
+
`#@native.parentNode.insertBefore(node, #@native)`
|
|
114
170
|
end
|
|
115
171
|
|
|
116
172
|
alias after add_next_sibling
|
|
@@ -119,7 +175,8 @@ class Node
|
|
|
119
175
|
#
|
|
120
176
|
# @param node [Node] the node to append to
|
|
121
177
|
def append_to(node)
|
|
122
|
-
node
|
|
178
|
+
node << self
|
|
179
|
+
self
|
|
123
180
|
end
|
|
124
181
|
|
|
125
182
|
# Get an array of ancestors.
|
|
@@ -130,7 +187,7 @@ class Node
|
|
|
130
187
|
#
|
|
131
188
|
# @return [NodeSet]
|
|
132
189
|
def ancestors(expression = nil)
|
|
133
|
-
return NodeSet
|
|
190
|
+
return NodeSet[] unless parent
|
|
134
191
|
|
|
135
192
|
parents = [parent]
|
|
136
193
|
|
|
@@ -143,12 +200,14 @@ class Node
|
|
|
143
200
|
end
|
|
144
201
|
|
|
145
202
|
if expression
|
|
146
|
-
parents.select! {|p|
|
|
147
|
-
p.matches? expression
|
|
148
|
-
}
|
|
203
|
+
parents.select! { |p| p =~ expression }
|
|
149
204
|
end
|
|
150
205
|
|
|
151
|
-
NodeSet.new
|
|
206
|
+
NodeSet.new(parents)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def attached?
|
|
210
|
+
`#@native.isConnected`
|
|
152
211
|
end
|
|
153
212
|
|
|
154
213
|
alias before add_previous_sibling
|
|
@@ -156,11 +215,12 @@ class Node
|
|
|
156
215
|
# Remove the node from its parent.
|
|
157
216
|
def remove
|
|
158
217
|
parent.remove_child(self) if parent
|
|
218
|
+
self
|
|
159
219
|
end
|
|
160
220
|
|
|
161
221
|
# Remove all the children of the node.
|
|
162
222
|
def clear
|
|
163
|
-
children.
|
|
223
|
+
children.remove
|
|
164
224
|
end
|
|
165
225
|
|
|
166
226
|
# @!attribute content
|
|
@@ -209,7 +269,7 @@ class Node
|
|
|
209
269
|
# @!attribute children
|
|
210
270
|
# @return [NodeSet] the children of the node
|
|
211
271
|
def children
|
|
212
|
-
NodeSet
|
|
272
|
+
NodeSet[Native::Array.new(`#@native.childNodes`)]
|
|
213
273
|
end
|
|
214
274
|
|
|
215
275
|
def children=(node)
|
|
@@ -221,12 +281,22 @@ class Node
|
|
|
221
281
|
node_type == COMMENT_NODE
|
|
222
282
|
end
|
|
223
283
|
|
|
224
|
-
#
|
|
284
|
+
# Return true if the node is a custom element.
|
|
285
|
+
def custom?
|
|
286
|
+
false
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# @!attribute [rw] document
|
|
225
290
|
# @return [Document?] the document the node is attached to
|
|
226
291
|
def document
|
|
227
292
|
DOM(`#@native.ownerDocument`) if defined?(`#@native.ownerDocument`)
|
|
228
293
|
end
|
|
229
294
|
|
|
295
|
+
# Detach a node and transfer it to another document.
|
|
296
|
+
def document=(new_document)
|
|
297
|
+
`#{Native.try_convert(new_document, new_document)}.adoptNode(#@native)`
|
|
298
|
+
end
|
|
299
|
+
|
|
230
300
|
# Return true if the node is a document.
|
|
231
301
|
def document?
|
|
232
302
|
node_type == DOCUMENT_NODE
|
|
@@ -258,16 +328,6 @@ class Node
|
|
|
258
328
|
node_type == DOCUMENT_FRAGMENT_NODE
|
|
259
329
|
end
|
|
260
330
|
|
|
261
|
-
# @!attribute inner_html
|
|
262
|
-
# @return [String] the inner HTML of the node
|
|
263
|
-
def inner_html
|
|
264
|
-
`#@native.innerHTML`
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def inner_html=(value)
|
|
268
|
-
`#@native.innerHTML = #{value}`
|
|
269
|
-
end
|
|
270
|
-
|
|
271
331
|
alias inner_text content
|
|
272
332
|
alias inner_text= content=
|
|
273
333
|
|
|
@@ -277,13 +337,6 @@ class Node
|
|
|
277
337
|
element_children.last
|
|
278
338
|
end
|
|
279
339
|
|
|
280
|
-
# Check if the node matches the given CSS selector.
|
|
281
|
-
#
|
|
282
|
-
# @param expression [String] the CSS selector
|
|
283
|
-
def matches?(expression)
|
|
284
|
-
false
|
|
285
|
-
end
|
|
286
|
-
|
|
287
340
|
# @!attribute name
|
|
288
341
|
# @return [String] the name of the node
|
|
289
342
|
def name
|
|
@@ -332,6 +385,14 @@ class Node
|
|
|
332
385
|
`#@native.nodeType`
|
|
333
386
|
end
|
|
334
387
|
|
|
388
|
+
# @!attribute outer_html
|
|
389
|
+
# @return [String] the simulated outer html of the node
|
|
390
|
+
def outer_html
|
|
391
|
+
div = $document.create_element("DIV")
|
|
392
|
+
div << self.dup
|
|
393
|
+
div.inner_html
|
|
394
|
+
end
|
|
395
|
+
|
|
335
396
|
# @!attribute parent
|
|
336
397
|
# @return [Element?] the parent of the node
|
|
337
398
|
def parent
|
|
@@ -339,7 +400,7 @@ class Node
|
|
|
339
400
|
end
|
|
340
401
|
|
|
341
402
|
def parent=(node)
|
|
342
|
-
`#@native.parentNode = #{Native.
|
|
403
|
+
`#@native.parentNode = #{Native.convert(node)}`
|
|
343
404
|
end
|
|
344
405
|
|
|
345
406
|
def parse(text, options = {})
|
|
@@ -350,6 +411,14 @@ class Node
|
|
|
350
411
|
raise NotImplementedError
|
|
351
412
|
end
|
|
352
413
|
|
|
414
|
+
# Prepend the node to the passed one.
|
|
415
|
+
#
|
|
416
|
+
# @param node [Node] the node to prepend to
|
|
417
|
+
def prepend_to(node)
|
|
418
|
+
node >> self
|
|
419
|
+
self
|
|
420
|
+
end
|
|
421
|
+
|
|
353
422
|
# @!attribute previous
|
|
354
423
|
# @return [Node?] the previous sibling of the node
|
|
355
424
|
def previous
|
|
@@ -375,6 +444,7 @@ class Node
|
|
|
375
444
|
# Remove the given node from the children of this node.
|
|
376
445
|
def remove_child(node)
|
|
377
446
|
`#@native.removeChild(#{Native.try_convert(node)})`
|
|
447
|
+
self
|
|
378
448
|
end
|
|
379
449
|
|
|
380
450
|
# Replace the node with the given one.
|
|
@@ -384,11 +454,23 @@ class Node
|
|
|
384
454
|
# @param node [Node] the node to replace with
|
|
385
455
|
# @return [Node] the passed node
|
|
386
456
|
def replace(node)
|
|
387
|
-
|
|
457
|
+
node = node.to_dom(document) if Opal.respond_to? node, :to_dom
|
|
458
|
+
|
|
459
|
+
unless native?(node)
|
|
460
|
+
if String === node
|
|
461
|
+
node = `#@native.ownerDocument.createTextNode(node)`
|
|
462
|
+
else
|
|
463
|
+
node = Native.convert(node)
|
|
464
|
+
end
|
|
465
|
+
end
|
|
388
466
|
|
|
389
|
-
node
|
|
467
|
+
`#@native.parentNode.replaceChild(node, #@native)`
|
|
468
|
+
|
|
469
|
+
DOM(node)
|
|
390
470
|
end
|
|
391
471
|
|
|
472
|
+
alias replace_with replace
|
|
473
|
+
|
|
392
474
|
alias text content
|
|
393
475
|
alias text= content=
|
|
394
476
|
|
|
@@ -1,25 +1,20 @@
|
|
|
1
1
|
module Browser; module DOM
|
|
2
2
|
|
|
3
|
+
# Allows manipulation of a set of {Node}s.
|
|
3
4
|
class NodeSet
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
list.each {|el|
|
|
11
|
-
if NodeSet === el
|
|
12
|
-
@literal.concat(el.to_a)
|
|
13
|
-
else
|
|
14
|
-
@literal.push DOM(Native.convert(el))
|
|
15
|
-
end
|
|
16
|
-
}
|
|
5
|
+
# Create a new {NodeSet} from the given nodes.
|
|
6
|
+
#
|
|
7
|
+
# Note that the nodes are flattened and converted with DOM automatically,
|
|
8
|
+
# this means you can pass {NodeSet}s and {Native::Array}s as well.
|
|
9
|
+
def self.[](*nodes)
|
|
10
|
+
new(nodes.flatten.map { |x| DOM(Native.convert(x)) }.uniq)
|
|
17
11
|
end
|
|
18
12
|
|
|
19
|
-
def
|
|
20
|
-
@literal
|
|
13
|
+
def initialize(literal)
|
|
14
|
+
@literal = literal
|
|
21
15
|
end
|
|
22
16
|
|
|
17
|
+
# Any other method will be called on every node in the set.
|
|
23
18
|
def method_missing(name, *args, &block)
|
|
24
19
|
unless @literal.respond_to? name
|
|
25
20
|
each {|el|
|
|
@@ -34,59 +29,93 @@ class NodeSet
|
|
|
34
29
|
if `result === #@literal`
|
|
35
30
|
self
|
|
36
31
|
elsif Array === result
|
|
37
|
-
NodeSet.new(
|
|
32
|
+
NodeSet.new(result)
|
|
38
33
|
else
|
|
39
34
|
result
|
|
40
35
|
end
|
|
41
36
|
end
|
|
42
37
|
|
|
43
|
-
def
|
|
44
|
-
|
|
38
|
+
def respond_to_missing?(name, *)
|
|
39
|
+
@literal.respond_to?(name)
|
|
45
40
|
end
|
|
46
41
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
# Get the first node matching the given CSS selectors.
|
|
43
|
+
#
|
|
44
|
+
# @param rules [Array<String>] the CSS selectors to match with
|
|
45
|
+
#
|
|
46
|
+
# @return [Node?]
|
|
47
|
+
def at_css(*rules)
|
|
48
|
+
each {|node|
|
|
49
|
+
if node = node.at_css(*rules)
|
|
50
|
+
return node
|
|
51
|
+
end
|
|
52
|
+
}
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
last.after node
|
|
54
|
+
nil
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
# Get the first node matching the given XPath.
|
|
58
|
+
#
|
|
59
|
+
# @param paths [Array<String>] the XPath to match with
|
|
60
|
+
#
|
|
61
|
+
# @return [Node?]
|
|
62
|
+
def at_xpath(*paths)
|
|
63
|
+
each {|node|
|
|
64
|
+
if node = node.at_xpath(*paths)
|
|
65
|
+
return node
|
|
66
|
+
end
|
|
67
|
+
}
|
|
58
68
|
|
|
59
|
-
|
|
60
|
-
raise NotImplementedError
|
|
69
|
+
nil
|
|
61
70
|
end
|
|
62
71
|
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
# Query for children matching the given CSS selector.
|
|
73
|
+
#
|
|
74
|
+
# @param path [String] the CSS selector
|
|
75
|
+
#
|
|
76
|
+
# @return [NodeSet]
|
|
77
|
+
def css(path)
|
|
78
|
+
NodeSet[@literal.map {|node|
|
|
79
|
+
node.css(path)
|
|
80
|
+
}]
|
|
65
81
|
end
|
|
66
82
|
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
# Create another {NodeSet} with all the nodes that match the given
|
|
84
|
+
# expression.
|
|
85
|
+
#
|
|
86
|
+
# @param expression [String] a CSS selector
|
|
87
|
+
#
|
|
88
|
+
# @return [NodeSet] the new {NodeSet} with the matching nodes
|
|
89
|
+
def filter(expression)
|
|
90
|
+
NodeSet[@literal.select { |node| node =~ expression }]
|
|
69
91
|
end
|
|
70
92
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
each { |n| result.concat(n.children) }
|
|
75
|
-
|
|
76
|
-
result
|
|
93
|
+
# Search for multiple selectors
|
|
94
|
+
def search(*what)
|
|
95
|
+
NodeSet[@literal.map { |node| node.search(*what) }]
|
|
77
96
|
end
|
|
78
97
|
|
|
79
|
-
|
|
80
|
-
|
|
98
|
+
# Outer HTML of the entire nodeset
|
|
99
|
+
def outer_html
|
|
100
|
+
@literal.map(&:outer_html).join
|
|
81
101
|
end
|
|
82
102
|
|
|
83
|
-
|
|
84
|
-
|
|
103
|
+
# Query for children matching the given XPath.
|
|
104
|
+
#
|
|
105
|
+
# @param path [String] the XPath
|
|
106
|
+
#
|
|
107
|
+
# @return [NodeSet]
|
|
108
|
+
def xpath(path)
|
|
109
|
+
NodeSet[@literal.map {|node|
|
|
110
|
+
node.xpath(path)
|
|
111
|
+
}]
|
|
85
112
|
end
|
|
86
113
|
|
|
87
|
-
def
|
|
88
|
-
|
|
114
|
+
def to_ary
|
|
115
|
+
@literal
|
|
89
116
|
end
|
|
117
|
+
|
|
118
|
+
alias to_a to_ary
|
|
90
119
|
end
|
|
91
120
|
|
|
92
121
|
end; end
|
data/opal/browser/dom/text.rb
CHANGED
|
@@ -5,8 +5,8 @@ module Browser; module DOM
|
|
|
5
5
|
# @see https://developer.mozilla.org/en-US/docs/Web/API/Text
|
|
6
6
|
class Text < CharacterData
|
|
7
7
|
# (see Document#create_text)
|
|
8
|
-
def self.create(
|
|
9
|
-
$document.create_text(
|
|
8
|
+
def self.create(content)
|
|
9
|
+
$document.create_text(content)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
# @!attribute [r] whole
|
data/opal/browser/dom.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'browser/dom/event'
|
|
2
1
|
require 'browser/dom/node_set'
|
|
3
2
|
require 'browser/dom/node'
|
|
4
3
|
require 'browser/dom/attribute'
|
|
@@ -7,9 +6,10 @@ require 'browser/dom/text'
|
|
|
7
6
|
require 'browser/dom/cdata'
|
|
8
7
|
require 'browser/dom/comment'
|
|
9
8
|
require 'browser/dom/element'
|
|
9
|
+
require 'browser/dom/document_or_shadow_root'
|
|
10
10
|
require 'browser/dom/document'
|
|
11
11
|
require 'browser/dom/document_fragment'
|
|
12
|
-
require 'browser/dom/
|
|
12
|
+
require 'browser/dom/shadow_root'
|
|
13
13
|
require 'browser/dom/mutation_observer'
|
|
14
14
|
|
|
15
15
|
module Kernel
|
|
@@ -34,29 +34,59 @@ module Kernel
|
|
|
34
34
|
DOM(`doc`)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
#
|
|
37
|
+
# @overload DOM(document = $document, &block)
|
|
38
|
+
#
|
|
39
|
+
# Create a DOM tree using the {Paggio::HTML} DSL.
|
|
40
|
+
#
|
|
41
|
+
# @param document [Browser::DOM::Document] the document instance
|
|
42
|
+
# we intend to use
|
|
43
|
+
#
|
|
44
|
+
# @return [Browser::DOM::Node, Browser::DOM::NodeSet]
|
|
45
|
+
#
|
|
46
|
+
# @overload DOM(string, document = $document)
|
|
47
|
+
#
|
|
48
|
+
# Create a DOM tree from a HTML string.
|
|
49
|
+
#
|
|
50
|
+
# @param string [String] the HTML string
|
|
51
|
+
# @param document [Browser::DOM::Document] the document instance
|
|
52
|
+
# we intend to use
|
|
53
|
+
#
|
|
54
|
+
# @return [Browser::DOM::Node]
|
|
55
|
+
#
|
|
56
|
+
# @overload DOM(native)
|
|
57
|
+
#
|
|
58
|
+
# Wrap a native element to create a DOM tree.
|
|
59
|
+
#
|
|
60
|
+
# @param native [Native] the Native node
|
|
61
|
+
#
|
|
62
|
+
# @return [Browser::DOM::Node]
|
|
38
63
|
#
|
|
39
|
-
# @return [Browser::DOM::Node]
|
|
40
64
|
def DOM(*args, &block)
|
|
41
65
|
if block
|
|
42
66
|
document = args.shift || $document
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
roots = Browser::DOM::Builder.new(document, element, &block).to_a
|
|
67
|
+
roots = Browser::DOM::Builder.new(document, &block).to_a
|
|
46
68
|
|
|
47
69
|
if roots.length == 1
|
|
48
70
|
roots.first
|
|
49
71
|
else
|
|
50
|
-
Browser::DOM::NodeSet.new(
|
|
72
|
+
Browser::DOM::NodeSet.new(roots)
|
|
51
73
|
end
|
|
52
74
|
else
|
|
53
75
|
what = args.shift
|
|
54
76
|
document = args.shift || $document
|
|
55
77
|
|
|
56
|
-
if
|
|
78
|
+
what = what.to_dom(document) if Opal.respond_to? what, :to_dom
|
|
79
|
+
|
|
80
|
+
if `typeof(#{what}) === 'undefined' || #{what} === null`
|
|
81
|
+
raise ArgumentError, 'argument is null'
|
|
82
|
+
elsif native?(what)
|
|
57
83
|
Browser::DOM::Node.new(what)
|
|
58
84
|
elsif Browser::DOM::Node === what
|
|
59
85
|
what
|
|
86
|
+
elsif Opal.respond_to? what, :each # eg. NodeSet, Array
|
|
87
|
+
document.create_element("DIV").tap do |div|
|
|
88
|
+
div << what
|
|
89
|
+
end
|
|
60
90
|
elsif String === what
|
|
61
91
|
%x{
|
|
62
92
|
var doc = #{Native.try_convert(document)}.createElement('div');
|
|
@@ -65,7 +95,7 @@ module Kernel
|
|
|
65
95
|
return #{DOM(`doc.childNodes.length == 1 ? doc.childNodes[0] : doc`)};
|
|
66
96
|
}
|
|
67
97
|
else
|
|
68
|
-
raise ArgumentError,
|
|
98
|
+
raise ArgumentError, 'argument is not DOM convertible'
|
|
69
99
|
end
|
|
70
100
|
end
|
|
71
101
|
end
|
|
@@ -74,12 +104,6 @@ end
|
|
|
74
104
|
module Browser
|
|
75
105
|
|
|
76
106
|
class Window
|
|
77
|
-
include DOM::Event::Target
|
|
78
|
-
|
|
79
|
-
target {|value|
|
|
80
|
-
$window if `#{value} == window`
|
|
81
|
-
}
|
|
82
|
-
|
|
83
107
|
# Get the {DOM::Document} for this window.
|
|
84
108
|
#
|
|
85
109
|
# @return [DOM::Document]
|