opal-browser 0.1.0.beta1 → 0.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +60 -0
  3. data/.yardopts +1 -1
  4. data/Gemfile +7 -2
  5. data/LICENSE +19 -0
  6. data/README.md +74 -10
  7. data/config.ru +2 -1
  8. data/index.html.erb +22 -0
  9. data/opal-browser.gemspec +9 -11
  10. data/opal/browser.rb +1 -1
  11. data/opal/browser/animation_frame.rb +66 -9
  12. data/opal/browser/canvas.rb +72 -18
  13. data/opal/browser/canvas/data.rb +1 -1
  14. data/opal/browser/console.rb +3 -37
  15. data/opal/browser/cookies.rb +80 -24
  16. data/opal/browser/css/declaration.rb +0 -5
  17. data/opal/browser/{timeout.rb → delay.rb} +13 -13
  18. data/opal/browser/dom.rb +0 -2
  19. data/opal/browser/dom/attribute.rb +6 -0
  20. data/opal/browser/dom/builder.rb +4 -8
  21. data/opal/browser/dom/character_data.rb +43 -7
  22. data/opal/browser/dom/document.rb +13 -11
  23. data/opal/browser/dom/element.rb +127 -29
  24. data/opal/browser/dom/element/image.rb +23 -0
  25. data/opal/browser/dom/element/offset.rb +27 -10
  26. data/opal/browser/dom/element/scroll.rb +32 -12
  27. data/opal/browser/dom/element/size.rb +29 -0
  28. data/opal/browser/dom/event.rb +88 -75
  29. data/opal/browser/dom/event/animation.rb +16 -4
  30. data/opal/browser/dom/event/audio_processing.rb +6 -4
  31. data/opal/browser/dom/event/base.rb +229 -64
  32. data/opal/browser/dom/event/before_unload.rb +6 -4
  33. data/opal/browser/dom/event/clipboard.rb +6 -4
  34. data/opal/browser/dom/event/close.rb +16 -4
  35. data/opal/browser/dom/event/composition.rb +16 -4
  36. data/opal/browser/dom/event/custom.rb +43 -8
  37. data/opal/browser/dom/event/device_light.rb +6 -4
  38. data/opal/browser/dom/event/device_motion.rb +17 -4
  39. data/opal/browser/dom/event/device_orientation.rb +16 -4
  40. data/opal/browser/dom/event/device_proximity.rb +6 -4
  41. data/opal/browser/dom/event/drag.rb +34 -28
  42. data/opal/browser/dom/event/focus.rb +21 -5
  43. data/opal/browser/dom/event/gamepad.rb +33 -20
  44. data/opal/browser/dom/event/hash_change.rb +6 -4
  45. data/opal/browser/dom/event/keyboard.rb +45 -23
  46. data/opal/browser/dom/event/message.rb +28 -8
  47. data/opal/browser/dom/event/mouse.rb +26 -25
  48. data/opal/browser/dom/event/page_transition.rb +6 -4
  49. data/opal/browser/dom/event/pop_state.rb +16 -4
  50. data/opal/browser/dom/event/progress.rb +16 -4
  51. data/opal/browser/dom/event/sensor.rb +6 -4
  52. data/opal/browser/dom/event/storage.rb +6 -4
  53. data/opal/browser/dom/event/touch.rb +10 -19
  54. data/opal/browser/dom/event/ui.rb +19 -3
  55. data/opal/browser/dom/event/wheel.rb +2 -2
  56. data/opal/browser/dom/mutation_observer.rb +65 -5
  57. data/opal/browser/dom/node.rb +164 -59
  58. data/opal/browser/dom/node_set.rb +4 -0
  59. data/opal/browser/dom/text.rb +16 -1
  60. data/opal/browser/event_source.rb +5 -2
  61. data/opal/browser/history.rb +51 -15
  62. data/opal/browser/http.rb +22 -7
  63. data/opal/browser/http/headers.rb +5 -0
  64. data/opal/browser/http/request.rb +40 -10
  65. data/opal/browser/immediate.rb +123 -9
  66. data/opal/browser/interval.rb +8 -13
  67. data/opal/browser/location.rb +13 -3
  68. data/opal/browser/navigator.rb +9 -6
  69. data/opal/browser/screen.rb +31 -5
  70. data/opal/browser/socket.rb +8 -4
  71. data/opal/browser/storage.rb +118 -33
  72. data/opal/browser/support.rb +232 -0
  73. data/opal/browser/utils.rb +24 -6
  74. data/opal/browser/version.rb +1 -1
  75. data/opal/browser/window.rb +1 -2
  76. data/opal/browser/window/scroll.rb +21 -11
  77. data/opal/browser/window/size.rb +16 -6
  78. data/opal/browser/window/view.rb +23 -5
  79. data/spec/dom/builder_spec.rb +19 -19
  80. data/spec/dom/document_spec.rb +6 -6
  81. data/spec/dom/element_spec.rb +5 -5
  82. data/spec/dom/event_spec.rb +20 -20
  83. data/spec/dom/mutation_observer_spec.rb +5 -5
  84. data/spec/dom/node_spec.rb +39 -27
  85. data/spec/dom_spec.rb +10 -8
  86. data/spec/event_source_spec.rb +12 -12
  87. data/spec/history_spec.rb +24 -15
  88. data/spec/http_spec.rb +18 -17
  89. data/spec/immediate_spec.rb +9 -7
  90. data/spec/runner.rb +114 -0
  91. data/spec/socket_spec.rb +8 -8
  92. data/spec/spec_helper.rb +1 -0
  93. data/spec/storage_spec.rb +6 -6
  94. data/spec/wgxpath.install.js +49 -0
  95. data/spec/window_spec.rb +2 -2
  96. metadata +21 -54
  97. data/opal/browser/compatibility.rb +0 -59
  98. data/opal/browser/compatibility/animation_frame.rb +0 -93
  99. data/opal/browser/compatibility/dom/document/window.rb +0 -15
  100. data/opal/browser/compatibility/dom/element/css.rb +0 -15
  101. data/opal/browser/compatibility/dom/element/matches.rb +0 -31
  102. data/opal/browser/compatibility/dom/element/offset.rb +0 -20
  103. data/opal/browser/compatibility/dom/element/scroll.rb +0 -25
  104. data/opal/browser/compatibility/dom/element/style.rb +0 -15
  105. data/opal/browser/compatibility/dom/mutation_observer.rb +0 -47
  106. data/opal/browser/compatibility/http/request.rb +0 -15
  107. data/opal/browser/compatibility/immediate.rb +0 -107
  108. data/opal/browser/compatibility/window/scroll.rb +0 -27
  109. data/opal/browser/compatibility/window/size.rb +0 -13
  110. data/opal/browser/compatibility/window/view.rb +0 -13
  111. data/opal/browser/dom/compatibility.rb +0 -8
  112. data/opal/browser/http/compatibility.rb +0 -1
  113. data/opal/browser/window/compatibility.rb +0 -3
