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,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,13 @@
1
+ module Browser; class Window; class View
2
+
3
+ unless C.has? :innerHeight
4
+ def width
5
+ `#@native.document.documentElement.clientWidth`
6
+ end
7
+
8
+ def height
9
+ `#@native.document.documentElement.clientHeight`
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