diamonds 0.1.5

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 (180) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +36 -0
  3. data/lib/diamonds.rb +74 -0
  4. data/lib/diamonds/Gemfile +28 -0
  5. data/lib/diamonds/README.md +254 -0
  6. data/lib/diamonds/Rakefile +5 -0
  7. data/lib/diamonds/apps/application.rb +15 -0
  8. data/lib/diamonds/apps/library.rb +321 -0
  9. data/lib/diamonds/apps/user_app.rb +5 -0
  10. data/lib/diamonds/config.ru +98 -0
  11. data/lib/diamonds/db/mysiteDB Back.sqlite3 +0 -0
  12. data/lib/diamonds/db/mysiteDB.sqlite3 +0 -0
  13. data/lib/diamonds/gems/auto_launch_browser.rb +22 -0
  14. data/lib/diamonds/gems/io.rb +146 -0
  15. data/lib/diamonds/gems/ruby_to_js.rb +173 -0
  16. data/lib/diamonds/gems/server_utils.rb +96 -0
  17. data/lib/diamonds/lib/opal-browser.rb +1 -0
  18. data/lib/diamonds/lib/opal/browser.rb +4 -0
  19. data/lib/diamonds/opal-browser.gemspec +21 -0
  20. data/lib/diamonds/opal/browser.rb +11 -0
  21. data/lib/diamonds/opal/browser/animation_frame.rb +111 -0
  22. data/lib/diamonds/opal/browser/canvas.rb +321 -0
  23. data/lib/diamonds/opal/browser/canvas/data.rb +63 -0
  24. data/lib/diamonds/opal/browser/canvas/gradient.rb +27 -0
  25. data/lib/diamonds/opal/browser/canvas/style.rb +113 -0
  26. data/lib/diamonds/opal/browser/canvas/text.rb +45 -0
  27. data/lib/diamonds/opal/browser/console.rb +103 -0
  28. data/lib/diamonds/opal/browser/cookies.rb +133 -0
  29. data/lib/diamonds/opal/browser/css.rb +24 -0
  30. data/lib/diamonds/opal/browser/css/declaration.rb +83 -0
  31. data/lib/diamonds/opal/browser/css/rule.rb +48 -0
  32. data/lib/diamonds/opal/browser/css/rule/style.rb +16 -0
  33. data/lib/diamonds/opal/browser/css/style_sheet.rb +83 -0
  34. data/lib/diamonds/opal/browser/css/unit.rb +188 -0
  35. data/lib/diamonds/opal/browser/database/sql.rb +194 -0
  36. data/lib/diamonds/opal/browser/delay.rb +78 -0
  37. data/lib/diamonds/opal/browser/dom.rb +84 -0
  38. data/lib/diamonds/opal/browser/dom/attribute.rb +26 -0
  39. data/lib/diamonds/opal/browser/dom/builder.rb +88 -0
  40. data/lib/diamonds/opal/browser/dom/cdata.rb +9 -0
  41. data/lib/diamonds/opal/browser/dom/character_data.rb +73 -0
  42. data/lib/diamonds/opal/browser/dom/comment.rb +9 -0
  43. data/lib/diamonds/opal/browser/dom/document.rb +149 -0
  44. data/lib/diamonds/opal/browser/dom/document_fragment.rb +7 -0
  45. data/lib/diamonds/opal/browser/dom/element.rb +474 -0
  46. data/lib/diamonds/opal/browser/dom/element/attributes.rb +87 -0
  47. data/lib/diamonds/opal/browser/dom/element/data.rb +67 -0
  48. data/lib/diamonds/opal/browser/dom/element/image.rb +23 -0
  49. data/lib/diamonds/opal/browser/dom/element/input.rb +28 -0
  50. data/lib/diamonds/opal/browser/dom/element/offset.rb +89 -0
  51. data/lib/diamonds/opal/browser/dom/element/position.rb +46 -0
  52. data/lib/diamonds/opal/browser/dom/element/scroll.rb +136 -0
  53. data/lib/diamonds/opal/browser/dom/element/select.rb +36 -0
  54. data/lib/diamonds/opal/browser/dom/element/size.rb +34 -0
  55. data/lib/diamonds/opal/browser/dom/element/template.rb +9 -0
  56. data/lib/diamonds/opal/browser/dom/element/textarea.rb +24 -0
  57. data/lib/diamonds/opal/browser/dom/mutation_observer.rb +178 -0
  58. data/lib/diamonds/opal/browser/dom/node.rb +464 -0
  59. data/lib/diamonds/opal/browser/dom/node_set.rb +110 -0
  60. data/lib/diamonds/opal/browser/dom/text.rb +36 -0
  61. data/lib/diamonds/opal/browser/effects.rb +50 -0
  62. data/lib/diamonds/opal/browser/event.rb +253 -0
  63. data/lib/diamonds/opal/browser/event/animation.rb +38 -0
  64. data/lib/diamonds/opal/browser/event/audio_processing.rb +33 -0
  65. data/lib/diamonds/opal/browser/event/base.rb +430 -0
  66. data/lib/diamonds/opal/browser/event/before_unload.rb +15 -0
  67. data/lib/diamonds/opal/browser/event/clipboard.rb +28 -0
  68. data/lib/diamonds/opal/browser/event/close.rb +47 -0
  69. data/lib/diamonds/opal/browser/event/composition.rb +50 -0
  70. data/lib/diamonds/opal/browser/event/custom.rb +65 -0
  71. data/lib/diamonds/opal/browser/event/device_light.rb +23 -0
  72. data/lib/diamonds/opal/browser/event/device_motion.rb +51 -0
  73. data/lib/diamonds/opal/browser/event/device_orientation.rb +48 -0
  74. data/lib/diamonds/opal/browser/event/device_proximity.rb +33 -0
  75. data/lib/diamonds/opal/browser/event/drag.rb +119 -0
  76. data/lib/diamonds/opal/browser/event/focus.rb +39 -0
  77. data/lib/diamonds/opal/browser/event/gamepad.rb +60 -0
  78. data/lib/diamonds/opal/browser/event/hash_change.rb +28 -0
  79. data/lib/diamonds/opal/browser/event/keyboard.rb +115 -0
  80. data/lib/diamonds/opal/browser/event/message.rb +70 -0
  81. data/lib/diamonds/opal/browser/event/mouse.rb +254 -0
  82. data/lib/diamonds/opal/browser/event/page_transition.rb +23 -0
  83. data/lib/diamonds/opal/browser/event/pop_state.rb +33 -0
  84. data/lib/diamonds/opal/browser/event/progress.rb +43 -0
  85. data/lib/diamonds/opal/browser/event/sensor.rb +15 -0
  86. data/lib/diamonds/opal/browser/event/storage.rb +43 -0
  87. data/lib/diamonds/opal/browser/event/touch.rb +60 -0
  88. data/lib/diamonds/opal/browser/event/ui.rb +38 -0
  89. data/lib/diamonds/opal/browser/event/wheel.rb +49 -0
  90. data/lib/diamonds/opal/browser/event_source.rb +70 -0
  91. data/lib/diamonds/opal/browser/history.rb +90 -0
  92. data/lib/diamonds/opal/browser/http.rb +169 -0
  93. data/lib/diamonds/opal/browser/http/binary.rb +58 -0
  94. data/lib/diamonds/opal/browser/http/headers.rb +109 -0
  95. data/lib/diamonds/opal/browser/http/request.rb +344 -0
  96. data/lib/diamonds/opal/browser/http/response.rb +115 -0
  97. data/lib/diamonds/opal/browser/immediate.rb +163 -0
  98. data/lib/diamonds/opal/browser/interval.rb +111 -0
  99. data/lib/diamonds/opal/browser/location.rb +87 -0
  100. data/lib/diamonds/opal/browser/navigator.rb +173 -0
  101. data/lib/diamonds/opal/browser/screen.rb +66 -0
  102. data/lib/diamonds/opal/browser/socket.rb +123 -0
  103. data/lib/diamonds/opal/browser/storage.rb +252 -0
  104. data/lib/diamonds/opal/browser/support.rb +287 -0
  105. data/lib/diamonds/opal/browser/utils.rb +74 -0
  106. data/lib/diamonds/opal/browser/version.rb +3 -0
  107. data/lib/diamonds/opal/browser/window.rb +120 -0
  108. data/lib/diamonds/opal/browser/window/scroll.rb +59 -0
  109. data/lib/diamonds/opal/browser/window/size.rb +59 -0
  110. data/lib/diamonds/opal/browser/window/view.rb +36 -0
  111. data/lib/diamonds/opal/opal-browser.rb +1 -0
  112. data/lib/diamonds/public/__OPAL_SOURCE_MAPS__/application.map +0 -0
  113. data/lib/diamonds/public/javascripts/font-awesome/HELP-US-OUT.txt +7 -0
  114. data/lib/diamonds/public/javascripts/font-awesome/css/font-awesome.css +2026 -0
  115. data/lib/diamonds/public/javascripts/font-awesome/css/font-awesome.min.css +1 -0
  116. data/lib/diamonds/public/javascripts/font-awesome/fonts/FontAwesome.otf +0 -0
  117. data/lib/diamonds/public/javascripts/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  118. data/lib/diamonds/public/javascripts/font-awesome/fonts/fontawesome-webfont.svg +640 -0
  119. data/lib/diamonds/public/javascripts/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  120. data/lib/diamonds/public/javascripts/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  121. data/lib/diamonds/public/javascripts/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
  122. data/lib/diamonds/public/javascripts/font-awesome/less/animated.less +34 -0
  123. data/lib/diamonds/public/javascripts/font-awesome/less/bordered-pulled.less +25 -0
  124. data/lib/diamonds/public/javascripts/font-awesome/less/core.less +12 -0
  125. data/lib/diamonds/public/javascripts/font-awesome/less/fixed-width.less +6 -0
  126. data/lib/diamonds/public/javascripts/font-awesome/less/font-awesome.less +17 -0
  127. data/lib/diamonds/public/javascripts/font-awesome/less/icons.less +677 -0
  128. data/lib/diamonds/public/javascripts/font-awesome/less/larger.less +13 -0
  129. data/lib/diamonds/public/javascripts/font-awesome/less/list.less +19 -0
  130. data/lib/diamonds/public/javascripts/font-awesome/less/mixins.less +26 -0
  131. data/lib/diamonds/public/javascripts/font-awesome/less/path.less +15 -0
  132. data/lib/diamonds/public/javascripts/font-awesome/less/rotated-flipped.less +20 -0
  133. data/lib/diamonds/public/javascripts/font-awesome/less/stacked.less +20 -0
  134. data/lib/diamonds/public/javascripts/font-awesome/less/variables.less +688 -0
  135. data/lib/diamonds/public/javascripts/font-awesome/scss/_animated.scss +34 -0
  136. data/lib/diamonds/public/javascripts/font-awesome/scss/_bordered-pulled.scss +25 -0
  137. data/lib/diamonds/public/javascripts/font-awesome/scss/_core.scss +12 -0
  138. data/lib/diamonds/public/javascripts/font-awesome/scss/_fixed-width.scss +6 -0
  139. data/lib/diamonds/public/javascripts/font-awesome/scss/_icons.scss +677 -0
  140. data/lib/diamonds/public/javascripts/font-awesome/scss/_larger.scss +13 -0
  141. data/lib/diamonds/public/javascripts/font-awesome/scss/_list.scss +19 -0
  142. data/lib/diamonds/public/javascripts/font-awesome/scss/_mixins.scss +26 -0
  143. data/lib/diamonds/public/javascripts/font-awesome/scss/_path.scss +15 -0
  144. data/lib/diamonds/public/javascripts/font-awesome/scss/_rotated-flipped.scss +20 -0
  145. data/lib/diamonds/public/javascripts/font-awesome/scss/_stacked.scss +20 -0
  146. data/lib/diamonds/public/javascripts/font-awesome/scss/_variables.scss +688 -0
  147. data/lib/diamonds/public/javascripts/font-awesome/scss/font-awesome.scss +17 -0
  148. data/lib/diamonds/public/javascripts/jquery-2.1.4.min.js +4 -0
  149. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  150. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  151. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_flat_10_000000_40x100.png +0 -0
  152. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  153. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  154. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  155. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  156. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  157. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  158. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-icons_222222_256x240.png +0 -0
  159. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-icons_228ef1_256x240.png +0 -0
  160. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-icons_ef8c08_256x240.png +0 -0
  161. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-icons_ffd27a_256x240.png +0 -0
  162. data/lib/diamonds/public/javascripts/jquery-ui/images/ui-icons_ffffff_256x240.png +0 -0
  163. data/lib/diamonds/public/javascripts/jquery-ui/jquery-ui.min.css +7 -0
  164. data/lib/diamonds/public/javascripts/jquery-ui/jquery-ui.min.js +13 -0
  165. data/lib/diamonds/public/javascripts/jquery-ui/jquery-ui.structure.min.css +5 -0
  166. data/lib/diamonds/public/javascripts/jquery-ui/jquery-ui.theme.min.css +5 -0
  167. data/lib/diamonds/public/javascripts/jquery.js +4 -0
  168. data/lib/diamonds/public/javascripts/jquery.ui.touch-punch.min.js +11 -0
  169. data/lib/diamonds/public/javascripts/ne pas utiliser version en retard jeezs_editor.js b/data/lib/diamonds/public/javascripts/ne pas utiliser version en retard → jeezs_editor.js +0 -0
  170. data/lib/diamonds/public/javascripts/standalone.js +2316 -0
  171. data/lib/diamonds/public/javascripts/standalone.min.js +1 -0
  172. data/lib/diamonds/public/javascripts/wysiwyg-editor.min.css +1 -0
  173. data/lib/diamonds/public/javascripts/wysiwyg-editor.min.js +1 -0
  174. data/lib/diamonds/public/javascripts/wysiwyg.min.js +1 -0
  175. data/lib/diamonds/user_app/main.rb +45 -0
  176. data/lib/diamonds/version.rb +3 -0
  177. data/lib/diamonds/views/index.erb +35 -0
  178. data/lib/diamonds/views/javascripts/jeezs_editor.js.erb +365 -0
  179. data/lib/diamonds/views/stylesheets/main.css.erb +244 -0
  180. metadata +490 -0