@@ -42,7 +42,7 @@ class Data
42
42
  end
43
43
 
44
44
  def length
45
- `#@native.length`
45
+ `#@native.data.length`
46
46
  end
47
47
 
48
48
  def [](index)
@@ -1,67 +1,43 @@
1
1
  module Browser
2
2
 
3
- # This class wraps a `window.console`.
3
+ # Manipulate the browser console.
4
+ #
5
+ # @see https://developer.mozilla.org/en-US/docs/Web/API/console
4
6
  class Console
5
7
  include Native
6
8
 
7
9
  # Clear the console.
8
- #
9
- # @return [self]
10
10
  def clear
11
11
  `#@native.clear()`
12
-
13
- self
14
12
  end
15
13
 
16
14
  # Print a stacktrace from the call site.
17
- #
18
- # @return [self]
19
15
  def trace
20
16
  `#@native.trace()`
21
-
22
- self
23
17
  end
24
18
 
25
19
  # Log the passed objects based on an optional initial format.
26
- #
27
- # @return [self]
28
20
  def log(*args)
29
21
  `#@native.log.apply(#@native, args)`
30
-
31
- self
32
22
  end
33
23
 
34
24
  # Log the passed objects based on an optional initial format as informational
35
25
  # log.
36
- #
37
- # @return [self]
38
26
  def info(*args)
39
27
  `#@native.info.apply(#@native, args)`
40
-
41
- self
42
28
  end
43
29
 
44
30
  # Log the passed objects based on an optional initial format as warning.
45
- #
46
- # @return [self]
47
31
  def warn(*args)
48
32
  `#@native.warn.apply(#@native, args)`
49
-
50
- self
51
33
  end
52
34
 
53
35
  # Log the passed objects based on an optional initial format as error.
54
- #
55
- # @return [self]
56
36
  def error(*args)
