h2ocube_rails_assets 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ // Zepto.js
2
+ // (c) 2010-2012 Thomas Fuchs
3
+ // Zepto.js may be freely distributed under the MIT license.
4
+
5
+ ;(function($){
6
+ $.fn.end = function(){
7
+ return this.prevObject || $()
8
+ }
9
+
10
+ $.fn.andSelf = function(){
11
+ return this.add(this.prevObject || $())
12
+ }
13
+
14
+ 'filter,add,not,eq,first,last,find,closest,parents,parent,children,siblings'.split(',').forEach(function(property){
15
+ var fn = $.fn[property]
16
+ $.fn[property] = function(){
17
+ var ret = fn.apply(this, arguments)
18
+ ret.prevObject = this
19
+ return ret
20
+ }
21
+ })
22
+ })(Zepto)
@@ -0,0 +1,115 @@
1
+ // Zepto.js
2
+ // (c) 2010-2012 Thomas Fuchs
3
+ // Zepto.js may be freely distributed under the MIT license.
4
+
5
+ ;(function($){
6
+ var touch = {},
7
+ touchTimeout, tapTimeout, swipeTimeout,
8
+ longTapDelay = 750, longTapTimeout
9
+
10
+ function parentIfText(node) {
11
+ return 'tagName' in node ? node : node.parentNode
12
+ }
13
+
14
+ function swipeDirection(x1, x2, y1, y2) {
15
+ var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
16
+ return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
17
+ }
18
+
19
+ function longTap() {
20
+ longTapTimeout = null
21
+ if (touch.last) {
22
+ touch.el.trigger('longTap')
23
+ touch = {}
24
+ }
25
+ }
26
+
27
+ function cancelLongTap() {
28
+ if (longTapTimeout) clearTimeout(longTapTimeout)
29
+ longTapTimeout = null
30
+ }
31
+
32
+ function cancelAll() {
33
+ if (touchTimeout) clearTimeout(touchTimeout)
34
+ if (tapTimeout) clearTimeout(tapTimeout)
35
+ if (swipeTimeout) clearTimeout(swipeTimeout)
36
+ if (longTapTimeout) clearTimeout(longTapTimeout)
37
+ touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
38
+ touch = {}
39
+ }
40
+
41
+ $(document).ready(function(){
42
+ var now, delta
43
+
44
+ $(document.body)
45
+ .bind('touchstart', function(e){
46
+ now = Date.now()
47
+ delta = now - (touch.last || now)
48
+ touch.el = $(parentIfText(e.touches[0].target))
49
+ touchTimeout && clearTimeout(touchTimeout)
50
+ touch.x1 = e.touches[0].pageX
51
+ touch.y1 = e.touches[0].pageY
52
+ if (delta > 0 && delta <= 250) touch.isDoubleTap = true
53
+ touch.last = now
54
+ longTapTimeout = setTimeout(longTap, longTapDelay)
55
+ })
56
+ .bind('touchmove', function(e){
57
+ cancelLongTap()
58
+ touch.x2 = e.touches[0].pageX
59
+ touch.y2 = e.touches[0].pageY
60
+ if (Math.abs(touch.x1 - touch.x2) > 10)
61
+ e.preventDefault()
62
+ })
63
+ .bind('touchend', function(e){
64
+ cancelLongTap()
65
+
66
+ // swipe
67
+ if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
68
+ (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
69
+
70
+ swipeTimeout = setTimeout(function() {
71
+ touch.el.trigger('swipe')
72
+ touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
73
+ touch = {}
74
+ }, 0)
75
+
76
+ // normal tap
77
+ else if ('last' in touch)
78
+
79
+ // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
80
+ // ('tap' fires before 'scroll')
81
+ tapTimeout = setTimeout(function() {
82
+
83
+ // trigger universal 'tap' with the option to cancelTouch()
84
+ // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
85
+ var event = $.Event('tap')
86
+ event.cancelTouch = cancelAll
87
+ touch.el.trigger(event)
88
+
89
+ // trigger double tap immediately
90
+ if (touch.isDoubleTap) {
91
+ touch.el.trigger('doubleTap')
92
+ touch = {}
93
+ }
94
+
95
+ // trigger single tap after 250ms of inactivity
96
+ else {
97
+ touchTimeout = setTimeout(function(){
98
+ touchTimeout = null
99
+ touch.el.trigger('singleTap')
100
+ touch = {}
101
+ }, 250)
102
+ }
103
+
104
+ }, 0)
105
+
106
+ })
107
+ .bind('touchcancel', cancelAll)
108
+
109
+ $(window).bind('scroll', cancelAll)
110
+ })
111
+
112
+ ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){
113
+ $.fn[m] = function(callback){ return this.bind(m, callback) }
114
+ })
115
+ })(Zepto)
@@ -0,0 +1,2 @@
1
+ //= require zepto
2
+ //= require_tree ./zepto
@@ -1,7 +1,9 @@
1
- /* Zepto v1.0rc1 - polyfill zepto event detect fx ajax form touch - zeptojs.com/license */
1
+ /* Zepto v1.0-1-ga3cab6c - polyfill zepto detect event ajax form fx - zeptojs.com/license */
2
+
3
+
2
4
  ;(function(undefined){
3
5
  if (String.prototype.trim === undefined) // fix for iOS 3.2
4
- String.prototype.trim = function(){ return this.replace(/^\s+/, '').replace(/\s+$/, '') }
6
+ String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g, '') }
5
7
 
6
8
  // For iOS 3.x
7
9
  // from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce
@@ -31,17 +33,19 @@
31
33
  }
32
34
 
33
35
  })()
36
+
34
37
  var Zepto = (function() {
35
- var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice,
38
+ var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice, filter = emptyArray.filter,
36
39
  document = window.document,
37
40
  elementDisplay = {}, classCache = {},
38
41
  getComputedStyle = document.defaultView.getComputedStyle,
39
42
  cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },
40
43
  fragmentRE = /^\s*<(\w+|!)[^>]*>/,
44
+ tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
45
+ rootNodeRE = /^(?:body|html)$/i,
41
46
 
42
- // Used by `$.zepto.init` to wrap elements, text/comment nodes, document,
43
- // and document fragment node types.
44
- elementTypes = [1, 3, 8, 9, 11],
47
+ // special attributes that should be get/set via method calls
48
+ methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
45
49
 
46
50
  adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],
47
51
  table = document.createElement('table'),
@@ -54,9 +58,10 @@ var Zepto = (function() {
54
58
  },
55
59
  readyRE = /complete|loaded|interactive/,
56
60
  classSelectorRE = /^\.([\w-]+)$/,
57
- idSelectorRE = /^#([\w-]+)$/,
61
+ idSelectorRE = /^#([\w-]*)$/,
58
62
  tagSelectorRE = /^[\w-]+$/,
59
- toString = ({}).toString,
63
+ class2type = {},
64
+ toString = class2type.toString,
60
65
  zepto = {},
61
66
  camelize, uniq,
62
67
  tempParent = document.createElement('div')
@@ -74,21 +79,23 @@ var Zepto = (function() {
74
79
  return match
75
80
  }
76
81
 
77
- function isFunction(value) { return toString.call(value) == "[object Function]" }
78
- function isObject(value) { return value instanceof Object }
79
- function isPlainObject(value) {
80
- var key, ctor
81
- if (toString.call(value) !== "[object Object]") return false
82
- ctor = (isFunction(value.constructor) && value.constructor.prototype)
83
- if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) return false
84
- for (key in value);
85
- return key === undefined || hasOwnProperty.call(value, key)
82
+ function type(obj) {
83
+ return obj == null ? String(obj) :
84
+ class2type[toString.call(obj)] || "object"
85
+ }
86
+
87
+ function isFunction(value) { return type(value) == "function" }
88
+ function isWindow(obj) { return obj != null && obj == obj.window }
89
+ function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }
90
+ function isObject(obj) { return type(obj) == "object" }
91
+ function isPlainObject(obj) {
92
+ return isObject(obj) && !isWindow(obj) && obj.__proto__ == Object.prototype
86
93
  }
87
94
  function isArray(value) { return value instanceof Array }
88
95
  function likeArray(obj) { return typeof obj.length == 'number' }
89
96
 
90
- function compact(array) { return array.filter(function(item){ return item !== undefined && item !== null }) }
91
- function flatten(array) { return array.length > 0 ? [].concat.apply([], array) : array }
97
+ function compact(array) { return filter.call(array, function(item){ return item != null }) }
98
+ function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }
92
99
  camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
