jqmobi-rails 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +8 -0
  3. data/LICENSE +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +68 -0
  6. data/jqmobi-rails.gemspec +17 -0
  7. data/lib/jqmobi/rails/engine.rb +6 -0
  8. data/lib/jqmobi/rails/version.rb +7 -0
  9. data/lib/jqmobi/rails.rb +7 -0
  10. data/lib/jqmobi-rails.rb +1 -0
  11. data/vendor/assets/javascripts/jq.mobi.js +1894 -0
  12. data/vendor/assets/javascripts/jq.mobi_ujs.js +393 -0
  13. data/vendor/assets/javascripts/jq.ui.js +3396 -0
  14. data/vendor/assets/javascripts/plugins/jq.actionsheet.js +99 -0
  15. data/vendor/assets/javascripts/plugins/jq.alphatable.js +136 -0
  16. data/vendor/assets/javascripts/plugins/jq.carousel.js +415 -0
  17. data/vendor/assets/javascripts/plugins/jq.css3animate.js +155 -0
  18. data/vendor/assets/javascripts/plugins/jq.drawer.js +224 -0
  19. data/vendor/assets/javascripts/plugins/jq.fx.js +110 -0
  20. data/vendor/assets/javascripts/plugins/jq.passwordBox.js +45 -0
  21. data/vendor/assets/javascripts/plugins/jq.popup.js +201 -0
  22. data/vendor/assets/javascripts/plugins/jq.scroller.js +540 -0
  23. data/vendor/assets/javascripts/plugins/jq.selectBox.js +315 -0
  24. data/vendor/assets/javascripts/plugins/jq.shake.js +39 -0
  25. data/vendor/assets/javascripts/plugins/jq.social.js +113 -0
  26. data/vendor/assets/javascripts/plugins/jq.swipe.js +121 -0
  27. data/vendor/assets/javascripts/plugins/jq.template.js +26 -0
  28. data/vendor/assets/javascripts/plugins/jq.web.min.js +66 -0
  29. data/vendor/assets/stylesheets/plugins/jq.actionsheet.css +57 -0
  30. data/vendor/assets/stylesheets/plugins/jq.popup.css +73 -0
  31. data/vendor/assets/stylesheets/plugins/jq.scroller.css +10 -0
  32. data/vendor/assets/stylesheets/plugins/jq.selectBox.css +35 -0
  33. 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
+ }