opal-browser 0.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.yardopts +1 -0
- data/Gemfile +11 -0
- data/README.md +106 -0
- data/Rakefile +5 -0
- data/config.ru +63 -0
- data/lib/opal/browser.rb +4 -0
- data/opal-browser.gemspec +23 -0
- data/opal/browser.rb +10 -0
- data/opal/browser/animation_frame.rb +29 -0
- data/opal/browser/canvas.rb +277 -0
- data/opal/browser/canvas/data.rb +73 -0
- data/opal/browser/canvas/gradient.rb +37 -0
- data/opal/browser/canvas/style.rb +123 -0
- data/opal/browser/canvas/text.rb +55 -0
- data/opal/browser/compatibility.rb +59 -0
- data/opal/browser/compatibility/animation_frame.rb +93 -0
- data/opal/browser/compatibility/dom/document/window.rb +15 -0
- data/opal/browser/compatibility/dom/element/css.rb +15 -0
- data/opal/browser/compatibility/dom/element/matches.rb +31 -0
- data/opal/browser/compatibility/dom/element/offset.rb +20 -0
- data/opal/browser/compatibility/dom/element/scroll.rb +25 -0
- data/opal/browser/compatibility/dom/element/style.rb +15 -0
- data/opal/browser/compatibility/dom/mutation_observer.rb +47 -0
- data/opal/browser/compatibility/http/request.rb +15 -0
- data/opal/browser/compatibility/immediate.rb +107 -0
- data/opal/browser/compatibility/window/scroll.rb +27 -0
- data/opal/browser/compatibility/window/size.rb +13 -0
- data/opal/browser/compatibility/window/view.rb +13 -0
- data/opal/browser/console.rb +137 -0
- data/opal/browser/cookies.rb +79 -0
- data/opal/browser/css.rb +24 -0
- data/opal/browser/css/declaration.rb +88 -0
- data/opal/browser/css/rule.rb +48 -0
- data/opal/browser/css/rule/style.rb +16 -0
- data/opal/browser/css/style_sheet.rb +83 -0
- data/opal/browser/css/unit.rb +188 -0
- data/opal/browser/dom.rb +95 -0
- data/opal/browser/dom/attribute.rb +19 -0
- data/opal/browser/dom/builder.rb +97 -0
- data/opal/browser/dom/cdata.rb +9 -0
- data/opal/browser/dom/character_data.rb +37 -0
- data/opal/browser/dom/comment.rb +9 -0
- data/opal/browser/dom/compatibility.rb +8 -0
- data/opal/browser/dom/document.rb +83 -0
- data/opal/browser/dom/document_fragment.rb +7 -0
- data/opal/browser/dom/element.rb +290 -0
- data/opal/browser/dom/element/input.rb +17 -0
- data/opal/browser/dom/element/offset.rb +67 -0
- data/opal/browser/dom/element/position.rb +37 -0
- data/opal/browser/dom/element/scroll.rb +49 -0
- data/opal/browser/dom/event.rb +240 -0
- data/opal/browser/dom/event/animation.rb +26 -0
- data/opal/browser/dom/event/audio_processing.rb +31 -0
- data/opal/browser/dom/event/base.rb +207 -0
- data/opal/browser/dom/event/before_unload.rb +13 -0
- data/opal/browser/dom/event/clipboard.rb +26 -0
- data/opal/browser/dom/event/close.rb +35 -0
- data/opal/browser/dom/event/composition.rb +38 -0
- data/opal/browser/dom/event/custom.rb +30 -0
- data/opal/browser/dom/event/device_light.rb +21 -0
- data/opal/browser/dom/event/device_motion.rb +38 -0
- data/opal/browser/dom/event/device_orientation.rb +36 -0
- data/opal/browser/dom/event/device_proximity.rb +31 -0
- data/opal/browser/dom/event/drag.rb +113 -0
- data/opal/browser/dom/event/focus.rb +23 -0
- data/opal/browser/dom/event/gamepad.rb +47 -0
- data/opal/browser/dom/event/hash_change.rb +26 -0
- data/opal/browser/dom/event/keyboard.rb +93 -0
- data/opal/browser/dom/event/message.rb +50 -0
- data/opal/browser/dom/event/mouse.rb +253 -0
- data/opal/browser/dom/event/page_transition.rb +21 -0
- data/opal/browser/dom/event/pop_state.rb +21 -0
- data/opal/browser/dom/event/progress.rb +31 -0
- data/opal/browser/dom/event/sensor.rb +13 -0
- data/opal/browser/dom/event/storage.rb +41 -0
- data/opal/browser/dom/event/touch.rb +69 -0
- data/opal/browser/dom/event/ui.rb +22 -0
- data/opal/browser/dom/event/wheel.rb +49 -0
- data/opal/browser/dom/mutation_observer.rb +118 -0
- data/opal/browser/dom/node.rb +317 -0
- data/opal/browser/dom/node_set.rb +88 -0
- data/opal/browser/dom/text.rb +21 -0
- data/opal/browser/effects.rb +39 -0
- data/opal/browser/event_source.rb +67 -0
- data/opal/browser/history.rb +54 -0
- data/opal/browser/http.rb +129 -0
- data/opal/browser/http/binary.rb +57 -0
- data/opal/browser/http/compatibility.rb +1 -0
- data/opal/browser/http/headers.rb +90 -0
- data/opal/browser/http/parameters.rb +8 -0
- data/opal/browser/http/request.rb +331 -0
- data/opal/browser/http/response.rb +115 -0
- data/opal/browser/immediate.rb +43 -0
- data/opal/browser/interval.rb +93 -0
- data/opal/browser/location.rb +77 -0
- data/opal/browser/navigator.rb +151 -0
- data/opal/browser/screen.rb +40 -0
- data/opal/browser/socket.rb +115 -0
- data/opal/browser/storage.rb +149 -0
- data/opal/browser/timeout.rb +60 -0
- data/opal/browser/utils.rb +56 -0
- data/opal/browser/version.rb +3 -0
- data/opal/browser/window.rb +113 -0
- data/opal/browser/window/compatibility.rb +3 -0
- data/opal/browser/window/scroll.rb +49 -0
- data/opal/browser/window/size.rb +35 -0
- data/opal/browser/window/view.rb +18 -0
- data/spec/dom/builder_spec.rb +69 -0
- data/spec/dom/document_spec.rb +40 -0
- data/spec/dom/element_spec.rb +46 -0
- data/spec/dom/event_spec.rb +127 -0
- data/spec/dom/mutation_observer_spec.rb +37 -0
- data/spec/dom/node_spec.rb +154 -0
- data/spec/dom_spec.rb +13 -0
- data/spec/event_source_spec.rb +42 -0
- data/spec/history_spec.rb +48 -0
- data/spec/http_spec.rb +87 -0
- data/spec/immediate_spec.rb +12 -0
- data/spec/json2.js +486 -0
- data/spec/sizzle.js +5 -0
- data/spec/socket_spec.rb +43 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/storage_spec.rb +26 -0
- data/spec/window_spec.rb +10 -0
- metadata +240 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
module Browser; module DOM
|
2
|
+
|
3
|
+
class NodeSet
|
4
|
+
attr_reader :document
|
5
|
+
|
6
|
+
def initialize(document, list = [])
|
7
|
+
@document = document
|
8
|
+
@literal = []
|
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
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(name, *args, &block)
|
20
|
+
unless @literal.respond_to? name
|
21
|
+
each {|el|
|
22
|
+
el.__send__(name, *args, &block)
|
23
|
+
}
|
24
|
+
|
25
|
+
return self
|
26
|
+
end
|
27
|
+
|
28
|
+
result = @literal.__send__ name, *args, &block
|
29
|
+
|
30
|
+
if `result === #@literal`
|
31
|
+
self
|
32
|
+
elsif Array === result
|
33
|
+
NodeSet.new(@document, result)
|
34
|
+
else
|
35
|
+
result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def dup
|
40
|
+
NodeSet.new(document, to_ary.dup)
|
41
|
+
end
|
42
|
+
|
43
|
+
def filter(expression)
|
44
|
+
NodeSet.new(document, @literal.select { |node| node.matches?(expression) })
|
45
|
+
end
|
46
|
+
|
47
|
+
def after(node)
|
48
|
+
last.after node
|
49
|
+
end
|
50
|
+
|
51
|
+
def at(path)
|
52
|
+
raise NotImplementedError
|
53
|
+
end
|
54
|
+
|
55
|
+
def at_css(*rules)
|
56
|
+
raise NotImplementedError
|
57
|
+
end
|
58
|
+
|
59
|
+
def at_xpath(*paths)
|
60
|
+
raise NotImplementedError
|
61
|
+
end
|
62
|
+
|
63
|
+
def before
|
64
|
+
first.before
|
65
|
+
end
|
66
|
+
|
67
|
+
def children
|
68
|
+
result = NodeSet.new(document)
|
69
|
+
|
70
|
+
each { |n| result.concat(n.children) }
|
71
|
+
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
def css(*paths)
|
76
|
+
raise NotImplementedError
|
77
|
+
end
|
78
|
+
|
79
|
+
def search(*what)
|
80
|
+
map { |n| n.search(*what) }.flatten.uniq
|
81
|
+
end
|
82
|
+
|
83
|
+
def inspect
|
84
|
+
"#<DOM::NodeSet: #{@literal.inspect[1 .. -2]}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end; end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Browser; module DOM
|
2
|
+
|
3
|
+
class Text < CharacterData
|
4
|
+
def self.create(*args)
|
5
|
+
$document.create_text(*args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def whole
|
9
|
+
`#@native.wholeText`
|
10
|
+
end
|
11
|
+
|
12
|
+
def split(offset)
|
13
|
+
`#@native.splitText(offset)`
|
14
|
+
end
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
"#<DOM::Text: #{data}>"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end; end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Browser; module DOM
|
2
|
+
|
3
|
+
class Document < Element
|
4
|
+
def active_element
|
5
|
+
DOM(`#@native.activeElement`)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Element
|
10
|
+
def show(what = :block)
|
11
|
+
style[:display] = what
|
12
|
+
end
|
13
|
+
|
14
|
+
def hide
|
15
|
+
style[:display] = :none
|
16
|
+
end
|
17
|
+
|
18
|
+
def toggle
|
19
|
+
if style![:display] == :none
|
20
|
+
show
|
21
|
+
else
|
22
|
+
hide
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def focus
|
27
|
+
`#@native.focus()`
|
28
|
+
end
|
29
|
+
|
30
|
+
def blur
|
31
|
+
`#@native.blur()`
|
32
|
+
end
|
33
|
+
|
34
|
+
def focused?
|
35
|
+
`#@native.hasFocus`
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end; end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Browser
|
2
|
+
|
3
|
+
# This class wraps `EventSource`.
|
4
|
+
class EventSource
|
5
|
+
def self.supported?
|
6
|
+
defined? `window.EventSource`
|
7
|
+
end
|
8
|
+
|
9
|
+
include Native
|
10
|
+
include DOM::Event::Target
|
11
|
+
|
12
|
+
target {|value|
|
13
|
+
EventSource.new(value) if Native.is_a?(value, `window.EventSource`)
|
14
|
+
}
|
15
|
+
|
16
|
+
# Create an {EventSource} on the given path.
|
17
|
+
#
|
18
|
+
# @param path [String] the path to use as source
|
19
|
+
# @yield if the block has no parameters it's instance_exec'd, otherwise it's
|
20
|
+
# called with self
|
21
|
+
def initialize(path, &block)
|
22
|
+
if native?(path)
|
23
|
+
super(path)
|
24
|
+
else
|
25
|
+
super(`new window.EventSource(path)`)
|
26
|
+
end
|
27
|
+
|
28
|
+
if block.arity == 0
|
29
|
+
instance_exec(&block)
|
30
|
+
else
|
31
|
+
block.call(self)
|
32
|
+
end if block
|
33
|
+
end
|
34
|
+
|
35
|
+
# @!attribute [r] url
|
36
|
+
# @return [String] the URL of the event source
|
37
|
+
alias_native :url
|
38
|
+
|
39
|
+
# @!attribute [r] state
|
40
|
+
# @return [:connecting, :open, :closed] the state of the event source
|
41
|
+
def state
|
42
|
+
%x{
|
43
|
+
switch (#@native.readyState) {
|
44
|
+
case window.EventSource.CONNECTING:
|
45
|
+
return "connecting";
|
46
|
+
|
47
|
+
case window.EventSource.OPEN:
|
48
|
+
return "open";
|
49
|
+
|
50
|
+
case window.EventSource.CLOSED:
|
51
|
+
return "closed";
|
52
|
+
}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
# Check if the event source is alive.
|
57
|
+
def alive?
|
58
|
+
state == :open
|
59
|
+
end
|
60
|
+
|
61
|
+
# Close the event source.
|
62
|
+
def close
|
63
|
+
`#@native.close()`
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'browser/location'
|
2
|
+
|
3
|
+
module Browser
|
4
|
+
|
5
|
+
class History
|
6
|
+
include Native
|
7
|
+
|
8
|
+
alias_native :length
|
9
|
+
|
10
|
+
def back(number = 1)
|
11
|
+
`#@native.go(-number)`
|
12
|
+
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def forward(number = 1)
|
17
|
+
`#@native.go(number)`
|
18
|
+
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def push(url, data = nil)
|
23
|
+
data = `null` if data.nil?
|
24
|
+
|
25
|
+
`#@native.pushState(data, null, url)`
|
26
|
+
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def replace(url, data = nil)
|
31
|
+
data = `null` if data.nil?
|
32
|
+
|
33
|
+
`#@native.replaceState(data, null, url)`
|
34
|
+
end
|
35
|
+
|
36
|
+
def current
|
37
|
+
$window.location.path
|
38
|
+
end
|
39
|
+
|
40
|
+
def state
|
41
|
+
`#@native.state`
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Window
|
46
|
+
# Get the {History} object for this window.
|
47
|
+
#
|
48
|
+
# @return [History]
|
49
|
+
def history
|
50
|
+
History.new(`#@native.history`) if `#@native.history`
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'promise'
|
2
|
+
|
3
|
+
require 'browser/http/binary'
|
4
|
+
require 'browser/http/headers'
|
5
|
+
require 'browser/http/request'
|
6
|
+
require 'browser/http/response'
|
7
|
+
require 'browser/http/compatibility'
|
8
|
+
|
9
|
+
module Browser
|
10
|
+
|
11
|
+
module HTTP
|
12
|
+
# Send an asynchronous request.
|
13
|
+
#
|
14
|
+
# @param method [Symbol] the HTTP method to use
|
15
|
+
# @param url [String] the URL to request
|
16
|
+
# @param data [String, Hash] the data to send
|
17
|
+
# @return [Response] the response
|
18
|
+
def self.send(method, url, data = nil, &block)
|
19
|
+
Promise.new.tap {|promise|
|
20
|
+
Request.new(&block).tap {|req|
|
21
|
+
req.on :success do |res|
|
22
|
+
promise.resolve(res)
|
23
|
+
end
|
24
|
+
|
25
|
+
req.on :failure do |res|
|
26
|
+
promise.reject(res)
|
27
|
+
end
|
28
|
+
}.open(method, url).send(data)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
# Send an asynchronous GET request.
|
33
|
+
#
|
34
|
+
# @param url [String] the URL to request
|
35
|
+
# @return [Response] the response
|
36
|
+
def self.get(url, &block)
|
37
|
+
send(:get, url, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Send an asynchronous HEAD request.
|
41
|
+
#
|
42
|
+
# @param url [String] the URL to request
|
43
|
+
# @return [Response] the response
|
44
|
+
def self.head(url, &block)
|
45
|
+
send(:head, url, &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Send an asynchrnous POST request.
|
49
|
+
#
|
50
|
+
# @param url [String] the URL to request
|
51
|
+
# @param data [String, Hash] the data to send
|
52
|
+
# @return [Response] the response
|
53
|
+
def self.post(url, data = nil, &block)
|
54
|
+
send(:post, url, data, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Send an asynchronous PUT request.
|
58
|
+
#
|
59
|
+
# @param url [String] the URL to request
|
60
|
+
# @param data [String, Hash] the data to send
|
61
|
+
# @return [Response] the response
|
62
|
+
def self.put(url, data = nil, &block)
|
63
|
+
send(:put, url, data, &block)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Send an asynchronous DELETE request.
|
67
|
+
#
|
68
|
+
# @param url [String] the URL to request
|
69
|
+
# @param data [String, Hash] the data to send
|
70
|
+
# @return [Response] the response
|
71
|
+
def self.delete(url, data = nil, &block)
|
72
|
+
send(:delete, url, data, &block)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Send a synchronous request.
|
76
|
+
#
|
77
|
+
# @param method [Symbol] the HTTP method to use
|
78
|
+
# @param url [String] the URL to request
|
79
|
+
# @param data [String, Hash] the data to send
|
80
|
+
# @return [Response] the response
|
81
|
+
def self.send!(method, url, data = nil, &block)
|
82
|
+
Request.new(&block).open(method, url, false).send(data)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Send a synchronous GET request.
|
86
|
+
#
|
87
|
+
# @param url [String] the URL to request
|
88
|
+
# @return [Response] the response
|
89
|
+
def self.get!(url, &block)
|
90
|
+
send!(:get, url, &block)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Send a synchronous HEAD request.
|
94
|
+
#
|
95
|
+
# @param url [String] the URL to request
|
96
|
+
# @return [Response] the response
|
97
|
+
def self.head!(url, &block)
|
98
|
+
send!(:head, url, &block)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Send a synchronous POST request.
|
102
|
+
#
|
103
|
+
# @param url [String] the URL to request
|
104
|
+
# @param data [String, Hash] the data to send
|
105
|
+
# @return [Response] the response
|
106
|
+
def self.post!(url, data = nil, &block)
|
107
|
+
send!(:post, url, data, &block)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Send a synchronous PUT request.
|
111
|
+
#
|
112
|
+
# @param url [String] the URL to request
|
113
|
+
# @param data [String, Hash] the data to send
|
114
|
+
# @return [Response] the response
|
115
|
+
def self.put!(url, data = nil, &block)
|
116
|
+
send!(:put, url, data, &block)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Send a synchronous DELETE request.
|
120
|
+
#
|
121
|
+
# @param url [String] the URL to request
|
122
|
+
# @param data [String, Hash] the data to send
|
123
|
+
# @return [Response] the response
|
124
|
+
def self.delete!(url, data = nil, &block)
|
125
|
+
send!(:delete, url, data, &block)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Browser; module HTTP
|
2
|
+
|
3
|
+
# Represents a binary result from a HTTP response.
|
4
|
+
class Binary
|
5
|
+
# @!attribute [r] type
|
6
|
+
# @return [:string, :buffer] the type of binary
|
7
|
+
attr_reader :type
|
8
|
+
|
9
|
+
# Create a binary from a value.
|
10
|
+
#
|
11
|
+
# @param value [String, Buffer] the binary
|
12
|
+
def initialize(value)
|
13
|
+
if String === value
|
14
|
+
@type = :string
|
15
|
+
@data = value
|
16
|
+
else
|
17
|
+
@type = :buffer
|
18
|
+
@data = value.to_a
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
include Enumerable
|
23
|
+
|
24
|
+
# Iterate over each byte in the binary.
|
25
|
+
#
|
26
|
+
# @yield [byte] the byte
|
27
|
+
# @return [self]
|
28
|
+
def each(&block)
|
29
|
+
return enum_for :each unless block
|
30
|
+
|
31
|
+
index = 0
|
32
|
+
length = self.length
|
33
|
+
|
34
|
+
while index < length
|
35
|
+
block.call(self[index])
|
36
|
+
|
37
|
+
index += 1
|
38
|
+
end
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
# Access a byte from the binary.
|
44
|
+
#
|
45
|
+
# @return [Integer] a byte
|
46
|
+
def [](index)
|
47
|
+
@type == :string ? `#@data.charCodeAt(index) & 0xff` : @data[index]
|
48
|
+
end
|
49
|
+
|
50
|
+
# @!attribute [r] length
|
51
|
+
# @return [Integer] the length of the binary
|
52
|
+
def length
|
53
|
+
@data.length
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end; end
|