Class: Request
- Includes:
- Chainable, CodeEvents
- Defined in:
- lib/source/redshift/request.rb
Defined Under Namespace
Classes: HTML, HeaderError, HttpMethodError, JSON, Response
Constant Summary collapse
- METHODS =
%w(GET POST PUT DELETE)
- OPTIONS =
{ :url => '', :data => {}, :link => 'ignore', :async => true, :format => nil, :method => 'post', :encoding => 'utf-8', :is_success => nil, :emulation => true, :url_encoded => true, :eval_scripts => false, :eval_response => false, :headers => { 'X-Requested-With' => 'XMLHttpRequest', 'Accept' => 'text/javascript, text/html, application/xml, text/xml, */*' } }
Instance Method Summary collapse
-
#cancel ⇒ Object
call-seq: req.cancel -> req.
-
#check(*args, &block) ⇒ Object
call-seq: req.check(arg, …) { |request,args_array| block } -> true or false.
-
#execute(options = {}) ⇒ Object
call-seq: req.execute(options = {}) -> req.
-
#headers ⇒ Object
call-seq: req.headers -> hash.
-
#initialize(options = {}) ⇒ Request
constructor
call-seq: Request.new(options = {}) -> request.
-
#on_state_change ⇒ Object
call-seq: req.on_state_change -> proc.
-
#process_scripts(str) ⇒ Object
call-seq: req.process_scripts(str) -> string or object.
-
#success? ⇒ Boolean
call-seq: req.success? -> true or false.
Methods included from Chainable
#call_chain, #chain, #clear_chain
Methods included from CodeEvents
Constructor Details
#initialize(options = {}) ⇒ Request
call-seq:
Request.new(options = {}) -> request
Returns a new request with the given options.
42 43 44 45 46 47 48 49 |
# File 'lib/source/redshift/request.rb', line 42 def initialize( = {}) `this.__xhr__ = typeof(ActiveXObject)=='undefined' ? new XMLHttpRequest : new ActiveXObject('MSXML2.XMLHTTP')` @options = OPTIONS.merge() `#{@options[:headers]}.__xhr__=this.__xhr__` # MooTools sets the ResponseHeaders in the xhr # def (@options[:headers]).[](name) # only during execution, but allows you to get # `this.__xhr__.getResponseHeader(name)` # at them at any time. I'm not sure whether it # end # is necessary for us to emulate this exactly. end |
Instance Method Details
#cancel ⇒ Object
call-seq:
req.cancel -> req
Cancels the request, fires its “cancel” callback, and returns req.
56 57 58 59 60 61 62 63 64 |
# File 'lib/source/redshift/request.rb', line 56 def cancel return self unless @running @running = false `this.__xhr__.abort` `this.__xhr__.onreadystatechange=function(){;}` `this.__xhr__=typeof(ActiveXObject)=='undefined' ? new XMLHttpRequest : new ActiveXObject('MSXML2.XMLHTTP')` self.fire(:cancel) return self end |
#check(*args, &block) ⇒ Object
call-seq:
req.check(arg, ...) { |request,args_array| block } -> true or false
returns true
when Request object is not running or gets cancelled, otherwise returns false. also, seems equipped to ‘chain’ some additional function after itself
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/source/redshift/request.rb', line 72 def check(*args, &block) return true unless @running case @options[:link] when 'cancel' self.cancel return true when 'chain' # self.chain(&block(self,args)) return false end return false end |
#execute(options = {}) ⇒ Object
call-seq:
req.execute(options = {}) -> req
Returns req
immediately if the request is already running. Otherwise, opens a connection and sends the data provided with the specified options.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/source/redshift/request.rb', line 91 def execute( = {}) # return self unless self.check(options) @options.update() raise(TypeError, 'can\'t convert %s to a String' % @options[:url].inspect) unless [String].include?(@options[:url].class) raise(TypeError, 'can\'t convert %s to a String' % @options[:method].inspect) unless [String, Symbol].include?(@options[:method].class) raise(TypeError, 'can\'t convert %s to a Hash' % @options[:data].inspect) unless [Hash].include?(@options[:data].class) raise(HttpMethodError, 'invalid HTTP method "%s" for %s' % [@options[:method],self]) unless METHODS.include?(method = @options[:method].to_s.upcase) @running = true data = @options[:data].to_query_string url = @options[:url] if @options[:format] format = "format=%s" % @options[:format] data = data.empty? ? format : [format, data].join('&') end if @options[:emulation] && %w(PUT DELETE).include?(method) _method = "_method=%s" % method data = data.empty? ? _method : [_method, data].join('&') method = 'POST' end if @options[:url_encoded] && method == 'POST' encoding = @options[:encoding] ? "; charset=%s" % @options[:encoding] : "" self.headers['Content-type'] = "application/x-www-form-urlencoded" + encoding end if data && method == 'GET' separator = url.include?('?') ? "&" : "?" url = [url, data].join(separator) data = nil end `this.__xhr__.open(method.__value__, url.__value__, #{@options[:async]})` `this.__xhr__.onreadystatechange = #{self.on_state_change}.__block__` @options[:headers].each do |k,v| `this.__xhr__.setRequestHeader(k.__value__,v.__value__)` # raise(HeaderError, "#{k} => #{v}") end self.fire(:request) `this.__xhr__.send($T(data)?data.__value__:'')` self.on_state_change.call unless @options[:async] return self end |
#headers ⇒ Object
call-seq:
req.headers -> hash
Returns req’s HTTP headers as a Hash
.
144 145 146 |
# File 'lib/source/redshift/request.rb', line 144 def headers @options[:headers] end |
#on_state_change ⇒ Object
call-seq:
req.on_state_change -> proc
Returns a Proc
object
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/source/redshift/request.rb', line 153 def on_state_change Proc.new do `var xhr=this.__xhr__` `if(xhr.readyState!=4||!#{@running}){return nil;}` @running = false @status = 0 `try{#{@status}=xhr.status}catch(e){;}` if self.success? @response = Response.new(self.process_scripts(`$q(xhr.responseText)`), `xhr.responseXML`) self.fire(:response, 0, @response).fire(:success, 0, @response).call_chain else @response = Response.new(nil,nil) self.fire(:response, 0, @response).fire(:failure, 0, @xhr) end `xhr.onreadystatechange=function(){;}` return nil end end |
#process_scripts(str) ⇒ Object
call-seq:
req.process_scripts(str) -> string or object
If the HTTP response consists of JavaScript alone or if req’s eval_response
option is set to true
, evaluates the entire text of the response as JavaScript and returns the result.
Otherwise, returns a copy of str with any <script>
tags and their content removed. If req’s eval_scripts
option is set to true
, evaluates the removed scripts.
188 189 190 191 |
# File 'lib/source/redshift/request.rb', line 188 def process_scripts(str) return Document.execute_js(str) if @options[:eval_response] || `/(ecma|java)script/.test(this.__xhr__.getResponseHeader('Content-Type'))` return str.strip_scripts(@options[:eval_scripts]) end |
#success? ⇒ Boolean
call-seq:
req.success? -> true or false
Returns true
if req’s status is in the 200s, false
otherwise.
198 199 200 |
# File 'lib/source/redshift/request.rb', line 198 def success? `#{@status}>=200&&#{@status}<300` end |