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,149 @@
1
+ #--
2
+ # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
3
+ # Version 2, December 2004
4
+ #
5
+ # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
6
+ # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
7
+ #
8
+ # 0. You just DO WHAT THE FUCK YOU WANT TO.
9
+ #++
10
+
11
+ require 'json'
12
+ require 'stringio'
13
+
14
+ module Browser
15
+
16
+ class Storage < Hash
17
+ def self.json_create(data)
18
+ data.delete(JSON.create_id)
19
+
20
+ Hash[data.map {|key, value|
21
+ [JSON.parse(key), value]
22
+ }]
23
+ end
24
+
25
+ attr_reader :name
26
+
27
+ def initialize(window, name)
28
+ super()
29
+
30
+ @window = window
31
+ @name = name
32
+
33
+ autosave!
34
+
35
+ init if respond_to? :init
36
+ end
37
+
38
+ def encoded_name
39
+ "$opal.storage.#{@name}"
40
+ end
41
+
42
+ def autosave?; @autosave; end
43
+ def autosave!; @autosave = true; end
44
+ def no_autosave!; @autosave = false; end
45
+
46
+ def replace(what)
47
+ if what.is_a?(String)
48
+ super JSON.parse(what)
49
+ else
50
+ super
51
+ end
52
+ end
53
+
54
+ %w([]= delete clear).each {|name|
55
+ define_method name do |*args|
56
+ # FIXME: remove the application when it's fixed
57
+ super(*args).tap {
58
+ save if autosave?
59
+ }
60
+ end
61
+ }
62
+
63
+ def save; end
64
+
65
+ if `window.localStorage`
66
+ def init
67
+ replace `#@window.localStorage[#{encoded_name}] || '{}'`
68
+ end
69
+
70
+ def save
71
+ `#@window.localStorage[#{encoded_name}] = #{JSON.dump(self)}`
72
+ end
73
+ elsif `window.globalStorage`
74
+ def init
75
+ replace `#@window.globalStorage[#@window.location.hostname][#{encoded_name}] || '{}'`
76
+ end
77
+
78
+ def save
79
+ `#@window.globalStorage[#@window.location.hostname][#{encoded_name}] = #{JSON.dump(self)}`
80
+ end
81
+ elsif `document.body.addBehavior`
82
+ def init
83
+ %x{
84
+ #@element = #@window.document.createElement('link');
85
+ #@element.addBehavior('#default#userData');
86
+
87
+ #@window.document.getElementsByTagName('head')[0].appendChild(#@element);
88
+
89
+ #@element.load(#{encoded_name});
90
+ }
91
+
92
+ replace `#@element.getAttribute(#{encoded_name}) || '{}'`
93
+ end
94
+
95
+ def save
96
+ %x{
97
+ #@element.setAttribute(#{encoded_name}, #{JSON.dump(self)});
98
+ #@element.save(#{encoded_name});
99
+ }
100
+ end
101
+ else
102
+ def init
103
+ $document.cookies.options expires: 60 * 60 * 24 * 365
104
+
105
+ replace $document.cookies[encoded_name]
106
+ end
107
+
108
+ def save
109
+ $document.cookies[encoded_name] = self
110
+ end
111
+ end
112
+
113
+ def to_json
114
+ io = StringIO.new("{")
115
+
116
+ io << JSON.create_id.to_json << ":" << self.class.name.to_json << ","
117
+
118
+ each {|key, value|
119
+ io << key.to_json.to_json << ":" << value.to_json << ","
120
+ }
121
+
122
+ io.seek(-1, IO::SEEK_CUR)
123
+ io << "}"
124
+
125
+ io.string
126
+ end
127
+ end
128
+
129
+ class SessionStorage < Storage
130
+ def init
131
+ replace `#@window.sessionStorage[#{encoded_name}] || '{}'`
132
+ end
133
+
134
+ def save
135
+ `#@window.sessionStorage[#{encoded_name}] = #{JSON.dump(self)}`
136
+ end
137
+ end
138
+
139
+ class Window
140
+ def storage(name = :default)
141
+ Storage.new(to_n, name)
142
+ end
143
+
144
+ def session_storage(name = :default)
145
+ SessionStorage.new(to_n, name)
146
+ end
147
+ end
148
+
149
+ end
@@ -0,0 +1,60 @@
1
+ module Browser
2
+
3
+ # This class wraps `setTimeout`.
4
+ class Timeout
5
+ # @!attribute [r] after
6
+ # @return [Number] the seconds after which the block is called
7
+ attr_reader :after
8
+
9
+ # Create and start a timeout.
10
+ #
11
+ # @param window [Window] the window to start the timeout on
12
+ # @param time [Number] seconds after which the block is called
13
+ def initialize(window, time, &block)
14
+ @window = Native.convert(window)
15
+ @after = time
16
+ @block = block
17
+
18
+ start
19
+ end
20
+
21
+ # Abort the timeout.
22
+ #
23
+ # @return [self]
24
+ def abort
25
+ `#@window.clearTimeout(#@id)`
26
+
27
+ self
28
+ end
29
+
30
+ def start
31
+ @id = `#@window.setTimeout(#{@block.to_n}, #@after * 1000)`
32
+
33
+ self
34
+ end
35
+ end
36
+
37
+ class Window
38
+ # Execute a block after the given seconds.
39
+ #
40
+ # @param time [Float] the seconds after it gets called
41
+ # @return [Timeout] the object representing the timeout
42
+ def after(time, &block)
43
+ Timeout.new(@native, time, &block)
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ class Proc
50
+ def after(time)
51
+ $window.after(time, &self)
52
+ end
53
+ end
54
+
55
+ module Kernel
56
+ # (see Browser::Window#once)
57
+ def after(time, &block)
58
+ $window.after(time, &block)
59
+ end
60
+ end
@@ -0,0 +1,56 @@
1
+ module Browser
2
+ Size = Struct.new(:width, :height)
3
+ Position = Struct.new(:x, :y)
4
+ end
5
+
6
+ class String
7
+ # Encode as URI component.
8
+ #
9
+ # @return [String] the string encoded for usage as URI component
10
+ def encode_uri_component
11
+ `encodeURIComponent(self)`
12
+ end
13
+
14
+ # Encode as URI.
15
+ #
16
+ # @return [String] the string encoded as URI
17
+ def encode_uri
18
+ `encodeURI(self)`
19
+ end
20
+
21
+ # Decode as URI component.
22
+ #
23
+ # @return [String] the string decoded as URI component
24
+ def decode_uri_component
25
+ `decodeURIComponent(self)`
26
+ end
27
+
28
+ # Decode as URI.
29
+ #
30
+ # @return [String] the string decoded as URI
31
+ def decode_uri
32
+ `decodeURI(self)`
33
+ end
34
+ end
35
+
36
+ class Hash
37
+ def self.decode_uri(string)
38
+ self[string.split(?&).map {|part|
39
+ name, value = part.split(?=)
40
+
41
+ [name.decode_uri_component, value.decode_uri_component]
42
+ }]
43
+ end
44
+
45
+ def encode_uri
46
+ map {|name, value|
47
+ "#{name.to_s.encode_uri_component}=#{value.to_s.encode_uri_component}"
48
+ }.join(?&)
49
+ end
50
+ end
51
+
52
+ class Object
53
+ def encode_uri
54
+ to_s.encode_uri
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ module Browser
2
+ VERSION = '0.1.0.beta1'
3
+ end
@@ -0,0 +1,113 @@
1
+ require 'browser/interval'
2
+ require 'browser/timeout'
3
+
4
+ require 'browser/window/view'
5
+ require 'browser/window/size'
6
+ require 'browser/window/scroll'
7
+ require 'browser/window/compatibility'
8
+
9
+ module Browser
10
+
11
+ # Wrapper class for the `window` object, an instance of it gets
12
+ # set to `$window`.
13
+ class Window
14
+ def self.open(url, options)
15
+ name = options.delete(:name)
16
+ features = options.map {|key, value|
17
+ value = case value
18
+ when true then :yes
19
+ when false then :no
20
+ else value
21
+ end
22
+
23
+ "#{key}=#{value}"
24
+ }.join(?,)
25
+
26
+ %x{
27
+ var win = window.open(#{url}, #{name}, #{features});
28
+
29
+ if (win == null) {
30
+ return nil;
31
+ }
32
+
33
+ return #{new(`win`)};
34
+ }
35
+ end
36
+
37
+ include Native
38
+
39
+ # Alert the passed string.
40
+ def alert(value)
41
+ `#@native.alert(value)`
42
+
43
+ value
44
+ end
45
+
46
+ # Display a prompt dialog with the passed string as text.
47
+ def prompt(value)
48
+ `#@native.prompt(value) || nil`
49
+ end
50
+
51
+ # Display a confirmation dialog with the passed string as text.
52
+ def confirm(value)
53
+ `#@native.confirm(value) || false`
54
+ end
55
+
56
+ # Get the {View} for the window.
57
+ #
58
+ # @return [View]
59
+ def view
60
+ View.new(self)
61
+ end
62
+
63
+ # Get the {Size} for this window.
64
+ #
65
+ # @return [Size]
66
+ def size
67
+ Size.new(self)
68
+ end
69
+
70
+ # Get the {Scroll} for this window.
71
+ #
72
+ # @return [Scroll]
73
+ def scroll
74
+ Scroll.new(self)
75
+ end
76
+
77
+ # Send a message to the window.
78
+ #
79
+ # @param message [String] the message
80
+ # @param options [Hash] optional `to: target`
81
+ def send!(message, options = {})
82
+ `#@native.postMessage(#{message}, #{options[:to] || '*'})`
83
+ end
84
+
85
+ def close
86
+ %x{
87
+ return (window.open('', '_self', '') && window.close()) ||
88
+ (window.opener = null && window.close()) ||
89
+ (window.opener = '' && window.close());
90
+ }
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ $window = Browser::Window.new(`window`)
97
+
98
+ module Kernel
99
+ # (see Browser::Window#alert)
100
+ def alert(value)
101
+ $window.alert(value)
102
+ end
103
+
104
+ # (see Browser::Window#prompt)
105
+ def prompt(value)
106
+ $window.prompt(value)
107
+ end
108
+
109
+ # (see Browser::Window#confirm)
110
+ def confirm(value)
111
+ $window.confirm(value)
112
+ end
113
+ end
@@ -0,0 +1,3 @@
1
+ require 'browser/compatibility/window/view'
2
+ require 'browser/compatibility/window/size'
3
+ require 'browser/compatibility/window/scroll'
@@ -0,0 +1,49 @@
1
+ module Browser; class Window
2
+
3
+ class Scroll
4
+ def initialize(window)
5
+ @window = window
6
+ @native = window.to_n
7
+ end
8
+
9
+ def position
10
+ %x{
11
+ var doc = #@native.document,
12
+ root = doc.documentElement,
13
+ body = doc.body;
14
+
15
+ var x = root.scrollLeft || body.scrollLeft,
16
+ y = root.scrollTop || body.scrollTop;
17
+ }
18
+
19
+ Position.new(`x`, `y`)
20
+ end
21
+
22
+ def x
23
+ position.x
24
+ end
25
+
26
+ def y
27
+ position.y
28
+ end
29
+
30
+ def to(what)
31
+ x = what[:x] || self.x
32
+ y = what[:y] || self.y
33
+
34
+ `#@native.scrollTo(#{x}, #{y})`
35
+
36
+ self
37
+ end
38
+
39
+ def by(what)
40
+ x = what[:x] || 0
41
+ y = what[:y] || 0
42
+
43
+ `#@native.scrollBy(#{x}, #{y})`
44
+
45
+ self
46
+ end
47
+ end
48
+
49
+ end; end
@@ -0,0 +1,35 @@
1
+ module Browser; class Window
2
+
3
+ class Size
4
+ def initialize(window)
5
+ @window = window
6
+ @native = window.to_n
7
+ end
8
+
9
+ def set(what)
10
+ width = what[:width] || self.width
11
+ height = what[:height] || self.height
12
+
13
+ `#@native.resizeTo(#{width}, #{height})`
14
+
15
+ self
16
+ end
17
+
18
+ def width
19
+ `#@native.outerWidth`
20
+ end
21
+
22
+ def width=(value)
23
+ set(width: value)
24
+ end
25
+
26
+ def height
27
+ `#@native.outerHeight`
28
+ end
29
+
30
+ def height=(value)
31
+ set(height: value)
32
+ end
33
+ end
34
+
35
+ end; end