57
37
  `#@native.error.apply(#@native, args)`
58
-
59
- self
60
38
  end
61
39
 
62
40
  # Time the given block with the given label.
63
- #
64
- # @return [self]
65
41
  def time(label, &block)
66
42
  raise ArgumentError, "no block given" unless block
67
43
 
@@ -76,13 +52,9 @@ class Console
76
52
  ensure
77
53
  `#@native.timeEnd()`
78
54
  end
79
-
80
- self
81
55
  end
82
56
 
83
57
  # Group the given block.
84
- #
85
- # @return [self]
86
58
  def group(*args, &block)
87
59
  raise ArgumentError, "no block given" unless block
88
60
 
@@ -97,13 +69,9 @@ class Console
97
69
  ensure
98
70
  `#@native.groupEnd()`
99
71
  end
100
-
101
- self
102
72
  end
103
73
 
104
74
  # Group the given block but collapse it.
105
- #
106
- # @return [self]
107
75
  def group!(*args, &block)
108
76
  return unless block_given?
109
77
 
@@ -118,8 +86,6 @@ class Console
118
86
  ensure
119
87
  `#@native.groupEnd()`
120
88
  end
121
-
122
- self
123
89
  end
124
90
  end
125
91
 
@@ -1,25 +1,36 @@
1
+ require 'stringio'
2
+
1
3
  module Browser
2
4
 
5
+ # Allows manipulation of browser cookies.
6
+ #
7
+ # @see https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
3
8
  class Cookies
9
+ # Default cookie options.
10
+ DEFAULT = {
11
+ expires: Time.now + 1.day,
12
+ secure: false
13
+ }
14
+
4
15
  include Enumerable
5
16
 
17
+ attr_reader :options
18
+
19
+ # Create a new {Cookies} wrapper.
20
+ #
21
+ # @param document [native] the native document object
6
22
  def initialize(document)
7
23
  @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
24
+ @options = DEFAULT.dup
19
25
  end
20
26
 
