opal-browser 0.1.0.beta1 → 0.2.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 (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