red 4.1.0 → 4.1.1

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.
@@ -0,0 +1,312 @@
1
+ `function $v(event){
2
+ var doc=$u,result=$u,type=$u,target=$u,code=$u,key=$u,f_key=$u,wheel=$u,right_click=$u,page=$u,client=$u,related_target=$u;
3
+ event = event || window.event;
4
+ doc = document;
5
+ if(!event){return nil;};
6
+ result=c$Event.m$new(null);
7
+ type = event.type;
8
+ target = event.target || event.srcElement;
9
+ while(target&&target.nodeType==3){target=event.parentNode;};
10
+ if(/key/.test(type)){
11
+ code=event.which || event.keyCode;
12
+ key=c$Event.c$KEYS.m$_brac(code);
13
+ if(type=='keydown'){f_key=code-111;if(f_key>0&&f_key<13){key=$s('f'+f_key);};};
14
+ key=$T(key)?key:$s(String.fromCharCode(code).toLowerCase());
15
+ }else{
16
+ if(type.match(/(click|mouse|menu)/i)){
17
+ doc=(!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
18
+ wheel=(type.match(/DOMMouseScroll|mousewheel/) ? (event.wheelDelta ? event.wheelDelta/40 : -(event.detail||0)) : nil);
19
+ right_click=event.which==3||event.button==2;
20
+ page={x:(event.pageX || event.clientX + doc.scrollLeft),y:(event.pageY || event.clientY + doc.scrollTop)};
21
+ client={x:(event.pageX ? event.pageX - window.pageXOffset : event.clientX),y:(event.pageY ? event.pageY - window.pageYOffset : event.clientY)};
22
+ if(type.match(/over|out/)){
23
+ switch(type){
24
+ case 'mouseover':related_target=event.relatedTarget || event.fromElement;break;
25
+ case 'mouseout':related_target=event.relatedTarget || event.toElement;break;
26
+ };
27
+ if(window.m$gecko_bool()){
28
+ try{while(related_target&&related_target.nodeType==3){related_target=related_target.parentNode;};}catch(e){related_target=false;};
29
+ }else{while(related_target&&related_target.nodeType==3){related_target.parentNode;};};
30
+ };
31
+ };
32
+ };
33
+ result.__native__=event;result.__code__=code;result.__key__=key;result.__type__=type;result.__target__=target;result.__wheel__=wheel;result.__right_click__=right_click;result.__related_target__=related_target;
34
+ result.__page__=page||{x:nil,y:nil};result.__client__=client||{x:nil,y:nil};
35
+ result.__shift__=event.shiftKey;result.__ctrl__=event.ctrlKey;result.__alt__=event.altKey;result.__meta__=event.metaKey;
36
+ return result;
37
+ }`
38
+
39
+ # +Event+ objects represent user interactions with the browser. Attempting to
40
+ # create an +Event+ object by calling <tt>Event.new</tt> results in
41
+ # +NewEventError+.
42
+ #
43
+ # +Event+ objects are handled by the methods in the +UserEvents+ module.
44
+ #
45
+ class Event
46
+ KEYS = {
47
+ 8 => :backspace,
48
+ 9 => :tab,
49
+ 13 => :enter,
50
+ 27 => :esc,
51
+ 32 => :space,
52
+ 37 => :left,
53
+ 38 => :up,
54
+ 39 => :right,
55
+ 40 => :down,
56
+ 46 => :delete
57
+ }
58
+
59
+ # Exception raised by calling <tt>Event.new</tt>.
60
+ #
61
+ class NewEventError < Exception
62
+ end
63
+
64
+ def initialize(raise_error) # :nodoc:
65
+ raise(NewEventError, 'Events can only be initialized by user interactions with the browser') unless `raise_error === null`
66
+ end
67
+
68
+ # call-seq:
69
+ # evnt.alt? -> true or false
70
+ #
71
+ # Returns +true+ if the alt key was depressed during the event, +false+
72
+ # otherwise.
73
+ #
74
+ # Document['#example'].listen(:click) {|element, event| puts "alt-clicked" if event.alt? }
75
+ #
76
+ # alt-clicking element '#example' produces:
77
+ #
78
+ # alt-clicked
79
+ #
80
+ def alt?
81
+ `this.__alt__`
82
+ end
83
+
84
+ # call-seq:
85
+ # evnt.base_type -> symbol
86
+ #
87
+ # Returns a symbol representing _evnt_'s event type, or +:base+ type if
88
+ # _evnt_ is a defined event.
89
+ #
90
+ # UserEvents.define(:shift_click, :base => 'click', :condition => proc {|element,event| event.shift? })
91
+ # Document['#example'].listen(:click) {|element, event| puts event.base_type }
92
+ # Document['#example'].listen(:shift_click) {|element, event| puts event.base_type }
93
+ #
94
+ # clicking or shift-clicking on element '#example' produces:
95
+ #
96
+ # click
97
+ #
98
+ def base_type
99
+ `$s(this.__type__)`
100
+ end
101
+
102
+ # call-seq:
103
+ # evnt.client -> {:x => integer, :y => integer}
104
+ #
105
+ # Returns a hash representing _evnt_'s distance in pixels from the left
106
+ # (_x_) and top (_y_) edges of the browser viewport.
107
+ #
108
+ # Document['#example'].listen(:click) {|element,event| puts event.client.inspect }
109
+ #
110
+ # clicking element '#example' at position (35,45) produces:
111
+ #
112
+ # {:x => 35, :y => 45}
113
+ #
114
+ def client
115
+ {:x => `this.__client__.x`, :y => `this.__client__.y`}
116
+ end
117
+
118
+ # call-seq:
119
+ # evnt.code -> integer or nil
120
+ #
121
+ # If _evnt_ involved a keystroke, returns the ASCII code of the key pressed,
122
+ # otherwise returns +nil+.
123
+ #
124
+ # Document['#example'].listen(:keypress) {|element, event| puts event.code }
125
+ #
126
+ # typing "test\n" into textarea '#example produces:
127
+ #
128
+ # 116
129
+ # 101
130
+ # 115
131
+ # 116
132
+ # 13
133
+ #
134
+ def code
135
+ `this.__code__ || nil`
136
+ end
137
+
138
+ # call-seq:
139
+ # evnt.ctrl? -> true or false
140
+ #
141
+ # Returns +true+ if the control key was depressed during the event, +false+
142
+ # otherwise.
143
+ #
144
+ # Document['#example'].listen(:click) {|element, event| puts "ctrl-clicked" if event.ctrl? }
145
+ #
146
+ # ctrl-clicking element '#example' produces:
147
+ #
148
+ # ctrl-clicked
149
+ #
150
+ def ctrl?
151
+ `this.__ctrl__`
152
+ end
153
+
154
+ # call-seq:
155
+ # evnt.key -> symbol or nil
156
+ #
157
+ # If _evnt_ involved a keystroke, returns a symbol representing the key
158
+ # pressed, otherwise returns +nil+.
159
+ #
160
+ # Document['#example'].listen(:keypress) {|element, event| puts event.key.inspect }
161
+ #
162
+ # typing "test\n" into textarea '#example produces:
163
+ #
164
+ # :t
165
+ # :e
166
+ # :s
167
+ # :t
168
+ # :enter
169
+ #
170
+ def key
171
+ `this.__key__ || nil`
172
+ end
173
+
174
+ # call-seq:
175
+ # evnt.kill! -> evnt
176
+ #
177
+ # Stops the event in place, preventing the default action as well as any
178
+ # further propagation, then returns _evnt_.
179
+ #
180
+ def kill!
181
+ self.stop_propagation.prevent_default
182
+ end
183
+
184
+ # call-seq:
185
+ # evnt.meta? -> true or false
186
+ #
187
+ # Returns +true+ if the meta key was depressed during the event, +false+
188
+ # otherwise.
189
+ #
190
+ # Document['#example'].listen(:click) {|element, event| puts "meta-clicked" if event.meta? }
191
+ #
192
+ # meta-clicking element '#example' produces:
193
+ #
194
+ # meta-clicked
195
+ #
196
+ def meta?
197
+ `this.__meta__`
198
+ end
199
+
200
+ # call-seq:
201
+ # evnt.page -> {:x => numeric, :y => numeric}
202
+ #
203
+ # Returns a hash representing _evnt_'s distance in pixels from the left
204
+ # (_x_) and top (_y_) edges of the current page, including pixels that may
205
+ # have scrolled out of view.
206
+ #
207
+ # Document['#example'].listen(:click) {|element,event| puts event.page.inspect }
208
+ #
209
+ # clicking element '#example' at position (35,45) after scrolling down 100
210
+ # pixels produces:
211
+ #
212
+ # {:x => 35, :y => 145}
213
+ #
214
+ def page
215
+ {:x => `this.__page__.x`, :y => `this.__page__.y`}
216
+ end
217
+
218
+ # call-seq:
219
+ # evnt.prevent_default -> evnt
220
+ #
221
+ # Instructs the event to abandon its default browser action, then returns
222
+ # _evnt_.
223
+ #
224
+ def prevent_default
225
+ native = `this.__native__`
226
+ `native.preventDefault?native.preventDefault():native.returnValue=false`
227
+ return self
228
+ end
229
+
230
+ # call-seq:
231
+ # evnt.right_click? -> true or false
232
+ #
233
+ # Returns +true+ if the event was a right click.
234
+ #
235
+ # elem = Document['#example'].listen(:click) {|element, event| puts "right-clicked" if event.right_click? }
236
+ #
237
+ # right-clicking element '#example' produces:
238
+ #
239
+ # right-clicked
240
+ #
241
+ def right_click?
242
+ `this.__right_click__`
243
+ end
244
+
245
+ # call-seq:
246
+ # evnt.shift? -> true or false
247
+ #
248
+ # Returns +true+ if the shift key was depressed during the event, +false+
249
+ # otherwise.
250
+ #
251
+ # Document['#example'].listen(:click) {|element, event| puts "shift-clicked" if event.shift? }
252
+ #
253
+ # shift-clicking element '#example' produces:
254
+ #
255
+ # shift-clicked
256
+ #
257
+ def shift?
258
+ `this.__shift__`
259
+ end
260
+
261
+ # call-seq:
262
+ # evnt.stop_propagation -> evnt
263
+ #
264
+ # Instructs the event to stop propagating, then returns _evnt_.
265
+ #
266
+ def stop_propagation
267
+ native = `this.__native__`
268
+ `native.stopPropagation?native.stopPropagation():native.cancelBubble=true`
269
+ return self
270
+ end
271
+
272
+ # call-seq:
273
+ # evnt.target -> element
274
+ #
275
+ # Returns the DOM element targeted by _evnt_, or +nil+ if no element was
276
+ # targeted. The target of an event may be a different element than _elem_.
277
+ #
278
+ # elem = Document['#outer']
279
+ #
280
+ # elem.listen :click do |element, event|
281
+ # puts "%s was clicked" % event.target.inspect
282
+ # puts "%s was indirectly clicked" % element.inspect
283
+ # end
284
+ #
285
+ # clicking element '#inner' inside '#outer' produces:
286
+ #
287
+ # #<Element: DIV id="inner"> was clicked
288
+ # #<Element: DIV id="outer"> was indirectly clicked
289
+ #
290
+ def target
291
+ `$E(this.__target__)`
292
+ end
293
+
294
+ # call-seq:
295
+ # evnt.wheel -> numeric or nil
296
+ #
297
+ # Returns a floating point number representing the velocity of the wheel
298
+ # movement executed during _evnt_. Positive values indicate upward
299
+ # scrolling, negative values indicate downward scrolling. Returns +nil+ if
300
+ # _evnt_ did not involve the mouse wheel.
301
+ #
302
+ # Document['#example'].listen(:mouse_wheel) {|element, event| puts event.wheel }
303
+ #
304
+ # wheeling the mousewheel downward by a single "click" over element
305
+ # '#example' produces:
306
+ #
307
+ # -1
308
+ #
309
+ def wheel
310
+ `this.__wheel__`
311
+ end
312
+ end
@@ -0,0 +1,5 @@
1
+ require 'chainable'
2
+ require 'cookie'
3
+ require 'request'
4
+ require 'situated'
5
+ require 'tween'
@@ -0,0 +1,276 @@
1
+ require 'chainable'
2
+ require 'code_events'
3
+
4
+ class Request
5
+ include CodeEvents
6
+ include Chainable
7
+
8
+ METHODS = %w(GET POST PUT DELETE)
9
+ OPTIONS = {
10
+ :url => '',
11
+ :data => {},
12
+ :link => 'ignore',
13
+ :async => true,
14
+ :format => nil,
15
+ :method => 'post',
16
+ :encoding => 'utf-8',
17
+ :is_success => nil,
18
+ :emulation => true,
19
+ :url_encoded => true,
20
+ :eval_scripts => false,
21
+ :eval_response => false,
22
+ :headers => {
23
+ 'X-Requested-With' => 'XMLHttpRequest',
24
+ 'Accept' => 'text/javascript, text/html, application/xml, text/xml, */*'
25
+ }
26
+ }
27
+
28
+ # call-seq:
29
+ # Request.new(options = {}) -> request
30
+ #
31
+ # Returns a new _request_ with the given options.
32
+ #
33
+ def initialize(options = {})
34
+ `this.__xhr__ = typeof(ActiveXObject)=='undefined' ? new XMLHttpRequest : new ActiveXObject('MSXML2.XMLHTTP')`
35
+ @options = OPTIONS.merge(options)
36
+ `#{@options[:headers]}.__xhr__=this.__xhr__` # MooTools sets the ResponseHeaders in the xhr
37
+ #def (@options[:headers]).[](name) # only during execution, but allows you to get
38
+ # `this.__xhr__.getResponseHeader(name)` # at them at any time. I'm not sure whether it
39
+ #end # is necessary for us to emulate this exactly.
40
+ end
41
+
42
+ # call-seq:
43
+ # req.cancel -> req
44
+ #
45
+ # Cancels the request, fires its "cancel" callback, and returns _req_.
46
+ #
47
+ def cancel
48
+ return self unless @running
49
+ @running = false
50
+ `this.__xhr__.abort`
51
+ `this.__xhr__.onreadystatechange=function(){;}`
52
+ `this.__xhr__=typeof(ActiveXObject)=='undefined' ? new XMLHttpRequest : new ActiveXObject('MSXML2.XMLHTTP')`
53
+ self.fire(:cancel)
54
+ return self
55
+ end
56
+
57
+ # call-seq:
58
+ # req.check(arg, ...) { |request,args_array| block } -> true or false
59
+ #
60
+ # returns +true+ when Request object is not running or gets cancelled, otherwise returns false.
61
+ # also, seems equipped to 'chain' some additional function after itself
62
+ #
63
+ def check(*args, &block)
64
+ return true unless @running
65
+ case @options[:link]
66
+ when 'cancel'
67
+ self.cancel
68
+ return true
69
+ when 'chain'
70
+ # self.chain(&block(self,args))
71
+ return false
72
+ end
73
+ return false
74
+ end
75
+
76
+ # call-seq:
77
+ # req.execute(options = {}) -> req
78
+ #
79
+ # Returns +req+ immediately if the request is already running. Otherwise,
80
+ # opens a connection and sends the data provided with the specified options.
81
+ #
82
+ def execute(options = {})
83
+ # return self unless self.check(options)
84
+ @options.update(options)
85
+ raise(TypeError, 'can\'t convert %s to a String' % @options[:url].inspect) unless [String].include?(@options[:url].class)
86
+ raise(TypeError, 'can\'t convert %s to a String' % @options[:method].inspect) unless [String, Symbol].include?(@options[:method].class)
87
+ raise(TypeError, 'can\'t convert %s to a Hash' % @options[:data].inspect) unless [Hash].include?(@options[:data].class)
88
+ raise(HttpMethodError, 'invalid HTTP method "%s" for %s' % [@options[:method],self]) unless METHODS.include?(method = @options[:method].to_s.upcase)
89
+
90
+ @running = true
91
+ data = @options[:data].to_query_string
92
+ url = @options[:url]
93
+
94
+ if @options[:format]
95
+ format = "format=%s" % @options[:format]
96
+ data = data.empty? ? format : [format, data].join('&')
97
+ end
98
+
99
+ if @options[:emulation] && %w(PUT DELETE).include?(method)
100
+ _method = "_method=%s" % method
101
+ data = data.empty? ? _method : [_method, data].join('&')
102
+ method = 'POST'
103
+ end
104
+
105
+ if @options[:url_encoded] && method == 'POST'
106
+ encoding = @options[:encoding] ? "; charset=%s" % @options[:encoding] : ""
107
+ self.headers['Content-type'] = "application/x-www-form-urlencoded" + encoding
108
+ end
109
+
110
+ if data && method == 'GET'
111
+ separator = url.include?('?') ? "&" : "?"
112
+ url = [url, data].join(separator)
113
+ data = nil
114
+ end
115
+
116
+ `this.__xhr__.open(method.__value__, url.__value__, #{@options[:async]})`
117
+ `this.__xhr__.onreadystatechange = #{self.on_state_change}.__block__`
118
+
119
+ @options[:headers].each do |k,v|
120
+ `this.__xhr__.setRequestHeader(k.__value__,v.__value__)`
121
+ # raise(HeaderError, "#{k} => #{v}")
122
+ end
123
+
124
+ self.fire(:request)
125
+ `this.__xhr__.send($T(data)?data.__value__:'')`
126
+ self.on_state_change.call unless @options[:async]
127
+ return self
128
+ end
129
+
130
+ # call-seq:
131
+ # req.failure! -> req
132
+ #
133
+ # Fires _req_'s "response" and "failure" callbacks, then returns _req_.
134
+ #
135
+ def failure!
136
+ self.fire(:response).fire(:failure, @xhr);
137
+ end
138
+
139
+ # call-seq:
140
+ # req.headers -> hash
141
+ #
142
+ # Returns _req_'s HTTP headers as a +Hash+.
143
+ #
144
+ def headers
145
+ @options[:headers]
146
+ end
147
+
148
+ # call-seq:
149
+ # req.on_state_change -> proc
150
+ #
151
+ # Returns a +Proc+ object
152
+ #
153
+ def on_state_change
154
+ Proc.new do
155
+ `var xhr=this.__xhr__`
156
+ `if(xhr.readyState!=4||!#{@running}){return nil;}`
157
+
158
+ @running = false
159
+ @status = 0
160
+
161
+ `try{#{@status}=xhr.status}catch(e){;}`
162
+
163
+ if self.success?
164
+ @response = {:text => `$q(xhr.responseText)`, :xml => `xhr.responseXML`}
165
+ self.success!(self.process_scripts(@response[:text]), @response[:xml])
166
+ else
167
+ @response = {:text => nil, :xml => nil};
168
+ self.failure!
169
+ end
170
+
171
+ `xhr.onreadystatechange=function(){;}`
172
+
173
+ return nil
174
+ end
175
+ end
176
+
177
+ # call-seq:
178
+ # req.process_scripts(str) -> string or object
179
+ #
180
+ # If the HTTP response consists of JavaScript alone or if _req_'s
181
+ # <tt>eval_response</tt> option is set to +true+, evaluates the entire
182
+ # text of the response as JavaScript and returns the result.
183
+ #
184
+ # Otherwise, returns a copy of _str_ with any <tt><script></tt> tags and
185
+ # their content removed. If _req_'s <tt>eval_scripts</tt> option is set to
186
+ # +true+, evaluates the removed scripts.
187
+ #
188
+ def process_scripts(str)
189
+ return Document.execute_js(str) if @options[:eval_response] || `/(ecma|java)script/.test(this.__xhr__.getResponseHeader('Content-Type'))`
190
+ return str.strip_scripts(@options[:eval_scripts])
191
+ end
192
+
193
+ # call-seq:
194
+ # req.success!(text, xml) -> req
195
+ #
196
+ # Fires _req_'s "response" and "success" callbacks, then returns _req_.
197
+ #
198
+ def success!(text, xml)
199
+ self.fire(:response, [text, xml]).fire(:success, [text, xml]).call_chain
200
+ end
201
+
202
+ # call-seq:
203
+ # req.success? -> true or false
204
+ #
205
+ # Returns +true+ if _req_'s status is in the 200s, +false+ otherwise.
206
+ #
207
+ def success?
208
+ `#{@status}>=200&&#{@status}<300`
209
+ end
210
+
211
+ # +HeaderError+ is raised when a +Request+ is executed with headers that are
212
+ # rejected by the XMLHTTPRequest object.
213
+ #
214
+ class HeaderError < StandardError
215
+ end
216
+
217
+ # +HttpMethodError+ is raised when a +Request+ object's HTTP method is not
218
+ # one of +GET+, +POST+, +PUT+, or +DELETE+.
219
+ #
220
+ class HttpMethodError < StandardError
221
+ end
222
+
223
+ class ::String
224
+ # call-seq:
225
+ # str.strip_scripts(evaluate = false) -> string
226
+ #
227
+ # Returns a copy of _str_ with the contents of any <tt><script></tt> tags
228
+ # removed. If _evaluate_ is set to true, the stripped scripts will be
229
+ # evaluated.
230
+ #
231
+ def strip_scripts(evaluate = false)
232
+ scripts = ''
233
+ result = `this.__value__.replace(/<script[^>]*>([\\s\\S]*?)<\\/script>/gi,function(){scripts.__value__+=arguments[1]+'\\n';return '';})`
234
+ Document.execute_js(scripts) if evaluate
235
+ return result
236
+ end
237
+ end
238
+
239
+ class ::Hash
240
+ # call-seq:
241
+ # hsh.to_query_string -> string
242
+ #
243
+ # Returns a string representing _hsh_ formatted as HTTP data.
244
+ #
245
+ def to_query_string(base = '')
246
+ query_string = []
247
+ self.each do |k,v|
248
+ next if v.nil?
249
+ k = base.empty? ? k.to_s : "%s[%s]" % [base,k]
250
+ case v
251
+ when Hash
252
+ result = v.to_query_string(k)
253
+ when Array
254
+ qs = {}
255
+ `for(var i=0,l=v.length;i<l;i++){#{qs[i] = v[i]}}`
256
+ #v.each_with_index do |v,i|
257
+ # qs[i] = v
258
+ #end
259
+ result = qs.to_query_string(k)
260
+ else
261
+ result = "%s=%s" % [k, `$q(encodeURIComponent(v))`]
262
+ end
263
+ query_string.push(result)
264
+ end
265
+ return query_string.join('&')
266
+ end
267
+ end
268
+
269
+ class HTML
270
+
271
+ end
272
+
273
+ class JSON
274
+
275
+ end
276
+ end