93
100
  function dasherize(str) {
94
101
  return str.replace(/::/g, '/')
@@ -97,7 +104,7 @@ var Zepto = (function() {
97
104
  .replace(/_/g, '-')
98
105
  .toLowerCase()
99
106
  }
100
- uniq = function(array){ return array.filter(function(item, idx){ return array.indexOf(item) == idx }) }
107
+ uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }
101
108
 
102
109
  function classRE(name) {
103
110
  return name in classCache ?
@@ -121,19 +128,35 @@ var Zepto = (function() {
121
128
  return elementDisplay[nodeName]
122
129
  }
123
130
 
131
+ function children(element) {
132
+ return 'children' in element ?
133
+ slice.call(element.children) :
134
+ $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
135
+ }
136
+
124
137
  // `$.zepto.fragment` takes a html string and an optional tag name
125
138
  // to generate DOM nodes nodes from the given html string.
126
139
  // The generated DOM nodes are returned as an array.
127
140
  // This function can be overriden in plugins for example to make
128
141
  // it compatible with browsers that don't support the DOM fully.
129
- zepto.fragment = function(html, name) {
142
+ zepto.fragment = function(html, name, properties) {
143
+ if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>")
130
144
  if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
131
145
  if (!(name in containers)) name = '*'
132
- var container = containers[name]
146
+
147
+ var nodes, dom, container = containers[name]
133
148
  container.innerHTML = '' + html
134
- return $.each(slice.call(container.childNodes), function(){
149
+ dom = $.each(slice.call(container.childNodes), function(){
135
150
  container.removeChild(this)
136
151
  })
152
+ if (isPlainObject(properties)) {
153
+ nodes = $(dom)
154
+ $.each(properties, function(key, value) {
155
+ if (methodAttributes.indexOf(key) > -1) nodes[key](value)
156
+ else nodes.attr(key, value)
157
+ })
158
+ }
159
+ return dom
137
160
  }
138
161
 
139
162
  // `$.zepto.Z` swaps out the prototype of the given `dom` array
@@ -142,7 +165,7 @@ var Zepto = (function() {
142
165
  // Explorer. This method can be overriden in plugins.
143
166
  zepto.Z = function(dom, selector) {
144
167
  dom = dom || []
145
- dom.__proto__ = arguments.callee.prototype
168
+ dom.__proto__ = $.fn
146
169
  dom.selector = selector || ''
147
170
  return dom
148
171
  }
@@ -168,17 +191,12 @@ var Zepto = (function() {
168
191
  var dom
169
192
  // normalize array if an array of nodes is given
170
193
  if (isArray(selector)) dom = compact(selector)
171
- // if a JavaScript object is given, return a copy of it
172
- // this is a somewhat peculiar option, but supported by
173
- // jQuery so we'll do it, too
174
- else if (isPlainObject(selector))
175
- dom = [$.extend({}, selector)], selector = null
176
- // wrap stuff like `document` or `window`
177
- else if (elementTypes.indexOf(selector.nodeType) >= 0 || selector === window)
178
- dom = [selector], selector = null
194
+ // Wrap DOM nodes. If a plain object is given, duplicate it.
195
+ else if (isObject(selector))
196
+ dom = [isPlainObject(selector) ? $.extend({}, selector) : selector], selector = null
179
197
  // If it's a html fragment, create nodes from it
180
198
  else if (fragmentRE.test(selector))
181
- dom = zepto.fragment(selector.trim(), RegExp.$1), selector = null
199
+ dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
182
200
  // If there's a context, create a collection on that context first, and select
183
201
  // nodes from there
184
202
  else if (context !== undefined) return $(context).find(selector)
@@ -190,21 +208,34 @@ var Zepto = (function() {
190
208
  }
191
209
 
192
210
  // `$` will be the base `Zepto` object. When calling this
193
- // function just call `$.zepto.init, whichs makes the implementation
211
+ // function just call `$.zepto.init, which makes the implementation
194
212
  // details of selecting nodes and creating Zepto collections
195
213
  // patchable in plugins.
196
214
  $ = function(selector, context){
197
215
  return zepto.init(selector, context)
198
216
  }
199
217
 
218
+ function extend(target, source, deep) {
219
+ for (key in source)
220
+ if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
221
+ if (isPlainObject(source[key]) && !isPlainObject(target[key]))
222
+ target[key] = {}
223
+ if (isArray(source[key]) && !isArray(target[key]))
224
+ target[key] = []
225
+ extend(target[key], source[key], deep)
226
+ }
227
+ else if (source[key] !== undefined) target[key] = source[key]
228
+ }
229
+
200
230
  // Copy all but undefined properties from one or more
201
231
  // objects to the `target` object.
202
232
  $.extend = function(target){
203
- slice.call(arguments, 1).forEach(function(source) {
204
- for (key in source)
205
- if (source[key] !== undefined)
206
- target[key] = source[key]
207
- })
233
+ var deep, args = slice.call(arguments, 1)
234
+ if (typeof target == 'boolean') {
235
+ deep = target
236
+ target = args.shift()
237
+ }
238
+ args.forEach(function(arg){ extend(target, arg, deep) })
208
239
  return target
209
240
  }
210
241
 
@@ -213,9 +244,9 @@ var Zepto = (function() {
213
244
  // This method can be overriden in plugins.
214
245
  zepto.qsa = function(element, selector){
215
246
  var found
216
- return (element === document && idSelectorRE.test(selector)) ?
217
- ( (found = element.getElementById(RegExp.$1)) ? [found] : emptyArray ) :
218
- (element.nodeType !== 1 && element.nodeType !== 9) ? emptyArray :
247
+ return (isDocument(element) && idSelectorRE.test(selector)) ?
248
+ ( (found = element.getElementById(RegExp.$1)) ? [found] : [] ) :
249
+ (element.nodeType !== 1 && element.nodeType !== 9) ? [] :
219
250
  slice.call(
220
251
  classSelectorRE.test(selector) ? element.getElementsByClassName(RegExp.$1) :
221
252
  tagSelectorRE.test(selector) ? element.getElementsByTagName(selector) :
@@ -227,23 +258,73 @@ var Zepto = (function() {
227
258
  return selector === undefined ? $(nodes) : $(nodes).filter(selector)
228
259
  }
229
260
 
261
+ $.contains = function(parent, node) {
262
+ return parent !== node && parent.contains(node)
263
+ }
264
+
230
265
  function funcArg(context, arg, idx, payload) {
231
- return isFunction(arg) ? arg.call(context, idx, payload) : arg
266
+ return isFunction(arg) ? arg.call(context, idx, payload) : arg
267
+ }
268
+
269
+ function setAttribute(node, name, value) {
270
+ value == null ? node.removeAttribute(name) : node.setAttribute(name, value)
271
+ }
272
+
273
+ // access className property while respecting SVGAnimatedString
274
+ function className(node, value){
275
+ var klass = node.className,
276
+ svg = klass && klass.baseVal !== undefined
277
+
278
+ if (value === undefined) return svg ? klass.baseVal : klass
279
+ svg ? (klass.baseVal = value) : (node.className = value)
280
+ }
281
+
282
+ // "true" => true
283
+ // "false" => false
284
+ // "null" => null
285
+ // "42" => 42
286
+ // "42.5" => 42.5
287
+ // JSON => parse if valid
288
+ // String => self
289
+ function deserializeValue(value) {
290
+ var num
291
+ try {
292
+ return value ?
293
+ value == "true" ||
294
+ ( value == "false" ? false :
295
+ value == "null" ? null :
296
+ !isNaN(num = Number(value)) ? num :
297
+ /^[\[\{]/.test(value) ? $.parseJSON(value) :
298
+ value )
299
+ : value
300
+ } catch(e) {
301
+ return value
302
+ }
232
303
  }
233
304
 
305
+ $.type = type
234
306
  $.isFunction = isFunction
235
- $.isObject = isObject
307
+ $.isWindow = isWindow
236
308
  $.isArray = isArray
237
309
  $.isPlainObject = isPlainObject
238
310
 
311
+ $.isEmptyObject = function(obj) {
312
+ var name
313
+ for (name in obj) return false
314
+ return true
315
+ }
316
+
239
317
  $.inArray = function(elem, array, i){
240
318
  return emptyArray.indexOf.call(array, elem, i)
241
319
  }
242
320
 
321
+ $.camelCase = camelize
243
322
  $.trim = function(str) { return str.trim() }
244
323
 
245
324
  // plugin compatibility
246
325
  $.uuid = 0
326
+ $.support = { }
327
+ $.expr = { }
247
328
 
248
329
  $.map = function(elements, callback){
249
330
  var value, values = [], i, key
@@ -273,6 +354,17 @@ var Zepto = (function() {
273
354
  return elements
274
355
  }
275
356
 
357
+ $.grep = function(elements, callback){
358
+ return filter.call(elements, callback)
359
+ }
360
+
361
+ if (window.JSON) $.parseJSON = JSON.parse
362
+
363
+ // Populate the class2type map
364
+ $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
365
+ class2type[ "[object " + name + "]" ] = name.toLowerCase()
366
+ })
367
+
276
368
  // Define methods that will be available on all
277
369
  // Zepto collections
278
370
  $.fn = {
@@ -281,13 +373,14 @@ var Zepto = (function() {
281
373
  forEach: emptyArray.forEach,
282
374
  reduce: emptyArray.reduce,
283
375
  push: emptyArray.push,
376
+ sort: emptyArray.sort,
284
377
  indexOf: emptyArray.indexOf,
285
378
  concat: emptyArray.concat,
286
379
 
287
380
  // `map` and `slice` in the jQuery API work differently
288
381
  // from their array counterparts
289
382
  map: function(fn){
290
- return $.map(this, function(el, i){ return fn.call(el, i, el) })
383
+ return $($.map(this, function(el, i){ return fn.call(el, i, el) }))
291
384
  },
292
385
  slice: function(){
293
386
  return $(slice.apply(this, arguments))
@@ -299,7 +392,7 @@ var Zepto = (function() {
299
392
  return this
300
393
  },
301
394
  get: function(idx){
302
- return idx === undefined ? slice.call(this) : this[idx]
395
+ return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
303
396
  },
304
397
  toArray: function(){ return this.get() },
305
398
  size: function(){
@@ -312,11 +405,14 @@ var Zepto = (function() {
312
405
  })
313
406
  },
314
407
  each: function(callback){
315
- this.forEach(function(el, idx){ callback.call(el, idx, el) })
408
+ emptyArray.every.call(this, function(el, idx){
409
+ return callback.call(el, idx, el) !== false
410
+ })
316
411
  return this
317
412
  },
318
413
  filter: function(selector){
319
- return $([].filter.call(this, function(element){
414
+ if (isFunction(selector)) return this.not(this.not(selector))
415
+ return $(filter.call(this, function(element){
320
416
  return zepto.matches(element, selector)
321
417
  }))
322
418
  },
@@ -341,6 +437,13 @@ var Zepto = (function() {
341
437
  }
342
438
  return $(nodes)
343
439
  },
440
+ has: function(selector){
441
+ return this.filter(function(){
442
+ return isObject(selector) ?
443
+ $.contains(this, selector) :
444
+ $(this).find(selector).size()
445
+ })
446
+ },
344
447
  eq: function(idx){
345
448
  return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)
346
449
  },
@@ -353,22 +456,30 @@ var Zepto = (function() {
353
456
  return el && !isObject(el) ? el : $(el)
354
457
  },
355
458
  find: function(selector){
356
- var result
357
- if (this.length == 1) result = zepto.qsa(this[0], selector)
459
+ var result, $this = this
460
+ if (typeof selector == 'object')
461
+ result = $(selector).filter(function(){
462
+ var node = this
463
+ return emptyArray.some.call($this, function(parent){
464
+ return $.contains(parent, node)
465
+ })
466
+ })
467
+ else if (this.length == 1) result = $(zepto.qsa(this[0], selector))
358
468
  else result = this.map(function(){ return zepto.qsa(this, selector) })
359
- return $(result)
469
+ return result
360
470
  },
361
471
  closest: function(selector, context){
362
- var node = this[0]
363
- while (node && !zepto.matches(node, selector))
364
- node = node !== context && node !== document && node.parentNode
472
+ var node = this[0], collection = false
473
+ if (typeof selector == 'object') collection = $(selector)
474
+ while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))
475
+ node = node !== context && !isDocument(node) && node.parentNode
365
476
  return $(node)
366
477
  },
367
478
  parents: function(selector){
368
479
  var ancestors = [], nodes = this
369
480
  while (nodes.length > 0)
370
481
  nodes = $.map(nodes, function(node){
371
- if ((node = node.parentNode) && node !== document && ancestors.indexOf(node) < 0) {
482
+ if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {
372
483
  ancestors.push(node)
373
484
  return node
374
485
  }
@@ -379,11 +490,14 @@ var Zepto = (function() {
379
490
  return filtered(uniq(this.pluck('parentNode')), selector)
380
491
  },
381
492
  children: function(selector){
382
- return filtered(this.map(function(){ return slice.call(this.children) }), selector)
493
+ return filtered(this.map(function(){ return children(this) }), selector)
494
+ },
495
+ contents: function() {
496
+ return this.map(function() { return slice.call(this.childNodes) })
383
497
  },
384
498
  siblings: function(selector){
385
499
  return filtered(this.map(function(i, el){
386
- return slice.call(el.parentNode.children).filter(function(child){ return child!==el })
500
+ return filter.call(children(el.parentNode), function(child){ return child!==el })
387
501
  }), selector)
388
502
  },
389
503
  empty: function(){
@@ -391,7 +505,7 @@ var Zepto = (function() {
391
505
  },
392
506
  // `pluck` is borrowed from Prototype.js
393
507
  pluck: function(property){
394
- return this.map(function(){ return this[property] })
508
+ return $.map(this, function(el){ return el[property] })
395
509
  },
396
510
  show: function(){
397
511
  return this.each(function(){
@@ -403,18 +517,37 @@ var Zepto = (function() {
403
517
  replaceWith: function(newContent){
404
518
  return this.before(newContent).remove()
405
519
  },
406
- wrap: function(newContent){
407
- return this.each(function(){
408
- $(this).wrapAll($(newContent)[0].cloneNode(false))
520
+ wrap: function(structure){
521
+ var func = isFunction(structure)
522
+ if (this[0] && !func)
523
+ var dom = $(structure).get(0),
524
+ clone = dom.parentNode || this.length > 1
525
+
526
+ return this.each(function(index){
527
+ $(this).wrapAll(
528
+ func ? structure.call(this, index) :
529
+ clone ? dom.cloneNode(true) : dom
530
+ )
409
531
  })
410
532
  },
411
- wrapAll: function(newContent){
533
+ wrapAll: function(structure){
412
534
  if (this[0]) {
413
- $(this[0]).before(newContent = $(newContent))
414
- newContent.append(this)
535
+ $(this[0]).before(structure = $(structure))
536
+ var children
537
+ // drill down to the inmost element
538
+ while ((children = structure.children()).length) structure = children.first()
539
+ $(structure).append(this)
415
540
  }
416
541
  return this
417
542
  },
543
+ wrapInner: function(structure){
544
+ var func = isFunction(structure)
545
+ return this.each(function(index){
546
+ var self = $(this), contents = self.contents(),
547
+ dom = func ? structure.call(this, index) : structure
548
+ contents.length ? contents.wrapAll(dom) : self.append(dom)
549
+ })
550
+ },
418
551
  unwrap: function(){
419
552
  this.parent().each(function(){
420
553
  $(this).replaceWith($(this).children())
@@ -422,16 +555,19 @@ var Zepto = (function() {
422
555
  return this
423
556
  },
424
557
  clone: function(){
425
- return $(this.map(function(){ return this.cloneNode(true) }))
558
+ return this.map(function(){ return this.cloneNode(true) })
426
559
  },
427
560
  hide: function(){
428
561
  return this.css("display", "none")
429
562
  },
430
563
  toggle: function(setting){
431
- return (setting === undefined ? this.css("display") == "none" : setting) ? this.show() : this.hide()
564
+ return this.each(function(){
565
+ var el = $(this)
566
+ ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide()
567
+ })
432
568
  },
433
- prev: function(){ return $(this.pluck('previousElementSibling')) },
434
- next: function(){ return $(this.pluck('nextElementSibling')) },
569
+ prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },
570
+ next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },
435
571
  html: function(html){
436
572
  return html === undefined ?
437
573
  (this.length > 0 ? this[0].innerHTML : null) :
@@ -454,60 +590,73 @@ var Zepto = (function() {
454
590
  ) :
455
591
  this.each(function(idx){
456
592
  if (this.nodeType !== 1) return
457
- if (isObject(name)) for (key in name) this.setAttribute(key, name[key])
458
- else this.setAttribute(name, funcArg(this, value, idx, this.getAttribute(name)))
593
+ if (isObject(name)) for (key in name) setAttribute(this, key, name[key])
594
+ else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))
459
595
  })
460
596
  },
461
597
  removeAttr: function(name){
462
- return this.each(function(){ if (this.nodeType === 1) this.removeAttribute(name) })
598
+ return this.each(function(){ this.nodeType === 1 && setAttribute(this, name) })
463
599
  },
464
600
  prop: function(name, value){
465
601
  return (value === undefined) ?
466
- (this[0] ? this[0][name] : undefined) :
602
+ (this[0] && this[0][name]) :
467
603
  this.each(function(idx){
468
604
  this[name] = funcArg(this, value, idx, this[name])
469
605
  })
470
606
  },
471
607
  data: function(name, value){
472
608
  var data = this.attr('data-' + dasherize(name), value)
473
- return data !== null ? data : undefined
609
+ return data !== null ? deserializeValue(data) : undefined
474
610
  },
475
611
  val: function(value){
476
612
  return (value === undefined) ?
477
- (this.length > 0 ? this[0].value : undefined) :
613
+ (this[0] && (this[0].multiple ?
614
+ $(this[0]).find('option').filter(function(o){ return this.selected }).pluck('value') :
615
+ this[0].value)
616
+ ) :
478
617
  this.each(function(idx){
479
618
  this.value = funcArg(this, value, idx, this.value)
480
619
  })
481
620
  },
482
- offset: function(){
621
+ offset: function(coordinates){
622
+ if (coordinates) return this.each(function(index){
623
+ var $this = $(this),
624
+ coords = funcArg(this, coordinates, index, $this.offset()),
625
+ parentOffset = $this.offsetParent().offset(),
626
+ props = {
627
+ top: coords.top - parentOffset.top,
628
+ left: coords.left - parentOffset.left
629
+ }
630
+
631
+ if ($this.css('position') == 'static') props['position'] = 'relative'
632
+ $this.css(props)
633
+ })
483
634
  if (this.length==0) return null
484
635
  var obj = this[0].getBoundingClientRect()
485
636
  return {
486
637
  left: obj.left + window.pageXOffset,
487
638
  top: obj.top + window.pageYOffset,
488
- width: obj.width,
489
- height: obj.height
639
+ width: Math.round(obj.width),
640
+ height: Math.round(obj.height)
490
641
  }
491
642
  },
492
643
  css: function(property, value){
493
- if (value === undefined && typeof property == 'string')
494
- return (
495
- this.length == 0
496
- ? undefined
497
- : this[0].style[camelize(property)] || getComputedStyle(this[0], '').getPropertyValue(property))
644
+ if (arguments.length < 2 && typeof property == 'string')
645
+ return this[0] && (this[0].style[camelize(property)] || getComputedStyle(this[0], '').getPropertyValue(property))
498
646
 
499
647
  var css = ''
500
- for (key in property)
501
- if(typeof property[key] == 'string' && property[key] == '')
502
- this.each(function(){ this.style.removeProperty(dasherize(key)) })
503
- else
504
- css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'
505
-
506
- if (typeof property == 'string')
507
- if (value == '')
648
+ if (type(property) == 'string') {
649
+ if (!value && value !== 0)
508
650
  this.each(function(){ this.style.removeProperty(dasherize(property)) })
509
651
  else
510
652
  css = dasherize(property) + ":" + maybeAddPx(property, value)
653
+ } else {
654
+ for (key in property)
655
+ if (!property[key] && property[key] !== 0)
656
+ this.each(function(){ this.style.removeProperty(dasherize(key)) })
657
+ else
658
+ css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'
659
+ }
511
660
 
512
661
  return this.each(function(){ this.style.cssText += ';' + css })
513
662
  },
@@ -515,63 +664,97 @@ var Zepto = (function() {
515
664
  return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])
516
665
  },
517
666
  hasClass: function(name){
518
- if (this.length < 1) return false
519
- else return classRE(name).test(this[0].className)
667
+ return emptyArray.some.call(this, function(el){
668
+ return this.test(className(el))
669
+ }, classRE(name))
520
670
  },
521
671
  addClass: function(name){
522
672
  return this.each(function(idx){
523
673
  classList = []
524
- var cls = this.className, newName = funcArg(this, name, idx, cls)
674
+ var cls = className(this), newName = funcArg(this, name, idx, cls)
525
675
  newName.split(/\s+/g).forEach(function(klass){
526
676
  if (!$(this).hasClass(klass)) classList.push(klass)
527
677
  }, this)
528
- classList.length && (this.className += (cls ? " " : "") + classList.join(" "))
678
+ classList.length && className(this, cls + (cls ? " " : "") + classList.join(" "))
529
679
  })
530
680
  },
531
681
  removeClass: function(name){
532
682
  return this.each(function(idx){
533
- if (name === undefined)
534
- return this.className = ''
535
- classList = this.className
683
+ if (name === undefined) return className(this, '')
684
+ classList = className(this)
536
685
  funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){
537
686
  classList = classList.replace(classRE(klass), " ")
538
687
  })
539
- this.className = classList.trim()
688
+ className(this, classList.trim())
540
689
  })
541
690
  },
542
691
  toggleClass: function(name, when){
543
692
  return this.each(function(idx){
544
- var newName = funcArg(this, name, idx, this.className)
545
- ;(when === undefined ? !$(this).hasClass(newName) : when) ?
546
- $(this).addClass(newName) : $(this).removeClass(newName)
693
+ var $this = $(this), names = funcArg(this, name, idx, className(this))
694
+ names.split(/\s+/g).forEach(function(klass){
695
+ (when === undefined ? !$this.hasClass(klass) : when) ?
696
+ $this.addClass(klass) : $this.removeClass(klass)
697
+ })
698
+ })
699
+ },
700
+ scrollTop: function(){
701
+ if (!this.length) return
702
+ return ('scrollTop' in this[0]) ? this[0].scrollTop : this[0].scrollY
703
+ },
704
+ position: function() {
705
+ if (!this.length) return
706
+
707
+ var elem = this[0],
708
+ // Get *real* offsetParent
709
+ offsetParent = this.offsetParent(),
710
+ // Get correct offsets
711
+ offset = this.offset(),
712
+ parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset()
713
+
714
+ // Subtract element margins
715
+ // note: when an element has margin: auto the offsetLeft and marginLeft
716
+ // are the same in Safari causing offset.left to incorrectly be 0
717
+ offset.top -= parseFloat( $(elem).css('margin-top') ) || 0
718
+ offset.left -= parseFloat( $(elem).css('margin-left') ) || 0
719
+
720
+ // Add offsetParent borders
721
+ parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0
722
+ parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0
723
+
724
+ // Subtract the two offsets
725
+ return {
726
+ top: offset.top - parentOffset.top,
727
+ left: offset.left - parentOffset.left
728
+ }
729
+ },
730
+ offsetParent: function() {
731
+ return this.map(function(){
732
+ var parent = this.offsetParent || document.body
733
+ while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static")
734
+ parent = parent.offsetParent
735
+ return parent
547
736
  })
548
737
  }
549
738
  }
550
739
 
740
+ // for now
741
+ $.fn.detach = $.fn.remove
742
+
551
743
  // Generate the `width` and `height` functions
552
744
  ;['width', 'height'].forEach(function(dimension){
553
745
  $.fn[dimension] = function(value){
554
- var offset, Dimension = dimension.replace(/./, function(m){ return m[0].toUpperCase() })
555
- if (value === undefined) return this[0] == window ? window['inner' + Dimension] :
556
- this[0] == document ? document.documentElement['offset' + Dimension] :
746
+ var offset, el = this[0],
747
+ Dimension = dimension.replace(/./, function(m){ return m[0].toUpperCase() })
748
+ if (value === undefined) return isWindow(el) ? el['inner' + Dimension] :
749
+ isDocument(el) ? el.documentElement['offset' + Dimension] :
557
750
  (offset = this.offset()) && offset[dimension]
558
751
  else return this.each(function(idx){
559
- var el = $(this)
752
+ el = $(this)
560
753
  el.css(dimension, funcArg(this, value, idx, el[dimension]()))
561
754
  })
562
755
  }
563
756
  })
564
757
 
565
- function insert(operator, target, node) {
566
- var parent = (operator % 2) ? target : target.parentNode
567
- parent ? parent.insertBefore(node,
568
- !operator ? target.nextSibling : // after
569
- operator == 1 ? parent.firstChild : // prepend
570
- operator == 2 ? target : // before
571
- null) : // append
572
- $(node).remove()
573
- }
574
-
575
758
  function traverseNode(node, fun) {
576
759
  fun(node)
577
760
  for (var key in node.childNodes) traverseNode(node.childNodes[key], fun)
@@ -579,28 +762,47 @@ var Zepto = (function() {
579
762
 
580
763
  // Generate the `after`, `prepend`, `before`, `append`,
581
764
  // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.
582
- adjacencyOperators.forEach(function(key, operator) {
583
- $.fn[key] = function(){
765
+ adjacencyOperators.forEach(function(operator, operatorIndex) {
766
+ var inside = operatorIndex % 2 //=> prepend, append
767
+
768
+ $.fn[operator] = function(){
584
769
  // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
585
- var nodes = $.map(arguments, function(n){ return isObject(n) ? n : zepto.fragment(n) })
770
+ var argType, nodes = $.map(arguments, function(arg) {
771
+ argType = type(arg)
772
+ return argType == "object" || argType == "array" || arg == null ?
773
+ arg : zepto.fragment(arg)
774
+ }),
775
+ parent, copyByClone = this.length > 1
586
776
  if (nodes.length < 1) return this
587
- var size = this.length, copyByClone = size > 1, inReverse = operator < 2
588
-
589
- return this.each(function(index, target){
590
- for (var i = 0; i < nodes.length; i++) {
591
- var node = nodes[inReverse ? nodes.length-i-1 : i]
592
- traverseNode(node, function(node){
593
- if (node.nodeName != null && node.nodeName.toUpperCase() === 'SCRIPT' && (!node.type || node.type === 'text/javascript'))
594
- window['eval'].call(window, node.innerHTML)
777
+
778
+ return this.each(function(_, target){
779
+ parent = inside ? target : target.parentNode
780
+
781
+ // convert all methods to a "before" operation
782
+ target = operatorIndex == 0 ? target.nextSibling :
783
+ operatorIndex == 1 ? target.firstChild :
784
+ operatorIndex == 2 ? target :
785
+ null
786
+
787
+ nodes.forEach(function(node){
788
+ if (copyByClone) node = node.cloneNode(true)
789
+ else if (!parent) return $(node).remove()
790
+
791
+ traverseNode(parent.insertBefore(node, target), function(el){
792
+ if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
793
+ (!el.type || el.type === 'text/javascript') && !el.src)
794
+ window['eval'].call(window, el.innerHTML)
595
795
  })
596
- if (copyByClone && index < size - 1) node = node.cloneNode(true)
597
- insert(operator, target, node)
598
- }
796
+ })
599
797
  })
600
798
  }
601
799
 
602
- $.fn[(operator % 2) ? key+'To' : 'insert'+(operator ? 'Before' : 'After')] = function(html){
603
- $(html)[key](this)
800
+ // after => insertAfter
801
+ // prepend => prependTo
802
+ // before => insertBefore
803
+ // append => appendTo
804
+ $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){
805
+ $(html)[operator](this)
604
806
  return this
605
807
  }
606
808
  })
@@ -608,18 +810,71 @@ var Zepto = (function() {
608
810
  zepto.Z.prototype = $.fn
609
811
 
610
812
  // Export internal API functions in the `$.zepto` namespace
611
- zepto.camelize = camelize
612
813
  zepto.uniq = uniq
814
+ zepto.deserializeValue = deserializeValue
613
815
  $.zepto = zepto
614
816
 
615
817
  return $
616
818
  })()
617
819
 
618
- // If `$` is not yet defined, point it to `Zepto`
619
820
  window.Zepto = Zepto
620
821
  '$' in window || (window.$ = Zepto)
822
+
621
823
  ;(function($){
622
- var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={}
824
+ function detect(ua){
825
+ var os = this.os = {}, browser = this.browser = {},
826
+ webkit = ua.match(/WebKit\/([\d.]+)/),
827
+ android = ua.match(/(Android)\s+([\d.]+)/),
828
+ ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
829
+ iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
830
+ webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
831
+ touchpad = webos && ua.match(/TouchPad/),
832
+ kindle = ua.match(/Kindle\/([\d.]+)/),
833
+ silk = ua.match(/Silk\/([\d._]+)/),
834
+ blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/),
835
+ bb10 = ua.match(/(BB10).*Version\/([\d.]+)/),
836
+ rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
837
+ playbook = ua.match(/PlayBook/),
838
+ chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
839
+ firefox = ua.match(/Firefox\/([\d.]+)/)
840
+
841
+ // Todo: clean this up with a better OS/browser seperation:
842
+ // - discern (more) between multiple browsers on android
843
+ // - decide if kindle fire in silk mode is android or not
844
+ // - Firefox on Android doesn't specify the Android version
845
+ // - possibly devide in os, device and browser hashes
846
+
847
+ if (browser.webkit = !!webkit) browser.version = webkit[1]
848
+
849
+ if (android) os.android = true, os.version = android[2]
850
+ if (iphone) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
851
+ if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
852
+ if (webos) os.webos = true, os.version = webos[2]
853
+ if (touchpad) os.touchpad = true
854
+ if (blackberry) os.blackberry = true, os.version = blackberry[2]
855
+ if (bb10) os.bb10 = true, os.version = bb10[2]
856
+ if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2]
857
+ if (playbook) browser.playbook = true
858
+ if (kindle) os.kindle = true, os.version = kindle[1]
859
+ if (silk) browser.silk = true, browser.version = silk[1]
860
+ if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true
861
+ if (chrome) browser.chrome = true, browser.version = chrome[1]
862
+ if (firefox) browser.firefox = true, browser.version = firefox[1]
863
+
864
+ os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) || (firefox && ua.match(/Tablet/)))
865
+ os.phone = !!(!os.tablet && (android || iphone || webos || blackberry || bb10 ||
866
+ (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) || (firefox && ua.match(/Mobile/))))
867
+ }
868
+
869
+ detect.call($, navigator.userAgent)
870
+ // make available to unit tests
871
+ $.__detect = detect
872
+
873
+ })(Zepto)
874
+
875
+ ;(function($){
876
+ var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={},
877
+ hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
623
878
 
624
879
  specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
625
880
 
@@ -646,32 +901,50 @@ window.Zepto = Zepto
646
901
  }
647
902
 
648
903
  function eachEvent(events, fn, iterator){
649
- if ($.isObject(events)) $.each(events, iterator)
904
+ if ($.type(events) != "string") $.each(events, iterator)
650
905
  else events.split(/\s/).forEach(function(type){ iterator(type, fn) })
651
906
  }
652
907
 
908
+ function eventCapture(handler, captureSetting) {
909
+ return handler.del &&
910
+ (handler.e == 'focus' || handler.e == 'blur') ||
911
+ !!captureSetting
912
+ }
913
+
914
+ function realEvent(type) {
915
+ return hover[type] || type
916
+ }
917
+
653
918
  function add(element, events, fn, selector, getDelegate, capture){
654
- capture = !!capture
655
919
  var id = zid(element), set = (handlers[id] || (handlers[id] = []))
656
920
  eachEvent(events, fn, function(event, fn){
657
- var delegate = getDelegate && getDelegate(fn, event),
658
- callback = delegate || fn
659
- var proxyfn = function (event) {
660
- var result = callback.apply(element, [event].concat(event.data))
661
- if (result === false) event.preventDefault()
921
+ var handler = parse(event)
922
+ handler.fn = fn
923
+ handler.sel = selector
924
+ // emulate mouseenter, mouseleave
925
+ if (handler.e in hover) fn = function(e){
926
+ var related = e.relatedTarget
927
+ if (!related || (related !== this && !$.contains(this, related)))
928
+ return handler.fn.apply(this, arguments)
929
+ }
930
+ handler.del = getDelegate && getDelegate(fn, event)
931
+ var callback = handler.del || fn
932
+ handler.proxy = function (e) {
933
+ var result = callback.apply(element, [e].concat(e.data))
934
+ if (result === false) e.preventDefault(), e.stopPropagation()
662
935
  return result
663
936
  }
664
- var handler = $.extend(parse(event), {fn: fn, proxy: proxyfn, sel: selector, del: delegate, i: set.length})
937
+ handler.i = set.length
665
938
  set.push(handler)
666
- element.addEventListener(handler.e, proxyfn, capture)
939
+ element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
667
940
  })
668
941
  }
669
- function remove(element, events, fn, selector){
942
+ function remove(element, events, fn, selector, capture){
670
943
  var id = zid(element)
671
944
  eachEvent(events || '', fn, function(event, fn){
672
945
  findHandlers(element, event, fn, selector).forEach(function(handler){
673
946
  delete handlers[id][handler.i]
674
- element.removeEventListener(handler.e, handler.proxy, false)
947
+ element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
675
948
  })
676
949
  })
677
950
  }
@@ -714,13 +987,17 @@ window.Zepto = Zepto
714
987
 
715
988
  var returnTrue = function(){return true},
716
989
  returnFalse = function(){return false},
990
+ ignoreProperties = /^([A-Z]|layer[XY]$)/,
717
991
  eventMethods = {
718
992
  preventDefault: 'isDefaultPrevented',
719
993
  stopImmediatePropagation: 'isImmediatePropagationStopped',
720
994
  stopPropagation: 'isPropagationStopped'
721
995
  }
722
996
  function createProxy(event) {
723
- var proxy = $.extend({originalEvent: event}, event)
997
+ var key, proxy = { originalEvent: event }
998
+ for (key in event)
999
+ if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
1000
+
724
1001
  $.each(eventMethods, function(name, predicate) {
725
1002
  proxy[name] = function(){
726
1003
  this[predicate] = returnTrue
@@ -744,14 +1021,6 @@ window.Zepto = Zepto
744
1021
  }
745
1022
 
746
1023
  $.fn.delegate = function(selector, event, callback){
747
- var capture = false
748
- if(event == 'blur' || event == 'focus'){
749
- if($.iswebkit)
750
- event = event == 'blur' ? 'focusout' : event == 'focus' ? 'focusin' : event
751
- else
752
- capture = true
753
- }
754
-
755
1024
  return this.each(function(i, element){
756
1025
  add(element, event, callback, selector, function(fn){
757
1026
  return function(e){
@@ -761,7 +1030,7 @@ window.Zepto = Zepto
761
1030
  return fn.apply(match, [evt].concat([].slice.call(arguments, 1)))
762
1031
  }
763
1032
  }
764
- }, capture)
1033
+ })
765
1034
  })
766
1035
  }
767
1036
  $.fn.undelegate = function(selector, event, callback){
@@ -780,16 +1049,16 @@ window.Zepto = Zepto
780
1049
  }
781
1050
 
782
1051
  $.fn.on = function(event, selector, callback){
783
- return selector == undefined || $.isFunction(selector) ?
784
- this.bind(event, selector) : this.delegate(selector, event, callback)
1052
+ return !selector || $.isFunction(selector) ?
1053
+ this.bind(event, selector || callback) : this.delegate(selector, event, callback)
785
1054
  }
786
1055
  $.fn.off = function(event, selector, callback){
787
- return selector == undefined || $.isFunction(selector) ?
788
- this.unbind(event, selector) : this.undelegate(selector, event, callback)
1056
+ return !selector || $.isFunction(selector) ?
1057
+ this.unbind(event, selector || callback) : this.undelegate(selector, event, callback)
789
1058
  }
790
1059
 
791
1060
  $.fn.trigger = function(event, data){
792
- if (typeof event == 'string') event = $.Event(event)
1061
+ if (typeof event == 'string' || $.isPlainObject(event)) event = $.Event(event)
793
1062
  fix(event)
794
1063
  event.data = data
795
1064
  return this.each(function(){
@@ -817,153 +1086,39 @@ window.Zepto = Zepto
817
1086
 
818
1087
  // shortcut methods for `.bind(event, fn)` for each event type
819
1088
  ;('focusin focusout load resize scroll unload click dblclick '+
820
- 'mousedown mouseup mousemove mouseover mouseout '+
1089
+ 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
821
1090
  'change select keydown keypress keyup error').split(' ').forEach(function(event) {
822
- $.fn[event] = function(callback){ return this.bind(event, callback) }
1091
+ $.fn[event] = function(callback) {
1092
+ return callback ?
1093
+ this.bind(event, callback) :
1094
+ this.trigger(event)
1095
+ }
823
1096
  })
824
1097
 
825
1098
  ;['focus', 'blur'].forEach(function(name) {
826
1099
  $.fn[name] = function(callback) {
827
1100
  if (callback) this.bind(name, callback)
828
- else if (this.length) try { this.get(0)[name]() } catch(e){}
1101
+ else this.each(function(){
1102
+ try { this[name]() }
1103
+ catch(e) {}
1104
+ })
829
1105
  return this
830
1106
  }
831
1107
  })
832
1108
 
833
1109
  $.Event = function(type, props) {
1110
+ if (typeof type != 'string') props = type, type = props.type
834
1111
  var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
835
1112
  if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
836
1113
  event.initEvent(type, bubbles, true, null, null, null, null, null, null, null, null, null, null, null, null)
1114
+ event.isDefaultPrevented = function(){ return this.defaultPrevented }
837
1115
  return event
838
1116
  }
839
1117
 
840
1118
  })(Zepto)
841
- ;(function($){
842
- function detect(ua){
843
- var os = this.os = {}, browser = this.browser = {},
844
- webkit = ua.match(/WebKit\/([\d.]+)/),
845
- android = ua.match(/(Android)\s+([\d.]+)/),
846
- ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
847
- iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
848
- webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
849
- touchpad = webos && ua.match(/TouchPad/),
850
- kindle = ua.match(/Kindle\/([\d.]+)/),
851
- silk = ua.match(/Silk\/([\d._]+)/),
852
- blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/)
853
-
854
- // todo clean this up with a better OS/browser
855
- // separation. we need to discern between multiple
856
- // browsers on android, and decide if kindle fire in
857
- // silk mode is android or not
858
-
859
- if (browser.webkit = !!webkit) browser.version = webkit[1]
860
1119
 
861
- if (android) os.android = true, os.version = android[2]
862
- if (iphone) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
863
- if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
864
- if (webos) os.webos = true, os.version = webos[2]
865
- if (touchpad) os.touchpad = true
866
- if (blackberry) os.blackberry = true, os.version = blackberry[2]
867
- if (kindle) os.kindle = true, os.version = kindle[1]
868
- if (silk) browser.silk = true, browser.version = silk[1]
869
- if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true
870
- }
871
-
872
- detect.call($, navigator.userAgent)
873
- // make available to unit tests
874
- $.__detect = detect
875
-
876
- })(Zepto)
877
- ;(function($, undefined){
878
- var prefix = '', eventPrefix, endEventName, endAnimationName,
879
- vendors = { Webkit: 'webkit', Moz: '', O: 'o', ms: 'MS' },
880
- document = window.document, testEl = document.createElement('div'),
881
- supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
882
- clearProperties = {}
883
-
884
- function downcase(str) { return str.toLowerCase() }
885
- function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : downcase(name) }
886
-
887
- $.each(vendors, function(vendor, event){
888
- if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
889
- prefix = '-' + downcase(vendor) + '-'
890
- eventPrefix = event
891
- return false
892
- }
893
- })
894
-
895
- clearProperties[prefix + 'transition-property'] =
896
- clearProperties[prefix + 'transition-duration'] =
897
- clearProperties[prefix + 'transition-timing-function'] =
898
- clearProperties[prefix + 'animation-name'] =
899
- clearProperties[prefix + 'animation-duration'] = ''
900
-
901
- $.fx = {
902
- off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),
903
- cssPrefix: prefix,
904
- transitionEnd: normalizeEvent('TransitionEnd'),
905
- animationEnd: normalizeEvent('AnimationEnd')
906
- }
907
-
908
- $.fn.animate = function(properties, duration, ease, callback){
909
- if ($.isObject(duration))
910
- ease = duration.easing, callback = duration.complete, duration = duration.duration
911
- if (duration) duration = duration / 1000
912
- return this.anim(properties, duration, ease, callback)
913
- }
914
-
915
- $.fn.anim = function(properties, duration, ease, callback){
916
- var transforms, cssProperties = {}, key, that = this, wrappedCallback, endEvent = $.fx.transitionEnd
917
- if (duration === undefined) duration = 0.4
918
- if ($.fx.off) duration = 0
919
-
920
- if (typeof properties == 'string') {
921
- // keyframe animation
922
- cssProperties[prefix + 'animation-name'] = properties
923
- cssProperties[prefix + 'animation-duration'] = duration + 's'
924
- endEvent = $.fx.animationEnd
925
- } else {
926
- // CSS transitions
927
- for (key in properties)
928
- if (supportedTransforms.test(key)) {
929
- transforms || (transforms = [])
930
- transforms.push(key + '(' + properties[key] + ')')
931
- }
932
- else cssProperties[key] = properties[key]
933
-
934
- if (transforms) cssProperties[prefix + 'transform'] = transforms.join(' ')
935
- if (!$.fx.off && typeof properties === 'object') {
936
- cssProperties[prefix + 'transition-property'] = Object.keys(properties).join(', ')
937
- cssProperties[prefix + 'transition-duration'] = duration + 's'
938
- cssProperties[prefix + 'transition-timing-function'] = (ease || 'linear')
939
- }
940
- }
941
-
942
- wrappedCallback = function(event){
943
- if (typeof event !== 'undefined') {
944
- if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below"
945
- $(event.target).unbind(endEvent, arguments.callee)
946
- }
947
- $(this).css(clearProperties)
948
- callback && callback.call(this)
949
- }
950
- if (duration > 0) this.bind(endEvent, wrappedCallback)
951
-
952
- setTimeout(function() {
953
- that.css(cssProperties)
954
- if (duration <= 0) setTimeout(function() {
955
- that.each(function(){ wrappedCallback.call(this) })
956
- }, 0)
957
- }, 0)
958
-
959
- return this
960
- }
961
-
962
- testEl = null
963
- })(Zepto)
964
1120
  ;(function($){
965
1121
  var jsonpID = 0,
966
- isObject = $.isObject,
967
1122
  document = window.document,
968
1123
  key,
969
1124
  name,
@@ -1030,35 +1185,42 @@ window.Zepto = Zepto
1030
1185
  function empty() {}
1031
1186
 
1032
1187
  $.ajaxJSONP = function(options){
1188
+ if (!('type' in options)) return $.ajax(options)
1189
+
1033
1190
  var callbackName = 'jsonp' + (++jsonpID),
1034
1191
  script = document.createElement('script'),
1035
- abort = function(){
1192
+ cleanup = function() {
1193
+ clearTimeout(abortTimeout)
1036
1194
  $(script).remove()
1037
- if (callbackName in window) window[callbackName] = empty
1038
- ajaxComplete('abort', xhr, options)
1195
+ delete window[callbackName]
1196
+ },
1197
+ abort = function(type){
1198
+ cleanup()
1199
+ // In case of manual abort or timeout, keep an empty function as callback
1200
+ // so that the SCRIPT tag that eventually loads won't result in an error.
1201
+ if (!type || type == 'timeout') window[callbackName] = empty
1202
+ ajaxError(null, type || 'abort', xhr, options)
1039
1203
  },
1040
1204
  xhr = { abort: abort }, abortTimeout
1041
1205
 
1042
- if (options.error) script.onerror = function() {
1043
- xhr.abort()
1044
- options.error()
1206
+ if (ajaxBeforeSend(xhr, options) === false) {
1207
+ abort('abort')
1208
+ return false
1045
1209
  }
1046
1210
 
1047
1211
  window[callbackName] = function(data){
1048
- clearTimeout(abortTimeout)
1049
- $(script).remove()
1050
- delete window[callbackName]
1212
+ cleanup()
1051
1213
  ajaxSuccess(data, xhr, options)
1052
1214
  }
1053
1215
 
1054
- serializeData(options)
1216
+ script.onerror = function() { abort('error') }
1217
+
1055
1218
  script.src = options.url.replace(/=\?/, '=' + callbackName)
1056
1219
  $('head').append(script)
1057
1220
 
1058
1221
  if (options.timeout > 0) abortTimeout = setTimeout(function(){
1059
- xhr.abort()
1060
- ajaxComplete('timeout', xhr, options)
1061
- }, options.timeout)
1222
+ abort('timeout')
1223
+ }, options.timeout)
1062
1224
 
1063
1225
  return xhr
1064
1226
  }
@@ -1093,10 +1255,15 @@ window.Zepto = Zepto
1093
1255
  // Whether the request is to another domain
1094
1256
  crossDomain: false,
1095
1257
  // Default timeout
1096
- timeout: 0
1258
+ timeout: 0,
1259
+ // Whether data should be serialized to string
1260
+ processData: true,
1261
+ // Whether the browser should be allowed to cache GET responses
1262
+ cache: true,
1097
1263
  }
1098
1264
 
1099
1265
  function mimeToDataType(mime) {
1266
+ if (mime) mime = mime.split(';', 2)[0]
1100
1267
  return mime && ( mime == htmlType ? 'html' :
1101
1268
  mime == jsonType ? 'json' :
1102
1269
  scriptTypeRE.test(mime) ? 'script' :
@@ -1109,7 +1276,8 @@ window.Zepto = Zepto
1109
1276
 
1110
1277
  // serialize payload and append it to the URL for GET requests
1111
1278
  function serializeData(options) {
1112
- if (isObject(options.data)) options.data = $.param(options.data)
1279
+ if (options.processData && options.data && $.type(options.data) != "string")
1280
+ options.data = $.param(options.data, options.traditional)
1113
1281
  if (options.data && (!options.type || options.type.toUpperCase() == 'GET'))
1114
1282
  options.url = appendQuery(options.url, options.data)
1115
1283
  }
@@ -1123,19 +1291,20 @@ window.Zepto = Zepto
1123
1291
  if (!settings.crossDomain) settings.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(settings.url) &&
1124
1292
  RegExp.$2 != window.location.host
1125
1293
 
1294
+ if (!settings.url) settings.url = window.location.toString()
1295
+ serializeData(settings)
1296
+ if (settings.cache === false) settings.url = appendQuery(settings.url, '_=' + Date.now())
1297
+
1126
1298
  var dataType = settings.dataType, hasPlaceholder = /=\?/.test(settings.url)
1127
1299
  if (dataType == 'jsonp' || hasPlaceholder) {
1128
1300
  if (!hasPlaceholder) settings.url = appendQuery(settings.url, 'callback=?')
1129
1301
  return $.ajaxJSONP(settings)
1130
1302
  }
1131
1303
 
1132
- if (!settings.url) settings.url = window.location.toString()
1133
- serializeData(settings)
1134
-
1135
1304
  var mime = settings.accepts[dataType],
1136
1305
  baseHeaders = { },
1137
1306
  protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol,
1138
- xhr = $.ajaxSettings.xhr(), abortTimeout
1307
+ xhr = settings.xhr(), abortTimeout
1139
1308
 
1140
1309
  if (!settings.crossDomain) baseHeaders['X-Requested-With'] = 'XMLHttpRequest'
1141
1310
  if (mime) {
@@ -1143,12 +1312,13 @@ window.Zepto = Zepto
1143
1312
  if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0]
1144
1313
  xhr.overrideMimeType && xhr.overrideMimeType(mime)
1145
1314
  }
1146
- if (settings.contentType || (settings.data && settings.type.toUpperCase() != 'GET'))
1315
+ if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET'))
1147
1316
  baseHeaders['Content-Type'] = (settings.contentType || 'application/x-www-form-urlencoded')
1148
1317
  settings.headers = $.extend(baseHeaders, settings.headers || {})
1149
1318
 
1150
1319
  xhr.onreadystatechange = function(){
1151
1320
  if (xhr.readyState == 4) {
1321
+ xhr.onreadystatechange = empty;
1152
1322
  clearTimeout(abortTimeout)
1153
1323
  var result, error = false
1154
1324
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {
@@ -1156,15 +1326,16 @@ window.Zepto = Zepto
1156
1326
  result = xhr.responseText
1157
1327
 
1158
1328
  try {
1329
+ // http://perfectionkills.com/global-eval-what-are-the-options/
1159
1330
  if (dataType == 'script') (1,eval)(result)
1160
1331
  else if (dataType == 'xml') result = xhr.responseXML
1161
- else if (dataType == 'json') result = blankRE.test(result) ? null : JSON.parse(result)
1332
+ else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result)
1162
1333
  } catch (e) { error = e }
1163
1334
 
1164
1335
  if (error) ajaxError(error, 'parsererror', xhr, settings)
1165
1336
  else ajaxSuccess(result, xhr, settings)
1166
1337
  } else {
1167
- ajaxError(null, 'error', xhr, settings)
1338
+ ajaxError(null, xhr.status ? 'error' : 'abort', xhr, settings)
1168
1339
  }
1169
1340
  }
1170
1341
  }
@@ -1190,40 +1361,60 @@ window.Zepto = Zepto
1190
1361
  return xhr
1191
1362
  }
1192
1363
 
1193
- $.get = function(url, success){ return $.ajax({ url: url, success: success }) }
1364
+ // handle optional data/success arguments
1365
+ function parseArguments(url, data, success, dataType) {
1366
+ var hasData = !$.isFunction(data)
1367
+ return {
1368
+ url: url,
1369
+ data: hasData ? data : undefined,
1370
+ success: !hasData ? data : $.isFunction(success) ? success : undefined,
1371
+ dataType: hasData ? dataType || success : success
1372
+ }
1373
+ }
1374
+
1375
+ $.get = function(url, data, success, dataType){
1376
+ return $.ajax(parseArguments.apply(null, arguments))
1377
+ }
1194
1378
 
1195
1379
  $.post = function(url, data, success, dataType){
1196
- if ($.isFunction(data)) dataType = dataType || success, success = data, data = null
1197
- return $.ajax({ type: 'POST', url: url, data: data, success: success, dataType: dataType })
1380
+ var options = parseArguments.apply(null, arguments)
1381
+ options.type = 'POST'
1382
+ return $.ajax(options)
1198
1383
  }
1199
1384
 
1200
- $.getJSON = function(url, success){
1201
- return $.ajax({ url: url, success: success, dataType: 'json' })
1385
+ $.getJSON = function(url, data, success){
1386
+ var options = parseArguments.apply(null, arguments)
1387
+ options.dataType = 'json'
1388
+ return $.ajax(options)
1202
1389
  }
1203
1390
 
1204
- $.fn.load = function(url, success){
1391
+ $.fn.load = function(url, data, success){
1205
1392
  if (!this.length) return this
1206
- var self = this, parts = url.split(/\s/), selector
1207
- if (parts.length > 1) url = parts[0], selector = parts[1]
1208
- $.get(url, function(response){
1393
+ var self = this, parts = url.split(/\s/), selector,
1394
+ options = parseArguments(url, data, success),
1395
+ callback = options.success
1396
+ if (parts.length > 1) options.url = parts[0], selector = parts[1]
1397
+ options.success = function(response){
1209
1398
  self.html(selector ?
1210
- $(document.createElement('div')).html(response.replace(rscript, "")).find(selector).html()
1399
+ $('<div>').html(response.replace(rscript, "")).find(selector)
1211
1400
  : response)
1212
- success && success.call(self)
1213
- })
1401
+ callback && callback.apply(self, arguments)
1402
+ }
1403
+ $.ajax(options)
1214
1404
  return this
1215
1405
  }
1216
1406
 
1217
1407
  var escape = encodeURIComponent
1218
1408
 
1219
1409
  function serialize(params, obj, traditional, scope){
1220
- var array = $.isArray(obj)
1410
+ var type, array = $.isArray(obj)
1221
1411
  $.each(obj, function(key, value) {
1412
+ type = $.type(value)
1222
1413
  if (scope) key = traditional ? scope : scope + '[' + (array ? '' : key) + ']'
1223
1414
  // handle data in serializeArray() format
1224
1415
  if (!scope && array) params.add(value.name, value.value)
1225
1416
  // recurse into nested objects
1226
- else if (traditional ? $.isArray(value) : isObject(value))
1417
+ else if (type == "array" || (!traditional && type == "object"))
1227
1418
  serialize(params, value, traditional, key)
1228
1419
  else params.add(key, value)
1229
1420
  })
@@ -1233,9 +1424,10 @@ window.Zepto = Zepto
1233
1424
  var params = []
1234
1425
  params.add = function(k, v){ this.push(escape(k) + '=' + escape(v)) }
1235
1426
  serialize(params, obj, traditional)
1236
- return params.join('&').replace('%20', '+')
1427
+ return params.join('&').replace(/%20/g, '+')
1237
1428
  }
1238
1429
  })(Zepto)
1430
+
1239
1431
  ;(function ($) {
1240
1432
  $.fn.serializeArray = function () {
1241
1433
  var result = [], el
@@ -1272,84 +1464,102 @@ window.Zepto = Zepto
1272
1464
  }
1273
1465
 
1274
1466
  })(Zepto)
1275
- ;(function($){
1276
- var touch = {}, touchTimeout
1277
1467
 
1278
- function parentIfText(node){
1279
- return 'tagName' in node ? node : node.parentNode
1468
+ ;(function($, undefined){
1469
+ var prefix = '', eventPrefix, endEventName, endAnimationName,
1470
+ vendors = { Webkit: 'webkit', Moz: '', O: 'o', ms: 'MS' },
1471
+ document = window.document, testEl = document.createElement('div'),
1472
+ supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
1473
+ transform,
1474
+ transitionProperty, transitionDuration, transitionTiming,
1475
+ animationName, animationDuration, animationTiming,
1476
+ cssReset = {}
1477
+
1478
+ function dasherize(str) { return downcase(str.replace(/([a-z])([A-Z])/, '$1-$2')) }
1479
+ function downcase(str) { return str.toLowerCase() }
1480
+ function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : downcase(name) }
1481
+
1482
+ $.each(vendors, function(vendor, event){
1483
+ if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
1484
+ prefix = '-' + downcase(vendor) + '-'
1485
+ eventPrefix = event
1486
+ return false
1487
+ }
1488
+ })
1489
+
1490
+ transform = prefix + 'transform'
1491
+ cssReset[transitionProperty = prefix + 'transition-property'] =
1492
+ cssReset[transitionDuration = prefix + 'transition-duration'] =
1493
+ cssReset[transitionTiming = prefix + 'transition-timing-function'] =
1494
+ cssReset[animationName = prefix + 'animation-name'] =
1495
+ cssReset[animationDuration = prefix + 'animation-duration'] =
1496
+ cssReset[animationTiming = prefix + 'animation-timing-function'] = ''
1497
+
1498
+ $.fx = {
1499
+ off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),
1500
+ speeds: { _default: 400, fast: 200, slow: 600 },
1501
+ cssPrefix: prefix,
1502
+ transitionEnd: normalizeEvent('TransitionEnd'),
1503
+ animationEnd: normalizeEvent('AnimationEnd')
1280
1504
  }
1281
1505
 
1282
- function swipeDirection(x1, x2, y1, y2){
1283
- var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
1284
- return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
1506
+ $.fn.animate = function(properties, duration, ease, callback){
1507
+ if ($.isPlainObject(duration))
1508
+ ease = duration.easing, callback = duration.complete, duration = duration.duration
1509
+ if (duration) duration = (typeof duration == 'number' ? duration :
1510
+ ($.fx.speeds[duration] || $.fx.speeds._default)) / 1000
1511
+ return this.anim(properties, duration, ease, callback)
1285
1512
  }
1286
1513
 
1287
- var longTapDelay = 750, longTapTimeout
1514
+ $.fn.anim = function(properties, duration, ease, callback){
1515
+ var key, cssValues = {}, cssProperties, transforms = '',
1516
+ that = this, wrappedCallback, endEvent = $.fx.transitionEnd
1517
+
1518
+ if (duration === undefined) duration = 0.4
1519
+ if ($.fx.off) duration = 0
1288
1520
 
1289
- function longTap(){
1290
- longTapTimeout = null
1291
- if (touch.last) {
1292
- touch.el.trigger('longTap')
1293
- touch = {}
1521
+ if (typeof properties == 'string') {
1522
+ // keyframe animation
1523
+ cssValues[animationName] = properties
1524
+ cssValues[animationDuration] = duration + 's'
1525
+ cssValues[animationTiming] = (ease || 'linear')
1526
+ endEvent = $.fx.animationEnd
1527
+ } else {
1528
+ cssProperties = []
1529
+ // CSS transitions
1530
+ for (key in properties)
1531
+ if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') '
1532
+ else cssValues[key] = properties[key], cssProperties.push(dasherize(key))
1533
+
1534
+ if (transforms) cssValues[transform] = transforms, cssProperties.push(transform)
1535
+ if (duration > 0 && typeof properties === 'object') {
1536
+ cssValues[transitionProperty] = cssProperties.join(', ')
1537
+ cssValues[transitionDuration] = duration + 's'
1538
+ cssValues[transitionTiming] = (ease || 'linear')
1539
+ }
1294
1540
  }
1295
- }
1296
1541
 
1297
- function cancelLongTap(){
1298
- if (longTapTimeout) clearTimeout(longTapTimeout)
1299
- longTapTimeout = null
1300
- }
1301
-
1302
- $(document).ready(function(){
1303
- var now, delta
1304
-
1305
- $(document.body).bind('touchstart', function(e){
1306
- now = Date.now()
1307
- delta = now - (touch.last || now)
1308
- touch.el = $(parentIfText(e.touches[0].target))
1309
- touchTimeout && clearTimeout(touchTimeout)
1310
- touch.x1 = e.touches[0].pageX
1311
- touch.y1 = e.touches[0].pageY
1312
- if (delta > 0 && delta <= 250) touch.isDoubleTap = true
1313
- touch.last = now
1314
- longTapTimeout = setTimeout(longTap, longTapDelay)
1315
- }).bind('touchmove', function(e){
1316
- cancelLongTap()
1317
- touch.x2 = e.touches[0].pageX
1318
- touch.y2 = e.touches[0].pageY
1319
- }).bind('touchend', function(e){
1320
- cancelLongTap()
1321
-
1322
- // double tap (tapped twice within 250ms)
1323
- if (touch.isDoubleTap) {
1324
- touch.el.trigger('doubleTap')
1325
- touch = {}
1326
-
1327
- // swipe
1328
- } else if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
1329
- (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)) {
1330
- touch.el.trigger('swipe') &&
1331
- touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
1332
- touch = {}
1333
-
1334
- // normal tap
1335
- } else if ('last' in touch) {
1336
- touch.el.trigger('tap')
1337
-
1338
- touchTimeout = setTimeout(function(){
1339
- touchTimeout = null
1340
- touch.el.trigger('singleTap')
1341
- touch = {}
1342
- }, 250)
1542
+ wrappedCallback = function(event){
1543
+ if (typeof event !== 'undefined') {
1544
+ if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below"
1545
+ $(event.target).unbind(endEvent, wrappedCallback)
1343
1546
  }
1344
- }).bind('touchcancel', function(){
1345
- if (touchTimeout) clearTimeout(touchTimeout)
1346
- if (longTapTimeout) clearTimeout(longTapTimeout)
1347
- longTapTimeout = touchTimeout = null
1348
- touch = {}
1349
- })
1350
- })
1547
+ $(this).css(cssReset)
1548
+ callback && callback.call(this)
1549
+ }
1550
+ if (duration > 0) this.bind(endEvent, wrappedCallback)
1351
1551
 
1352
- ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){
1353
- $.fn[m] = function(callback){ return this.bind(m, callback) }
1354
- })
1552
+ // trigger page reflow so new elements can animate
1553
+ this.size() && this.get(0).clientLeft
1554
+
1555
+ this.css(cssValues)
1556
+
1557
+ if (duration <= 0) setTimeout(function() {
1558
+ that.each(function(){ wrappedCallback.call(this) })
1559
+ }, 0)
1560
+
1561
+ return this
1562
+ }
1563
+
1564
+ testEl = null
1355
1565
  })(Zepto)