red 4.1.0 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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