batman-rails 0.0.4 → 0.0.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.
- data/README.md +1 -1
- data/lib/batman/rails/version.rb +2 -2
- data/vendor/assets/javascripts/batman/batman.coffee +5825 -0
- data/vendor/assets/javascripts/batman/batman.jquery.coffee +71 -0
- data/vendor/assets/javascripts/batman/batman.rails.coffee +134 -0
- data/vendor/assets/javascripts/batman/batman.solo.coffee +496 -0
- metadata +18 -18
- data/vendor/assets/javascripts/batman/batman.jquery.js +0 -75
- data/vendor/assets/javascripts/batman/batman.js +0 -7134
- data/vendor/assets/javascripts/batman/batman.rails.js +0 -83
- data/vendor/assets/javascripts/batman/batman.solo.js +0 -418
@@ -0,0 +1,71 @@
|
|
1
|
+
#
|
2
|
+
# batman.jquery.coffee
|
3
|
+
# batman.js
|
4
|
+
#
|
5
|
+
# Created by Nick Small
|
6
|
+
# Copyright 2011, Shopify
|
7
|
+
#
|
8
|
+
|
9
|
+
# Include this file instead of batman.nodep if your
|
10
|
+
# project already uses jQuery. It will map a few
|
11
|
+
# batman.js methods to existing jQuery methods.
|
12
|
+
|
13
|
+
|
14
|
+
Batman.Request::send = (data) ->
|
15
|
+
options =
|
16
|
+
url: @get 'url'
|
17
|
+
type: @get 'method'
|
18
|
+
dataType: @get 'type'
|
19
|
+
data: data || @get 'data'
|
20
|
+
username: @get 'username'
|
21
|
+
password: @get 'password'
|
22
|
+
headers: @get 'headers'
|
23
|
+
beforeSend: =>
|
24
|
+
@fire 'loading'
|
25
|
+
|
26
|
+
success: (response, textStatus, xhr) =>
|
27
|
+
@set 'status', xhr.status
|
28
|
+
@set 'response', response
|
29
|
+
@fire 'success', response
|
30
|
+
|
31
|
+
error: (xhr, status, error) =>
|
32
|
+
@set 'status', xhr.status
|
33
|
+
@set 'response', xhr.responseText
|
34
|
+
xhr.request = @
|
35
|
+
@fire 'error', xhr
|
36
|
+
|
37
|
+
complete: =>
|
38
|
+
@fire 'loaded'
|
39
|
+
|
40
|
+
if @get('method') in ['PUT', 'POST']
|
41
|
+
|
42
|
+
unless @hasFileUploads()
|
43
|
+
options.contentType = @get 'contentType'
|
44
|
+
else
|
45
|
+
options.contentType = false
|
46
|
+
options.processData = false
|
47
|
+
options.data = @constructor.objectToFormData(options.data)
|
48
|
+
|
49
|
+
jQuery.ajax options
|
50
|
+
|
51
|
+
Batman.mixins.animation =
|
52
|
+
show: (addToParent) ->
|
53
|
+
jq = $(@)
|
54
|
+
show = ->
|
55
|
+
jq.show 600
|
56
|
+
|
57
|
+
if addToParent
|
58
|
+
addToParent.append?.appendChild @
|
59
|
+
addToParent.before?.parentNode.insertBefore @, addToParent.before
|
60
|
+
|
61
|
+
jq.hide()
|
62
|
+
setTimeout show, 0
|
63
|
+
else
|
64
|
+
show()
|
65
|
+
@
|
66
|
+
|
67
|
+
hide: (removeFromParent) ->
|
68
|
+
$(@).hide 600, =>
|
69
|
+
@parentNode?.removeChild @ if removeFromParent
|
70
|
+
Batman.DOM.didRemoveNode(@)
|
71
|
+
@
|
@@ -0,0 +1,134 @@
|
|
1
|
+
applyExtra = (Batman) ->
|
2
|
+
|
3
|
+
# `param` and `buildParams` stolen from jQuery
|
4
|
+
#
|
5
|
+
# jQuery JavaScript Library
|
6
|
+
# http://jquery.com/
|
7
|
+
#
|
8
|
+
# Copyright 2011, John Resig
|
9
|
+
# Dual licensed under the MIT or GPL Version 2 licenses.
|
10
|
+
# http://jquery.org/license
|
11
|
+
# Rails really doesn't like collection[0][rules], it wants collection[][rules],
|
12
|
+
# so we will give it that.
|
13
|
+
rbracket = /\[\]$/
|
14
|
+
r20 = /%20/g
|
15
|
+
param = (a) ->
|
16
|
+
return a if typeof a is 'string'
|
17
|
+
s = []
|
18
|
+
add = (key, value) ->
|
19
|
+
value = value() if typeof value is 'function'
|
20
|
+
value = '' unless value?
|
21
|
+
s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value)
|
22
|
+
|
23
|
+
if Batman.typeOf(a) is 'Array'
|
24
|
+
for value, name of a
|
25
|
+
add name, value
|
26
|
+
else
|
27
|
+
for own k, v of a
|
28
|
+
buildParams k, v, add
|
29
|
+
s.join("&").replace r20, "+"
|
30
|
+
|
31
|
+
buildParams = (prefix, obj, add) ->
|
32
|
+
if Batman.typeOf(obj) is 'Array'
|
33
|
+
for v, i in obj
|
34
|
+
if rbracket.test(prefix)
|
35
|
+
add prefix, v
|
36
|
+
else
|
37
|
+
buildParams prefix + "[]", v, add
|
38
|
+
else if obj? and typeof obj == "object"
|
39
|
+
for name of obj
|
40
|
+
buildParams prefix + "[" + name + "]", obj[name], add
|
41
|
+
else
|
42
|
+
add prefix, obj
|
43
|
+
|
44
|
+
numericKeys = [1, 2, 3, 4, 5, 6, 7, 10, 11]
|
45
|
+
date_re = ///
|
46
|
+
^
|
47
|
+
(\d{4}|[+\-]\d{6}) # 1 YYYY
|
48
|
+
(?:-(\d{2}) # 2 MM
|
49
|
+
(?:-(\d{2}))?)? # 3 DD
|
50
|
+
(?:
|
51
|
+
T(\d{2}): # 4 HH
|
52
|
+
(\d{2}) # 5 mm
|
53
|
+
(?::(\d{2}) # 6 ss
|
54
|
+
(?:\.(\d{3}))?)? # 7 msec
|
55
|
+
(?:(Z)| # 8 Z
|
56
|
+
([+\-]) # 9 ±
|
57
|
+
(\d{2}) # 10 tzHH
|
58
|
+
(?::(\d{2}))? # 11 tzmm
|
59
|
+
)?
|
60
|
+
)?
|
61
|
+
$
|
62
|
+
///
|
63
|
+
|
64
|
+
Batman.mixin Batman.Encoders,
|
65
|
+
railsDate:
|
66
|
+
defaultTimezoneOffset: (new Date()).getTimezoneOffset()
|
67
|
+
encode: (value) -> value
|
68
|
+
decode: (value) ->
|
69
|
+
# Thanks to https://github.com/csnover/js-iso8601 for the majority of this algorithm.
|
70
|
+
# MIT Licensed
|
71
|
+
if value?
|
72
|
+
if (obj = date_re.exec(value))
|
73
|
+
# avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
|
74
|
+
for key in numericKeys
|
75
|
+
obj[key] = +obj[key] or 0
|
76
|
+
|
77
|
+
# allow undefined days and months
|
78
|
+
obj[2] = (+obj[2] || 1) - 1;
|
79
|
+
obj[3] = +obj[3] || 1;
|
80
|
+
|
81
|
+
# process timezone by adjusting minutes
|
82
|
+
if obj[8] != "Z" and obj[9] != undefined
|
83
|
+
minutesOffset = obj[10] * 60 + obj[11]
|
84
|
+
minutesOffset = 0 - minutesOffset if obj[9] == "+"
|
85
|
+
else
|
86
|
+
minutesOffset = Batman.Encoders.railsDate.defaultTimezoneOffset
|
87
|
+
return new Date(Date.UTC(obj[1], obj[2], obj[3], obj[4], obj[5] + minutesOffset, obj[6], obj[7]))
|
88
|
+
else
|
89
|
+
Batman.developer.warn "Unrecognized rails date #{value}!"
|
90
|
+
return Date.parse(value)
|
91
|
+
|
92
|
+
class Batman.RailsStorage extends Batman.RestStorage
|
93
|
+
|
94
|
+
_serializeToFormData: (data) -> param(data)
|
95
|
+
|
96
|
+
urlForRecord: -> @_addJsonExtension(super)
|
97
|
+
urlForCollection: -> @_addJsonExtension(super)
|
98
|
+
|
99
|
+
_addJsonExtension: (url) ->
|
100
|
+
if url.indexOf('?') isnt -1 or url.substr(-5, 5) is '.json'
|
101
|
+
return url
|
102
|
+
url + '.json'
|
103
|
+
|
104
|
+
_errorsFrom422Response: (response) -> JSON.parse(response)
|
105
|
+
|
106
|
+
@::before 'update', 'create', (env, next) ->
|
107
|
+
if @serializeAsForm && !Batman.Request.dataHasFileUploads(env.options.data)
|
108
|
+
env.options.data = @_serializeToFormData(env.options.data)
|
109
|
+
next()
|
110
|
+
|
111
|
+
@::after 'update', 'create', ({error, record, response}, next) ->
|
112
|
+
env = arguments[0]
|
113
|
+
if error
|
114
|
+
# Rails validation errors
|
115
|
+
if error.request?.get('status') == 422
|
116
|
+
try
|
117
|
+
validationErrors = @_errorsFrom422Response(response)
|
118
|
+
catch extractionError
|
119
|
+
env.error = extractionError
|
120
|
+
return next()
|
121
|
+
|
122
|
+
for key, errorsArray of validationErrors
|
123
|
+
for validationError in errorsArray
|
124
|
+
record.get('errors').add(key, validationError)
|
125
|
+
|
126
|
+
env.result = record
|
127
|
+
env.error = record.get('errors')
|
128
|
+
return next()
|
129
|
+
next()
|
130
|
+
|
131
|
+
if (module? && require?)
|
132
|
+
module.exports = applyExtra
|
133
|
+
else
|
134
|
+
applyExtra(Batman)
|
@@ -0,0 +1,496 @@
|
|
1
|
+
#
|
2
|
+
# batman.solo.coffee
|
3
|
+
# batman.js
|
4
|
+
#
|
5
|
+
# Created by Nick Small
|
6
|
+
# Copyright 2011, Shopify
|
7
|
+
#
|
8
|
+
`
|
9
|
+
/*!
|
10
|
+
* Reqwest! A general purpose XHR connection manager
|
11
|
+
* (c) Dustin Diaz 2011
|
12
|
+
* https://github.com/ded/reqwest
|
13
|
+
* license MIT
|
14
|
+
*/
|
15
|
+
!function (name, definition) {
|
16
|
+
if (typeof module != 'undefined') module.exports = definition()
|
17
|
+
else if (typeof define == 'function' && define.amd) define(name, definition)
|
18
|
+
else this[name] = definition()
|
19
|
+
}('reqwest', function () {
|
20
|
+
|
21
|
+
var context = this
|
22
|
+
, win = window
|
23
|
+
, doc = document
|
24
|
+
, old = context.reqwest
|
25
|
+
, twoHundo = /^20\d$/
|
26
|
+
, byTag = 'getElementsByTagName'
|
27
|
+
, readyState = 'readyState'
|
28
|
+
, contentType = 'Content-Type'
|
29
|
+
, requestedWith = 'X-Requested-With'
|
30
|
+
, head = doc[byTag]('head')[0]
|
31
|
+
, uniqid = 0
|
32
|
+
, lastValue // data stored by the most recent JSONP callback
|
33
|
+
, xmlHttpRequest = 'XMLHttpRequest'
|
34
|
+
, isArray = typeof Array.isArray == 'function' ? Array.isArray : function (a) {
|
35
|
+
return a instanceof Array
|
36
|
+
}
|
37
|
+
, defaultHeaders = {
|
38
|
+
contentType: 'application/x-www-form-urlencoded'
|
39
|
+
, accept: {
|
40
|
+
'*': 'text/javascript, text/html, application/xml, text/xml, */*'
|
41
|
+
, xml: 'application/xml, text/xml'
|
42
|
+
, html: 'text/html'
|
43
|
+
, text: 'text/plain'
|
44
|
+
, json: 'application/json, text/javascript'
|
45
|
+
, js: 'application/javascript, text/javascript'
|
46
|
+
}
|
47
|
+
, requestedWith: xmlHttpRequest
|
48
|
+
}
|
49
|
+
, xhr = win[xmlHttpRequest] ?
|
50
|
+
function () {
|
51
|
+
return new XMLHttpRequest()
|
52
|
+
} :
|
53
|
+
function () {
|
54
|
+
return new ActiveXObject('Microsoft.XMLHTTP')
|
55
|
+
}
|
56
|
+
|
57
|
+
function handleReadyState(o, success, error) {
|
58
|
+
return function () {
|
59
|
+
if (o && o[readyState] == 4) {
|
60
|
+
if (twoHundo.test(o.status)) {
|
61
|
+
success(o)
|
62
|
+
} else {
|
63
|
+
error(o)
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
function setHeaders(http, o) {
|
70
|
+
var headers = o.headers || {}, h
|
71
|
+
headers.Accept = headers.Accept || defaultHeaders.accept[o.type] || defaultHeaders.accept['*']
|
72
|
+
// breaks cross-origin requests with legacy browsers
|
73
|
+
if (!o.crossOrigin && !headers[requestedWith]) headers[requestedWith] = defaultHeaders.requestedWith
|
74
|
+
if (!headers[contentType]) headers[contentType] = o.contentType || defaultHeaders.contentType
|
75
|
+
for (h in headers) {
|
76
|
+
headers.hasOwnProperty(h) && http.setRequestHeader(h, headers[h])
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
function generalCallback(data) {
|
81
|
+
lastValue = data
|
82
|
+
}
|
83
|
+
|
84
|
+
function urlappend(url, s) {
|
85
|
+
return url + (/\?/.test(url) ? '&' : '?') + s
|
86
|
+
}
|
87
|
+
|
88
|
+
function handleJsonp(o, fn, err, url) {
|
89
|
+
var reqId = uniqid++
|
90
|
+
, cbkey = o.jsonpCallback || 'callback' // the 'callback' key
|
91
|
+
, cbval = o.jsonpCallbackName || ('reqwest_' + reqId) // the 'callback' value
|
92
|
+
, cbreg = new RegExp('((^|\\?|&)' + cbkey + ')=([^&]+)')
|
93
|
+
, match = url.match(cbreg)
|
94
|
+
, script = doc.createElement('script')
|
95
|
+
, loaded = 0
|
96
|
+
|
97
|
+
if (match) {
|
98
|
+
if (match[3] === '?') {
|
99
|
+
url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name
|
100
|
+
} else {
|
101
|
+
cbval = match[3] // provided callback func name
|
102
|
+
}
|
103
|
+
} else {
|
104
|
+
url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em
|
105
|
+
}
|
106
|
+
|
107
|
+
win[cbval] = generalCallback
|
108
|
+
|
109
|
+
script.type = 'text/javascript'
|
110
|
+
script.src = url
|
111
|
+
script.async = true
|
112
|
+
if (typeof script.onreadystatechange !== 'undefined') {
|
113
|
+
// need this for IE due to out-of-order onreadystatechange(), binding script
|
114
|
+
// execution to an event listener gives us control over when the script
|
115
|
+
// is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
|
116
|
+
script.event = 'onclick'
|
117
|
+
script.htmlFor = script.id = '_reqwest_' + reqId
|
118
|
+
}
|
119
|
+
|
120
|
+
script.onload = script.onreadystatechange = function () {
|
121
|
+
if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {
|
122
|
+
return false
|
123
|
+
}
|
124
|
+
script.onload = script.onreadystatechange = null
|
125
|
+
script.onclick && script.onclick()
|
126
|
+
// Call the user callback with the last value stored and clean up values and scripts.
|
127
|
+
o.success && o.success(lastValue)
|
128
|
+
lastValue = undefined
|
129
|
+
head.removeChild(script)
|
130
|
+
loaded = 1
|
131
|
+
}
|
132
|
+
|
133
|
+
// Add the script to the DOM head
|
134
|
+
head.appendChild(script)
|
135
|
+
}
|
136
|
+
|
137
|
+
function getRequest(o, fn, err) {
|
138
|
+
var method = (o.method || 'GET').toUpperCase()
|
139
|
+
, url = typeof o === 'string' ? o : o.url
|
140
|
+
// convert non-string objects to query-string form unless o.processData is false
|
141
|
+
, data = (o.processData !== false && o.data && typeof o.data !== 'string')
|
142
|
+
? reqwest.toQueryString(o.data)
|
143
|
+
: (o.data || null)
|
144
|
+
, http
|
145
|
+
|
146
|
+
// if we're working on a GET request and we have data then we should append
|
147
|
+
// query string to end of URL and not post data
|
148
|
+
if ((o.type == 'jsonp' || method == 'GET') && data) {
|
149
|
+
url = urlappend(url, data)
|
150
|
+
data = null
|
151
|
+
}
|
152
|
+
|
153
|
+
if (o.type == 'jsonp') return handleJsonp(o, fn, err, url)
|
154
|
+
|
155
|
+
http = xhr()
|
156
|
+
http.open(method, url, true)
|
157
|
+
setHeaders(http, o)
|
158
|
+
http.onreadystatechange = handleReadyState(http, fn, err)
|
159
|
+
o.before && o.before(http)
|
160
|
+
http.send(data)
|
161
|
+
return http
|
162
|
+
}
|
163
|
+
|
164
|
+
function Reqwest(o, fn) {
|
165
|
+
this.o = o
|
166
|
+
this.fn = fn
|
167
|
+
init.apply(this, arguments)
|
168
|
+
}
|
169
|
+
|
170
|
+
function setType(url) {
|
171
|
+
var m = url.match(/\.(json|jsonp|html|xml)(\?|$)/)
|
172
|
+
return m ? m[1] : 'js'
|
173
|
+
}
|
174
|
+
|
175
|
+
function init(o, fn) {
|
176
|
+
this.url = typeof o == 'string' ? o : o.url
|
177
|
+
this.timeout = null
|
178
|
+
var type = o.type || setType(this.url)
|
179
|
+
, self = this
|
180
|
+
fn = fn || function () {}
|
181
|
+
|
182
|
+
if (o.timeout) {
|
183
|
+
this.timeout = setTimeout(function () {
|
184
|
+
self.abort()
|
185
|
+
}, o.timeout)
|
186
|
+
}
|
187
|
+
|
188
|
+
function complete(resp) {
|
189
|
+
o.timeout && clearTimeout(self.timeout)
|
190
|
+
self.timeout = null
|
191
|
+
o.complete && o.complete(resp)
|
192
|
+
}
|
193
|
+
|
194
|
+
function success(resp) {
|
195
|
+
var r = resp.responseText
|
196
|
+
if (r) {
|
197
|
+
switch (type) {
|
198
|
+
case 'json':
|
199
|
+
try {
|
200
|
+
resp = win.JSON ? win.JSON.parse(r) : eval('(' + r + ')')
|
201
|
+
} catch (err) {
|
202
|
+
return error(resp, 'Could not parse JSON in response', err)
|
203
|
+
}
|
204
|
+
break;
|
205
|
+
case 'js':
|
206
|
+
resp = eval(r)
|
207
|
+
break;
|
208
|
+
case 'html':
|
209
|
+
resp = r
|
210
|
+
break;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
fn(resp)
|
215
|
+
o.success && o.success(resp)
|
216
|
+
|
217
|
+
complete(resp)
|
218
|
+
}
|
219
|
+
|
220
|
+
function error(resp, msg, t) {
|
221
|
+
o.error && o.error(resp, msg, t)
|
222
|
+
complete(resp)
|
223
|
+
}
|
224
|
+
|
225
|
+
this.request = getRequest(o, success, error)
|
226
|
+
}
|
227
|
+
|
228
|
+
Reqwest.prototype = {
|
229
|
+
abort: function () {
|
230
|
+
this.request.abort()
|
231
|
+
}
|
232
|
+
|
233
|
+
, retry: function () {
|
234
|
+
init.call(this, this.o, this.fn)
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
function reqwest(o, fn) {
|
239
|
+
return new Reqwest(o, fn)
|
240
|
+
}
|
241
|
+
|
242
|
+
// normalize newline variants according to spec -> CRLF
|
243
|
+
function normalize(s) {
|
244
|
+
return s ? s.replace(/\r?\n/g, '\r\n') : ''
|
245
|
+
}
|
246
|
+
|
247
|
+
function serial(el, cb) {
|
248
|
+
var n = el.name
|
249
|
+
, t = el.tagName.toLowerCase()
|
250
|
+
, optCb = function(o) {
|
251
|
+
// IE gives value="" even where there is no value attribute
|
252
|
+
// 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273
|
253
|
+
if (o && !o.disabled)
|
254
|
+
cb(n, normalize(o.attributes.value && o.attributes.value.specified ? o.value : o.text))
|
255
|
+
}
|
256
|
+
|
257
|
+
// don't serialize elements that are disabled or without a name
|
258
|
+
if (el.disabled || !n) return;
|
259
|
+
|
260
|
+
switch (t) {
|
261
|
+
case 'input':
|
262
|
+
if (!/reset|button|image|file/i.test(el.type)) {
|
263
|
+
var ch = /checkbox/i.test(el.type)
|
264
|
+
, ra = /radio/i.test(el.type)
|
265
|
+
, val = el.value;
|
266
|
+
// WebKit gives us "" instead of "on" if a checkbox has no value, so correct it here
|
267
|
+
(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))
|
268
|
+
}
|
269
|
+
break;
|
270
|
+
case 'textarea':
|
271
|
+
cb(n, normalize(el.value))
|
272
|
+
break;
|
273
|
+
case 'select':
|
274
|
+
if (el.type.toLowerCase() === 'select-one') {
|
275
|
+
optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)
|
276
|
+
} else {
|
277
|
+
for (var i = 0; el.length && i < el.length; i++) {
|
278
|
+
el.options[i].selected && optCb(el.options[i])
|
279
|
+
}
|
280
|
+
}
|
281
|
+
break;
|
282
|
+
}
|
283
|
+
}
|
284
|
+
|
285
|
+
// collect up all form elements found from the passed argument elements all
|
286
|
+
// the way down to child elements; pass a '<form>' or form fields.
|
287
|
+
// called with 'this'=callback to use for serial() on each element
|
288
|
+
function eachFormElement() {
|
289
|
+
var cb = this
|
290
|
+
, e, i, j
|
291
|
+
, serializeSubtags = function(e, tags) {
|
292
|
+
for (var i = 0; i < tags.length; i++) {
|
293
|
+
var fa = e[byTag](tags[i])
|
294
|
+
for (j = 0; j < fa.length; j++) serial(fa[j], cb)
|
295
|
+
}
|
296
|
+
}
|
297
|
+
|
298
|
+
for (i = 0; i < arguments.length; i++) {
|
299
|
+
e = arguments[i]
|
300
|
+
if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)
|
301
|
+
serializeSubtags(e, [ 'input', 'select', 'textarea' ])
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
// standard query string style serialization
|
306
|
+
function serializeQueryString() {
|
307
|
+
return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))
|
308
|
+
}
|
309
|
+
|
310
|
+
// { 'name': 'value', ... } style serialization
|
311
|
+
function serializeHash() {
|
312
|
+
var hash = {}
|
313
|
+
eachFormElement.apply(function (name, value) {
|
314
|
+
if (name in hash) {
|
315
|
+
hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])
|
316
|
+
hash[name].push(value)
|
317
|
+
} else hash[name] = value
|
318
|
+
}, arguments)
|
319
|
+
return hash
|
320
|
+
}
|
321
|
+
|
322
|
+
// [ { name: 'name', value: 'value' }, ... ] style serialization
|
323
|
+
reqwest.serializeArray = function () {
|
324
|
+
var arr = []
|
325
|
+
eachFormElement.apply(function(name, value) {
|
326
|
+
arr.push({name: name, value: value})
|
327
|
+
}, arguments)
|
328
|
+
return arr
|
329
|
+
}
|
330
|
+
|
331
|
+
reqwest.serialize = function () {
|
332
|
+
if (arguments.length === 0) return ''
|
333
|
+
var opt, fn
|
334
|
+
, args = Array.prototype.slice.call(arguments, 0)
|
335
|
+
|
336
|
+
opt = args.pop()
|
337
|
+
opt && opt.nodeType && args.push(opt) && (opt = null)
|
338
|
+
opt && (opt = opt.type)
|
339
|
+
|
340
|
+
if (opt == 'map') fn = serializeHash
|
341
|
+
else if (opt == 'array') fn = reqwest.serializeArray
|
342
|
+
else fn = serializeQueryString
|
343
|
+
|
344
|
+
return fn.apply(null, args)
|
345
|
+
}
|
346
|
+
|
347
|
+
reqwest.toQueryString = function (o) {
|
348
|
+
var qs = '', i
|
349
|
+
, enc = encodeURIComponent
|
350
|
+
, push = function (k, v) {
|
351
|
+
qs += enc(k) + '=' + enc(v) + '&'
|
352
|
+
}
|
353
|
+
|
354
|
+
if (isArray(o)) {
|
355
|
+
for (i = 0; o && i < o.length; i++) push(o[i].name, o[i].value)
|
356
|
+
} else {
|
357
|
+
for (var k in o) {
|
358
|
+
if (!Object.hasOwnProperty.call(o, k)) continue;
|
359
|
+
var v = o[k]
|
360
|
+
if (isArray(v)) {
|
361
|
+
for (i = 0; i < v.length; i++) push(k, v[i])
|
362
|
+
} else push(k, o[k])
|
363
|
+
}
|
364
|
+
}
|
365
|
+
|
366
|
+
// spaces should be + according to spec
|
367
|
+
return qs.replace(/&$/, '').replace(/%20/g,'+')
|
368
|
+
}
|
369
|
+
|
370
|
+
// jQuery and Zepto compatibility, differences can be remapped here so you can call
|
371
|
+
// .ajax.compat(options, callback)
|
372
|
+
reqwest.compat = function (o, fn) {
|
373
|
+
if (o) {
|
374
|
+
o.type && (o.method = o.type) && delete o.type
|
375
|
+
o.dataType && (o.type = o.dataType)
|
376
|
+
o.jsonpCallback && (o.jsonpCallbackName = o.jsonpCallback) && delete o.jsonpCallback
|
377
|
+
o.jsonp && (o.jsonpCallback = o.jsonp)
|
378
|
+
}
|
379
|
+
return new Reqwest(o, fn)
|
380
|
+
}
|
381
|
+
|
382
|
+
return reqwest
|
383
|
+
})
|
384
|
+
|
385
|
+
`
|
386
|
+
(exports ? this).reqwest = if window? then window.reqwest else reqwest
|
387
|
+
|
388
|
+
# `param` and `buildParams` stolen from jQuery
|
389
|
+
#
|
390
|
+
# jQuery JavaScript Library v1.6.1
|
391
|
+
# http://jquery.com/
|
392
|
+
#
|
393
|
+
# Copyright 2011, John Resig
|
394
|
+
# Dual licensed under the MIT or GPL Version 2 licenses.
|
395
|
+
# http://jquery.org/license
|
396
|
+
rbracket = /\[\]$/
|
397
|
+
r20 = /%20/g
|
398
|
+
param = (a) ->
|
399
|
+
return a if typeof a is 'string'
|
400
|
+
s = []
|
401
|
+
add = (key, value) ->
|
402
|
+
value = value() if typeof value is 'function'
|
403
|
+
value = '' unless value?
|
404
|
+
s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value)
|
405
|
+
|
406
|
+
if Batman.typeOf(a) is 'Array'
|
407
|
+
for value, name of a
|
408
|
+
add name, value
|
409
|
+
else
|
410
|
+
for own k, v of a
|
411
|
+
buildParams k, v, add
|
412
|
+
s.join("&").replace r20, "+"
|
413
|
+
|
414
|
+
buildParams = (prefix, obj, add) ->
|
415
|
+
if Batman.typeOf(obj) is 'Array'
|
416
|
+
for v, i in obj
|
417
|
+
if rbracket.test(prefix)
|
418
|
+
add prefix, v
|
419
|
+
else
|
420
|
+
buildParams prefix + "[" + (if typeof v == "object" or Batman.typeOf(v) is 'Array' then i else "") + "]", v, add
|
421
|
+
else if obj? and typeof obj == "object"
|
422
|
+
for name of obj
|
423
|
+
buildParams prefix + "[" + name + "]", obj[name], add
|
424
|
+
else
|
425
|
+
add prefix, obj
|
426
|
+
|
427
|
+
Batman.Request::send = (data) ->
|
428
|
+
data ?= @get('data')
|
429
|
+
@fire 'loading'
|
430
|
+
|
431
|
+
options =
|
432
|
+
url: @get 'url'
|
433
|
+
method: @get 'method'
|
434
|
+
type: @get 'type'
|
435
|
+
headers: @get 'headers'
|
436
|
+
|
437
|
+
success: (response) =>
|
438
|
+
@set 'response', response
|
439
|
+
@set 'status', (xhr?.status or 200)
|
440
|
+
@fire 'success', response
|
441
|
+
|
442
|
+
error: (xhr) =>
|
443
|
+
@set 'response', xhr.responseText || xhr.content
|
444
|
+
@set 'status', xhr.status
|
445
|
+
xhr.request = @
|
446
|
+
@fire 'error', xhr
|
447
|
+
|
448
|
+
complete: =>
|
449
|
+
@fire 'loaded'
|
450
|
+
|
451
|
+
if options.method in ['PUT', 'POST']
|
452
|
+
if @hasFileUploads()
|
453
|
+
options.data = @constructor.objectToFormData(data)
|
454
|
+
else
|
455
|
+
options.contentType = @get('contentType')
|
456
|
+
options.data = param(data)
|
457
|
+
|
458
|
+
else
|
459
|
+
options.data = data
|
460
|
+
|
461
|
+
# Fires the request. Grab a reference to the xhr object so we can get the status code elsewhere.
|
462
|
+
xhr = (reqwest options).request
|
463
|
+
|
464
|
+
prefixes = ['Webkit', 'Moz', 'O', 'ms', '']
|
465
|
+
Batman.mixins.animation =
|
466
|
+
initialize: ->
|
467
|
+
for prefix in prefixes
|
468
|
+
@style["#{prefix}Transform"] = 'scale(0, 0)'
|
469
|
+
@style.opacity = 0
|
470
|
+
|
471
|
+
@style["#{prefix}TransitionProperty"] = "#{if prefix then '-' + prefix.toLowerCase() + '-' else ''}transform, opacity"
|
472
|
+
@style["#{prefix}TransitionDuration"] = "0.8s, 0.55s"
|
473
|
+
@style["#{prefix}TransformOrigin"] = "left top"
|
474
|
+
@
|
475
|
+
show: (addToParent) ->
|
476
|
+
show = =>
|
477
|
+
@style.opacity = 1
|
478
|
+
for prefix in prefixes
|
479
|
+
@style["#{prefix}Transform"] = 'scale(1, 1)'
|
480
|
+
@
|
481
|
+
|
482
|
+
if addToParent
|
483
|
+
addToParent.append?.appendChild @
|
484
|
+
addToParent.before?.parentNode.insertBefore @, addToParent.before
|
485
|
+
|
486
|
+
setTimeout show, 0
|
487
|
+
else
|
488
|
+
show()
|
489
|
+
@
|
490
|
+
hide: (shouldRemove) ->
|
491
|
+
@style.opacity = 0
|
492
|
+
for prefix in prefixes
|
493
|
+
@style["#{prefix}Transform"] = 'scale(0, 0)'
|
494
|
+
|
495
|
+
setTimeout((=> @parentNode?.removeChild @), 600) if shouldRemove
|
496
|
+
@
|