opal-browser 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +11 -0
  5. data/README.md +106 -0
  6. data/Rakefile +5 -0
  7. data/config.ru +63 -0
  8. data/lib/opal/browser.rb +4 -0
  9. data/opal-browser.gemspec +23 -0
  10. data/opal/browser.rb +10 -0
  11. data/opal/browser/animation_frame.rb +29 -0
  12. data/opal/browser/canvas.rb +277 -0
  13. data/opal/browser/canvas/data.rb +73 -0
  14. data/opal/browser/canvas/gradient.rb +37 -0
  15. data/opal/browser/canvas/style.rb +123 -0
  16. data/opal/browser/canvas/text.rb +55 -0
  17. data/opal/browser/compatibility.rb +59 -0
  18. data/opal/browser/compatibility/animation_frame.rb +93 -0
  19. data/opal/browser/compatibility/dom/document/window.rb +15 -0
  20. data/opal/browser/compatibility/dom/element/css.rb +15 -0
  21. data/opal/browser/compatibility/dom/element/matches.rb +31 -0
  22. data/opal/browser/compatibility/dom/element/offset.rb +20 -0
  23. data/opal/browser/compatibility/dom/element/scroll.rb +25 -0
  24. data/opal/browser/compatibility/dom/element/style.rb +15 -0
  25. data/opal/browser/compatibility/dom/mutation_observer.rb +47 -0
  26. data/opal/browser/compatibility/http/request.rb +15 -0
  27. data/opal/browser/compatibility/immediate.rb +107 -0
  28. data/opal/browser/compatibility/window/scroll.rb +27 -0
  29. data/opal/browser/compatibility/window/size.rb +13 -0
  30. data/opal/browser/compatibility/window/view.rb +13 -0
  31. data/opal/browser/console.rb +137 -0
  32. data/opal/browser/cookies.rb +79 -0
  33. data/opal/browser/css.rb +24 -0
  34. data/opal/browser/css/declaration.rb +88 -0
  35. data/opal/browser/css/rule.rb +48 -0
  36. data/opal/browser/css/rule/style.rb +16 -0
  37. data/opal/browser/css/style_sheet.rb +83 -0
  38. data/opal/browser/css/unit.rb +188 -0
  39. data/opal/browser/dom.rb +95 -0
  40. data/opal/browser/dom/attribute.rb +19 -0
  41. data/opal/browser/dom/builder.rb +97 -0
  42. data/opal/browser/dom/cdata.rb +9 -0
  43. data/opal/browser/dom/character_data.rb +37 -0
  44. data/opal/browser/dom/comment.rb +9 -0
  45. data/opal/browser/dom/compatibility.rb +8 -0
  46. data/opal/browser/dom/document.rb +83 -0
  47. data/opal/browser/dom/document_fragment.rb +7 -0
  48. data/opal/browser/dom/element.rb +290 -0
  49. data/opal/browser/dom/element/input.rb +17 -0
  50. data/opal/browser/dom/element/offset.rb +67 -0
  51. data/opal/browser/dom/element/position.rb +37 -0
  52. data/opal/browser/dom/element/scroll.rb +49 -0
  53. data/opal/browser/dom/event.rb +240 -0
  54. data/opal/browser/dom/event/animation.rb +26 -0
  55. data/opal/browser/dom/event/audio_processing.rb +31 -0
  56. data/opal/browser/dom/event/base.rb +207 -0
  57. data/opal/browser/dom/event/before_unload.rb +13 -0
  58. data/opal/browser/dom/event/clipboard.rb +26 -0
  59. data/opal/browser/dom/event/close.rb +35 -0
  60. data/opal/browser/dom/event/composition.rb +38 -0
  61. data/opal/browser/dom/event/custom.rb +30 -0
  62. data/opal/browser/dom/event/device_light.rb +21 -0
  63. data/opal/browser/dom/event/device_motion.rb +38 -0
  64. data/opal/browser/dom/event/device_orientation.rb +36 -0
  65. data/opal/browser/dom/event/device_proximity.rb +31 -0
  66. data/opal/browser/dom/event/drag.rb +113 -0
  67. data/opal/browser/dom/event/focus.rb +23 -0
  68. data/opal/browser/dom/event/gamepad.rb +47 -0
  69. data/opal/browser/dom/event/hash_change.rb +26 -0
  70. data/opal/browser/dom/event/keyboard.rb +93 -0
  71. data/opal/browser/dom/event/message.rb +50 -0
  72. data/opal/browser/dom/event/mouse.rb +253 -0
  73. data/opal/browser/dom/event/page_transition.rb +21 -0
  74. data/opal/browser/dom/event/pop_state.rb +21 -0
  75. data/opal/browser/dom/event/progress.rb +31 -0
  76. data/opal/browser/dom/event/sensor.rb +13 -0
  77. data/opal/browser/dom/event/storage.rb +41 -0
  78. data/opal/browser/dom/event/touch.rb +69 -0
  79. data/opal/browser/dom/event/ui.rb +22 -0
  80. data/opal/browser/dom/event/wheel.rb +49 -0
  81. data/opal/browser/dom/mutation_observer.rb +118 -0
  82. data/opal/browser/dom/node.rb +317 -0
  83. data/opal/browser/dom/node_set.rb +88 -0
  84. data/opal/browser/dom/text.rb +21 -0
  85. data/opal/browser/effects.rb +39 -0
  86. data/opal/browser/event_source.rb +67 -0
  87. data/opal/browser/history.rb +54 -0
  88. data/opal/browser/http.rb +129 -0
  89. data/opal/browser/http/binary.rb +57 -0
  90. data/opal/browser/http/compatibility.rb +1 -0
  91. data/opal/browser/http/headers.rb +90 -0
  92. data/opal/browser/http/parameters.rb +8 -0
  93. data/opal/browser/http/request.rb +331 -0
  94. data/opal/browser/http/response.rb +115 -0
  95. data/opal/browser/immediate.rb +43 -0
  96. data/opal/browser/interval.rb +93 -0
  97. data/opal/browser/location.rb +77 -0
  98. data/opal/browser/navigator.rb +151 -0
  99. data/opal/browser/screen.rb +40 -0
  100. data/opal/browser/socket.rb +115 -0
  101. data/opal/browser/storage.rb +149 -0
  102. data/opal/browser/timeout.rb +60 -0
  103. data/opal/browser/utils.rb +56 -0
  104. data/opal/browser/version.rb +3 -0
  105. data/opal/browser/window.rb +113 -0
  106. data/opal/browser/window/compatibility.rb +3 -0
  107. data/opal/browser/window/scroll.rb +49 -0
  108. data/opal/browser/window/size.rb +35 -0
  109. data/opal/browser/window/view.rb +18 -0
  110. data/spec/dom/builder_spec.rb +69 -0
  111. data/spec/dom/document_spec.rb +40 -0
  112. data/spec/dom/element_spec.rb +46 -0
  113. data/spec/dom/event_spec.rb +127 -0
  114. data/spec/dom/mutation_observer_spec.rb +37 -0
  115. data/spec/dom/node_spec.rb +154 -0
  116. data/spec/dom_spec.rb +13 -0
  117. data/spec/event_source_spec.rb +42 -0
  118. data/spec/history_spec.rb +48 -0
  119. data/spec/http_spec.rb +87 -0
  120. data/spec/immediate_spec.rb +12 -0
  121. data/spec/json2.js +486 -0
  122. data/spec/sizzle.js +5 -0
  123. data/spec/socket_spec.rb +43 -0
  124. data/spec/spec_helper.rb +37 -0
  125. data/spec/storage_spec.rb +26 -0
  126. data/spec/window_spec.rb +10 -0
  127. metadata +240 -0