@@ -0,0 +1,169 @@
1
+ require 'promise'
2
+
3
+ require 'browser/http/binary'
4
+ require 'browser/http/headers'
5
+ require 'browser/http/request'
6
+ require 'browser/http/response'
7
+
8
+ module Browser
9
+
10
+ module HTTP
11
+ # Check if HTTP requests are supported.
12
+ def self.supported?
13
+ Browser.supports?('XHR') || Browser.supports?('ActiveXObject')
14
+ end
15
+
16
+ # Send an asynchronous request.
17
+ #
18
+ # @param method [Symbol] the HTTP method to use
19
+ # @param url [String] the URL to request
20
+ # @param data [String, Hash] the data to send
21
+ #
22
+ # @yieldparam request [Request] the request to configure
23
+ #
24
+ # @return [Promise] a promise that will be resolved with the response
25
+ def self.send(method, url, data = nil, &block)
26
+ Promise.new.tap {|promise|
27
+ Request.new(&block).tap {|req|
28
+ req.on :success do |res|
29
+ promise.resolve(res)
30
+ end
31
+
32
+ req.on :failure do |res|
33
+ promise.reject(res)
34
+ end
35
+ }.open(method, url).send(data)
36
+ }
37
+ end
38
+
39
+ # Send an asynchronous GET request.
40
+ #
41
+ # @param url [String] the URL to request
42
+ #
43
+ # @yieldparam request [Request] the request to configure
44
+ #
45
+ # @return [Promise] a promise that will be resolved with the response
46
+ def self.get(url, &block)
47
+ send(:get, url, &block)
48
+ end
49
+
50
+ # Send an asynchronous HEAD request.
51
+ #
52
+ # @param url [String] the URL to request
53
+ #
54
+ # @yieldparam request [Request] the request to configure
55
+ #
56
+ # @return [Promise] a promise that will be resolved with the response
57
+ def self.head(url, &block)
58
+ send(:head, url, &block)
59
+ end
60
+
61
+ # Send an asynchrnous POST request.
62
+ #
63
+ # @param url [String] the URL to request
64
+ # @param data [String, Hash] the data to send
65
+ #
66
+ # @yieldparam request [Request] the request to configure
67
+ #
68
+ # @return [Promise] a promise that will be resolved with the response
69
+ def self.post(url, data = nil, &block)
70
+ send(:post, url, data, &block)
71
+ end
72
+
73
+ # Send an asynchronous PUT request.
74
+ #
75
+ # @param url [String] the URL to request
76
+ # @param data [String, Hash] the data to send
77
+ #
78
+ # @yieldparam request [Request] the request to configure
79
+ #
80
+ # @return [Promise] a promise that will be resolved with the response
81
+ def self.put(url, data = nil, &block)
82
+ send(:put, url, data, &block)
83
+ end
84
+
85
+ # Send an asynchronous DELETE request.
86
+ #
87
+ # @param url [String] the URL to request
88
+ # @param data [String, Hash] the data to send
89
+ #
90
+ # @yieldparam request [Request] the request to configure
91
+ #
92
+ # @return [Promise] a promise that will be resolved with the response
93
+ def self.delete(url, data = nil, &block)
94
+ send(:delete, url, data, &block)
95
+ end
96
+
97
+ # Send a synchronous request.
98
+ #
99
+ # @param method [Symbol] the HTTP method to use
100
+ # @param url [String] the URL to request
101
+ # @param data [String, Hash] the data to send
102
+ #
103
+ # @yieldparam request [Request] the request to configure
104
+ #
105
+ # @return [Response] the response
106
+ def self.send!(method, url, data = nil, &block)
107
+ Request.new(&block).open(method, url, false).send(data)
108
+ end
109
+
110
+ # Send a synchronous GET request.
111
+ #
112
+ # @param url [String] the URL to request
113
+ #
114
+ # @yieldparam request [Request] the request to configure
115
+ #
116
+ # @return [Response] the response
117
+ def self.get!(url, &block)
118
+ send!(:get, url, &block)
119
+ end
120
+
121
+ # Send a synchronous HEAD request.
122
+ #
123
+ # @param url [String] the URL to request
124
+ #
125
+ # @yieldparam request [Request] the request to configure
126
+ #
127
+ # @return [Response] the response
128
+ def self.head!(url, &block)
129
+ send!(:head, url, &block)
130
+ end
131
+
132
+ # Send a synchronous POST request.
133
+ #
134
+ # @param url [String] the URL to request
135
+ # @param data [String, Hash] the data to send
136
+ #
137
+ # @yieldparam request [Request] the request to configure
138
+ #
139
+ # @return [Response] the response
140
+ def self.post!(url, data = nil, &block)
141
+ send!(:post, url, data, &block)
142
+ end
143
+
144
+ # Send a synchronous PUT request.
145
+ #
146
+ # @param url [String] the URL to request
147
+ # @param data [String, Hash] the data to send
148
+ #
149
+ # @yieldparam request [Request] the request to configure
150
+ #
151
+ # @return [Response] the response
152
+ def self.put!(url, data = nil, &block)
153
+ send!(:put, url, data, &block)
154
+ end
155
+
156
+ # Send a synchronous DELETE request.
157
+ #
158
+ # @param url [String] the URL to request
159
+ # @param data [String, Hash] the data to send
160
+ #
161
+ # @yieldparam request [Request] the request to configure
162
+ #
163
+ # @return [Response] the response
164
+ def self.delete!(url, data = nil, &block)
165
+ send!(:delete, url, data, &block)
166
+ end
167
+ end
168
+
169
+ end
@@ -0,0 +1,58 @@
1
+ module Browser; module HTTP
2
+
3
+ # Represents a binary result from a HTTP response.
4
+ class Binary
5
+ # @!attribute [r] type
6
+ # @return [:string, :buffer] the type of binary
7
+ attr_reader :type
8
+
9
+ # Create a binary from a value.
10
+ #
11
+ # @param value [String, Buffer] the binary
12
+ def initialize(value)
13
+ if String === value
14
+ @type = :string
15
+ @data = value
16
+ else
17
+ @type = :buffer
18
+ @data = value.to_a
19
+ end
20
+ end
21
+
22
+ include Enumerable
23
+
24
+ # Iterate over each byte in the binary.
25
+ #
26
+ # @yield [byte] the byte
27
+ #
28
+ # @return [self]
29
+ def each(&block)
30
+ return enum_for :each unless block
31
+
32
+ index = 0
33
+ length = self.length
34
+
35
+ while index < length
36
+ block.call(self[index])
37
+
38
+ index += 1
39
+ end
40
+
41
+ self
42
+ end
43
+
44
+ # Access a byte from the binary.
45
+ #
46
+ # @return [Integer] a byte
47
+ def [](index)
48
+ @type == :string ? `#@data.charCodeAt(index) & 0xff` : @data[index]
49
+ end
50
+
51
+ # @!attribute [r] length
52
+ # @return [Integer] the length of the binary
53
+ def length
54
+ @data.length
55
+ end
56
+ end
57
+
58
+ end; end
@@ -0,0 +1,109 @@
1
+ module Browser; module HTTP
2
+
3
+ # Represents a single HTTP header.
4
+ Header = Struct.new(:name, :value)
5
+
6
+ # Represents HTTP headers.
7
+ class Headers
8
+ # Parse HTTP headers from a string.
9
+ #
10
+ # @param string [String] the whole HTTP headers response
11
+ # @return [Headers] the parsed headers
12
+ def self.parse(string)
13
+ self[string.lines.map { |l| l.chomp.split(/\s*:\s*/) }]
14
+ end
15
+
16
+ # Create {Headers} from a hash.
17
+ #
18
+ # @param hash [Hash]
19
+ def self.[](hash)
20
+ result = new
21
+
22
+ hash.each {|name, value|
23
+ result[name] = value
24
+ }
25
+
26
+ result
27
+ end
28
+
29
+ include Enumerable
30
+
31
+ # Create an empty {Headers}.
32
+ def initialize
33
+ @hash = Hash.new
34
+ end
35
+
36
+ # Clear the {Headers}.
37
+ def clear
38
+ @hash.clear
39
+ end
40
+
41
+ # Enumerate over the headers.
42
+ #
43
+ # @yieldparam name [String] the name of the header
44
+ # @yieldparam value [String] the value of the header
45
+ #
46
+ # @return [self]
47
+ def each(&block)
48
+ return enum_for :each unless block
49
+
50
+ @hash.each {|_, header|
51
+ block.call [header.name, header.value]
52
+ }
53
+
54
+ self
55
+ end
56
+
57
+ # Get the value of a header.
58
+ #
59
+ # @param name [String] the name of the header
60
+ #
61
+ # @return [String] the value of the header
62
+ def [](name)
63
+ @hash[name.downcase]
64
+ end
65
+
66
+ # Set a value for the header.
67
+ #
68
+ # @param name [String] the name of the header
69
+ # @param value [String] the value of the header
70
+ def []=(name, value)
71
+ header = Header.new(name, value)
72
+
73
+ @hash[name.downcase] = header
74
+ end
75
+
76
+ # Push a header.
77
+ #
78
+ # @param header [Header] the header to push
79
+ #
80
+ # @return [self]
81
+ def <<(header)
82
+ @hash[header.name.downcase] = header
83
+
84
+ self
85
+ end
86
+
87
+ alias push <<
88
+
89
+ # Merge in place other headers.
90
+ #
91
+ # @param other [Headers, Hash, #each] the headers to merge
92
+ #
93
+ # @return [self]
94
+ def merge!(other)
95
+ other.each {|name, value|
96
+ self[name] = value
97
+ }
98
+
99
+ self
100
+ end
101
+
102
+ # @!attribute [r] length
103
+ # @return [Integer] the number of headers
104
+ def length
105
+ @hash.length
106
+ end
107
+ end
108
+
109
+ end; end
@@ -0,0 +1,344 @@
1
+ module Browser; module HTTP
2
+
3
+ class Request
4
+ include Native
5
+ include Event::Target
6
+
7
+ # Default headers.
8
+ HEADERS = {
9
+ 'X-Requested-With' => 'XMLHttpRequest',
10
+ 'X-Opal-Version' => RUBY_ENGINE_VERSION,
11
+ 'Accept' => 'text/javascript, text/html, application/xml, text/xml, */*'
12
+ }
13
+
14
+ STATES = %w[uninitialized loading loaded interactive complete]
15
+
16
+ # @!attribute [r] headers
17
+ # @return [Headers] the request headers
18
+ attr_reader :headers
19
+
20
+ # @!attribute [r] response
21
+ # @return [Response] the response associated with this request
22
+ attr_reader :response
23
+
24
+ # @!attribute [r] method
25
+ # @return [Symbol] the HTTP method for this request
26
+ attr_reader :method
27
+
28
+ # @!attribute [r] url
29
+ # @return [String, #to_s] the URL for this request
30
+ attr_reader :url
31
+
32
+ # Create a request with the optionally given configuration block.
33
+ #
34
+ # @yield [request] if the block has a parameter the request is passed
35
+ # otherwise it's instance_exec'd
36
+ def initialize(&block)
37
+ super(transport)
38
+
39
+ @parameters = {}
40
+ @query = {}
41
+ @headers = Headers[HEADERS]
42
+ @method = :get
43
+ @asynchronous = true
44
+ @binary = false
45
+ @cacheable = true
46
+ @opened = false
47
+ @sent = false
48
+ @completed = false
49
+ @callbacks = Hash.new { |h, k| h[k] = [] }
50
+
51
+ if block.arity == 0
52
+ instance_exec(&block)
53
+ else
54
+ block.call(self)
55
+ end if block
56
+ end
57
+
58
+ # @!method transport
59
+ # @private
60
+ if Browser.supports? :XHR
61
+ def transport
62
+ `new XMLHttpRequest()`
63
+ end
64
+ elsif Browser.supports? :ActiveX
65
+ def transport
66
+ `new ActiveXObject("MSXML2.XMLHTTP.3.0")`
67
+ end
68
+ else
69
+ def transport
70
+ raise NotImplementedError
71
+ end
72
+ end
73
+
74
+ # Check if the request has been opened.
75
+ def opened?
76
+ @opened
77
+ end
78
+
79
+ # Check if the request has been sent.
80
+ def sent?
81
+ @sent
82
+ end
83
+
84
+ # Check if the request has completed.
85
+ def completed?
86
+ @completed
87
+ end
88
+
89
+ # Check the request is asynchronous.
90
+ def asynchronous?
91
+ @asynchronous
92
+ end
93
+
94
+ # Check the request is synchronous.
95
+ def synchronous?
96
+ !@asynchronous
97
+ end
98
+
99
+ # Make the request asynchronous.
100
+ def asynchronous!
101
+ @asynchronous = true
102
+ end
103
+
104
+ # Make the request synchronous.
105
+ def synchronous!
106
+ @asynchronous = false
107
+ end
108
+
109
+ # Check the request is binary.
110
+ def binary?
111
+ @binary
112
+ end
113
+
114
+ # Make the request binary.
115
+ def binary!
116
+ @binary = true
117
+ end
118
+
119
+ # Check if the request is cacheable.
120
+ def cacheable?
121
+ @cacheable
122
+ end
123
+
124
+ # Disable caching for this request.
125
+ def no_cache!
126
+ @cacheable = false
127
+ end
128
+
129
+ # Get or set the user used for authentication.
130
+ #
131
+ # @param value [String] when passed it sets, when omitted it gets
132
+ #
133
+ # @return [String]
134
+ def user(value = nil)
135
+ value ? @user = value : @user
136
+ end
137
+
138
+ # Get or set the password used for authentication.
139
+ #
140
+ # @param value [String] when passed it sets, when omitted it gets
141
+ #
142
+ # @return [String]
143
+ def password(value = nil)
144
+ value ? @password = value : @password
145
+ end
146
+
147
+ # Get or set the MIME type of the request.
148
+ #
149
+ # @param value [String] when passed it sets, when omitted it gets
150
+ #
151
+ # @return [String]
152
+ def mime_type(value = nil)
153
+ value ? @mime_type = value : @mime_type
154
+ end
155
+
156
+ # Get or set the Content-Type of the request.
157
+ #
158
+ # @param value [String] when passed it sets, when omitted it gets
159
+ #
160
+ # @return [String]
161
+ def content_type(value = nil)
162
+ value ? @content_type = value : @content_type
163
+ end
164
+
165
+ # Get or set the encoding of the request.
166
+ #
167
+ # @param value [String] when passed it sets, when omitted it gets
168
+ #
169
+ # @return [String]
170
+ def encoding(value = nil)
171
+ value ? @encoding = value : @encoding
172
+ end
173
+
174
+ # Set the request parameters.
175
+ #
176
+ # @param hash [Hash] the parameters
177
+ #
178
+ # @return [Hash]
179
+ def parameters(hash = nil)
180
+ hash ? @parameters = hash : @parameters
181
+ end
182
+
183
+ # Set the URI query.
184
+ #
185
+ # @param hash [Hash] the query
186
+ #
187
+ # @return [Hash]
188
+ def query(hash = nil)
189
+ hash ? @query = hash : @query
190
+ end
191
+
192
+ # Register an event on the request.
193
+ #
194
+ # @param what [Symbol, String] the event name
195
+ #
196
+ # @yieldparam response [Response] the response for the event
197
+ def on(what, *, &block)
198
+ if STATES.include?(what) || %w[success failure].include?(what) || Integer === what
199
+ @callbacks[what] << block
200
+ else
201
+ super
202
+ end
203
+ end
204
+
205
+ # Open the request.
206
+ #
207
+ # @param method [Symbol] the HTTP method to use
208
+ # @param url [String, #to_s] the URL to send the request to
209
+ # @param asynchronous [Boolean] whether the request is asynchronous or not
210
+ # @param user [String] the user to use for authentication
211
+ # @param password [String] the password to use for authentication
212
+ #
213
+ # @return [self]
214
+ def open(method = nil, url = nil, asynchronous = nil, user = nil, password = nil)
215
+ raise 'the request has already been opened' if opened?
216
+
217
+ @method = method unless method.nil?
218
+ @url = url unless url.nil?
219
+ @asynchronous = asynchronous unless asynchronous.nil?
220
+ @user = user unless user.nil?
221
+ @password = password unless password.nil?
222
+
223
+ url = @url
224
+
225
+ # add a dummy random parameter to the query to try circumvent caching
226
+ unless cacheable?
227
+ @query[:_] = rand
228
+ end
229
+
230
+ # add the encoded query to the @url, prepending the right character if
231
+ # there was already a query in the defined @url or not
232
+ unless @query.empty?
233
+ if url.include? ??
234
+ url += ?&
235
+ else
236
+ url += ??
237
+ end
238
+
239
+ url += @query.encode_uri
240
+ end
241
+
242
+ `#@native.open(#{@method.to_s.upcase}, #{url.to_s}, #{@asynchronous}, #{@user.to_n}, #{@password.to_n})`
243
+
244
+ # if there are no registered callbacks no point in setting the event
245
+ # handler
246
+ unless @callbacks.empty?
247
+ `#@native.onreadystatechange = #{callback}`
248
+ end
249
+
250
+ @opened = true
251
+
252
+ self
253
+ end
254
+
255
+ # Send the request with optional parameters.
256
+ #
257
+ # @param parameters [String, Hash] the data to send
258
+ #
259
+ # @return [Response] the response
260
+ def send(parameters = @parameters)
261
+ raise 'the request has not been opened' unless opened?
262
+
263
+ raise 'the request has already been sent' if sent?
264
+
265
+ # try to circumvent caching setting an If-Modified-Since header with a very
266
+ # old date
267
+ unless cacheable?
268
+ `#@native.setRequestHeader("If-Modified-Since", "Tue, 11 Sep 2001 12:46:00 GMT")`
269
+ end
270
+
271
+ @headers.each {|name, value|
272
+ `#@native.setRequestHeader(#{name.to_s}, #{value.to_s})`
273
+ }
274
+
275
+ if @content_type
276
+ header = @content_type
277
+ header += "; charset=#{@encoding}" if @encoding
278
+
279
+ `#@native.setRequestHeader('Content-Type', header)`
280
+ end
281
+
282
+ if binary?
283
+ if Buffer.supported?
284
+ `#@native.responseType = 'arraybuffer'`
285
+ else
286
+ `#@native.overrideMimeType('text/plain; charset=x-user-defined')`
287
+ end
288
+ end
289
+
290
+ if mime_type && !binary?
291
+ `#@native.overrideMimeType(#@mime_type)`
292
+ end
293
+
294
+ @sent = true
295
+ @response = Response.new(self)
296
+
297
+ if String === parameters
298
+ data = parameters
299
+ elsif Hash === parameters && !parameters.empty?
300
+ data = parameters.map {|vals|
301
+ vals.map(&:encode_uri_component).join(?=)
302
+ }.join(?&)
303
+
304
+ unless @content_type
305
+ `#@native.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')`
306
+ end
307
+ else
308
+ data = `null`
309
+ end
310
+
311
+ `#@native.send(#{data})`
312
+
313
+ @response
314
+ end
315
+
316
+ # Abort the request.
317
+ def abort
318
+ `#@native.abort()`
319
+ end
320
+
321
+ private
322
+ def callback
323
+ -> event {
324
+ state = STATES[`#@native.readyState`]
325
+ res = response
326
+
327
+ @callbacks[state].each { |b| b.(res) }
328
+
329
+ if state == :complete
330
+ @completed = true
331
+
332
+ @callbacks[res.status.code].each { |b| b.(res) }
333
+
334
+ if res.success?
335
+ @callbacks[:success].each { |b| b.(res) }
336
+ else
337
+ @callbacks[:failure].each { |b| b.(res) }
338
+ end
339
+ end
340
+ }
341
+ end
342
+ end
343
+
344
+ end; end