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,79 @@
1
+ module Browser
2
+
3
+ class Cookies
4
+ include Enumerable
5
+
6
+ def initialize(document)
7
+ @document = document
8
+
9
+ @options = {
10
+ expires: Time.now + 1.day,
11
+ path: '',
12
+ domain: '',
13
+ secure: ''
14
+ }
15
+ end
16
+
17
+ def options (value = nil)
18
+ value ? @options.merge!(value) : @options
19
+ end
20
+
21
+ def [] (name)
22
+ matches = `#@document.cookie`.scan(/#{Regexp.escape(key.encode_uri_component)}=([^;]*)/)
23
+
24
+ return if matches.empty?
25
+
26
+ result = matches.map {|cookie|
27
+ JSON.parse(cookie.match(/^.*?=(.*)$/)[1].decode_uri_component)
28
+ }
29
+
30
+ result.length == 1 ? result.first : result
31
+ end
32
+
33
+ def []= (name, value, options = {})
34
+ `#@document.cookie = #{encode name, value.is_a?(String) ? value : JSON.dump(value), @options.merge(options)}`
35
+ end
36
+
37
+ def delete (name)
38
+ `#@document.cookie = #{encode name, '', expires: Time.now}`
39
+ end
40
+
41
+ def keys
42
+ Array(`#@document.cookie.split(/; /)`).map {|cookie|
43
+ cookie.split(/\s*=\s*/).first
44
+ }
45
+ end
46
+
47
+ def values
48
+ keys.map {|key|
49
+ self[key]
50
+ }
51
+ end
52
+
53
+ def each
54
+ keys.each {|key|
55
+ yield key, self[key]
56
+ }
57
+ end
58
+
59
+ def clear
60
+ keys.each {|key|
61
+ delete key
62
+ }
63
+ end
64
+
65
+ protected
66
+ def encode (key, value, options = {})
67
+ result = "#{key.encode_uri_component}=#{value.encode_uri_component}; "
68
+
69
+ result += "max-age=#{options[:max_age]}; " if options[:max_age]
70
+ result += "expires=#{options[:expires].to_utc}; " if options[:expires]
71
+ result += "path=#{options[:path]}; " if options[:path]
72
+ result += "domain=#{options[:domain]}; " if options[:domain]
73
+ result += 'secure' if options[:secure]
74
+
75
+ result
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,24 @@
1
+ require 'browser/css/declaration'
2
+ require 'browser/css/style_sheet'
3
+ require 'browser/css/rule'
4
+ require 'browser/css/rule/style'
5
+
6
+ module Kernel
7
+ # Create a <style> element from a string or a block using the
8
+ # {Browser::CSS::Builder} DSL.
9
+ #
10
+ # @param text [String] the CSS text
11
+ # @return [Browser::DOM::Element] the create <style> element
12
+ def CSS(text = nil, &block)
13
+ style = $document.create_element(:style)
14
+ style[:type] = 'text/css'
15
+
16
+ if block
17
+ style.inner_text = Paggio.css(&block)
18
+ else
19
+ style.inner_text = text
20
+ end
21
+
22
+ style
23
+ end
24
+ end
@@ -0,0 +1,88 @@
1
+ module Browser; module CSS
2
+
3
+ class Declaration
4
+ include Native
5
+ include Enumerable
6
+
7
+ def rule
8
+ Rule.new(`#@native.parentRule`) if defined?(`#@native.parentRule`)
9
+ end
10
+
11
+ def assign(data)
12
+ data.each {|name, value|
13
+ self[name] = value
14
+ }
15
+
16
+ self
17
+ end
18
+
19
+ def replace(string)
20
+ `#@native.cssText = #{string}`
21
+
22
+ self
23
+ end
24
+
25
+ def apply(&block)
26
+ Paggio::CSS::Definition.new(&block).each {|style|
27
+ # FIXME: use ternary operator when it's fixed
28
+ if style.important
29
+ `#@native.setProperty(#{style.name}, #{style.value}, "important")`
30
+ else
31
+ `#@native.setProperty(#{style.name}, #{style.value}, "")`
32
+ end
33
+ }
34
+
35
+ self
36
+ end
37
+
38
+ def delete(name)
39
+ `#@native.removeProperty(#{name})`
40
+ end
41
+
42
+ def [](name)
43
+ %x{
44
+ var result = #@native.getPropertyValue(#{name});
45
+
46
+ if (result == null || result === "") {
47
+ return nil;
48
+ }
49
+
50
+ return result;
51
+ }
52
+ end
53
+
54
+ def []=(name, value)
55
+ `#@native.setProperty(#{name}, #{value.to_s}, "")`
56
+ end
57
+
58
+ def important?(name)
59
+ `#@native.getPropertyPriority(#{name}) == "important"`
60
+ end
61
+
62
+ def each(&block)
63
+ return enum_for :each unless block_given?
64
+
65
+ %x{
66
+ for (var i = 0, length = #@native.length; i < length; i++) {
67
+ var name = #@native.item(i);
68
+
69
+ #{yield `name`, self[`name`]}
70
+ }
71
+ }
72
+
73
+ self
74
+ end
75
+
76
+ alias_native :length
77
+ alias_native :to_s, :cssText
78
+
79
+ def method_missing(name, value = nil)
80
+ if name.end_with? ?=
81
+ self[name[0 .. -2]] = value
82
+ else
83
+ self[name]
84
+ end
85
+ end
86
+ end
87
+
88
+ end; end
@@ -0,0 +1,48 @@
1
+ module Browser; module CSS
2
+
3
+ class Rule
4
+ include Native
5
+
6
+ STYLE_RULE = 1
7
+ CHARSET_RULE = 2
8
+ IMPORT_RULE = 3
9
+ MEDIA_RULE = 4
10
+ FONT_FACE_RULE = 5
11
+ PAGE_RULE = 6
12
+ KEYFRAMES_RULE = 7
13
+ KEYFRAME_RULE = 8
14
+ NAMESPACE_RULE = 10
15
+ COUNTER_STYLE_RULE = 11
16
+ SUPPORTS_RULE = 12
17
+ DOCUMENT_RULE = 13
18
+ FONT_FEATURE_VALUES_RULE = 14
19
+ VIEWPORT_RULE = 15
20
+ REGION_STYLE_RULE = 16
21
+
22
+ def self.new(rule)
23
+ if self == Rule
24
+ @classes ||= [nil, Style]
25
+
26
+ if klass = @classes[`rule.type`]
27
+ klass.new(rule)
28
+ else
29
+ raise ArgumentError, 'cannot instantiate a non derived Rule object'
30
+ end
31
+ else
32
+ super(rule)
33
+ end
34
+ end
35
+
36
+ alias_native :text, :cssText
37
+ alias_native :to_s, :cssText
38
+
39
+ def parent
40
+ Rule.new(`#@native.parentRule`) if `#@native.parentRule != null`
41
+ end
42
+
43
+ def style_sheet
44
+ StyleSheet.new(`#@native.parentStyleSheet`) if `#@native.parentStyleSheet != null`
45
+ end
46
+ end
47
+
48
+ end; end
@@ -0,0 +1,16 @@
1
+ module Browser; module CSS; class Rule
2
+
3
+ class Style < Rule
4
+ alias_native :selector, :selectorText
5
+ alias_native :id, :selectorText
6
+
7
+ def declaration
8
+ Declaration.new(`#@native.style`)
9
+ end
10
+
11
+ def method_missing(*args, &block)
12
+ declaration.__send__(*args, &block)
13
+ end
14
+ end
15
+
16
+ end; end; end
@@ -0,0 +1,83 @@
1
+ module Browser; module CSS
2
+
3
+ class StyleSheet
4
+ include Native
5
+
6
+ def initialize(what)
7
+ if what.is_a? DOM::Element
8
+ super(`#{what.to_n}.sheet`)
9
+ else
10
+ super(what)
11
+ end
12
+ end
13
+
14
+ alias_native :disabled?, :disabled
15
+ alias_native :href
16
+ alias_native :title
17
+ alias_native :type
18
+
19
+ def media
20
+ Media.new(`#@native.media`) if `#@native.media != null`
21
+ end
22
+
23
+ def owner
24
+ DOM(`#@native.ownerNode`)
25
+ end
26
+
27
+ def parent
28
+ Sheet.new(`#@native.parentStyleSheet`) if `#@native.parentStyleSheet != null`
29
+ end
30
+
31
+ def rules
32
+ Native::Array.new(`#@native.cssRules`) { |e|
33
+ Rule.new(e)
34
+ }
35
+ end
36
+
37
+ def delete(index)
38
+ `#@native.deleteRule(index)`
39
+ end
40
+
41
+ def insert(index, rule)
42
+ `#@native.insertRule(#{rule}, #{index})`
43
+ end
44
+
45
+ def rule(selector, body)
46
+ unless String === selector
47
+ selector = selector.join ', '
48
+ end
49
+
50
+ unless String === body
51
+ body = body.map {|name, value|
52
+ "#{name}: #{value};"
53
+ }.join "\n"
54
+ end
55
+
56
+ insert(length, "#{selector} { #{body} }")
57
+ end
58
+
59
+ def [](id)
60
+ rules.find { |r| log r; r.id == id }
61
+ end
62
+
63
+ def method_missing(*args, &block)
64
+ rules.__send__(*args, &block)
65
+ end
66
+
67
+ class Media < Native::Array
68
+ alias_native :text, :mediaText
69
+ alias_native :to_s, :mediaText
70
+
71
+ def push(medium)
72
+ `#@native.appendMedium(#{medium})`
73
+
74
+ self
75
+ end
76
+
77
+ def delete(medium)
78
+ `#@native.deleteMedium(#{medium})`
79
+ end
80
+ end
81
+ end
82
+
83
+ end; end
@@ -0,0 +1,188 @@
1
+ module Browser; module CSS
2
+
3
+ class Unit
4
+ COMPATIBLE = %i[in pt mm cm px pc]
5
+
6
+ attr_reader :type
7
+
8
+ def initialize(number, type)
9
+ @number = number
10
+ @type = type
11
+ end
12
+
13
+ def coerce(other)
14
+ return self, other
15
+ end
16
+
17
+ def ==(other)
18
+ @number == convert(other, @type)
19
+ end
20
+
21
+ def ===(other)
22
+ @type == other.type && @number == other.to_f
23
+ end
24
+
25
+ alias eql? ==
26
+
27
+ def hash
28
+ [@number, @type].hash
29
+ end
30
+
31
+ %i[em ex ch rem vh vw vmin vmax px mm cm in pt pc].each {|name|
32
+ define_method name do
33
+ Unit.new(convert(self, name), name)
34
+ end
35
+ }
36
+
37
+ def +(other)
38
+ return Unit.new(@number + other, @type) unless Unit === other
39
+
40
+ if @type == other.type
41
+ Unit.new(@number + other.to_f, @type)
42
+ elsif compatible?(self) and compatible?(other)
43
+ Unit.new(@number + convert(other, @type), @type)
44
+ else
45
+ raise ArgumentError, "#{other.type} isn't compatible with #{@type}"
46
+ end
47
+ end
48
+
49
+ def -(other)
50
+ return Unit.new(@number - other, @type) unless Unit === other
51
+
52
+ if @type == other.type
53
+ Unit.new(@number - other.to_f, @type)
54
+ elsif compatible?(self) and compatible?(other)
55
+ Unit.new(@number - convert(other, @type), @type)
56
+ else
57
+ raise ArgumentError, "#{other.type} isn't compatible with #{@type}"
58
+ end
59
+ end
60
+
61
+ def *(other)
62
+ return Unit.new(@number * other, @type) unless Unit === other
63
+
64
+ if @type == other.type
65
+ Unit.new(@number * other.to_f, @type)
66
+ elsif compatible?(self) and compatible?(other)
67
+ Unit.new(@number * convert(other, @type), @type)
68
+ else
69
+ raise ArgumentError, "#{other.type} isn't compatible with #{@type}"
70
+ end
71
+ end
72
+
73
+ def /(other)
74
+ return Unit.new(@number / other, @type) unless Unit === other
75
+
76
+ if @type == other.type
77
+ Unit.new(@number / other.to_f, @type)
78
+ elsif compatible?(self) and compatible?(other)
79
+ Unit.new(@number / convert(other, @type), @type)
80
+ else
81
+ raise ArgumentError, "#{other.type} isn't compatible with #{@type}"
82
+ end
83
+ end
84
+
85
+ def -@
86
+ Unit.new(@number * -1, @type)
87
+ end
88
+
89
+ def +@
90
+ Unit.new(@number, @type)
91
+ end
92
+
93
+ def to_i
94
+ @number.to_i
95
+ end
96
+
97
+ def to_f
98
+ @number.to_f
99
+ end
100
+
101
+ def to_u
102
+ self
103
+ end
104
+
105
+ def to_s
106
+ "#{@number}#{@type}"
107
+ end
108
+
109
+ alias to_str to_s
110
+ alias inspect to_s
111
+
112
+ private
113
+ def compatible?(unit)
114
+ COMPATIBLE.include?(unit.type)
115
+ end
116
+
117
+ def convert(unit, type)
118
+ value = unit.to_f
119
+
120
+ return value if unit.type == type
121
+
122
+ px = case unit.type
123
+ when :in then value * 96
124
+ when :pt then value * 4.0 / 3.0
125
+ when :pc then value / 12 * 4.0 / 3.0
126
+ when :mm then value * 3.77953
127
+ when :cm then value * 10 * 3.77953
128
+ when :px then value
129
+ end
130
+
131
+ case type
132
+ when :in then px / 96.0
133
+ when :pt then px / 4.0 / 3.0
134
+ when :pc then px * 12 / 4.0 / 3.0
135
+ when :mm then px / 3.77953
136
+ when :cm then px / 10 / 3.77953
137
+ when :px then px
138
+ end
139
+ end
140
+ end
141
+
142
+ end; end
143
+
144
+ class Numeric
145
+ Unit = Browser::CSS::Unit
146
+
147
+ %i[em ex ch rem vh vw vmin vmax px mm cm in pt pc].each {|name|
148
+ define_method name do
149
+ Unit.new(self, name)
150
+ end
151
+ }
152
+
153
+ alias old_percent %
154
+
155
+ def %(other = nil)
156
+ if other
157
+ old_percent(other)
158
+ else
159
+ Unit.new(self, :%)
160
+ end
161
+ end
162
+
163
+ def to_u
164
+ self
165
+ end
166
+ end
167
+
168
+ class String
169
+ def to_u
170
+ if matches = self.match(/^([\d+.]+)(.+)?$/)
171
+ value = matches[1].to_f
172
+
173
+ if unit = matches[2]
174
+ value.__send__(unit.downcase)
175
+ else
176
+ value
177
+ end
178
+ else
179
+ 0
180
+ end
181
+ end
182
+ end
183
+
184
+ class NilClass
185
+ def to_u
186
+ 0
187
+ end
188
+ end