@@ -0,0 +1,21 @@
1
+ module Browser; module DOM; class Event
2
+
3
+ class PageTransition < Event
4
+ def self.supported?
5
+ not $$[:PageTransitionEvent].nil?
6
+ end
7
+
8
+ class Definition < Definition
9
+ def persisted=(value)
10
+ `#@native.persisted = #{value}`
11
+ end
12
+ end
13
+
14
+ def self.create(name, &block)
15
+ new(`new PageTransitionEvent(#{name}, #{Definition.new(&block)})`)
16
+ end
17
+
18
+ alias_native :persisted?, :persisted
19
+ end
20
+
21
+ end; end; end
@@ -0,0 +1,21 @@
1
+ module Browser; module DOM; class Event
2
+
3
+ class PopState < Event
4
+ def self.supported?
5
+ not $$[:PopStateEvent].nil?
6
+ end
7
+
8
+ class Definition < Definition
9
+ def state=(value)
10
+ `#@native.state = #{value}`
11
+ end
12
+ end
13
+
14
+ def self.create(name, &block)
15
+ new(`new PopStateEvent(#{name}, #{Definition.new(&block)})`)
16
+ end
17
+
18
+ alias_native :state
19
+ end
20
+
21
+ end; end; end
@@ -0,0 +1,31 @@
1
+ module Browser; module DOM; class Event
2
+
3
+ class Progress < Event
4
+ def self.supported?
5
+ not $$[:ProgressEvent].nil?
6
+ end
7
+
8
+ class Definition < Definition
9
+ def computable=(value)
10
+ `#@native.computableLength = #{value}`
11
+ end
12
+
13
+ def loaded=(value)
14
+ `#@native.loaded = #{value}`
15
+ end
16
+
17
+ def total=(value)
18
+ `#@native.total = #{value}`
19
+ end
20
+ end
21
+
22
+ def self.create(name, &block)
23
+ new(`new ProgressEvent(#{name}, #{Definition.new(&block)})`)
24
+ end
25
+
26
+ alias_native :computable?, :computableLength
27
+ alias_native :loaded
28
+ alias_native :total
29
+ end
30
+
31
+ end; end; end
@@ -0,0 +1,13 @@
1
+ module Browser; module DOM; class Event
2
+
3
+ class Sensor < Event
4
+ def self.supported?
5
+ not $$[:SensorEvent].nil?
6
+ end
7
+
8
+ def self.create(name, &block)
9
+ new(`new SensorEvent(#{name}, #{Definition.new(&block)})`)
10
+ end
11
+ end
12
+
13
+ end; end; end
@@ -0,0 +1,41 @@
1
+ module Browser; module DOM; class Event
2
+
3
+ class Storage < Event
4
+ def self.supported?
5
+ not $$[:StorageEvent].nil?
6
+ end
7
+
8
+ class Definition < Definition
9
+ def key=(value)
10
+ `#@native.key = #{value}`
11
+ end
12
+
13
+ def new=(value)
14
+ `#@native.newValue = #{value}`
15
+ end
16
+
17
+ def old=(value)
18
+ `#@native.oldValue = #{value}`
19
+ end
20
+
21
+ def area=(value)
22
+ `#@native.storageArea = #{value}`
23
+ end
24
+
25
+ def url=(value)
26
+ `#@native.url = #{value}`
27
+ end
28
+ end
29
+
30
+ def self.create(name, &block)
31
+ new(`new StorageEvent(#{name}, #{Definition.new(&block)})`)
32
+ end
33
+
34
+ alias_native :key
35
+ alias_native :new, :newValue
36
+ alias_native :old, :oldValue
37
+ alias_native :area, :storageArea
38
+ alias_native :url
39
+ end
40
+
41
+ end; end; end
@@ -0,0 +1,69 @@
1
+ module Browser; module DOM; class Event
2
+
3
+ class Touch < Event
4
+ def self.supported?
5
+ not $$[:TouchEvent].nil?
6
+ end
7
+
8
+ class Definition < Definition
9
+ def alt!
10
+ `#@native.altKey = true`
11
+ end
12
+
13
+ def ctrl!
14
+ `#@native.ctrlKey = true`
15
+ end
16
+
17
+ def meta!
18
+ `#@native.metaKey = true`
19
+ end
20
+
21
+ def shift!
22
+ `#@native.shiftKey = true`
23
+ end
24
+ end
25
+
26
+ def self.create(name, &block)
27
+ new(`new TouchEvent(#{name}, #{Definition.new(&block)})`)
28
+ end
29
+
30
+ def alt?
31
+ `#@native.altKey`
32
+ end
33
+
34
+ def ctrl?
35
+ `#@native.ctrlKey`
36
+ end
37
+
38
+ def meta?
39
+ `#@native.metaKey`
40
+ end
41
+
42
+ def shift?
43
+ `#@native.shiftKey`
44
+ end
45
+
46
+ # TODO: implement touches and targetTouches
47
+
48
+ def cancel?
49
+ name.downcase == 'touchcancel'
50
+ end
51
+
52
+ def end?
53
+ name.downcase == 'touchend'
54
+ end
55
+
56
+ def leave?
57
+ name.downcase == 'touchleave'
58
+ end
59
+
60
+ def move?
61
+ name.downcase == 'touchmove'
62
+ end
63
+
64
+ def start?
65
+ name.downcase == 'touchstart'
66
+ end
67
+ end
68
+
69
+ end; end; end
@@ -0,0 +1,22 @@
1
+ module Browser; module DOM; class Event
2
+
3
+ class UI < Event
4
+ class Definition < Definition
5
+ def detail=(value)
6
+ `#@native.detail = #{value}`
7
+ end
8
+
9
+ def view=(value)
10
+ `#@native.view = #{value}`
11
+ end
12
+ end
13
+
14
+ def self.create(name, &block)
15
+ new(`new UIEvent(#{name}, #{Definition.new(&block)})`)
16
+ end
17
+
18
+ alias_native :detail
19
+ alias_native :view
20
+ end
21
+
22
+ end; end; end
@@ -0,0 +1,49 @@
1
+ module Browser; module DOM; class Event
2
+
3
+ class Wheel < UI
4
+ def self.supported?
5
+ not $$[:WheelEvent].nil?
6
+ end
7
+
8
+ class Definition < Definition
9
+ def x=(value)
10
+ `#@native.deltaX = #{value}`
11
+ end
12
+
13
+ def y=(value)
14
+ `#@native.deltaY = #{value}`
15
+ end
16
+
17
+ def z=(value)
18
+ `#@native.deltaZ = #{value}`
19
+ end
20
+
21
+ def mode=(value)
22
+ value = case value
23
+ when :pixel then `WheelEvent.DOM_DELTA_PIXEL`
24
+ when :line then `WheelEvent.DOM_DELTA_LINE`
25
+ when :page then `WheelEvent.DOM_DELTA_PAGE`
26
+ end
27
+
28
+ `#@native.deltaMode = #{value}`
29
+ end
30
+ end
31
+
32
+ def self.create(name, &block)
33
+ new(`new WheelEvent(#{name}, #{Definition.new(&block)})`)
34
+ end
35
+
36
+ alias_native :x, :deltaX
37
+ alias_native :y, :deltaY
38
+ alias_native :z, :deltaZ
39
+
40
+ def mode
41
+ case `#@native.deltaMode`
42
+ when `WheelEvent.DOM_DELTA_PIXEL` then :pixel
43
+ when `WheelEvent.DOM_DELTA_LINE` then :line
44
+ when `WheelEvent.DOM_DELTA_PAGE` then :page
45
+ end
46
+ end
47
+ end
48
+
49
+ end; end; end
@@ -0,0 +1,118 @@
1
+ module Browser; module DOM
2
+
3
+ class MutationObserver
4
+ include Native
5
+
6
+ class Record
7
+ include Native
8
+
9
+ def type
10
+ case `#@native.type`
11
+ when :attributes then :attributes
12
+ when :childList then :tree
13
+ when :characterData then :cdata
14
+ end
15
+ end
16
+
17
+ def attributes?; type == :attributes; end
18
+ def tree?; type == :tree; end
19
+ def cdata?; type == :cdata; end
20
+
21
+ def added
22
+ array = if `#@native.addedNodes != null`
23
+ Native::Array.new(`#@native.addedNodes`)
24
+ else
25
+ []
26
+ end
27
+
28
+ NodeSet.new($document, array)
29
+ end
30
+
31
+ def removed
32
+ array = if `#@native.removedNodes != null`
33
+ Native::Array.new(`#@native.removedNodes`)
34
+ else
35
+ []
36
+ end
37
+
38
+ NodeSet.new($document, array)
39
+ end
40
+
41
+ def target
42
+ DOM(`#@native.target`)
43
+ end
44
+
45
+ alias_native :old, :oldValue
46
+ alias_native :attribute, :attributeName
47
+ end
48
+
49
+ def initialize(&block)
50
+ %x{
51
+ var func = function(records) {
52
+ return #{block.call(`records`.map { |r| Browser::DOM::MutationObserver::Record.new(r) })};
53
+ }
54
+ }
55
+
56
+ super(`new window.MutationObserver(func)`)
57
+ end
58
+
59
+ def observe(target, options = nil)
60
+ unless options
61
+ options = {
62
+ children: true,
63
+ tree: true,
64
+ attributes: :old,
65
+ cdata: :old
66
+ }
67
+ end
68
+
69
+ `#@native.observe(#{Native.convert(target)}, #{convert(options)})`
70
+
71
+ self
72
+ end
73
+
74
+ def take
75
+ `#@native.takeRecords()`.map { |r| Record.new(r) }
76
+ end
77
+
78
+ def disconnect
79
+ `#@native.disconnect()`
80
+ end
81
+
82
+ private
83
+ def convert(hash)
84
+ options = Native(`{}`)
85
+
86
+ if hash[:children]
87
+ options[:childList] = true
88
+ end
89
+
90
+ if hash[:tree]
91
+ options[:subtree] = true
92
+ end
93
+
94
+ if attrs = hash[:attributes]
95
+ options[:attributes] = true
96
+
97
+ if attrs == :old
98
+ options[:attributeOldValue] = true
99
+ end
100
+ end
101
+
102
+ if filter = hash[:filter]
103
+ options[:attributeFilter] = filter
104
+ end
105
+
106
+ if cdata = hash[:cdata]
107
+ options[:characterData] = true
108
+
109
+ if cdata == :old
110
+ options[:characterDataOldValue] = true
111
+ end
112
+ end
113
+
114
+ options.to_n
115
+ end
116
+ end
117
+
118
+ end; end
@@ -0,0 +1,317 @@
1
+ module Browser; module DOM
2
+
3
+ class Node
4
+ include Native
5
+
6
+ ELEMENT_NODE = 1
7
+ ATTRIBUTE_NODE = 2
8
+ TEXT_NODE = 3
9
+ CDATA_SECTION_NODE = 4
10
+ ENTITY_REFERENCE_NOCE = 5
11
+ ENTITY_NODE = 6
12
+ PROCESSING_INSTRUCTION_NODE = 7
13
+ COMMENT_NODE = 8
14
+ DOCUMENT_NODE = 9
15
+ DOCUMENT_TYPE_NODE = 10
16
+ DOCUMENT_FRAGMENT_NODE = 11
17
+ NOTATION_NODE = 12
18
+
19
+ def self.new(value)
20
+ if self == Node
21
+ @classes ||= [nil, Element, Attribute, Text, CDATA, nil, nil, nil, Comment, Document, nil, DocumentFragment]
22
+
23
+ if klass = @classes[`value.nodeType`]
24
+ klass.new(value)
25
+ else
26
+ raise ArgumentError, 'cannot instantiate a non derived Node object'
27
+ end
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def ==(other)
34
+ `#@native === #{Native.try_convert(other)}`
35
+ end
36
+
37
+ def =~(name)
38
+ self.name.downcase == name.downcase
39
+ end
40
+
41
+ def <<(node)
42
+ add_child(node)
43
+ end
44
+
45
+ def <=>(other)
46
+ raise NotImplementedError
47
+ end
48
+
49
+ def add_child(node)
50
+ if native?(node)
51
+ `#@native.appendChild(node)`
52
+ elsif node.respond_to? :each
53
+ node.each { |n| add_child(n) }
54
+ elsif String === node
55
+ `#@native.appendChild(#@native.ownerDocument.createTextNode(node))`
56
+ else
57
+ `#@native.appendChild(#{Native.convert(node)})`
58
+ end
59
+
60
+ self
61
+ end
62
+
63
+ def add_next_sibling(node)
64
+ `#@native.parentNode.insertBefore(node, #@native.nextSibling)`
65
+
66
+ self
67
+ end
68
+
69
+ def add_previous_sibling(node)
70
+ `#@native.parentNode.insertBefore(node, #@native)`
71
+
72
+ self
73
+ end
74
+
75
+ alias after add_next_sibling
76
+
77
+ def append_to(element)
78
+ element.add_child(self)
79
+
80
+ self
81
+ end
82
+
83
+ def ancestors(expression = nil)
84
+ return NodeSet.new(document) unless parent
85
+
86
+ parents = [parent]
87
+
88
+ while parent = parents.last.parent
89
+ parents << parent
90
+ end
91
+
92
+ if Document === parents.last
93
+ parents.pop
94
+ end
95
+
96
+ return NodeSet.new(document, parents) unless expression
97
+
98
+ NodeSet.new document, parents.select {|p|
99
+ p.matches?(expression)
100
+ }
101
+ end
102
+
103
+ alias before add_previous_sibling
104
+
105
+ def remove
106
+ detach
107
+ clear
108
+
109
+ self
110
+ end
111
+
112
+ def detach
113
+ parent.remove_child(self) if parent
114
+
115
+ self
116
+ end
117
+
118
+ def clear; end
119
+
120
+ def remove_child(element)
121
+ `#@native.removeChild(#{Native.try_convert(element)})`
122
+
123
+ self
124
+ end
125
+
126
+ def clear
127
+ children.each(&:remove)
128
+ end
129
+
130
+ def blank?
131
+ raise NotImplementedError
132
+ end
133
+
134
+ def cdata?
135
+ node_type == CDATA_SECTION_NODE
136
+ end
137
+
138
+ def child
139
+ children.first
140
+ end
141
+
142
+ def children
143
+ NodeSet.new(document, Native::Array.new(`#@native.childNodes`))
144
+ end
145
+
146
+ def children=(node)
147
+ raise NotImplementedError
148
+ end
149
+
150
+ def comment?
151
+ node_type == COMMENT_NODE
152
+ end
153
+
154
+ def document
155
+ DOM(`#@native.ownerDocument`)
156
+ end
157
+
158
+ def document?
159
+ node_type == DOCUMENT_NODE
160
+ end
161
+
162
+ def elem?
163
+ node_type == ELEMENT_NODE
164
+ end
165
+
166
+ alias element? elem?
167
+
168
+ def element_children
169
+ children.select(&:element?)
170
+ end
171
+
172
+ alias elements element_children
173
+
174
+ def first_element_child
175
+ element_children.first
176
+ end
177
+
178
+ def fragment?
179
+ node_type == DOCUMENT_FRAGMENT_NODE
180
+ end
181
+
182
+ def hash
183
+ # TODO: implement this properly
184
+ end
185
+
186
+ def inner_html(*)
187
+ `#@native.innerHTML`
188
+ end
189
+
190
+ def inner_html=(value)
191
+ `#@native.innerHTML = #{value}`
192
+ end
193
+
194
+ def inner_text(*)
195
+ `#@native.textContent`
196
+ end
197
+
198
+ alias content inner_text
199
+
200
+ def inner_text=(value)
201
+ `#@native.textContent = #{value}`
202
+ end
203
+
204
+ alias content= inner_text=
205
+
206
+ def last_element_child
207
+ element_children.last
208
+ end
209
+
210
+ def matches?(expression)
211
+ false
212
+ end
213
+
214
+ def name
215
+ `#@native.nodeName || nil`
216
+ end
217
+
218
+ def name=(value)
219
+ `#@native.nodeName = #{value.to_s}`
220
+ end
221
+
222
+ def namespace
223
+ `#@native.namespaceURI || nil`
224
+ end
225
+
226
+ def next
227
+ DOM(`#@native.nextSibling`) if `#@native.nextSibling != null`
228
+ end
229
+
230
+ def next_element
231
+ current = self.next
232
+
233
+ while current && !current.element?
234
+ current = current.next
235
+ end
236
+
237
+ current
238
+ end
239
+
240
+ alias next_sibling next
241
+
242
+ alias node_name name
243
+
244
+ alias node_name= name=
245
+
246
+ def node_type
247
+ `#@native.nodeType`
248
+ end
249
+
250
+ def parent
251
+ DOM(`#@native.parentNode`) if `#@native.parentNode != null`
252
+ end
253
+
254
+ def parent= (node)
255
+ `#@native.parentNode = #{Native.try_convert(node)}`
256
+ end
257
+
258
+ def parse (text, options = {})
259
+ raise NotImplementedError
260
+ end
261
+
262
+ def path
263
+ raise NotImplementedError
264
+ end
265
+
266
+ def previous
267
+ DOM(`#@native.previousSibling`) if `#@native.previousSibling != null`
268
+ end
269
+
270
+ alias previous= add_previous_sibling
271
+
272
+ def previous_element
273
+ current = self.previous
274
+
275
+ while current && !current.element?
276
+ current = current.previous
277
+ end
278
+
279
+ current
280
+ end
281
+
282
+ alias previous_sibling previous
283
+
284
+ # TODO: implement for NodeSet
285
+ def replace(node)
286
+ `#@native.parentNode.replaceChild(#@native, #{Native.try_convert(node)})`
287
+
288
+ node
289
+ end
290
+
291
+ alias text inner_text
292
+ alias text= inner_text=
293
+
294
+ def text?
295
+ node_type == TEXT_NODE
296
+ end
297
+
298
+ def traverse(&block)
299
+ raise NotImplementedError
300
+ end
301
+
302
+ alias type node_type
303
+
304
+ def value
305
+ `#@native.nodeValue || nil`
306
+ end
307
+
308
+ def value=(value)
309
+ `#@native.nodeValue = value`
310
+ end
311
+
312
+ def inspect
313
+ "#<DOM::Node: #{name}>"
314
+ end
315
+ end
316
+
317
+ end; end