jqmobi-rails 0.0.0
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/.gitignore +17 -0
- data/Gemfile +8 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +68 -0
- data/jqmobi-rails.gemspec +17 -0
- data/lib/jqmobi/rails/engine.rb +6 -0
- data/lib/jqmobi/rails/version.rb +7 -0
- data/lib/jqmobi/rails.rb +7 -0
- data/lib/jqmobi-rails.rb +1 -0
- data/vendor/assets/javascripts/jq.mobi.js +1894 -0
- data/vendor/assets/javascripts/jq.mobi_ujs.js +393 -0
- data/vendor/assets/javascripts/jq.ui.js +3396 -0
- data/vendor/assets/javascripts/plugins/jq.actionsheet.js +99 -0
- data/vendor/assets/javascripts/plugins/jq.alphatable.js +136 -0
- data/vendor/assets/javascripts/plugins/jq.carousel.js +415 -0
- data/vendor/assets/javascripts/plugins/jq.css3animate.js +155 -0
- data/vendor/assets/javascripts/plugins/jq.drawer.js +224 -0
- data/vendor/assets/javascripts/plugins/jq.fx.js +110 -0
- data/vendor/assets/javascripts/plugins/jq.passwordBox.js +45 -0
- data/vendor/assets/javascripts/plugins/jq.popup.js +201 -0
- data/vendor/assets/javascripts/plugins/jq.scroller.js +540 -0
- data/vendor/assets/javascripts/plugins/jq.selectBox.js +315 -0
- data/vendor/assets/javascripts/plugins/jq.shake.js +39 -0
- data/vendor/assets/javascripts/plugins/jq.social.js +113 -0
- data/vendor/assets/javascripts/plugins/jq.swipe.js +121 -0
- data/vendor/assets/javascripts/plugins/jq.template.js +26 -0
- data/vendor/assets/javascripts/plugins/jq.web.min.js +66 -0
- data/vendor/assets/stylesheets/plugins/jq.actionsheet.css +57 -0
- data/vendor/assets/stylesheets/plugins/jq.popup.css +73 -0
- data/vendor/assets/stylesheets/plugins/jq.scroller.css +10 -0
- data/vendor/assets/stylesheets/plugins/jq.selectBox.css +35 -0
- metadata +77 -0
@@ -0,0 +1,1894 @@
|
|
1
|
+
/**
|
2
|
+
* jqMobi is a query selector class for HTML5 mobile apps on a WebkitBrowser.
|
3
|
+
* Since most mobile devices (Android, iOS, webOS) use a WebKit browser, you only need to target one browser.
|
4
|
+
* We are able to increase the speed greatly by removing support for legacy desktop browsers and taking advantage of browser features, like native JSON parsing and querySelectorAll
|
5
|
+
|
6
|
+
|
7
|
+
* MIT License
|
8
|
+
* @author AppMobi
|
9
|
+
* @api private
|
10
|
+
*/
|
11
|
+
if (!window.jq || typeof (jq) !== "function") {
|
12
|
+
/**
|
13
|
+
* This is our master jq object that everything is built upon.
|
14
|
+
* $ is a pointer to this object
|
15
|
+
* @title jqMobi
|
16
|
+
* @api private
|
17
|
+
*/
|
18
|
+
var jq = (function(window) {
|
19
|
+
"use strict";
|
20
|
+
var undefined, document = window.document,
|
21
|
+
emptyArray = [],
|
22
|
+
slice = emptyArray.slice,
|
23
|
+
classCache = [],
|
24
|
+
eventHandlers = [],
|
25
|
+
_eventID = 1,
|
26
|
+
jsonPHandlers = [],
|
27
|
+
_jsonPID = 1,
|
28
|
+
fragementRE=/^\s*<(\w+)[^>]*>/,
|
29
|
+
_attrCache={};
|
30
|
+
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Internal function to test if a class name fits in a regular expression
|
34
|
+
* @param {String} name to search against
|
35
|
+
* @return {Boolean}
|
36
|
+
* @api private
|
37
|
+
*/
|
38
|
+
function classRE(name) {
|
39
|
+
return name in classCache ? classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'));
|
40
|
+
}
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Internal function that returns a array of unique elements
|
44
|
+
* @param {Array} array to compare against
|
45
|
+
* @return {Array} array of unique elements
|
46
|
+
* @api private
|
47
|
+
*/
|
48
|
+
function unique(arr) {
|
49
|
+
for (var i = 0; i < arr.length; i++) {
|
50
|
+
if (arr.indexOf(arr[i]) != i) {
|
51
|
+
arr.splice(i, 1);
|
52
|
+
i--;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
return arr;
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Given a set of nodes, it returns them as an array. Used to find
|
60
|
+
* siblings of an element
|
61
|
+
* @param {Nodelist} Node list to search
|
62
|
+
* @param {Object} [element] to find siblings off of
|
63
|
+
* @return {Array} array of sibblings
|
64
|
+
* @api private
|
65
|
+
*/
|
66
|
+
function siblings(nodes, element) {
|
67
|
+
var elems = [];
|
68
|
+
if (nodes == undefined)
|
69
|
+
return elems;
|
70
|
+
|
71
|
+
for (; nodes; nodes = nodes.nextSibling) {
|
72
|
+
if (nodes.nodeType == 1 && nodes !== element) {
|
73
|
+
elems.push(nodes);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
return elems;
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* This is the internal jqMobi object that gets extended and added on to it
|
81
|
+
* This is also the start of our query selector engine
|
82
|
+
* @param {String|Element|Object|Array} selector
|
83
|
+
* @param {String|Element|Object} [context]
|
84
|
+
*/
|
85
|
+
var $jqm = function(toSelect, what) {
|
86
|
+
this.length = 0;
|
87
|
+
if (!toSelect) {
|
88
|
+
return this;
|
89
|
+
} else if (toSelect instanceof $jqm && what == undefined) {
|
90
|
+
return toSelect;
|
91
|
+
} else if ($.isFunction(toSelect)) {
|
92
|
+
return $(document).ready(toSelect);
|
93
|
+
} else if ($.isArray(toSelect) && toSelect.length != undefined) { //Passing in an array or object
|
94
|
+
for (var i = 0; i < toSelect.length; i++)
|
95
|
+
this[this.length++] = toSelect[i];
|
96
|
+
return this;
|
97
|
+
} else if ($.isObject(toSelect) && $.isObject(what)) { //var tmp=$("span"); $("p").find(tmp);
|
98
|
+
if (toSelect.length == undefined) {
|
99
|
+
if (toSelect.parentNode == what)
|
100
|
+
this[this.length++] = toSelect;
|
101
|
+
} else {
|
102
|
+
for (var i = 0; i < toSelect.length; i++)
|
103
|
+
if (toSelect[i].parentNode == what)
|
104
|
+
this[this.length++] = toSelect[i];
|
105
|
+
}
|
106
|
+
return this;
|
107
|
+
} else if ($.isObject(toSelect) && what == undefined) { //Single object
|
108
|
+
this[this.length++] = toSelect;
|
109
|
+
return this;
|
110
|
+
} else if (what !== undefined) {
|
111
|
+
if (what instanceof $jqm) {
|
112
|
+
return what.find(toSelect);
|
113
|
+
}
|
114
|
+
|
115
|
+
} else {
|
116
|
+
what = document;
|
117
|
+
}
|
118
|
+
|
119
|
+
var dom = this.selector(toSelect, what);
|
120
|
+
if (!dom) {
|
121
|
+
return this;
|
122
|
+
}
|
123
|
+
//reverse the query selector all storage
|
124
|
+
else if ($.isArray(dom)) {
|
125
|
+
for (var j = 0; j < dom.length; j++) {
|
126
|
+
this[this.length++] = dom[j];
|
127
|
+
}
|
128
|
+
} else {
|
129
|
+
this[this.length++] = dom;
|
130
|
+
return this;
|
131
|
+
}
|
132
|
+
return this;
|
133
|
+
};
|
134
|
+
|
135
|
+
/**
|
136
|
+
* This calls the $jqm function
|
137
|
+
* @param {String|Element|Object|Array} selector
|
138
|
+
* @param {String|Element|Object} [context]
|
139
|
+
*/
|
140
|
+
var $ = function(selector, what) {
|
141
|
+
return new $jqm(selector, what);
|
142
|
+
};
|
143
|
+
|
144
|
+
/**
|
145
|
+
* this is the query selector library for elements
|
146
|
+
* @param {String} selector
|
147
|
+
* @param {String|Element|Object} [context]
|
148
|
+
* @api private
|
149
|
+
*/
|
150
|
+
|
151
|
+
function _selector(selector, what) {
|
152
|
+
var dom;
|
153
|
+
if (selector[0] === "#" && selector.indexOf(" ") === -1 && selector.indexOf(">") === -1) {
|
154
|
+
if (what == document)
|
155
|
+
dom = what.getElementById(selector.replace("#", ""));
|
156
|
+
else
|
157
|
+
dom = [].slice.call(what.querySelectorAll(selector));
|
158
|
+
return dom;
|
159
|
+
}
|
160
|
+
selector=selector.trim();
|
161
|
+
if (selector[0] === "<" && selector[selector.length - 1] === ">") //html
|
162
|
+
{
|
163
|
+
var tmp = document.createElement("div");
|
164
|
+
tmp.innerHTML = selector.trim();
|
165
|
+
dom = [].slice.call(tmp.childNodes);
|
166
|
+
} else {
|
167
|
+
dom = [].slice.call(what.querySelectorAll(selector));
|
168
|
+
}
|
169
|
+
return dom;
|
170
|
+
}
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Map takes in elements and executes a callback function on each and returns a collection
|
174
|
+
```
|
175
|
+
$.map([1,2],function(ind){return ind+1});
|
176
|
+
```
|
177
|
+
|
178
|
+
* @param {Array|Object} elements
|
179
|
+
* @param {Function} callback
|
180
|
+
* @return {Object} jqMobi object with elements in it
|
181
|
+
* @title $.map(elements,callback)
|
182
|
+
*/
|
183
|
+
$.map = function(elements, callback) {
|
184
|
+
var value, values = [],
|
185
|
+
i, key;
|
186
|
+
if ($.isArray(elements))
|
187
|
+
for (i = 0; i < elements.length; i++) {
|
188
|
+
value = callback(elements[i], i);
|
189
|
+
if (value !== undefined)
|
190
|
+
values.push(value);
|
191
|
+
}
|
192
|
+
else if ($.isObject(elements))
|
193
|
+
for (key in elements) {
|
194
|
+
if (!elements.hasOwnProperty(key))
|
195
|
+
continue;
|
196
|
+
value = callback(elements[key], key);
|
197
|
+
if (value !== undefined)
|
198
|
+
values.push(value);
|
199
|
+
}
|
200
|
+
return $([values]);
|
201
|
+
};
|
202
|
+
|
203
|
+
/**
|
204
|
+
* Iterates through elements and executes a callback. Returns if false
|
205
|
+
```
|
206
|
+
$.each([1,2],function(ind){console.log(ind);});
|
207
|
+
```
|
208
|
+
|
209
|
+
* @param {Array|Object} elements
|
210
|
+
* @param {Function} callback
|
211
|
+
* @return {Array} elements
|
212
|
+
* @title $.each(elements,callback)
|
213
|
+
*/
|
214
|
+
$.each = function(elements, callback) {
|
215
|
+
var i, key;
|
216
|
+
if ($.isArray(elements))
|
217
|
+
for (i = 0; i < elements.length; i++) {
|
218
|
+
if (callback(i, elements[i]) === false)
|
219
|
+
return elements;
|
220
|
+
}
|
221
|
+
else if ($.isObject(elements))
|
222
|
+
for (key in elements) {
|
223
|
+
if (!elements.hasOwnProperty(key))
|
224
|
+
continue;
|
225
|
+
if (callback(key, elements[key]) === false)
|
226
|
+
return elements;
|
227
|
+
}
|
228
|
+
return elements;
|
229
|
+
};
|
230
|
+
|
231
|
+
/**
|
232
|
+
* Extends an object with additional arguments
|
233
|
+
```
|
234
|
+
$.extend({foo:'bar'});
|
235
|
+
$.extend(element,{foo:'bar'});
|
236
|
+
```
|
237
|
+
|
238
|
+
* @param {Object} [target] element
|
239
|
+
* @param any number of additional arguments
|
240
|
+
* @return {Object} [target]
|
241
|
+
* @title $.extend(target,{params})
|
242
|
+
*/
|
243
|
+
$.extend = function(target) {
|
244
|
+
if (target == undefined)
|
245
|
+
target = this;
|
246
|
+
if (arguments.length === 1) {
|
247
|
+
for (var key in target)
|
248
|
+
this[key] = target[key];
|
249
|
+
return this;
|
250
|
+
} else {
|
251
|
+
slice.call(arguments, 1).forEach(function(source) {
|
252
|
+
for (var key in source)
|
253
|
+
target[key] = source[key];
|
254
|
+
});
|
255
|
+
}
|
256
|
+
return target;
|
257
|
+
};
|
258
|
+
|
259
|
+
/**
|
260
|
+
* Checks to see if the parameter is an array
|
261
|
+
```
|
262
|
+
var arr=[];
|
263
|
+
$.isArray(arr);
|
264
|
+
```
|
265
|
+
|
266
|
+
* @param {Object} element
|
267
|
+
* @return {Boolean}
|
268
|
+
* @example $.isArray([1]);
|
269
|
+
* @title $.isArray(param)
|
270
|
+
*/
|
271
|
+
$.isArray = function(obj) {
|
272
|
+
return obj instanceof Array && obj['push'] != undefined; //ios 3.1.3 doesn't have Array.isArray
|
273
|
+
};
|
274
|
+
|
275
|
+
/**
|
276
|
+
* Checks to see if the parameter is a function
|
277
|
+
```
|
278
|
+
var func=function(){};
|
279
|
+
$.isFunction(func);
|
280
|
+
```
|
281
|
+
|
282
|
+
* @param {Object} element
|
283
|
+
* @return {Boolean}
|
284
|
+
* @title $.isFunction(param)
|
285
|
+
*/
|
286
|
+
$.isFunction = function(obj) {
|
287
|
+
return typeof obj === "function";
|
288
|
+
};
|
289
|
+
/**
|
290
|
+
* Checks to see if the parameter is a object
|
291
|
+
```
|
292
|
+
var foo={bar:'bar'};
|
293
|
+
$.isObject(foo);
|
294
|
+
```
|
295
|
+
|
296
|
+
* @param {Object} element
|
297
|
+
* @return {Boolean}
|
298
|
+
* @title $.isObject(param)
|
299
|
+
*/
|
300
|
+
$.isObject = function(obj) {
|
301
|
+
return typeof obj === "object";
|
302
|
+
}
|
303
|
+
|
304
|
+
|
305
|
+
/**
|
306
|
+
* Prototype for jqm object. Also extens $.fn
|
307
|
+
*/
|
308
|
+
$.fn = $jqm.prototype = {
|
309
|
+
constructor: $jqm,
|
310
|
+
forEach: emptyArray.forEach,
|
311
|
+
reduce: emptyArray.reduce,
|
312
|
+
push: emptyArray.push,
|
313
|
+
indexOf: emptyArray.indexOf,
|
314
|
+
concat: emptyArray.concat,
|
315
|
+
selector: _selector,
|
316
|
+
oldElement: undefined,
|
317
|
+
slice: emptyArray.slice,
|
318
|
+
/**
|
319
|
+
* This is a utility function for .end()
|
320
|
+
* @param {Object} params
|
321
|
+
* @return {Object} a jqMobi with params.oldElement set to this
|
322
|
+
* @api private
|
323
|
+
*/
|
324
|
+
setupOld: function(params) {
|
325
|
+
if (params == undefined)
|
326
|
+
return $();
|
327
|
+
params.oldElement = this;
|
328
|
+
return params;
|
329
|
+
|
330
|
+
},
|
331
|
+
/**
|
332
|
+
* This is a wrapper to $.map on the selected elements
|
333
|
+
```
|
334
|
+
$().map(function(){this.value+=ind});
|
335
|
+
```
|
336
|
+
|
337
|
+
* @param {Function} callback
|
338
|
+
* @return {Object} a jqMobi object
|
339
|
+
* @title $().map(function)
|
340
|
+
*/
|
341
|
+
map: function(fn) {
|
342
|
+
return $.map(this, function(el, i) {
|
343
|
+
return fn.call(el, i, el);
|
344
|
+
});
|
345
|
+
},
|
346
|
+
/**
|
347
|
+
* Iterates through all elements and applys a callback function
|
348
|
+
```
|
349
|
+
$().each(function(){console.log(this.value)});
|
350
|
+
```
|
351
|
+
|
352
|
+
* @param {Function} callback
|
353
|
+
* @return {Object} a jqMobi object
|
354
|
+
* @title $().each(function)
|
355
|
+
*/
|
356
|
+
each: function(callback) {
|
357
|
+
this.forEach(function(el, idx) {
|
358
|
+
callback.call(el, idx, el);
|
359
|
+
});
|
360
|
+
return this;
|
361
|
+
},
|
362
|
+
/**
|
363
|
+
* This is executed when DOMContentLoaded happens, or after if you've registered for it.
|
364
|
+
```
|
365
|
+
$(document).ready(function(){console.log('I'm ready');});
|
366
|
+
```
|
367
|
+
|
368
|
+
* @param {Function} callback
|
369
|
+
* @return {Object} a jqMobi object
|
370
|
+
* @title $().ready(function)
|
371
|
+
*/
|
372
|
+
|
373
|
+
ready: function(callback) {
|
374
|
+
if (document.readyState === "complete" || document.readyState === "loaded")
|
375
|
+
callback();
|
376
|
+
document.addEventListener("DOMContentLoaded", callback, false);
|
377
|
+
return this;
|
378
|
+
},
|
379
|
+
/**
|
380
|
+
* Searches through the collection and reduces them to elements that match the selector
|
381
|
+
```
|
382
|
+
$("#foo").find('.bar');
|
383
|
+
$("#foo").find($('.bar'));
|
384
|
+
$("#foo").find($('.bar').get());
|
385
|
+
```
|
386
|
+
|
387
|
+
* @param {String|Object|Array} selector
|
388
|
+
* @return {Object} a jqMobi object filtered
|
389
|
+
* @title $().find(selector)
|
390
|
+
|
391
|
+
*/
|
392
|
+
find: function(sel) {
|
393
|
+
if (this.length === 0)
|
394
|
+
return undefined;
|
395
|
+
var elems = [];
|
396
|
+
var tmpElems;
|
397
|
+
for (var i = 0; i < this.length; i++) {
|
398
|
+
tmpElems = ($(sel, this[i]));
|
399
|
+
|
400
|
+
for (var j = 0; j < tmpElems.length; j++) {
|
401
|
+
elems.push(tmpElems[j]);
|
402
|
+
}
|
403
|
+
}
|
404
|
+
return $(unique(elems));
|
405
|
+
},
|
406
|
+
/**
|
407
|
+
* Gets or sets the innerHTML for the collection.
|
408
|
+
* If used as a get, the first elements innerHTML is returned
|
409
|
+
```
|
410
|
+
$("#foo").html(); //gets the first elements html
|
411
|
+
$("#foo").html('new html');//sets the html
|
412
|
+
```
|
413
|
+
|
414
|
+
* @param {String} html to set
|
415
|
+
* @return {Object} a jqMobi object
|
416
|
+
* @title $().html([html])
|
417
|
+
*/
|
418
|
+
html: function(html) {
|
419
|
+
if (this.length === 0)
|
420
|
+
return undefined;
|
421
|
+
if (html === undefined)
|
422
|
+
return this[0].innerHTML;
|
423
|
+
for (var i = 0; i < this.length; i++) {
|
424
|
+
this[i].innerHTML = html;
|
425
|
+
}
|
426
|
+
return this;
|
427
|
+
},
|
428
|
+
/**
|
429
|
+
* Gets or sets the innerText for the collection.
|
430
|
+
* If used as a get, the first elements innerText is returned
|
431
|
+
```
|
432
|
+
$("#foo").text(); //gets the first elements text;
|
433
|
+
$("#foo").text('new text'); //sets the text
|
434
|
+
```
|
435
|
+
|
436
|
+
* @param {String} text to set
|
437
|
+
* @return {Object} a jqMobi object
|
438
|
+
* @title $().text([text])
|
439
|
+
*/
|
440
|
+
text: function(text) {
|
441
|
+
if (this.length === 0)
|
442
|
+
return undefined;
|
443
|
+
if (text === undefined)
|
444
|
+
return this[0].textContent;
|
445
|
+
for (var i = 0; i < this.length; i++) {
|
446
|
+
this[i].textContent = text;
|
447
|
+
}
|
448
|
+
return this;
|
449
|
+
},
|
450
|
+
/**
|
451
|
+
* Gets or sets a css property for the collection
|
452
|
+
* If used as a get, the first elements css property is returned
|
453
|
+
```
|
454
|
+
$().css("background"); // Gets the first elements background
|
455
|
+
$().css("background","red") //Sets the elements background to red
|
456
|
+
```
|
457
|
+
|
458
|
+
* @param {String} attribute to get
|
459
|
+
* @param {String} value to set as
|
460
|
+
* @return {Object} a jqMobi object
|
461
|
+
* @title $().css(attribute,[value])
|
462
|
+
*/
|
463
|
+
css: function(attribute, value, obj) {
|
464
|
+
var toAct = obj != undefined ? obj : this[0];
|
465
|
+
if (this.length === 0)
|
466
|
+
return undefined;
|
467
|
+
if (value == undefined && typeof (attribute) === "string") {
|
468
|
+
var styles = window.getComputedStyle(toAct);
|
469
|
+
return toAct.style[attribute] ? toAct.style[attribute]: window.getComputedStyle(toAct)[attribute] ;
|
470
|
+
}
|
471
|
+
for (var i = 0; i < this.length; i++) {
|
472
|
+
if ($.isObject(attribute)) {
|
473
|
+
for (var j in attribute) {
|
474
|
+
this[i].style[j] = attribute[j];
|
475
|
+
}
|
476
|
+
} else {
|
477
|
+
this[i].style[attribute] = value;
|
478
|
+
}
|
479
|
+
}
|
480
|
+
return this;
|
481
|
+
},
|
482
|
+
/**
|
483
|
+
* Sets the innerHTML of all elements to an empty string
|
484
|
+
```
|
485
|
+
$().empty();
|
486
|
+
```
|
487
|
+
|
488
|
+
* @return {Object} a jqMobi object
|
489
|
+
* @title $().empty()
|
490
|
+
*/
|
491
|
+
empty: function() {
|
492
|
+
for (var i = 0; i < this.length; i++) {
|
493
|
+
this[i].innerHTML = '';
|
494
|
+
}
|
495
|
+
return this;
|
496
|
+
},
|
497
|
+
/**
|
498
|
+
* Sets the elements display property to "none".
|
499
|
+
* This will also store the old property into an attribute for hide
|
500
|
+
```
|
501
|
+
$().hide();
|
502
|
+
```
|
503
|
+
|
504
|
+
* @return {Object} a jqMobi object
|
505
|
+
* @title $().hide()
|
506
|
+
*/
|
507
|
+
hide: function() {
|
508
|
+
if (this.length === 0)
|
509
|
+
return this;
|
510
|
+
for (var i = 0; i < this.length; i++) {
|
511
|
+
if (this.css("display", null, this[i]) != "none") {
|
512
|
+
this[i].setAttribute("jqmOldStyle", this.css("display", null, this[i]));
|
513
|
+
this[i].style.display = "none";
|
514
|
+
}
|
515
|
+
}
|
516
|
+
return this;
|
517
|
+
},
|
518
|
+
/**
|
519
|
+
* Shows all the elements by setting the css display property
|
520
|
+
* We look to see if we were retaining an old style (like table-cell) and restore that, otherwise we set it to block
|
521
|
+
```
|
522
|
+
$().show();
|
523
|
+
```
|
524
|
+
|
525
|
+
* @return {Object} a jqMobi object
|
526
|
+
* @title $().show()
|
527
|
+
*/
|
528
|
+
show: function() {
|
529
|
+
if (this.length === 0)
|
530
|
+
return this;
|
531
|
+
for (var i = 0; i < this.length; i++) {
|
532
|
+
if (this.css("display", null, this[i]) == "none") {
|
533
|
+
this[i].style.display = this[i].getAttribute("jqmOldStyle") ? this[i].getAttribute("jqmOldStyle") : 'block';
|
534
|
+
this[i].removeAttribute("jqmOldStyle");
|
535
|
+
}
|
536
|
+
}
|
537
|
+
return this;
|
538
|
+
},
|
539
|
+
/**
|
540
|
+
* Toggle the visibility of a div
|
541
|
+
```
|
542
|
+
$().toggle();
|
543
|
+
$().toggle(true); //force showing
|
544
|
+
```
|
545
|
+
|
546
|
+
* @param {Boolean} [show] -force the hiding or showing of the element
|
547
|
+
* @return {Object} a jqMobi object
|
548
|
+
* @title $().toggle([show])
|
549
|
+
*/
|
550
|
+
toggle: function(show) {
|
551
|
+
var show2 = show === true ? true : false;
|
552
|
+
for (var i = 0; i < this.length; i++) {
|
553
|
+
if (window.getComputedStyle(this[i])['display'] !== "none" || (show !== undefined && show2 === false)) {
|
554
|
+
this[i].setAttribute("jqmOldStyle", this[i].style.display)
|
555
|
+
this[i].style.display = "none";
|
556
|
+
} else {
|
557
|
+
this[i].style.display = this[i].getAttribute("jqmOldStyle") != undefined ? this[i].getAttribute("jqmOldStyle") : 'block';
|
558
|
+
this[i].removeAttribute("jqmOldStyle");
|
559
|
+
}
|
560
|
+
}
|
561
|
+
return this;
|
562
|
+
},
|
563
|
+
/**
|
564
|
+
* Gets or sets an elements value
|
565
|
+
* If used as a getter, we return the first elements value. If nothing is in the collection, we return undefined
|
566
|
+
```
|
567
|
+
$().value; //Gets the first elements value;
|
568
|
+
$().value="bar"; //Sets all elements value to bar
|
569
|
+
```
|
570
|
+
|
571
|
+
* @param {String} [value] to set
|
572
|
+
* @return {String|Object} A string as a getter, jqMobi object as a setter
|
573
|
+
* @title $().val([value])
|
574
|
+
*/
|
575
|
+
val: function(value) {
|
576
|
+
if (this.length === 0)
|
577
|
+
return undefined;
|
578
|
+
if (value == undefined)
|
579
|
+
return this[0].value;
|
580
|
+
for (var i = 0; i < this.length; i++) {
|
581
|
+
this[i].value = value;
|
582
|
+
}
|
583
|
+
return this;
|
584
|
+
},
|
585
|
+
/**
|
586
|
+
* Gets or sets an attribute on an element
|
587
|
+
* If used as a getter, we return the first elements value. If nothing is in the collection, we return undefined
|
588
|
+
```
|
589
|
+
$().attr("foo"); //Gets the first elements 'foo' attribute
|
590
|
+
$().attr("foo","bar");//Sets the elements 'foo' attribute to 'bar'
|
591
|
+
$().attr("foo",{bar:'bar'}) //Adds the object to an internal cache
|
592
|
+
```
|
593
|
+
|
594
|
+
* @param {String|Object} attribute to act upon. If it's an object (hashmap), it will set the attributes based off the kvp.
|
595
|
+
* @param {String|Array|Object|function} [value] to set
|
596
|
+
* @return {String|Object|Array|Function} If used as a getter, return the attribute value. If a setter, return a jqMobi object
|
597
|
+
* @title $().attr(attribute,[value])
|
598
|
+
*/
|
599
|
+
attr: function(attr, value) {
|
600
|
+
if (this.length === 0)
|
601
|
+
return undefined;
|
602
|
+
if (value === undefined && !$.isObject(attr)) {
|
603
|
+
|
604
|
+
var val = (this[0].jqmCacheId&&_attrCache[this[0].jqmCacheId][attr])?(this[0].jqmCacheId&&_attrCache[this[0].jqmCacheId][attr]):this[0].getAttribute(attr);
|
605
|
+
return val;
|
606
|
+
}
|
607
|
+
for (var i = 0; i < this.length; i++) {
|
608
|
+
if ($.isObject(attr)) {
|
609
|
+
for (var key in attr) {
|
610
|
+
$(this[i]).attr(key,attr[key]);
|
611
|
+
}
|
612
|
+
}
|
613
|
+
else if($.isArray(value)||$.isObject(value)||$.isFunction(value))
|
614
|
+
{
|
615
|
+
|
616
|
+
if(!this[i].jqmCacheId)
|
617
|
+
this[i].jqmCacheId=$.uuid();
|
618
|
+
|
619
|
+
if(!_attrCache[this[i].jqmCacheId])
|
620
|
+
_attrCache[this[i].jqmCacheId]={}
|
621
|
+
_attrCache[this[i].jqmCacheId][attr]=value;
|
622
|
+
}
|
623
|
+
else if (value == null && value !== undefined)
|
624
|
+
{
|
625
|
+
this[i].removeAttribute(attr);
|
626
|
+
if(this[i].jqmCacheId&&_attrCache[this[i].jqmCacheId][attr])
|
627
|
+
delete _attrCache[this[i].jqmCacheId][attr];
|
628
|
+
}
|
629
|
+
else{
|
630
|
+
this[i].setAttribute(attr, value);
|
631
|
+
}
|
632
|
+
}
|
633
|
+
return this;
|
634
|
+
},
|
635
|
+
/**
|
636
|
+
* Removes an attribute on the elements
|
637
|
+
```
|
638
|
+
$().removeAttr("foo");
|
639
|
+
```
|
640
|
+
|
641
|
+
* @param {String} attributes that can be space delimited
|
642
|
+
* @return {Object} jqMobi object
|
643
|
+
* @title $().removeAttr(attribute)
|
644
|
+
*/
|
645
|
+
removeAttr: function(attr) {
|
646
|
+
var that = this;
|
647
|
+
for (var i = 0; i < this.length; i++) {
|
648
|
+
attr.split(/\s+/g).forEach(function(param) {
|
649
|
+
that[i].removeAttribute(param);
|
650
|
+
if(that[i].jqmCacheId&&_attrCache[that[i].jqmCacheId][attr])
|
651
|
+
delete _attrCache[that[i].jqmCacheId][attr];
|
652
|
+
});
|
653
|
+
}
|
654
|
+
return this;
|
655
|
+
},
|
656
|
+
/**
|
657
|
+
* Removes elements based off a selector
|
658
|
+
```
|
659
|
+
$().remove(".foo");//Remove off a string selector
|
660
|
+
var element=$("#foo").get();
|
661
|
+
$().remove(element); //Remove by an element
|
662
|
+
$().remove($(".foo")); //Remove by a collection
|
663
|
+
```
|
664
|
+
|
665
|
+
* @param {String|Object|Array} selector to filter against
|
666
|
+
* @return {Object} jqMobi object
|
667
|
+
* @title $().remove(selector)
|
668
|
+
*/
|
669
|
+
remove: function(selector) {
|
670
|
+
var elems = $(this).filter(selector);
|
671
|
+
if (elems == undefined)
|
672
|
+
return this;
|
673
|
+
for (var i = 0; i < elems.length; i++) {
|
674
|
+
elems[i].parentNode.removeChild(elems[i]);
|
675
|
+
}
|
676
|
+
return this;
|
677
|
+
},
|
678
|
+
/**
|
679
|
+
* Adds a css class to elements.
|
680
|
+
```
|
681
|
+
$().addClass("selected");
|
682
|
+
```
|
683
|
+
|
684
|
+
* @param {String} classes that are space delimited
|
685
|
+
* @return {Object} jqMobi object
|
686
|
+
* @title $().addClass(name)
|
687
|
+
*/
|
688
|
+
addClass: function(name) {
|
689
|
+
for (var i = 0; i < this.length; i++) {
|
690
|
+
var cls = this[i].className;
|
691
|
+
var classList = [];
|
692
|
+
var that = this;
|
693
|
+
name.split(/\s+/g).forEach(function(cname) {
|
694
|
+
if (!that.hasClass(cname, that[i]))
|
695
|
+
classList.push(cname);
|
696
|
+
});
|
697
|
+
|
698
|
+
this[i].className += (cls ? " " : "") + classList.join(" ");
|
699
|
+
this[i].className = this[i].className.trim();
|
700
|
+
}
|
701
|
+
return this;
|
702
|
+
},
|
703
|
+
/**
|
704
|
+
* Removes a css class from elements.
|
705
|
+
```
|
706
|
+
$().removeClass("foo"); //single class
|
707
|
+
$().removeClass("foo selected");//remove multiple classess
|
708
|
+
```
|
709
|
+
|
710
|
+
* @param {String} classes that are space delimited
|
711
|
+
* @return {Object} jqMobi object
|
712
|
+
* @title $().removeClass(name)
|
713
|
+
*/
|
714
|
+
removeClass: function(name) {
|
715
|
+
for (var i = 0; i < this.length; i++) {
|
716
|
+
if (name == undefined) {
|
717
|
+
this[i].className = '';
|
718
|
+
return this;
|
719
|
+
}
|
720
|
+
var classList = this[i].className;
|
721
|
+
name.split(/\s+/g).forEach(function(cname) {
|
722
|
+
classList = classList.replace(classRE(cname), " ");
|
723
|
+
});
|
724
|
+
if (classList.length > 0)
|
725
|
+
this[i].className = classList.trim();
|
726
|
+
else
|
727
|
+
this[i].className = "";
|
728
|
+
}
|
729
|
+
return this;
|
730
|
+
},
|
731
|
+
/**
|
732
|
+
* Checks to see if an element has a class.
|
733
|
+
```
|
734
|
+
$().hasClass('foo');
|
735
|
+
$().hasClass('foo',element);
|
736
|
+
```
|
737
|
+
|
738
|
+
* @param {String} class name to check against
|
739
|
+
* @param {Object} [element] to check against
|
740
|
+
* @return {Boolean}
|
741
|
+
* @title $().hasClass(name,[element])
|
742
|
+
*/
|
743
|
+
hasClass: function(name, element) {
|
744
|
+
if (this.length === 0)
|
745
|
+
return false;
|
746
|
+
if (!element)
|
747
|
+
element = this[0];
|
748
|
+
return classRE(name).test(element.className);
|
749
|
+
},
|
750
|
+
/**
|
751
|
+
* Appends to the elements
|
752
|
+
* We boil everything down to a jqMobi object and then loop through that.
|
753
|
+
* If it's HTML, we create a dom element so we do not break event bindings.
|
754
|
+
* if it's a script tag, we evaluate it.
|
755
|
+
```
|
756
|
+
$().append("<div></div>"); //Creates the object from the string and appends it
|
757
|
+
$().append($("#foo")); //Append an object;
|
758
|
+
```
|
759
|
+
|
760
|
+
* @param {String|Object} Element/string to add
|
761
|
+
* @param {Boolean} [insert] insert or append
|
762
|
+
* @return {Object} jqMobi object
|
763
|
+
* @title $().append(element,[insert])
|
764
|
+
*/
|
765
|
+
append: function(element, insert) {
|
766
|
+
if (element && element.length != undefined && element.length === 0)
|
767
|
+
return this;
|
768
|
+
if ($.isArray(element) || $.isObject(element))
|
769
|
+
element = $(element);
|
770
|
+
var i;
|
771
|
+
|
772
|
+
for (i = 0; i < this.length; i++) {
|
773
|
+
if (element.length && typeof element != "string") {
|
774
|
+
element = $(element);
|
775
|
+
for (var j = 0; j < element.length; j++)
|
776
|
+
insert != undefined ? this[i].insertBefore(element[j], this[i].firstChild) : this[i].appendChild(element[j]);
|
777
|
+
} else {
|
778
|
+
var obj =fragementRE.test(element)?$(element):undefined;
|
779
|
+
if (obj == undefined || obj.length == 0) {
|
780
|
+
obj = document.createTextNode(element);
|
781
|
+
}
|
782
|
+
if (obj.nodeName != undefined && obj.nodeName.toLowerCase() == "script" && (!obj.type || obj.type.toLowerCase() === 'text/javascript')) {
|
783
|
+
window.eval(obj.innerHTML);
|
784
|
+
} else if(obj instanceof $jqm) {
|
785
|
+
for(var k=0;k<obj.length;k++)
|
786
|
+
{
|
787
|
+
insert != undefined ? this[i].insertBefore(obj[k], this[i].firstChild) : this[i].appendChild(obj[k]);
|
788
|
+
}
|
789
|
+
}
|
790
|
+
else {
|
791
|
+
insert != undefined ? this[i].insertBefore(obj, this[i].firstChild) : this[i].appendChild(obj);
|
792
|
+
}
|
793
|
+
}
|
794
|
+
}
|
795
|
+
return this;
|
796
|
+
},
|
797
|
+
/**
|
798
|
+
* Prepends to the elements
|
799
|
+
* This simply calls append and sets insert to true
|
800
|
+
```
|
801
|
+
$().prepend("<div></div>");//Creates the object from the string and appends it
|
802
|
+
$().prepend($("#foo")); //Prepends an object
|
803
|
+
```
|
804
|
+
|
805
|
+
* @param {String|Object} Element/string to add
|
806
|
+
* @return {Object} jqMobi object
|
807
|
+
* @title $().prepend(element)
|
808
|
+
*/
|
809
|
+
prepend: function(element) {
|
810
|
+
return this.append(element, 1);
|
811
|
+
},
|
812
|
+
/**
|
813
|
+
* Inserts collection before the target (adjacent)
|
814
|
+
```
|
815
|
+
$().insertBefore(jq("#target"));
|
816
|
+
```
|
817
|
+
|
818
|
+
* @param {String|Object} Target
|
819
|
+
* @title $().insertBefore(target);
|
820
|
+
*/
|
821
|
+
insertBefore: function(target, after) {
|
822
|
+
if (this.length == 0)
|
823
|
+
return this;
|
824
|
+
target = $(target).get(0);
|
825
|
+
if (!target || target.length == 0)
|
826
|
+
return this;
|
827
|
+
for (var i = 0; i < this.length; i++)
|
828
|
+
{
|
829
|
+
after ? target.parentNode.insertBefore(this[i], target.nextSibling) : target.parentNode.insertBefore(this[i], target);
|
830
|
+
}
|
831
|
+
return this;
|
832
|
+
},
|
833
|
+
/**
|
834
|
+
* Inserts collection after the target (adjacent)
|
835
|
+
```
|
836
|
+
$().insertAfter(jq("#target"));
|
837
|
+
```
|
838
|
+
* @param {String|Object} target
|
839
|
+
* @title $().insertAfter(target);
|
840
|
+
*/
|
841
|
+
insertAfter: function(target) {
|
842
|
+
this.insertBefore(target, true);
|
843
|
+
},
|
844
|
+
/**
|
845
|
+
* Returns the raw DOM element.
|
846
|
+
```
|
847
|
+
$().get(); //returns the first element
|
848
|
+
$().get(2);// returns the third element
|
849
|
+
```
|
850
|
+
|
851
|
+
* @param {Int} [index]
|
852
|
+
* @return {Object} raw DOM element
|
853
|
+
* @title $().get([index])
|
854
|
+
*/
|
855
|
+
get: function(index) {
|
856
|
+
index = index == undefined ? 0 : index;
|
857
|
+
if (index < 0)
|
858
|
+
index += this.length;
|
859
|
+
return (this[index]) ? this[index] : undefined;
|
860
|
+
},
|
861
|
+
/**
|
862
|
+
* Returns the offset of the element, including traversing up the tree
|
863
|
+
```
|
864
|
+
$().offset();
|
865
|
+
```
|
866
|
+
|
867
|
+
* @return {Object} with left, top, width and height properties
|
868
|
+
* @title $().offset()
|
869
|
+
*/
|
870
|
+
offset: function() {
|
871
|
+
if (this.length === 0)
|
872
|
+
return undefined;
|
873
|
+
var obj = this[0].getBoundingClientRect();
|
874
|
+
return {
|
875
|
+
left: obj.left + window.pageXOffset,
|
876
|
+
top: obj.top + window.pageYOffset,
|
877
|
+
width: parseInt(this[0].style.width),
|
878
|
+
height: parseInt(this[0].style.height)
|
879
|
+
};
|
880
|
+
},
|
881
|
+
/**
|
882
|
+
* Returns the parent nodes of the elements based off the selector
|
883
|
+
```
|
884
|
+
$("#foo").parent('.bar');
|
885
|
+
$("#foo").parent($('.bar'));
|
886
|
+
$("#foo").parent($('.bar').get());
|
887
|
+
```
|
888
|
+
|
889
|
+
* @param {String|Array|Object} [selector]
|
890
|
+
* @return {Object} jqMobi object with unique parents
|
891
|
+
* @title $().parent(selector)
|
892
|
+
*/
|
893
|
+
parent: function(selector) {
|
894
|
+
if (this.length == 0)
|
895
|
+
return undefined;
|
896
|
+
var elems = [];
|
897
|
+
for (var i = 0; i < this.length; i++) {
|
898
|
+
if (this[i].parentNode)
|
899
|
+
elems.push(this[i].parentNode);
|
900
|
+
}
|
901
|
+
return this.setupOld($(unique(elems)).filter(selector));
|
902
|
+
},
|
903
|
+
/**
|
904
|
+
* Returns the child nodes of the elements based off the selector
|
905
|
+
```
|
906
|
+
$("#foo").children('.bar'); //Selector
|
907
|
+
$("#foo").children($('.bar')); //Objects
|
908
|
+
$("#foo").children($('.bar').get()); //Single element
|
909
|
+
```
|
910
|
+
|
911
|
+
* @param {String|Array|Object} [selector]
|
912
|
+
* @return {Object} jqMobi object with unique children
|
913
|
+
* @title $().children(selector)
|
914
|
+
*/
|
915
|
+
children: function(selector) {
|
916
|
+
|
917
|
+
if (this.length == 0)
|
918
|
+
return undefined;
|
919
|
+
var elems = [];
|
920
|
+
for (var i = 0; i < this.length; i++) {
|
921
|
+
elems = elems.concat(siblings(this[i].firstChild));
|
922
|
+
}
|
923
|
+
return this.setupOld($((elems)).filter(selector));
|
924
|
+
|
925
|
+
},
|
926
|
+
/**
|
927
|
+
* Returns the siblings of the element based off the selector
|
928
|
+
```
|
929
|
+
$("#foo").siblings('.bar'); //Selector
|
930
|
+
$("#foo").siblings($('.bar')); //Objects
|
931
|
+
$("#foo").siblings($('.bar').get()); //Single element
|
932
|
+
```
|
933
|
+
|
934
|
+
* @param {String|Array|Object} [selector]
|
935
|
+
* @return {Object} jqMobi object with unique siblings
|
936
|
+
* @title $().siblings(selector)
|
937
|
+
*/
|
938
|
+
siblings: function(selector) {
|
939
|
+
if (this.length == 0)
|
940
|
+
return undefined;
|
941
|
+
var elems = [];
|
942
|
+
for (var i = 0; i < this.length; i++) {
|
943
|
+
if (this[i].parentNode)
|
944
|
+
elems = elems.concat(siblings(this[i].parentNode.firstChild, this[i]));
|
945
|
+
}
|
946
|
+
return this.setupOld($(elems).filter(selector));
|
947
|
+
},
|
948
|
+
/**
|
949
|
+
* Returns the closest element based off the selector and optional context
|
950
|
+
```
|
951
|
+
$("#foo").closest('.bar'); //Selector
|
952
|
+
$("#foo").closest($('.bar')); //Objects
|
953
|
+
$("#foo").closest($('.bar').get()); //Single element
|
954
|
+
```
|
955
|
+
|
956
|
+
* @param {String|Array|Object} selector
|
957
|
+
* @param {Object} [context]
|
958
|
+
* @return {Object} Returns a jqMobi object with the closest element based off the selector
|
959
|
+
* @title $().closest(selector,[context]);
|
960
|
+
*/
|
961
|
+
closest: function(selector, context) {
|
962
|
+
if (this.length == 0)
|
963
|
+
return undefined;
|
964
|
+
var elems = [],
|
965
|
+
cur = this[0];
|
966
|
+
|
967
|
+
var start = $(selector, context);
|
968
|
+
if (start.length == 0)
|
969
|
+
return $();
|
970
|
+
while (cur && start.indexOf(cur) == -1) {
|
971
|
+
cur = cur !== context && cur !== document && cur.parentNode;
|
972
|
+
}
|
973
|
+
return $(cur);
|
974
|
+
|
975
|
+
},
|
976
|
+
/**
|
977
|
+
* Filters elements based off the selector
|
978
|
+
```
|
979
|
+
$("#foo").filter('.bar'); //Selector
|
980
|
+
$("#foo").filter($('.bar')); //Objects
|
981
|
+
$("#foo").filter($('.bar').get()); //Single element
|
982
|
+
```
|
983
|
+
|
984
|
+
* @param {String|Array|Object} selector
|
985
|
+
* @return {Object} Returns a jqMobi object after the filter was run
|
986
|
+
* @title $().filter(selector);
|
987
|
+
*/
|
988
|
+
filter: function(selector) {
|
989
|
+
if (this.length == 0)
|
990
|
+
return undefined;
|
991
|
+
|
992
|
+
if (selector == undefined)
|
993
|
+
return this;
|
994
|
+
var elems = [];
|
995
|
+
for (var i = 0; i < this.length; i++) {
|
996
|
+
var val = this[i];
|
997
|
+
if (val.parentNode && $(selector, val.parentNode).indexOf(val) >= 0)
|
998
|
+
elems.push(val);
|
999
|
+
}
|
1000
|
+
return this.setupOld($(unique(elems)));
|
1001
|
+
},
|
1002
|
+
/**
|
1003
|
+
* Basically the reverse of filter. Return all elements that do NOT match the selector
|
1004
|
+
```
|
1005
|
+
$("#foo").not('.bar'); //Selector
|
1006
|
+
$("#foo").not($('.bar')); //Objects
|
1007
|
+
$("#foo").not($('.bar').get()); //Single element
|
1008
|
+
```
|
1009
|
+
|
1010
|
+
* @param {String|Array|Object} selector
|
1011
|
+
* @return {Object} Returns a jqMobi object after the filter was run
|
1012
|
+
* @title $().not(selector);
|
1013
|
+
*/
|
1014
|
+
not: function(selector) {
|
1015
|
+
if (this.length == 0)
|
1016
|
+
return undefined;
|
1017
|
+
var elems = [];
|
1018
|
+
for (var i = 0; i < this.length; i++) {
|
1019
|
+
var val = this[i];
|
1020
|
+
if (val.parentNode && $(selector, val.parentNode).indexOf(val) == -1)
|
1021
|
+
elems.push(val);
|
1022
|
+
}
|
1023
|
+
return this.setupOld($(unique(elems)));
|
1024
|
+
},
|
1025
|
+
/**
|
1026
|
+
* Gets or set data-* attribute parameters on elements
|
1027
|
+
* When used as a getter, it's only the first element
|
1028
|
+
```
|
1029
|
+
$().data("foo"); //Gets the data-foo attribute for the first element
|
1030
|
+
$().data("foo","bar"); //Sets the data-foo attribute for all elements
|
1031
|
+
$().data("foo",{bar:'bar'});//object as the data
|
1032
|
+
```
|
1033
|
+
|
1034
|
+
* @param {String} key
|
1035
|
+
* @param {String|Array|Object} value
|
1036
|
+
* @return {String|Object} returns the value or jqMobi object
|
1037
|
+
* @title $().data(key,[value]);
|
1038
|
+
*/
|
1039
|
+
data: function(key, value) {
|
1040
|
+
return this.attr('data-' + key, value);
|
1041
|
+
},
|
1042
|
+
/**
|
1043
|
+
* Rolls back the jqMobi elements when filters were applied
|
1044
|
+
* This can be used after .not(), .filter(), .children(), .parent()
|
1045
|
+
```
|
1046
|
+
$().filter(".panel").end(); //This will return the collection BEFORE filter is applied
|
1047
|
+
```
|
1048
|
+
|
1049
|
+
* @return {Object} returns the previous jqMobi object before filter was applied
|
1050
|
+
* @title $().end();
|
1051
|
+
*/
|
1052
|
+
end: function() {
|
1053
|
+
return this.oldElement != undefined ? this.oldElement : $();
|
1054
|
+
},
|
1055
|
+
/**
|
1056
|
+
* Clones the nodes in the collection.
|
1057
|
+
```
|
1058
|
+
$().clone();// Deep clone of all elements
|
1059
|
+
$().clone(false); //Shallow clone
|
1060
|
+
```
|
1061
|
+
|
1062
|
+
* @param {Boolean} [deep] - do a deep copy or not
|
1063
|
+
* @return {Object} jqMobi object of cloned nodes
|
1064
|
+
* @title $().clone();
|
1065
|
+
*/
|
1066
|
+
clone: function(deep) {
|
1067
|
+
deep = deep === false ? false : true;
|
1068
|
+
if (this.length == 0)
|
1069
|
+
return undefined;
|
1070
|
+
var elems = [];
|
1071
|
+
for (var i = 0; i < this.length; i++) {
|
1072
|
+
elems.push(this[i].cloneNode(deep));
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
return $(elems);
|
1076
|
+
},
|
1077
|
+
/**
|
1078
|
+
* Returns the number of elements in the collection
|
1079
|
+
```
|
1080
|
+
$().size();
|
1081
|
+
```
|
1082
|
+
|
1083
|
+
* @return {Int}
|
1084
|
+
* @title $().size();
|
1085
|
+
*/
|
1086
|
+
size: function() {
|
1087
|
+
return this.length;
|
1088
|
+
},
|
1089
|
+
/**
|
1090
|
+
* Serailizes a form into a query string
|
1091
|
+
```
|
1092
|
+
$().serialize(grouping);
|
1093
|
+
```
|
1094
|
+
* @param {String} [grouping] - optional grouping to the fields -e.g users[name]
|
1095
|
+
* @return {String}
|
1096
|
+
* @title $().serialize(grouping)
|
1097
|
+
*/
|
1098
|
+
serialize: function(grouping) {
|
1099
|
+
if (this.length == 0)
|
1100
|
+
return "";
|
1101
|
+
var params = {};
|
1102
|
+
for (var i = 0; i < this.length; i++)
|
1103
|
+
{
|
1104
|
+
this.slice.call(this[i].elements).forEach(function(elem) {
|
1105
|
+
var type = elem.getAttribute("type");
|
1106
|
+
if (elem.nodeName.toLowerCase() != "fieldset" && !elem.disabled && type != "submit"
|
1107
|
+
&& type != "reset" && type != "button" && ((type != "radio" && type != "checkbox") || elem.checked))
|
1108
|
+
params[elem.getAttribute("name")] = elem.value;
|
1109
|
+
});
|
1110
|
+
}
|
1111
|
+
return $.param(params,grouping);
|
1112
|
+
}
|
1113
|
+
};
|
1114
|
+
|
1115
|
+
|
1116
|
+
/* AJAX functions */
|
1117
|
+
|
1118
|
+
function empty() {
|
1119
|
+
}
|
1120
|
+
var ajaxSettings = {
|
1121
|
+
type: 'GET',
|
1122
|
+
beforeSend: empty,
|
1123
|
+
success: empty,
|
1124
|
+
error: empty,
|
1125
|
+
complete: empty,
|
1126
|
+
context: undefined,
|
1127
|
+
timeout: 0,
|
1128
|
+
crossDomain:false
|
1129
|
+
};
|
1130
|
+
/**
|
1131
|
+
* Execute a jsonP call, allowing cross domain scripting
|
1132
|
+
* options.url - URL to call
|
1133
|
+
* options.success - Success function to call
|
1134
|
+
* options.error - Error function to call
|
1135
|
+
```
|
1136
|
+
$.jsonP({url:'mysite.php?callback=?&foo=bar',success:function(){},error:function(){}});
|
1137
|
+
```
|
1138
|
+
|
1139
|
+
* @param {Object} options
|
1140
|
+
* @title $.jsonP(options)
|
1141
|
+
*/
|
1142
|
+
$.jsonP = function(options) {
|
1143
|
+
var callbackName = 'jsonp_callback' + (++_jsonPID);
|
1144
|
+
var abortTimeout = "",
|
1145
|
+
context;
|
1146
|
+
var script = document.createElement("script");
|
1147
|
+
var abort = function() {
|
1148
|
+
$(script).remove();
|
1149
|
+
if (window[callbackName])
|
1150
|
+
window[callbackName] = empty;
|
1151
|
+
};
|
1152
|
+
window[callbackName] = function(data) {
|
1153
|
+
clearTimeout(abortTimeout);
|
1154
|
+
$(script).remove();
|
1155
|
+
delete window[callbackName];
|
1156
|
+
options.success.call(context, data);
|
1157
|
+
};
|
1158
|
+
script.src = options.url.replace(/=\?/, '=' + callbackName);
|
1159
|
+
if(options.error)
|
1160
|
+
{
|
1161
|
+
script.onerror=function(){
|
1162
|
+
clearTimeout(abortTimeout);
|
1163
|
+
options.error.call(context, "", 'error');
|
1164
|
+
}
|
1165
|
+
}
|
1166
|
+
$('head').append(script);
|
1167
|
+
if (options.timeout > 0)
|
1168
|
+
abortTimeout = setTimeout(function() {
|
1169
|
+
options.error.call(context, "", 'timeout');
|
1170
|
+
}, options.timeout);
|
1171
|
+
return {};
|
1172
|
+
};
|
1173
|
+
|
1174
|
+
/**
|
1175
|
+
* Execute an Ajax call with the given options
|
1176
|
+
* options.type - Type of request
|
1177
|
+
* options.beforeSend - function to execute before sending the request
|
1178
|
+
* options.success - success callback
|
1179
|
+
* options.error - error callback
|
1180
|
+
* options.complete - complete callback - callled with a success or error
|
1181
|
+
* options.timeout - timeout to wait for the request
|
1182
|
+
* options.url - URL to make request against
|
1183
|
+
* options.contentType - HTTP Request Content Type
|
1184
|
+
* options.headers - Object of headers to set
|
1185
|
+
* options.dataType - Data type of request
|
1186
|
+
* options.data - data to pass into request. $.param is called on objects
|
1187
|
+
```
|
1188
|
+
var opts={
|
1189
|
+
type:"GET",
|
1190
|
+
success:function(data){},
|
1191
|
+
url:"mypage.php",
|
1192
|
+
data:{bar:'bar'},
|
1193
|
+
}
|
1194
|
+
$.ajax(opts);
|
1195
|
+
```
|
1196
|
+
|
1197
|
+
* @param {Object} options
|
1198
|
+
* @title $.ajax(options)
|
1199
|
+
*/
|
1200
|
+
$.ajax = function(opts) {
|
1201
|
+
var xhr;
|
1202
|
+
try {
|
1203
|
+
xhr = new window.XMLHttpRequest();
|
1204
|
+
var settings = opts || {};
|
1205
|
+
for (var key in ajaxSettings) {
|
1206
|
+
if (!settings[key])
|
1207
|
+
settings[key] = ajaxSettings[key];
|
1208
|
+
}
|
1209
|
+
|
1210
|
+
if (!settings.url)
|
1211
|
+
settings.url = window.location;
|
1212
|
+
if (!settings.contentType)
|
1213
|
+
settings.contentType = "application/x-www-form-urlencoded";
|
1214
|
+
if (!settings.headers)
|
1215
|
+
settings.headers = {};
|
1216
|
+
|
1217
|
+
if (!settings.dataType)
|
1218
|
+
settings.dataType = "text/html";
|
1219
|
+
else {
|
1220
|
+
switch (settings.dataType) {
|
1221
|
+
case "script":
|
1222
|
+
settings.dataType = 'text/javascript, application/javascript';
|
1223
|
+
break;
|
1224
|
+
case "json":
|
1225
|
+
settings.dataType = 'application/json';
|
1226
|
+
break;
|
1227
|
+
case "xml":
|
1228
|
+
settings.dataType = 'application/xml, text/xml';
|
1229
|
+
break;
|
1230
|
+
case "html":
|
1231
|
+
settings.dataType = 'text/html';
|
1232
|
+
break;
|
1233
|
+
case "text":
|
1234
|
+
settings.dataType = 'text/plain';
|
1235
|
+
break;
|
1236
|
+
default:
|
1237
|
+
settings.dataType = "text/html";
|
1238
|
+
break;
|
1239
|
+
case "jsonp":
|
1240
|
+
return $.jsonP(opts);
|
1241
|
+
break;
|
1242
|
+
}
|
1243
|
+
}
|
1244
|
+
if ($.isObject(settings.data))
|
1245
|
+
settings.data = $.param(settings.data);
|
1246
|
+
if (settings.type.toLowerCase() === "get" && settings.data) {
|
1247
|
+
if (settings.url.indexOf("?") === -1)
|
1248
|
+
settings.url += "?" + settings.data;
|
1249
|
+
else
|
1250
|
+
settings.url += "&" + settings.data;
|
1251
|
+
}
|
1252
|
+
|
1253
|
+
if (/=\?/.test(settings.url)) {
|
1254
|
+
return $.jsonP(settings);
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
if (!settings.crossDomain) settings.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(settings.url) &&
|
1258
|
+
RegExp.$2 != window.location.host;
|
1259
|
+
|
1260
|
+
if(!settings.crossDomain)
|
1261
|
+
settings.headers = $.extend({'X-Requested-With': 'XMLHttpRequest'}, settings.headers);
|
1262
|
+
var abortTimeout;
|
1263
|
+
var context = settings.context;
|
1264
|
+
var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol;
|
1265
|
+
xhr.onreadystatechange = function() {
|
1266
|
+
var mime = settings.dataType;
|
1267
|
+
if (xhr.readyState === 4) {
|
1268
|
+
clearTimeout(abortTimeout);
|
1269
|
+
var result, error = false;
|
1270
|
+
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0&&protocol=='file:') {
|
1271
|
+
if (mime === 'application/json' && !(/^\s*$/.test(xhr.responseText))) {
|
1272
|
+
try {
|
1273
|
+
result = JSON.parse(xhr.responseText);
|
1274
|
+
} catch (e) {
|
1275
|
+
error = e;
|
1276
|
+
}
|
1277
|
+
} else
|
1278
|
+
result = xhr.responseText;
|
1279
|
+
//If we're looking at a local file, we assume that no response sent back means there was an error
|
1280
|
+
if(xhr.status===0&&result.length===0)
|
1281
|
+
error=true;
|
1282
|
+
if (error)
|
1283
|
+
settings.error.call(context, xhr, 'parsererror', error);
|
1284
|
+
else {
|
1285
|
+
settings.success.call(context, result, 'success', xhr);
|
1286
|
+
}
|
1287
|
+
} else {
|
1288
|
+
error = true;
|
1289
|
+
settings.error.call(context, xhr, 'error');
|
1290
|
+
}
|
1291
|
+
settings.complete.call(context, xhr, error ? 'error' : 'success');
|
1292
|
+
}
|
1293
|
+
};
|
1294
|
+
xhr.open(settings.type, settings.url, true);
|
1295
|
+
|
1296
|
+
if (settings.contentType)
|
1297
|
+
settings.headers['Content-Type'] = settings.contentType;
|
1298
|
+
for (var name in settings.headers)
|
1299
|
+
xhr.setRequestHeader(name, settings.headers[name]);
|
1300
|
+
if (settings.beforeSend.call(context, xhr, settings) === false) {
|
1301
|
+
xhr.abort();
|
1302
|
+
return false;
|
1303
|
+
}
|
1304
|
+
|
1305
|
+
if (settings.timeout > 0)
|
1306
|
+
abortTimeout = setTimeout(function() {
|
1307
|
+
xhr.onreadystatechange = empty;
|
1308
|
+
xhr.abort();
|
1309
|
+
settings.error.call(context, xhr, 'timeout');
|
1310
|
+
}, settings.timeout);
|
1311
|
+
xhr.send(settings.data);
|
1312
|
+
} catch (e) {
|
1313
|
+
console.log(e);
|
1314
|
+
}
|
1315
|
+
return xhr;
|
1316
|
+
};
|
1317
|
+
|
1318
|
+
|
1319
|
+
/**
|
1320
|
+
* Shorthand call to an Ajax GET request
|
1321
|
+
```
|
1322
|
+
$.get("mypage.php?foo=bar",function(data){});
|
1323
|
+
```
|
1324
|
+
|
1325
|
+
* @param {String} url to hit
|
1326
|
+
* @param {Function} success
|
1327
|
+
* @title $.get(url,success)
|
1328
|
+
*/
|
1329
|
+
$.get = function(url, success) {
|
1330
|
+
return this.ajax({
|
1331
|
+
url: url,
|
1332
|
+
success: success
|
1333
|
+
});
|
1334
|
+
};
|
1335
|
+
/**
|
1336
|
+
* Shorthand call to an Ajax POST request
|
1337
|
+
```
|
1338
|
+
$.post("mypage.php",{bar:'bar'},function(data){});
|
1339
|
+
```
|
1340
|
+
|
1341
|
+
* @param {String} url to hit
|
1342
|
+
* @param {Object} [data] to pass in
|
1343
|
+
* @param {Function} success
|
1344
|
+
* @param {String} [dataType]
|
1345
|
+
* @title $.post(url,[data],success,[dataType])
|
1346
|
+
*/
|
1347
|
+
$.post = function(url, data, success, dataType) {
|
1348
|
+
if (typeof (data) === "function") {
|
1349
|
+
success = data;
|
1350
|
+
data = {};
|
1351
|
+
}
|
1352
|
+
if (dataType === undefined)
|
1353
|
+
dataType = "html";
|
1354
|
+
return this.ajax({
|
1355
|
+
url: url,
|
1356
|
+
type: "POST",
|
1357
|
+
data: data,
|
1358
|
+
dataType: dataType,
|
1359
|
+
success: success
|
1360
|
+
});
|
1361
|
+
};
|
1362
|
+
/**
|
1363
|
+
* Shorthand call to an Ajax request that expects a JSON response
|
1364
|
+
```
|
1365
|
+
$.getJSON("mypage.php",{bar:'bar'},function(data){});
|
1366
|
+
```
|
1367
|
+
|
1368
|
+
* @param {String} url to hit
|
1369
|
+
* @param {Object} [data]
|
1370
|
+
* @param {Function} [success]
|
1371
|
+
* @title $.getJSON(url,data,success)
|
1372
|
+
*/
|
1373
|
+
$.getJSON = function(url, data, success) {
|
1374
|
+
if (typeof (data) === "function") {
|
1375
|
+
success = data;
|
1376
|
+
data = {};
|
1377
|
+
}
|
1378
|
+
return this.ajax({
|
1379
|
+
url: url,
|
1380
|
+
data: data,
|
1381
|
+
success: success,
|
1382
|
+
dataType: "json"
|
1383
|
+
});
|
1384
|
+
};
|
1385
|
+
|
1386
|
+
/**
|
1387
|
+
* Converts an object into a key/value par with an optional prefix. Used for converting objects to a query string
|
1388
|
+
```
|
1389
|
+
var obj={
|
1390
|
+
foo:'foo',
|
1391
|
+
bar:'bar'
|
1392
|
+
}
|
1393
|
+
var kvp=$.param(obj,'data');
|
1394
|
+
```
|
1395
|
+
|
1396
|
+
* @param {Object} object
|
1397
|
+
* @param {String} [prefix]
|
1398
|
+
* @return {String} Key/value pair representation
|
1399
|
+
* @title $.param(object,[prefix];
|
1400
|
+
*/
|
1401
|
+
$.param = function(obj, prefix) {
|
1402
|
+
var str = [];
|
1403
|
+
if (obj instanceof $jqm) {
|
1404
|
+
obj.each(function() {
|
1405
|
+
var k = prefix ? prefix + "[]" : this.id,
|
1406
|
+
v = this.value;
|
1407
|
+
str.push((k) + "=" + encodeURIComponent(v));
|
1408
|
+
});
|
1409
|
+
} else {
|
1410
|
+
for (var p in obj) {
|
1411
|
+
var k = prefix ? prefix + "[" + p + "]" : p,
|
1412
|
+
v = obj[p];
|
1413
|
+
str.push($.isObject(v) ? $.param(v, k) : (k) + "=" + encodeURIComponent(v));
|
1414
|
+
}
|
1415
|
+
}
|
1416
|
+
return str.join("&");
|
1417
|
+
};
|
1418
|
+
/**
|
1419
|
+
* Used for backwards compatibility. Uses native JSON.parse function
|
1420
|
+
```
|
1421
|
+
var obj=$.parseJSON("{\"bar\":\"bar\"}");
|
1422
|
+
```
|
1423
|
+
|
1424
|
+
* @params {String} string
|
1425
|
+
* @return {Object}
|
1426
|
+
* @title $.parseJSON(string)
|
1427
|
+
*/
|
1428
|
+
$.parseJSON = function(string) {
|
1429
|
+
return JSON.parse(string);
|
1430
|
+
};
|
1431
|
+
/**
|
1432
|
+
* Helper function to convert XML into the DOM node representation
|
1433
|
+
```
|
1434
|
+
var xmlDoc=$.parseXML("<xml><foo>bar</foo></xml>");
|
1435
|
+
```
|
1436
|
+
|
1437
|
+
* @param {String} string
|
1438
|
+
* @return {Object} DOM nodes
|
1439
|
+
* @title $.parseXML(string)
|
1440
|
+
*/
|
1441
|
+
$.parseXML = function(string) {
|
1442
|
+
return (new DOMParser).parseFromString(string, "text/xml");
|
1443
|
+
};
|
1444
|
+
/**
|
1445
|
+
* Helper function to parse the user agent. Sets the following
|
1446
|
+
* .os.webkit
|
1447
|
+
* .os.android
|
1448
|
+
* .os.ipad
|
1449
|
+
* .os.iphone
|
1450
|
+
* .os.webos
|
1451
|
+
* .os.touchpad
|
1452
|
+
* .os.blackberry
|
1453
|
+
* .os.opera
|
1454
|
+
* .os.fennec
|
1455
|
+
* @api private
|
1456
|
+
*/
|
1457
|
+
function detectUA($, userAgent) {
|
1458
|
+
$.os = {};
|
1459
|
+
$.os.webkit = userAgent.match(/WebKit\/([\d.]+)/) ? true : false;
|
1460
|
+
$.os.android = userAgent.match(/(Android)\s+([\d.]+)/) || userAgent.match(/Silk-Accelerated/) ? true : false;
|
1461
|
+
$.os.ipad = userAgent.match(/(iPad).*OS\s([\d_]+)/) ? true : false;
|
1462
|
+
$.os.iphone = !$.os.ipad && userAgent.match(/(iPhone\sOS)\s([\d_]+)/) ? true : false;
|
1463
|
+
$.os.webos = userAgent.match(/(webOS|hpwOS)[\s\/]([\d.]+)/) ? true : false;
|
1464
|
+
$.os.touchpad = $.os.webos && userAgent.match(/TouchPad/) ? true : false;
|
1465
|
+
$.os.ios = $.os.ipad || $.os.iphone;
|
1466
|
+
$.os.blackberry = userAgent.match(/BlackBerry/) || userAgent.match(/PlayBook/) ? true : false;
|
1467
|
+
$.os.opera = userAgent.match(/Opera Mobi/) ? true : false;
|
1468
|
+
$.os.fennec = userAgent.match(/fennec/i) ? true : false;
|
1469
|
+
$.os.desktop = !($.os.ios || $.os.android || $.os.blackberry || $.os.opera || $.os.fennec);
|
1470
|
+
}
|
1471
|
+
detectUA($, navigator.userAgent);
|
1472
|
+
$.__detectUA = detectUA; //needed for unit tests
|
1473
|
+
if (typeof String.prototype.trim !== 'function') {
|
1474
|
+
|
1475
|
+
/**
|
1476
|
+
* Helper function for iOS 3.1.3
|
1477
|
+
*/
|
1478
|
+
String.prototype.trim = function() {
|
1479
|
+
this.replace(/(\r\n|\n|\r)/gm, "").replace(/^\s+|\s+$/, '');
|
1480
|
+
return this
|
1481
|
+
};
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
/**
|
1485
|
+
* Utility function to create a psuedo GUID
|
1486
|
+
```
|
1487
|
+
var id= $.uuid();
|
1488
|
+
```
|
1489
|
+
* @title $.uuid
|
1490
|
+
*/
|
1491
|
+
$.uuid = function () {
|
1492
|
+
var S4 = function () {
|
1493
|
+
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
1494
|
+
}
|
1495
|
+
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
1496
|
+
};
|
1497
|
+
/**
|
1498
|
+
Zepto.js events
|
1499
|
+
@api private
|
1500
|
+
*/
|
1501
|
+
|
1502
|
+
//The following is modified from Zepto.js / events.js
|
1503
|
+
//We've removed depricated jQuery events like .live and allow anonymous functions to be removed
|
1504
|
+
var $$ = $.qsa,
|
1505
|
+
handlers = {},
|
1506
|
+
_jqmid = 1,
|
1507
|
+
specialEvents = {};
|
1508
|
+
/**
|
1509
|
+
* Gets or sets the expando property on a javascript element
|
1510
|
+
* Also increments the internal counter for elements;
|
1511
|
+
* @param {Object} element
|
1512
|
+
* @return {Int} jqmid
|
1513
|
+
* @api private
|
1514
|
+
*/
|
1515
|
+
function jqmid(element) {
|
1516
|
+
return element._jqmid || (element._jqmid = _jqmid++);
|
1517
|
+
}
|
1518
|
+
/**
|
1519
|
+
* Searches through a local array that keeps track of event handlers for proxying.
|
1520
|
+
* Since we listen for multiple events, we match up the event, function and selector.
|
1521
|
+
* This is used to find, execute, remove proxied event functions
|
1522
|
+
* @param {Object} element
|
1523
|
+
* @param {String} [event]
|
1524
|
+
* @param {Function} [function]
|
1525
|
+
* @param {String|Object|Array} [selector]
|
1526
|
+
* @return {Function|null} handler function or false if not found
|
1527
|
+
* @api private
|
1528
|
+
*/
|
1529
|
+
function findHandlers(element, event, fn, selector) {
|
1530
|
+
event = parse(event);
|
1531
|
+
if (event.ns)
|
1532
|
+
var matcher = matcherFor(event.ns);
|
1533
|
+
return (handlers[jqmid(element)] || []).filter(function(handler) {
|
1534
|
+
return handler && (!event.e || handler.e == event.e) && (!event.ns || matcher.test(handler.ns)) && (!fn || handler.fn == fn || (typeof handler.fn === 'function' && typeof fn === 'function' && "" + handler.fn === "" + fn)) && (!selector || handler.sel == selector);
|
1535
|
+
});
|
1536
|
+
}
|
1537
|
+
/**
|
1538
|
+
* Splits an event name by "." to look for namespaces (e.g touch.click)
|
1539
|
+
* @param {String} event
|
1540
|
+
* @return {Object} an object with the event name and namespace
|
1541
|
+
* @api private
|
1542
|
+
*/
|
1543
|
+
function parse(event) {
|
1544
|
+
var parts = ('' + event).split('.');
|
1545
|
+
return {
|
1546
|
+
e: parts[0],
|
1547
|
+
ns: parts.slice(1).sort().join(' ')
|
1548
|
+
};
|
1549
|
+
}
|
1550
|
+
/**
|
1551
|
+
* Regular expression checker for event namespace checking
|
1552
|
+
* @param {String} namespace
|
1553
|
+
* @return {Regex} regular expression
|
1554
|
+
* @api private
|
1555
|
+
*/
|
1556
|
+
function matcherFor(ns) {
|
1557
|
+
return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)');
|
1558
|
+
}
|
1559
|
+
|
1560
|
+
/**
|
1561
|
+
* Utility function that will loop through events that can be a hash or space delimited and executes the function
|
1562
|
+
* @param {String|Object} events
|
1563
|
+
* @param {Function} fn
|
1564
|
+
* @param {Iterator} [iterator]
|
1565
|
+
* @api private
|
1566
|
+
*/
|
1567
|
+
function eachEvent(events, fn, iterator) {
|
1568
|
+
if ($.isObject(events))
|
1569
|
+
$.each(events, iterator);
|
1570
|
+
else
|
1571
|
+
events.split(/\s/).forEach(function(type) {
|
1572
|
+
iterator(type, fn)
|
1573
|
+
});
|
1574
|
+
}
|
1575
|
+
|
1576
|
+
/**
|
1577
|
+
* Helper function for adding an event and creating the proxy handler function.
|
1578
|
+
* All event handlers call this to wire event listeners up. We create proxy handlers so they can be removed then.
|
1579
|
+
* This is needed for delegate/on
|
1580
|
+
* @param {Object} element
|
1581
|
+
* @param {String|Object} events
|
1582
|
+
* @param {Function} function that will be executed when event triggers
|
1583
|
+
* @param {String|Array|Object} [selector]
|
1584
|
+
* @param {Boolean} [getDelegate]
|
1585
|
+
* @api private
|
1586
|
+
*/
|
1587
|
+
function add(element, events, fn, selector, getDelegate) {
|
1588
|
+
var id = jqmid(element),
|
1589
|
+
set = (handlers[id] || (handlers[id] = []));
|
1590
|
+
|
1591
|
+
eachEvent(events, fn, function(event, fn) {
|
1592
|
+
var delegate = getDelegate && getDelegate(fn, event),
|
1593
|
+
callback = delegate || fn;
|
1594
|
+
var proxyfn = function(event) {
|
1595
|
+
var result = callback.apply(element, [event].concat(event.data));
|
1596
|
+
if (result === false)
|
1597
|
+
event.preventDefault();
|
1598
|
+
return result;
|
1599
|
+
};
|
1600
|
+
var handler = $.extend(parse(event), {
|
1601
|
+
fn: fn,
|
1602
|
+
proxy: proxyfn,
|
1603
|
+
sel: selector,
|
1604
|
+
del: delegate,
|
1605
|
+
i: set.length
|
1606
|
+
});
|
1607
|
+
set.push(handler);
|
1608
|
+
element.addEventListener(handler.e, proxyfn, false);
|
1609
|
+
});
|
1610
|
+
}
|
1611
|
+
|
1612
|
+
/**
|
1613
|
+
* Helper function to remove event listeners. We look through each event and then the proxy handler array to see if it exists
|
1614
|
+
* If found, we remove the listener and the entry from the proxy array. If no function is specified, we remove all listeners that match
|
1615
|
+
* @param {Object} element
|
1616
|
+
* @param {String|Object} events
|
1617
|
+
* @param {Function} [fn]
|
1618
|
+
* @param {String|Array|Object} [selector]
|
1619
|
+
* @api private
|
1620
|
+
*/
|
1621
|
+
function remove(element, events, fn, selector) {
|
1622
|
+
|
1623
|
+
var id = jqmid(element);
|
1624
|
+
eachEvent(events || '', fn, function(event, fn) {
|
1625
|
+
findHandlers(element, event, fn, selector).forEach(function(handler) {
|
1626
|
+
delete handlers[id][handler.i];
|
1627
|
+
element.removeEventListener(handler.e, handler.proxy, false);
|
1628
|
+
});
|
1629
|
+
});
|
1630
|
+
}
|
1631
|
+
|
1632
|
+
$.event = {
|
1633
|
+
add: add,
|
1634
|
+
remove: remove
|
1635
|
+
}
|
1636
|
+
|
1637
|
+
/**
|
1638
|
+
* Binds an event to each element in the collection and executes the callback
|
1639
|
+
```
|
1640
|
+
$().bind('click',function(){console.log('I clicked '+this.id);});
|
1641
|
+
```
|
1642
|
+
|
1643
|
+
* @param {String|Object} event
|
1644
|
+
* @param {Function} callback
|
1645
|
+
* @return {Object} jqMobi object
|
1646
|
+
* @title $().bind(event,callback)
|
1647
|
+
*/
|
1648
|
+
$.fn.bind = function(event, callback) {
|
1649
|
+
for (var i = 0; i < this.length; i++) {
|
1650
|
+
add(this[i], event, callback);
|
1651
|
+
}
|
1652
|
+
return this;
|
1653
|
+
};
|
1654
|
+
/**
|
1655
|
+
* Unbinds an event to each element in the collection. If a callback is passed in, we remove just that one, otherwise we remove all callbacks for those events
|
1656
|
+
```
|
1657
|
+
$().unbind('click'); //Unbinds all click events
|
1658
|
+
$().unbind('click',myFunc); //Unbinds myFunc
|
1659
|
+
```
|
1660
|
+
|
1661
|
+
* @param {String|Object} event
|
1662
|
+
* @param {Function} [callback]
|
1663
|
+
* @return {Object} jqMobi object
|
1664
|
+
* @title $().unbind(event,[callback]);
|
1665
|
+
*/
|
1666
|
+
$.fn.unbind = function(event, callback) {
|
1667
|
+
for (var i = 0; i < this.length; i++) {
|
1668
|
+
remove(this[i], event, callback);
|
1669
|
+
}
|
1670
|
+
return this;
|
1671
|
+
};
|
1672
|
+
|
1673
|
+
/**
|
1674
|
+
* Binds an event to each element in the collection that will only execute once. When it executes, we remove the event listener then right away so it no longer happens
|
1675
|
+
```
|
1676
|
+
$().one('click',function(){console.log('I was clicked once');});
|
1677
|
+
```
|
1678
|
+
|
1679
|
+
* @param {String|Object} event
|
1680
|
+
* @param {Function} [callback]
|
1681
|
+
* @return jqMobi object
|
1682
|
+
* @title $().one(event,callback);
|
1683
|
+
*/
|
1684
|
+
$.fn.one = function(event, callback) {
|
1685
|
+
return this.each(function(i, element) {
|
1686
|
+
add(this, event, callback, null, function(fn, type) {
|
1687
|
+
return function() {
|
1688
|
+
var result = fn.apply(element, arguments);
|
1689
|
+
remove(element, type, fn);
|
1690
|
+
return result;
|
1691
|
+
}
|
1692
|
+
});
|
1693
|
+
});
|
1694
|
+
};
|
1695
|
+
|
1696
|
+
/**
|
1697
|
+
* internal variables
|
1698
|
+
* @api private
|
1699
|
+
*/
|
1700
|
+
|
1701
|
+
var returnTrue = function() {
|
1702
|
+
return true
|
1703
|
+
},
|
1704
|
+
returnFalse = function() {
|
1705
|
+
return false
|
1706
|
+
},
|
1707
|
+
eventMethods = {
|
1708
|
+
preventDefault: 'isDefaultPrevented',
|
1709
|
+
stopImmediatePropagation: 'isImmediatePropagationStopped',
|
1710
|
+
stopPropagation: 'isPropagationStopped'
|
1711
|
+
};
|
1712
|
+
/**
|
1713
|
+
* Creates a proxy function for event handlers
|
1714
|
+
* @param {String} event
|
1715
|
+
* @return {Function} proxy
|
1716
|
+
* @api private
|
1717
|
+
*/
|
1718
|
+
function createProxy(event) {
|
1719
|
+
var proxy = $.extend({
|
1720
|
+
originalEvent: event
|
1721
|
+
}, event);
|
1722
|
+
$.each(eventMethods, function(name, predicate) {
|
1723
|
+
proxy[name] = function() {
|
1724
|
+
this[predicate] = returnTrue;
|
1725
|
+
return event[name].apply(event, arguments);
|
1726
|
+
};
|
1727
|
+
proxy[predicate] = returnFalse;
|
1728
|
+
})
|
1729
|
+
return proxy;
|
1730
|
+
}
|
1731
|
+
|
1732
|
+
/**
|
1733
|
+
* Delegate an event based off the selector. The event will be registered at the parent level, but executes on the selector.
|
1734
|
+
```
|
1735
|
+
$("#div").delegate("p",'click',callback);
|
1736
|
+
```
|
1737
|
+
|
1738
|
+
* @param {String|Array|Object} selector
|
1739
|
+
* @param {String|Object} event
|
1740
|
+
* @param {Function} callback
|
1741
|
+
* @return {Object} jqMobi object
|
1742
|
+
* @title $().delegate(selector,event,callback)
|
1743
|
+
*/
|
1744
|
+
$.fn.delegate = function(selector, event, callback) {
|
1745
|
+
for (var i = 0; i < this.length; i++) {
|
1746
|
+
var element = this[i];
|
1747
|
+
add(element, event, callback, selector, function(fn) {
|
1748
|
+
return function(e) {
|
1749
|
+
var evt, match = $(e.target).closest(selector, element).get(0);
|
1750
|
+
if (match) {
|
1751
|
+
evt = $.extend(createProxy(e), {
|
1752
|
+
currentTarget: match,
|
1753
|
+
liveFired: element
|
1754
|
+
});
|
1755
|
+
return fn.apply(match, [evt].concat([].slice.call(arguments, 1)));
|
1756
|
+
}
|
1757
|
+
}
|
1758
|
+
});
|
1759
|
+
}
|
1760
|
+
return this;
|
1761
|
+
};
|
1762
|
+
|
1763
|
+
/**
|
1764
|
+
* Unbinds events that were registered through delegate. It acts upon the selector and event. If a callback is specified, it will remove that one, otherwise it removes all of them.
|
1765
|
+
```
|
1766
|
+
$("#div").undelegate("p",'click',callback);//Undelegates callback for the click event
|
1767
|
+
$("#div").undelegate("p",'click');//Undelegates all click events
|
1768
|
+
```
|
1769
|
+
|
1770
|
+
* @param {String|Array|Object} selector
|
1771
|
+
* @param {String|Object} event
|
1772
|
+
* @param {Function} callback
|
1773
|
+
* @return {Object} jqMobi object
|
1774
|
+
* @title $().undelegate(selector,event,[callback]);
|
1775
|
+
*/
|
1776
|
+
$.fn.undelegate = function(selector, event, callback) {
|
1777
|
+
for (var i = 0; i < this.length; i++) {
|
1778
|
+
remove(this[i], event, callback, selector);
|
1779
|
+
}
|
1780
|
+
return this;
|
1781
|
+
}
|
1782
|
+
|
1783
|
+
/**
|
1784
|
+
* Similar to delegate, but the function parameter order is easier to understand.
|
1785
|
+
* If selector is undefined or a function, we just call .bind, otherwise we use .delegate
|
1786
|
+
```
|
1787
|
+
$("#div").on("click","p",callback);
|
1788
|
+
```
|
1789
|
+
|
1790
|
+
* @param {String|Array|Object} selector
|
1791
|
+
* @param {String|Object} event
|
1792
|
+
* @param {Function} callback
|
1793
|
+
* @return {Object} jqMobi object
|
1794
|
+
* @title $().on(event,selector,callback);
|
1795
|
+
*/
|
1796
|
+
$.fn.on = function(event, selector, callback) {
|
1797
|
+
return selector === undefined || $.isFunction(selector) ? this.bind(event, selector) : this.delegate(selector, event, callback);
|
1798
|
+
};
|
1799
|
+
/**
|
1800
|
+
* Removes event listeners for .on()
|
1801
|
+
* If selector is undefined or a function, we call unbind, otherwise it's undelegate
|
1802
|
+
```
|
1803
|
+
$().off("click","p",callback); //Remove callback function for click events
|
1804
|
+
$().off("click","p") //Remove all click events
|
1805
|
+
```
|
1806
|
+
|
1807
|
+
* @param {String|Object} event
|
1808
|
+
* @param {String|Array|Object} selector
|
1809
|
+
* @param {Sunction} callback
|
1810
|
+
* @return {Object} jqMobi object
|
1811
|
+
* @title $().off(event,selector,[callback])
|
1812
|
+
*/
|
1813
|
+
$.fn.off = function(event, selector, callback) {
|
1814
|
+
return selector === undefined || $.isFunction(selector) ? this.unbind(event, selector) : this.undelegate(selector, event, callback);
|
1815
|
+
};
|
1816
|
+
|
1817
|
+
/**
|
1818
|
+
This triggers an event to be dispatched. Usefull for emulating events, etc.
|
1819
|
+
```
|
1820
|
+
$().trigger("click",{foo:'bar'});//Trigger the click event and pass in data
|
1821
|
+
```
|
1822
|
+
|
1823
|
+
* @param {String|Object} event
|
1824
|
+
* @param {Object} [data]
|
1825
|
+
* @return {Object} jqMobi object
|
1826
|
+
* @title $().trigger(event,data);
|
1827
|
+
*/
|
1828
|
+
$.fn.trigger = function(event, data) {
|
1829
|
+
if (typeof event == 'string')
|
1830
|
+
event = $.Event(event);
|
1831
|
+
event.data = data;
|
1832
|
+
for (var i = 0; i < this.length; i++) {
|
1833
|
+
this[i].dispatchEvent(event)
|
1834
|
+
}
|
1835
|
+
return this;
|
1836
|
+
};
|
1837
|
+
|
1838
|
+
/**
|
1839
|
+
* Creates a custom event to be used internally.
|
1840
|
+
* @param {String} type
|
1841
|
+
* @param {Object} [properties]
|
1842
|
+
* @return {event} a custom event that can then be dispatched
|
1843
|
+
* @title $.Event(type,props);
|
1844
|
+
*/
|
1845
|
+
|
1846
|
+
$.Event = function(type, props) {
|
1847
|
+
var event = document.createEvent(specialEvents[type] || 'Events'),
|
1848
|
+
bubbles = true;
|
1849
|
+
if (props)
|
1850
|
+
for (var name in props)
|
1851
|
+
(name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]);
|
1852
|
+
event.initEvent(type, bubbles, true, null, null, null, null, null, null, null, null, null, null, null, null);
|
1853
|
+
return event;
|
1854
|
+
};
|
1855
|
+
|
1856
|
+
/**
|
1857
|
+
* Creates a proxy function so you can change the 'this' context in the function
|
1858
|
+
```
|
1859
|
+
var newObj={foo:bar}
|
1860
|
+
$("#main").bind("click",$.proxy(function(evt){console.log(this)},newObj);
|
1861
|
+
```
|
1862
|
+
|
1863
|
+
* @param {Function} Callback
|
1864
|
+
* @param {Object} Context
|
1865
|
+
* @title $.proxy(callback,context);
|
1866
|
+
*/
|
1867
|
+
|
1868
|
+
$.proxy=function(fnc,ctx){
|
1869
|
+
var tmp=function(evt){
|
1870
|
+
|
1871
|
+
return fnc.call(ctx,evt);
|
1872
|
+
}
|
1873
|
+
return tmp;
|
1874
|
+
}
|
1875
|
+
|
1876
|
+
/**
|
1877
|
+
* End of APIS
|
1878
|
+
* @api private
|
1879
|
+
*/
|
1880
|
+
|
1881
|
+
//End zepto/events.js
|
1882
|
+
return $;
|
1883
|
+
|
1884
|
+
})(window);
|
1885
|
+
'$' in window || (window.$ = jq);
|
1886
|
+
//Helper function used in jq.mobi.plugins.
|
1887
|
+
if (!window.numOnly) {
|
1888
|
+
window.numOnly = function numOnly(val) {
|
1889
|
+
if (isNaN(parseFloat(val)))
|
1890
|
+
val = val.replace(/[^0-9.-]/, "");
|
1891
|
+
return parseFloat(val);
|
1892
|
+
}
|
1893
|
+
}
|
1894
|
+
}
|