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,15 @@
|
|
1
|
+
module Browser; module DOM; class Document < Element
|
2
|
+
|
3
|
+
unless C.has? `document`, :defaultView
|
4
|
+
if C.has? `document`, :parentWindow
|
5
|
+
def window
|
6
|
+
`#@native.parentWindow`
|
7
|
+
end
|
8
|
+
else
|
9
|
+
def window
|
10
|
+
raise NotImplementedError, 'window from document is unsupported'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end; end; end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Browser; module DOM; class Element
|
2
|
+
|
3
|
+
unless C.respond_to?(:Element, :querySelectorAll)
|
4
|
+
if C.sizzle?
|
5
|
+
def css(path)
|
6
|
+
NodeSet.new(document, `Sizzle(#{path}, #@native)`)
|
7
|
+
end
|
8
|
+
else
|
9
|
+
def css(*)
|
10
|
+
raise NotImplementedError, 'fetching by selector unsupported'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end; end; end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Browser; module DOM; class Element
|
2
|
+
|
3
|
+
unless C.respond_to?(:Element, :matches)
|
4
|
+
if C.respond_to?(:Element, :oMatchesSelector)
|
5
|
+
def matches?(selector)
|
6
|
+
`#@native.oMatchesSelector(#{selector})`
|
7
|
+
end
|
8
|
+
elsif C.respond_to?(:Element, :msMatchesSelector)
|
9
|
+
def matches?(selector)
|
10
|
+
`#@native.msMatchesSelector(#{selector})`
|
11
|
+
end
|
12
|
+
elsif C.respond_to?(:Element, :mozMatchesSelector)
|
13
|
+
def matches?(selector)
|
14
|
+
`#@native.mozMatchesSelector(#{selector})`
|
15
|
+
end
|
16
|
+
elsif C.respond_to?(:Element, :webkitMatchesSelector)
|
17
|
+
def matches?(selector)
|
18
|
+
`#@native.webkitMatchesSelector(#{selector})`
|
19
|
+
end
|
20
|
+
elsif C.sizzle?
|
21
|
+
def matches?(selector)
|
22
|
+
`Sizzle.matchesSelector(#@native, #{selector})`
|
23
|
+
end
|
24
|
+
else
|
25
|
+
def matches?(*)
|
26
|
+
raise NotImplementedError, 'matches by selector unsupported'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end; end; end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Browser; module DOM; class Element
|
2
|
+
|
3
|
+
class Offset
|
4
|
+
unless C.has? `document.body`, :getBoundingClientRect
|
5
|
+
def position
|
6
|
+
doc = document
|
7
|
+
root = doc.root.to_n
|
8
|
+
win = doc.window.to_n
|
9
|
+
|
10
|
+
%x{
|
11
|
+
var y = (#{win}.pageYOffset || #{root}.scrollTop) - (#{root}.clientTop || 0),
|
12
|
+
x = (#{win}.pageXOffset || #{root}.scrollLeft) - (#{root}.clientLeft || 0);
|
13
|
+
}
|
14
|
+
|
15
|
+
Browser::Position.new(`x`, `y`)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end; end; end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Browser; module DOM; class Element
|
2
|
+
|
3
|
+
unless C.has? `document.body`, :scrollLeft
|
4
|
+
if C.has? `document.body`, :pageXOffset
|
5
|
+
def scroll(to = nil)
|
6
|
+
if to
|
7
|
+
if x = to[:x]
|
8
|
+
`#@native.pageXOffset = #{x}`
|
9
|
+
end
|
10
|
+
|
11
|
+
if y = to[:y]
|
12
|
+
`#@native.pageYOffset = #{y}`
|
13
|
+
end
|
14
|
+
else
|
15
|
+
Position.new(`#@native.pageXOffset`, `#@native.pageYOffset`)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
else
|
19
|
+
def scroll(*)
|
20
|
+
raise NotImplementedError, 'scroll on element not supported'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end; end; end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Browser; module DOM; class Element
|
2
|
+
|
3
|
+
unless C.has? :getComputedStyle
|
4
|
+
if C.has?(`document.documentElement`, :currentStyle)
|
5
|
+
def style!
|
6
|
+
CSS::Declaration.new(`#@native.currentStyle`)
|
7
|
+
end
|
8
|
+
else
|
9
|
+
def style!
|
10
|
+
raise NotImplementedError, 'computed style unsupported'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end; end; end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Browser; module DOM
|
2
|
+
|
3
|
+
unless defined?(`window.MutationObserver`)
|
4
|
+
class MutationObserver
|
5
|
+
class Record
|
6
|
+
attr_reader :type, :target, :old, :attribute
|
7
|
+
|
8
|
+
def initialize(*)
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
def attributes?; type == :attributes; end
|
13
|
+
def tree?; type == :tree; end
|
14
|
+
def cdata?; type == :cdata; end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(&block)
|
18
|
+
@block = block
|
19
|
+
@observed = []
|
20
|
+
end
|
21
|
+
|
22
|
+
def observe(target, options = nil)
|
23
|
+
unless options
|
24
|
+
options = {
|
25
|
+
children: true,
|
26
|
+
tree: true,
|
27
|
+
attributes: :old,
|
28
|
+
cdata: :old
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def take
|
36
|
+
result, @records = @records, []
|
37
|
+
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
def disconnect
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end; end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Browser; module HTTP; class Request
|
2
|
+
|
3
|
+
unless C.has? :XMLHttpRequest
|
4
|
+
if C.has? :ActiveXObject
|
5
|
+
def transport
|
6
|
+
`new ActiveXObject("MSXML2.XMLHTTP.3.0")`
|
7
|
+
end
|
8
|
+
else
|
9
|
+
def transport
|
10
|
+
raise NotImplementedError, 'XMLHttpRequest is unsupported'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end; end; end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Browser
|
2
|
+
|
3
|
+
module Compatibility
|
4
|
+
def self.immediate?(prefix = nil)
|
5
|
+
if prefix
|
6
|
+
has?("#{prefix}SetImmediate")
|
7
|
+
else
|
8
|
+
has?(:setImmediate)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.post_message?
|
13
|
+
return false unless has?(:postMessage) && !has?(:importScripts)
|
14
|
+
|
15
|
+
%x{
|
16
|
+
var ok = true,
|
17
|
+
old = window.onmessage;
|
18
|
+
|
19
|
+
window.onmessage = function() { ok = false; };
|
20
|
+
window.postMessage("", "*")
|
21
|
+
window.onmessage = old;
|
22
|
+
|
23
|
+
return ok;
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.ready_state_change?
|
28
|
+
`"onreadystatechange" in window.document.createElement("script")`
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Immediate
|
33
|
+
if C.immediate?
|
34
|
+
def dispatch
|
35
|
+
@id = `window.setImmediate(function() {
|
36
|
+
#{@function.call(@arguments, &@block)};
|
37
|
+
})`
|
38
|
+
end
|
39
|
+
|
40
|
+
def prevent
|
41
|
+
`window.clearImmediate(#@id)`
|
42
|
+
end
|
43
|
+
elsif C.immediate? :ms
|
44
|
+
def dispatch
|
45
|
+
@id = `window.msSetImmediate(function() {
|
46
|
+
#{@function.call(@arguments, &@block)};
|
47
|
+
})`
|
48
|
+
end
|
49
|
+
|
50
|
+
def prevent
|
51
|
+
`window.msClearImmediate(#@id)`
|
52
|
+
end
|
53
|
+
elsif C.post_message?
|
54
|
+
@@tasks = {}
|
55
|
+
@@prefix = "opal.browser.immediate.#{rand(1_000_000)}."
|
56
|
+
|
57
|
+
$window.on :message do |e|
|
58
|
+
if String === e.data && e.data.start_with?(@@prefix)
|
59
|
+
if task = @@tasks.delete(e.data[@@prefix.length .. -1])
|
60
|
+
task[0].call(*task[1], &task[2])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def dispatch
|
66
|
+
@id = rand(1_000_000).to_s
|
67
|
+
@@tasks[@id] = [@function, @arguments, @block]
|
68
|
+
|
69
|
+
$window.send! "#{@@prefix}#{@id}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def prevent
|
73
|
+
@@tasks.delete(@id)
|
74
|
+
end
|
75
|
+
elsif C.ready_state_change?
|
76
|
+
def dispatch
|
77
|
+
%x{
|
78
|
+
var script = document.createElement("script");
|
79
|
+
|
80
|
+
script.onreadystatechange = function() {
|
81
|
+
if (!#{aborted?}) {
|
82
|
+
#{@function.call(@arguments, &@block)};
|
83
|
+
}
|
84
|
+
|
85
|
+
script.onreadystatechange = null;
|
86
|
+
script.parentNode.removeChild(script);
|
87
|
+
};
|
88
|
+
|
89
|
+
document.documentElement.appendChild(script);
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def prevent; end
|
94
|
+
else
|
95
|
+
def dispatch
|
96
|
+
@id = `window.setTimeout(function() {
|
97
|
+
#{@function.call(*@arguments, &@block)};
|
98
|
+
}, 0)`
|
99
|
+
end
|
100
|
+
|
101
|
+
def prevent
|
102
|
+
`window.clearTimeout(#@id)`
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Browser; class Window; class Scroll
|
2
|
+
|
3
|
+
unless C.has? `document.documentElement`, :scrollLeft
|
4
|
+
if C.has? :pageXOffset
|
5
|
+
def position
|
6
|
+
Position.new(x, y)
|
7
|
+
end
|
8
|
+
|
9
|
+
def x
|
10
|
+
`#@native.pageXOffset`
|
11
|
+
end
|
12
|
+
|
13
|
+
def y
|
14
|
+
`#@native.pageYOffset`
|
15
|
+
end
|
16
|
+
else
|
17
|
+
def x
|
18
|
+
raise NotImplementedError, 'window scroll unsupported'
|
19
|
+
end
|
20
|
+
|
21
|
+
def y
|
22
|
+
raise NotImplementedError, 'window scroll unsupported'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end; end; end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Browser; class Window; class Size
|
2
|
+
|
3
|
+
unless C.has? :outerHeight
|
4
|
+
def width
|
5
|
+
raise NotImplementedError, 'window outer size not supported'
|
6
|
+
end
|
7
|
+
|
8
|
+
def height
|
9
|
+
raise NotImplementedError, 'window outer size not supported'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end; end; end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Browser
|
2
|
+
|
3
|
+
# This class wraps a `window.console`.
|
4
|
+
class Console
|
5
|
+
include Native
|
6
|
+
|
7
|
+
# Clear the console.
|
8
|
+
#
|
9
|
+
# @return [self]
|
10
|
+
def clear
|
11
|
+
`#@native.clear()`
|
12
|
+
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
# Print a stacktrace from the call site.
|
17
|
+
#
|
18
|
+
# @return [self]
|
19
|
+
def trace
|
20
|
+
`#@native.trace()`
|
21
|
+
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Log the passed objects based on an optional initial format.
|
26
|
+
#
|
27
|
+
# @return [self]
|
28
|
+
def log(*args)
|
29
|
+
`#@native.log.apply(#@native, args)`
|
30
|
+
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Log the passed objects based on an optional initial format as informational
|
35
|
+
# log.
|
36
|
+
#
|
37
|
+
# @return [self]
|
38
|
+
def info(*args)
|
39
|
+
`#@native.info.apply(#@native, args)`
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# Log the passed objects based on an optional initial format as warning.
|
45
|
+
#
|
46
|
+
# @return [self]
|
47
|
+
def warn(*args)
|
48
|
+
`#@native.warn.apply(#@native, args)`
|
49
|
+
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
# Log the passed objects based on an optional initial format as error.
|
54
|
+
#
|
55
|
+
# @return [self]
|
56
|
+
def error(*args)
|
57
|
+
`#@native.error.apply(#@native, args)`
|
58
|
+
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
# Time the given block with the given label.
|
63
|
+
#
|
64
|
+
# @return [self]
|
65
|
+
def time(label, &block)
|
66
|
+
raise ArgumentError, "no block given" unless block
|
67
|
+
|
68
|
+
`#@native.time(label)`
|
69
|
+
|
70
|
+
begin
|
71
|
+
if block.arity == 0
|
72
|
+
instance_exec(&block)
|
73
|
+
else
|
74
|
+
block.call(self)
|
75
|
+
end
|
76
|
+
ensure
|
77
|
+
`#@native.timeEnd()`
|
78
|
+
end
|
79
|
+
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
# Group the given block.
|
84
|
+
#
|
85
|
+
# @return [self]
|
86
|
+
def group(*args, &block)
|
87
|
+
raise ArgumentError, "no block given" unless block
|
88
|
+
|
89
|
+
`#@native.group.apply(#@native, args)`
|
90
|
+
|
91
|
+
begin
|
92
|
+
if block.arity == 0
|
93
|
+
instance_exec(&block)
|
94
|
+
else
|
95
|
+
block.call(self)
|
96
|
+
end
|
97
|
+
ensure
|
98
|
+
`#@native.groupEnd()`
|
99
|
+
end
|
100
|
+
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
# Group the given block but collapse it.
|
105
|
+
#
|
106
|
+
# @return [self]
|
107
|
+
def group!(*args, &block)
|
108
|
+
return unless block_given?
|
109
|
+
|
110
|
+
`#@native.groupCollapsed.apply(#@native, args)`
|
111
|
+
|
112
|
+
begin
|
113
|
+
if block.arity == 0
|
114
|
+
instance_exec(&block)
|
115
|
+
else
|
116
|
+
block.call(self)
|
117
|
+
end
|
118
|
+
ensure
|
119
|
+
`#@native.groupEnd()`
|
120
|
+
end
|
121
|
+
|
122
|
+
self
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class Window
|
127
|
+
# Get the {Console} for this window.
|
128
|
+
#
|
129
|
+
# @return [Console]
|
130
|
+
def console
|
131
|
+
Console.new(`#@native.console`)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
$console = $window.console
|
136
|
+
|
137
|
+
end
|