21
- def [] (name)
22
- matches = `#@document.cookie`.scan(/#{Regexp.escape(key.encode_uri_component)}=([^;]*)/)
27
+ # Access the cookie with the given name.
28
+ #
29
+ # @param name [String] the name of the cookie
30
+ #
31
+ # @return [Object]
32
+ def [](name)
33
+ matches = `#@document.cookie`.scan(/#{Regexp.escape(name.encode_uri_component)}=([^;]*)/)
23
34
 
24
35
  return if matches.empty?
25
36
 
@@ -30,49 +41,94 @@ class Cookies
30
41
  result.length == 1 ? result.first : result
31
42
  end
32
43
 
33
- def []= (name, value, options = {})
44
+ # Set a cookie.
45
+ #
46
+ # Options
47
+ # -------
48
+ # + **max_age** - the max age of the cookie in seconds
49
+ # + **expires** - the expire date as {Time}
50
+ # + **path** - the path where the cookie is valid on
51
+ # + **domain** - the domain where the cookie is valid on
52
+ # + **secure** - whether the cookie is secure or not
53
+ #
54
+ # @param name [String] the name of the cookie
55
+ # @param value [Object] the data to set
56
+ # @param options [Hash] the options for the cookie
57
+ def []=(name, value, options = {})
34
58
  `#@document.cookie = #{encode name, value.is_a?(String) ? value : JSON.dump(value), @options.merge(options)}`
35
59
  end
36
60
 
37
- def delete (name)
61
+ # Delete a cookie.
62
+ #
63
+ # @param name [String] the name of the cookie
64
+ def delete(name)
38
65
  `#@document.cookie = #{encode name, '', expires: Time.now}`
39
66
  end
40
67
 
68
+ # @!attribute [r] keys
69
+ # @return [Array<String>] all the cookie names
41
70
  def keys
42
71
  Array(`#@document.cookie.split(/; /)`).map {|cookie|
43
72
  cookie.split(/\s*=\s*/).first
44
73
  }
45
74
  end
46
75
 
76
+ # @!attribute [r] values
77
+ # @return [Array] all the cookie values
47
78
  def values
48
79
  keys.map {|key|
49
80
  self[key]
50
81
  }
51
82
  end
52
83
 
53
- def each
84
+ # Enumerate the cookies.
85
+ #
86
+ # @yieldparam key [String] the name of the cookie
87
+ # @yieldparam value [String] the value of the cookie
88
+ #
89
+ # @return [self]
90
+ def each(&block)
91
+ return enum_for :each unless block
92
+
54
93
  keys.each {|key|
55
94
  yield key, self[key]
56
95
  }
96
+
97
+ self
57
98
  end
58
99
 
100
+ # Delete all the cookies
101
+ #
102
+ # @return [self]
59
103
  def clear
60
104
  keys.each {|key|
61
105
  delete key
62
106
  }
107
+
108
+ self
63
109
  end
64
110
 
65
111
  protected
66
- def encode (key, value, options = {})
67
- result = "#{key.encode_uri_component}=#{value.encode_uri_component}; "
112
+ def encode(key, value, options = {})
113
+ io = StringIO.new
114
+
115
+ io << key.encode_uri_component << ?= << value.encode_uri_component << '; '
68
116
 
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]
117
+ io << 'max-age=' << options[:max_age] << '; ' if options[:max_age]
118
+ io << 'expires=' << options[:expires].to_utc << '; ' if options[:expires]
119
+ io << 'path=' << options[:path] << '; ' if options[:path]
120
+ io << 'domain=' << options[:domain] << '; ' if options[:domain]
121
+ io << 'secure' if options[:secure]
122
+
123
+ io.string
124
+ end
125
+ end
74
126
 
75
- result
127
+ class DOM::Document < DOM::Element
128
+ # @!attribute [r] cookies
129
+ # @return [Cookies] the cookies for the document
130
+ def cookies
131
+ Cookies.new(@native) if defined?(`#@native.cookie`)
76
132
  end
77
133
  end
78
134
 
@@ -18,21 +18,16 @@ class Declaration
18
18
 
19
19
  def replace(string)
20
20
  `#@native.cssText = #{string}`
21
-
22
- self
23
21
  end
24
22
 
25
23
  def apply(&block)
26
24
  Paggio::CSS::Definition.new(&block).each {|style|
27
- # FIXME: use ternary operator when it's fixed
28
25
  if style.important
29
26
  `#@native.setProperty(#{style.name}, #{style.value}, "important")`
30
27
  else
31
28
  `#@native.setProperty(#{style.name}, #{style.value}, "")`
32
29
  end
33
30
  }
34
-
35
- self
36
31
  end
37
32
 
38
33
  def delete(name)
@@ -1,15 +1,18 @@
1
1
  module Browser
2
2
 
3
- # This class wraps `setTimeout`.
4
- class Timeout
3
+ # Allows you to delay the call to a function which gets called after the
4
+ # given time.
5
+ #
6
+ # @see https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout
7
+ class Delay
5
8
  # @!attribute [r] after
6
- # @return [Number] the seconds after which the block is called
9
+ # @return [Float] the seconds after which the block is called
7
10
  attr_reader :after
8
11
 
9
12
  # Create and start a timeout.
10
13
  #
11
14
  # @param window [Window] the window to start the timeout on
12
- # @param time [Number] seconds after which the block is called
15
+ # @param time [Float] seconds after which the block is called
13
16
  def initialize(window, time, &block)
14
17
  @window = Native.convert(window)
15
18
  @after = time
@@ -19,18 +22,13 @@ class Timeout
19
22
  end
20
23
 
21
24
  # Abort the timeout.
22
- #
23
- # @return [self]
24
25
  def abort
25
26
  `#@window.clearTimeout(#@id)`
26
-
27
- self
28
27
  end
29
28
 
29
+ # Start the delay.
30
30
  def start
31
31
  @id = `#@window.setTimeout(#{@block.to_n}, #@after * 1000)`
32
-
33
- self
34
32
  end
35
33
  end
36
34
 
@@ -38,22 +36,24 @@ class Window
38
36
  # Execute a block after the given seconds.
39
37
  #
40
38
  # @param time [Float] the seconds after it gets called
41
- # @return [Timeout] the object representing the timeout
39
+ #
40
+ # @return [Delay] the object representing the timeout
42
41
  def after(time, &block)
43
- Timeout.new(@native, time, &block)
42
+ Delay.new(@native, time, &block)
44
43
  end
45
44
  end
46
45
 
47
46
  end
48
47
 
49
48
  class Proc
49
+ # (see Browser::Window#after)
50
50
  def after(time)
51
51
  $window.after(time, &self)
52
52
  end
53
53
  end
54
54
 
55
55
  module Kernel
56
- # (see Browser::Window#once)
56
+ # (see Browser::Window#after)
57
57
  def after(time, &block)
58
58
  $window.after(time, &block)
59
59
  end
@@ -12,8 +12,6 @@ require 'browser/dom/document_fragment'
12
12
  require 'browser/dom/builder'
13
13
  require 'browser/dom/mutation_observer'
14
14
 
15
- require 'browser/dom/compatibility'
16
-
17
15
  module Kernel
18
16
  # Parse an XML string into a DOM usable {Browser::DOM::Document}
19
17
  #
@@ -1,16 +1,22 @@
1
1
  module Browser; module DOM
2
2
 
3
+ # Encapsulates an {Element} attribute.
3
4
  class Attribute
4
5
  include Native
5
6
 
7
+ # Returns true if the attribute is an id.
6
8
  def id?
7
9
  `#@native.isId`
8
10
  end
9
11
 
12
+ # @!attribute [r] name
13
+ # @return [String] the name of the attribute
10
14
  def name
11
15
  `#@native.name`
12
16
  end
13
17
 
18
+ # @!attribute [r] value
19
+ # @return [String] the value of the attribute
14
20
  def value
15
21
  `#@native.value`
16
22
  end
@@ -9,10 +9,6 @@ class Paggio::HTML::Element < BasicObject
9
9
  def on(*args, &block)
10
10
  (@on ||= []) << [args, block]
11
11
  end
12
-
13
- def style(*args, &block)
14
- @style = [args, block]
15
- end
16
12
  end
17
13
 
18
14
  module Browser; module DOM
@@ -79,10 +75,6 @@ Builder.for Paggio::HTML::Element do |b, item|
79
75
  }
