opal-browser 0.1.0.beta1

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.
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