80
76
  end
81
77
 
82
- if style = `item.style || nil`
83
- dom.style(*style[0], &style[1])
84
- end
85
-
86
78
  if inner = `item.inner_html || nil`
87
79
  dom.inner_html = inner
88
80
  else
@@ -94,4 +86,8 @@ Builder.for Paggio::HTML::Element do |b, item|
94
86
  dom
95
87
  end
96
88
 
89
+ Builder.for DOM::Node do |b, item|
90
+ item
91
+ end
92
+
97
93
  end; end
@@ -1,34 +1,70 @@
1
1
  module Browser; module DOM
2
2
 
3
3
  class CharacterData < Node
4
+ # Append data to the node.
5
+ #
6
+ # @param string [String] the data to add
7
+ #
8
+ # @return [self]
9
+ def append(string)
10
+ `#@native.appendData(string)`
11
+
12
+ self
13
+ end
14
+
15
+ # @!attribute [r] data
16
+ # @return [String] the data of the node
4
17
  def data
5
18
  `#@native.data`
6
19
  end
7
20
 
8
- def append(string)
9
- `#@native.appendData(string)`
21
+ # Delete data from the node.
22
+ #
23
+ # @param count [Integer] how much data to delete
24
+ # @param offset [Integer] the offset to start at
25
+ #
26
+ # @return [self]
27
+ def delete(count, offset = 0)
28
+ `#@native.deleteData(offset, count)`
10
29
 
11
30
  self
12
31
  end
13
32
 
33
+ # Insert data in the node.
34
+ #
35
+ # @param string [String] the data to insert
36
+ # @param offset [Integer] the offset to start at
37
+ #
38
+ # @return [self]
14
39
  def insert(string, offset = 0)
15
40
  `#@native.insertData(offset, string)`
16
41
 
17
42
  self
18
43
  end
19
44
 
20
- def delete(count, offset = 0)
21
- `#@native.deleteData(offset, count)`
22
-
23
- self
24
- end
45
+ # @!attribute [r] length
46
+ # @return [Integer] the length of the node
47
+ alias_native :length
25
48
 
49
+ # Replace data in the node.
50
+ #
51
+ # @param string [String] the data to replace with
52
+ # @param offset [Integer] the offset to start at
53
+ # @param count [Integer] how much data to replace
54
+ #
55
+ # @return [self]
26
56
  def replace(string, offset = 0, count = `#@native.length`)
27
57
  `#@native.replaceData(offset, count, string)`
28
58
 
29
59
  self
30
60
  end
31
61
 
62
+ # Get a substring of the data.
63
+ #
64
+ # @param count [Integer] how much data to lice
65
+ # @param offset [Integer] the offset to start at
66
+ #
67
+ # @return [String] the substring
32
68
  def substring(count, offset = 0)
33
69
  `#@native.substringData(offset, count)`
34
70
  end