diff --git a/bower.json b/bower.json
index e2ec281..038aac3 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "scrolly",
- "version": "0.4.6",
+ "version": "0.5.0",
"description": "Scrolly: fast vanilla JS scrollbar plugin.",
"keywords": [
"scroll", "scrollbar", "scrolly", "bar",
@@ -13,7 +13,7 @@
},
"devDependencies": {
"jbone": "*",
- "react": "^0.12.1"
+ "react": "^0.14.3"
},
"ignore": [
".gitignore",
diff --git a/gulpfile.js b/gulpfile.js
index 445733d..830647c 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -186,7 +186,8 @@ gulp.task('vendor', function () {
*/
gulp.task('vendor-react', function () {
return gulp.src([
- vendor('react/react.js')
+ vendor('react/react.js'),
+ vendor('react/react-dom.js')
])
.pipe(gulp.dest(paths.js));
});
diff --git a/package.json b/package.json
index 933ed55..51f78c1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "scrolly",
- "version": "0.4.6",
+ "version": "0.5.0",
"description": "Scrolly: fast vanilla JS scrollbar plugin.",
"keywords": [
"scroll", "scrollbar", "scrolly", "bar",
@@ -23,7 +23,7 @@
"gulp-less": "*",
"gulp-livereload": "*",
"gulp-plumber": "*",
- "gulp-react": "^2.0",
+ "gulp-react": "^3.1",
"gulp-rename": "*",
"gulp-uglify": "*",
"gulp-wrapper": "*",
diff --git a/public/css/styles-example.css b/public/css/styles-example.css
index 5a6c41a..f83748e 100644
--- a/public/css/styles-example.css
+++ b/public/css/styles-example.css
@@ -1,3 +1,3 @@
-body{font-family:"Helvetica Neue",Arial,Helvetica,sans-serif;font-size:12px}article{clear:both;float:none;padding:.2em 1em}.scrolly{float:left;width:25%;height:400px}.scrolly>.area.test1{background:#f2e4d8}.scrolly>.area.test1.scrolly.area+.bar{background:#808ca6}.scrolly>.area.test1.scrolly.area+.bar .thumb{background:#283d59}.scrolly .scrolly{background:rgba(0,0,0,0.1);width:100%}
+body{font-family:"Helvetica Neue",Arial,Helvetica,sans-serif;font-size:12px}article{clear:both;float:none;padding:.2em 1em}.scrolly{float:left;width:25%;height:400px}.scrolly>.area.test1{background:#F2E4D8}.scrolly>.area.test1.scrolly.area+.bar{background:#808CA6}.scrolly>.area.test1.scrolly.area+.bar .thumb{background:#283D59}.scrolly .scrolly{background:rgba(0,0,0,0.1);width:100%}
-/* scrolly v0.4.6, 2015.01.12 */
+/* scrolly v0.5.0, 2015.11.26 */
diff --git a/public/css/styles-scrolly.css b/public/css/styles-scrolly.css
index b5b1dc2..a9a8d65 100644
--- a/public/css/styles-scrolly.css
+++ b/public/css/styles-scrolly.css
@@ -1,3 +1,3 @@
.no-user-select{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.scrolly{display:block;overflow:hidden}.scrolly>.area{position:relative;top:0;display:block;overflow:auto;visibility:visible;z-index:1}.scrolly+.bar{background:rgba(255,255,255,0.3);border:0;display:block;position:relative;float:left;left:0;margin-left:-12px;opacity:.2;width:12px;visibility:hidden;z-index:2}.scrolly+.bar>.thumb{position:absolute;top:0;right:2px;background:rgba(0,0,0,0.5);border-radius:4px;width:8px;height:12px}.scrolly+.bar,.scrolly+.bar>.thumb{cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.scrolly+.bar.on-drag,.scrolly+.bar:hover{border-left:1px solid rgba(0,0,0,0.2);opacity:.8;margin-left:-19px;width:18px}.scrolly+.bar.on-drag>.thumb,.scrolly+.bar:hover>.thumb{border-radius:7px;width:14px}.scrolly:hover+.bar,.scrolly+.bar.on-drag,.scrolly+.bar:hover{background:rgba(255,255,255,0.6)}
-/* scrolly v0.4.6, 2015.01.12 */
+/* scrolly v0.5.0, 2015.11.26 */
diff --git a/public/js/react-dom.js b/public/js/react-dom.js
new file mode 100644
index 0000000..02299f1
--- /dev/null
+++ b/public/js/react-dom.js
@@ -0,0 +1,42 @@
+/**
+ * ReactDOM v0.14.3
+ *
+ * Copyright 2013-2015, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ */
+// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
+;(function(f) {
+ // CommonJS
+ if (typeof exports === "object" && typeof module !== "undefined") {
+ module.exports = f(require('react'));
+
+ // RequireJS
+ } else if (typeof define === "function" && define.amd) {
+ define(['react'], f);
+
+ //
```
-Or include like npm module (with nodejs or browserify)
+Or include it like npm module (with nodejs or browserify)
```javascript
var $ = require('jbone');
@@ -85,11 +93,11 @@ $(".header").addClass("loaded");
## AJAX, Deferred
-This part is not covered on jBone. Yuo can select one of a huge amount implementations AJAX and Promises/A+.
+This part is not covered in jBone. You can choose one of a huge amount of AJAX implementations as well as standard Promises/A+ implementations.
For example: [when](https://github.com/cujojs/when), [Q](https://github.com/kriskowal/q), [simply-deferred](https://github.com/sudhirj/simply-deferred), [AJAX](microjs.com/#ajax).
-Example AJAX connecting:
+Example of AJAX connection:
```javascript
// connect reqwest on your page https://rawgithub.com/ded/reqwest/master/reqwest.min.js
@@ -101,7 +109,7 @@ $.ajax({
});
```
-Example Deferred connecting:
+Example of connection with Deferred Object:
```javascript
// connect simply-deferred on your page https://rawgithub.com/sudhirj/simply-deferred/master/deferred.min.js
@@ -115,6 +123,26 @@ $.when(deferred).then(function(response) {
});
```
+## Browser support
+
+Internet Explorer 11+
+
+Safari 6+
+
+iOS 5+ Safari
+
+Android 2.3+ Browser
+
+Chrome
+
+Firefox
+
+## IE9 polyfills
+
+* [classList](https://github.com/remy/polyfills/blob/master/classList.js) (since IE10)
+* [dataset](https://github.com/remy/polyfills/blob/master/dataset.js) (since IE11)
+
+
## API
[jBone](https://github.com/kupriyanenko/jbone/wiki/jBone)
@@ -135,6 +163,11 @@ $.when(deferred).then(function(response) {
* [.val(value)](https://github.com/kupriyanenko/jbone/wiki/Attributes#valvalue)
* [.css(propertyName, value)](https://github.com/kupriyanenko/jbone/wiki/Attributes#csspropertyname-value)
* [.css(properties)](https://github.com/kupriyanenko/jbone/wiki/Attributes#cssproperties)
+* [.addClass(className)](https://github.com/kupriyanenko/jbone/wiki/Attributes#addclassclassname)
+* [.removeClass(className)](https://github.com/kupriyanenko/jbone/wiki/Attributes#removeclassclassname)
+* [.toggleClass(className)](https://github.com/kupriyanenko/jbone/wiki/Attributes#toggleclassclassname)
+* [.toggleClass(className, state)](https://github.com/kupriyanenko/jbone/wiki/Attributes#toggleclassclassname-state)
+* [.hasClass(className)](https://github.com/kupriyanenko/jbone/wiki/Attributes#hasclassclassname)
[Data](https://github.com/kupriyanenko/jbone/wiki/Data)
@@ -147,8 +180,8 @@ $.when(deferred).then(function(response) {
[Event](https://github.com/kupriyanenko/jbone/wiki/Event)
-* [.on(event[, selector], handler)](https://github.com/kupriyanenko/jbone/wiki/Event#onevent-selector-handler)
-* [.one(event[, selector], handler)](https://github.com/kupriyanenko/jbone/wiki/Event#oneevent-selector-handler)
+* [.on(event[, selector, data], handler)](https://github.com/kupriyanenko/jbone/wiki/Event#onevent-selector-data-handler)
+* [.one(event[, selector, data], handler)](https://github.com/kupriyanenko/jbone/wiki/Event#oneevent-selector-data-handler)
* [.off(event[, handler])](https://github.com/kupriyanenko/jbone/wiki/Event#offevent-handler)
* [.trigger(event)](https://github.com/kupriyanenko/jbone/wiki/Event#triggerevent)
@@ -157,7 +190,7 @@ $.when(deferred).then(function(response) {
* [.html()](https://github.com/kupriyanenko/jbone/wiki/Manipulation#html)
* [.html(content)](https://github.com/kupriyanenko/jbone/wiki/Manipulation#htmlcontent)
* [.append(content)](https://github.com/kupriyanenko/jbone/wiki/Manipulation#appendcontent)
-* [.appendTo(target)](https://github.com/kupriyanenko/jbone/wiki/Manipulation#appendtotarget)
+* [.appendTo(element)](https://github.com/kupriyanenko/jbone/wiki/Manipulation#appendtoelement)
* [.empty()](https://github.com/kupriyanenko/jbone/wiki/Manipulation#empty)
* [.remove()](https://github.com/kupriyanenko/jbone/wiki/Manipulation#remove)
@@ -168,12 +201,19 @@ $.when(deferred).then(function(response) {
* [.eq(index)](https://github.com/kupriyanenko/jbone/wiki/Traversing#eqindex)
* [.parent()](https://github.com/kupriyanenko/jbone/wiki/Traversing#parent)
* [.toArray()](https://github.com/kupriyanenko/jbone/wiki/Traversing#toarray)
+* [.add(selector)](https://github.com/kupriyanenko/jbone/wiki/Traversing#addselector)
+* [.add(elements)](https://github.com/kupriyanenko/jbone/wiki/Traversing#addelements)
+* [.add(html)](https://github.com/kupriyanenko/jbone/wiki/Traversing#addhtml)
+* [.add(selection)](https://github.com/kupriyanenko/jbone/wiki/Traversing#addselection)
+* [.add(selector, context)](https://github.com/kupriyanenko/jbone/wiki/Traversing#addselector-context)
[Utilities](https://github.com/kupriyanenko/jbone/wiki/Utilities)
* [jBone.merge(first, second)](https://github.com/kupriyanenko/jbone/wiki/Utilities#jbonemergefirst-second)
* [jBone.contains(container, contained)](https://github.com/kupriyanenko/jbone/wiki/Utilities#jbonecontainscontainer-contained)
* [jBone.extend(target[, object1][, objectN])](https://github.com/kupriyanenko/jbone/wiki/Utilities#jboneextendtarget-object1-objectn)
+* [jBone.makeArray(obj)](https://github.com/kupriyanenko/jbone/wiki/Utilities#jbonemakearrayobj)
+* [jBone.unique(array)](https://github.com/kupriyanenko/jbone/wiki/Utilities#jboneuniquearray)
[Array methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Methods)
@@ -196,6 +236,10 @@ $.when(deferred).then(function(response) {
* [.reduce()](https://developer.mozilla.org/docs/JavaScript/Reference/Global_Objects/Array/reduce)
* [.reduceRight()](https://developer.mozilla.org/docs/JavaScript/Reference/Global_Objects/Array/reduceRight)
+[Internals](https://github.com/kupriyanenko/jbone/wiki/Internals)
+
+* [.pushStack(elements)](https://github.com/kupriyanenko/jbone/wiki/Internals#pushstackelements)
+
## Running the Tests
### Node
diff --git a/vendor/jbone/bower.json b/vendor/jbone/bower.json
index 2ad1c3f..6be272b 100644
--- a/vendor/jbone/bower.json
+++ b/vendor/jbone/bower.json
@@ -1,15 +1,40 @@
{
"name": "jbone",
- "version": "1.0.20",
+ "version": "1.1.2",
+ "description": "Library for DOM manipulation",
"main": "dist/jbone.js",
+ "homepage": "http://jbone.js.org",
"ignore": [
- "**/.*",
- "node_modules",
- "bower_components"
+ ".gitignore",
+ ".travis.yml",
+ "component.json",
+ "Gruntfile.js",
+ "package.json",
+ "perf",
+ "src",
+ "build",
+ "test"
],
"devDependencies": {
"mocha": "1.18.2",
"expect": "0.2.0",
"astrobench": "0.1.1"
+ },
+ "keywords": [
+ "jquery",
+ "jbone",
+ "backbone",
+ "javascript",
+ "DOM",
+ "events",
+ "library"
+ ],
+ "authors": [
+ "Alexey Kupriyanenko "
+ ],
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/kupriyanenko/jbone"
}
}
diff --git a/vendor/jbone/build/bower-install.js b/vendor/jbone/build/bower-install.js
deleted file mode 100644
index 28de8b8..0000000
--- a/vendor/jbone/build/bower-install.js
+++ /dev/null
@@ -1,15 +0,0 @@
-var which = require("which"),
- spawn = require("child_process").spawn;
-
-try {
- which.sync("bower");
-} catch(error) {
- console.error("Bower must be installed to build jBone.");
- console.error("Please install Bower by running the following command:");
- console.error("npm install -g bower");
- process.exit(0);
-}
-
-spawn("bower", ["install"], {
- stdio: "inherit"
-});
diff --git a/vendor/jbone/build/footer.js b/vendor/jbone/build/footer.js
deleted file mode 100644
index fb21078..0000000
--- a/vendor/jbone/build/footer.js
+++ /dev/null
@@ -1,19 +0,0 @@
-if (typeof module === "object" && module && typeof module.exports === "object") {
- // Expose jBone as module.exports in loaders that implement the Node
- // module pattern (including browserify). Do not create the global, since
- // the user will be storing it themselves locally, and globals are frowned
- // upon in the Node module world.
- module.exports = jBone;
-}
-// Register as a AMD module
-else if (typeof define === "function" && define.amd) {
- define(function() {
- return jBone;
- });
-
- win.jBone = win.$ = jBone;
-} else if (typeof win === "object" && typeof win.document === "object") {
- win.jBone = win.$ = jBone;
-}
-
-}(window));
diff --git a/vendor/jbone/build/phantom-shim.js b/vendor/jbone/build/phantom-shim.js
deleted file mode 100644
index a0b650a..0000000
--- a/vendor/jbone/build/phantom-shim.js
+++ /dev/null
@@ -1,23 +0,0 @@
-if (!Function.prototype.bind) {
- Function.prototype.bind = function (oThis) {
- if (typeof this !== "function") {
- // closest thing possible to the ECMAScript 5 internal IsCallable function
- throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
- }
-
- var aArgs = Array.prototype.slice.call(arguments, 1),
- fToBind = this,
- fNOP = function () {},
- fBound = function () {
- return fToBind.apply(
- this instanceof fNOP && oThis ? this : oThis,
- aArgs.concat(Array.prototype.slice.call(arguments))
- );
- };
-
- fNOP.prototype = this.prototype;
- fBound.prototype = new fNOP();
-
- return fBound;
- };
-}
diff --git a/vendor/jbone/build/topper.js b/vendor/jbone/build/topper.js
deleted file mode 100644
index 2ecf455..0000000
--- a/vendor/jbone/build/topper.js
+++ /dev/null
@@ -1 +0,0 @@
-(function (win) {
diff --git a/vendor/jbone/component.json b/vendor/jbone/component.json
deleted file mode 100644
index 0b40a60..0000000
--- a/vendor/jbone/component.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "name": "jbone",
- "repo": "kupriyanenko/jbone",
- "description": "JavaScript Library for DOM manipulation. Replacement jQuery for Backbone in browsers (2.5kb gzipped)",
- "version": "1.0.20",
- "keywords": [
- "jquery",
- "jbone",
- "backbone",
- "javascript",
- "library"
- ],
- "dependencies": {},
- "development": {},
- "license": "MIT",
- "main": "dist/jbone.js",
- "scripts": [
- "dist/jbone.js",
- "dist/jbone.min.js"
- ]
-}
diff --git a/vendor/jbone/dist/jbone.js b/vendor/jbone/dist/jbone.js
index f1d7ce5..0c2c06c 100644
--- a/vendor/jbone/dist/jbone.js
+++ b/vendor/jbone/dist/jbone.js
@@ -1,9 +1,9 @@
/*!
- * jBone v1.0.20 - 2014-11-27 - Library for DOM manipulation
+ * jBone v1.1.2 - 2015-10-09 - Library for DOM manipulation
*
- * https://github.com/kupriyanenko/jbone
+ * http://jbone.js.org
*
- * Copyright 2014 Alexey Kupriyanenko
+ * Copyright 2015 Alexey Kupriyanenko
* Released under the MIT license.
*/
@@ -36,8 +36,7 @@ isObject = function(el) {
return el instanceof Object;
},
isFunction = function(el) {
- var getType = {};
- return el && getType.toString.call(el) === "[object Function]";
+ return ({}).toString.call(el) === "[object Function]";
},
isArray = function(el) {
return Array.isArray(el);
@@ -194,6 +193,12 @@ function isArraylike(obj) {
typeof length === "number" && length > 0 && (length - 1) in obj;
}
+fn.pushStack = function(elems) {
+ var ret = jBone.merge(this.constructor(), elems);
+
+ return ret;
+};
+
jBone.merge = function(first, second) {
var l = second.length,
i = first.length,
@@ -209,32 +214,19 @@ jBone.merge = function(first, second) {
};
jBone.contains = function(container, contained) {
- var result;
-
- container.reverse().some(function(el) {
- if (el.contains(contained)) {
- return result = el;
- }
- });
-
- return result;
+ return container.contains(contained);
};
jBone.extend = function(target) {
- var k, kl, i, tg;
-
- splice.call(arguments, 1).forEach(function(object) {
- if (!object) {
- return;
- }
+ var tg;
- k = keys(object);
- kl = k.length;
- i = 0;
+ splice.call(arguments, 1).forEach(function(source) {
tg = target; //caching target for perf improvement
- for (; i < kl; i++) {
- tg[k[i]] = object[k[i]];
+ if (source) {
+ for (var prop in source) {
+ tg[prop] = source[prop];
+ }
}
});
@@ -255,6 +247,22 @@ jBone.makeArray = function(arr, results) {
return ret;
};
+jBone.unique = function(array) {
+ if (array == null) {
+ return [];
+ }
+
+ var result = [];
+
+ for (var i = 0, length = array.length; i < length; i++) {
+ var value = array[i];
+ if (result.indexOf(value) < 0) {
+ result.push(value);
+ }
+ }
+ return result;
+};
+
function BoneEvent(e, data) {
var key, setter;
@@ -266,6 +274,11 @@ function BoneEvent(e, data) {
this.defaultPrevented = true;
return e[key]();
};
+ } else if (key === "stopImmediatePropagation") {
+ this[key] = function() {
+ this.immediatePropagationStopped = true;
+ return e[key]();
+ };
} else if (isFunction(e[key])) {
this[key] = function() {
return e[key]();
@@ -281,7 +294,11 @@ function BoneEvent(e, data) {
}
}
- jBone.extend(this, data);
+ jBone.extend(this, data, {
+ isImmediatePropagationStopped: function() {
+ return !!this.immediatePropagationStopped;
+ }
+ });
}
jBone.Event = function(event, data) {
@@ -306,163 +323,84 @@ jBone.Event = function(event, data) {
}, data);
};
-fn.on = function(event) {
- var args = arguments,
- length = this.length,
- i = 0,
- callback, target, namespace, fn, events, eventType, expectedTarget, addListener;
-
- if (args.length === 2) {
- callback = args[1];
- } else {
- target = args[1];
- callback = args[2];
- }
-
- addListener = function(el) {
+jBone.event = {
+
+ /**
+ * Attach a handler to an event for the elements
+ * @param {Node} el - Events will be attached to this DOM Node
+ * @param {String} types - One or more space-separated event types and optional namespaces
+ * @param {Function} handler - A function to execute when the event is triggered
+ * @param {Object} [data] - Data to be passed to the handler in event.data
+ * @param {String} [selector] - A selector string to filter the descendants of the selected elements
+ */
+ add: function(el, types, handler, data, selector) {
jBone.setId(el);
- events = jBone.getData(el).events;
- event.split(" ").forEach(function(event) {
- eventType = event.split(".")[0];
- namespace = event.split(".").splice(1).join(".");
- events[eventType] = events[eventType] || [];
-
- fn = function(e) {
- if (e.namespace && e.namespace !== namespace) {
- return;
- }
- expectedTarget = null;
- if (!target) {
- callback.call(el, e);
- } else if (~jBone(el).find(target).indexOf(e.target) || (expectedTarget = jBone.contains(jBone(el).find(target), e.target))) {
- expectedTarget = expectedTarget || e.target;
- e = new BoneEvent(e, {
- currentTarget: expectedTarget
- });
+ var eventHandler = function(e) {
+ jBone.event.dispatch.call(el, e);
+ },
+ events = jBone.getData(el).events,
+ eventType, t, event;
- callback.call(expectedTarget, e);
- }
- };
-
- events[eventType].push({
- namespace: namespace,
- fn: fn,
- originfn: callback
- });
-
- el.addEventListener && el.addEventListener(eventType, fn, false);
- });
- };
-
- for (; i < length; i++) {
- addListener(this[i]);
- }
-
- return this;
-};
-
-fn.one = function(event) {
- var args = arguments,
- i = 0,
- length = this.length,
- callback, target, addListener;
-
- if (args.length === 2) {
- callback = args[1];
- } else {
- target = args[1], callback = args[2];
- }
+ types = types.split(" ");
+ t = types.length;
+ while (t--) {
+ event = types[t];
- addListener = function(el) {
- event.split(" ").forEach(function(event) {
- var fn = function(e) {
- jBone(el).off(event, fn);
- callback.call(el, e);
- };
+ eventType = event.split(".")[0];
+ events[eventType] = events[eventType] || [];
- if (!target) {
- jBone(el).on(event, fn);
+ if (events[eventType].length) {
+ // override with previous event handler
+ eventHandler = events[eventType][0].fn;
} else {
- jBone(el).on(event, target, fn);
- }
- });
- };
-
- for (; i < length; i++) {
- addListener(this[i]);
- }
-
- return this;
-};
-
-fn.trigger = function(event) {
- var events = [],
- i = 0,
- length = this.length,
- dispatchEvents;
-
- if (!event) {
- return this;
- }
-
- if (isString(event)) {
- events = event.split(" ").map(function(event) {
- return jBone.Event(event);
- });
- } else {
- event = event instanceof Event ? event : jBone.Event(event);
- events = [event];
- }
-
- dispatchEvents = function(el) {
- events.forEach(function(event) {
- if (!event.type) {
- return;
+ el.addEventListener && el.addEventListener(eventType, eventHandler, false);
}
- el.dispatchEvent && el.dispatchEvent(event);
- });
- };
-
- for (; i < length; i++) {
- dispatchEvents(this[i]);
- }
-
- return this;
-};
-
-fn.off = function(event, fn) {
- var i = 0,
- length = this.length,
- removeListener = function(events, eventType, index, el, e) {
- var callback;
-
- // get callback
- if ((fn && e.originfn === fn) || !fn) {
- callback = e.fn;
- }
-
- if (events[eventType][index].fn === callback) {
- el.removeEventListener(eventType, callback);
+ events[eventType].push({
+ namespace: event.split(".").splice(1).join("."),
+ fn: eventHandler,
+ selector: selector,
+ data: data,
+ originfn: handler
+ });
+ }
+ },
- // remove handler from cache
- jBone._cache.events[jBone.getData(el).jid][eventType].splice(index, 1);
- }
- },
- events, namespace, removeListeners, eventType;
+ /**
+ * Remove an event handler
+ * @param {Node} el - Events will be deattached from this DOM Node
+ * @param {String} types - One or more space-separated event types and optional namespaces
+ * @param {Function} handler - A handler function previously attached for the event(s)
+ */
+ remove: function(el, types, handler) {
+ var removeListener = function(events, eventType, index, el, e) {
+ var callback;
+
+ // get callback
+ if ((handler && e.originfn === handler) || !handler) {
+ callback = e.fn;
+ }
- removeListeners = function(el) {
- var l, eventsByType, e;
+ if (events[eventType][index].fn === callback) {
+ // remove handler from cache
+ events[eventType].splice(index, 1);
- events = jBone.getData(el).events;
+ if (!events[eventType].length) {
+ el.removeEventListener(eventType, callback);
+ }
+ }
+ },
+ events = jBone.getData(el).events,
+ l,
+ eventsByType;
if (!events) {
return;
}
// remove all events
- if (!event && events) {
+ if (!types && events) {
return keys(events).forEach(function(eventType) {
eventsByType = events[eventType];
l = eventsByType.length;
@@ -473,9 +411,10 @@ fn.off = function(event, fn) {
});
}
- event.split(" ").forEach(function(event) {
- eventType = event.split(".")[0];
- namespace = event.split(".").splice(1).join(".");
+ types.split(" ").forEach(function(eventName) {
+ var eventType = eventName.split(".")[0],
+ namespace = eventName.split(".").splice(1).join("."),
+ e;
// remove named events
if (events[eventType]) {
@@ -504,10 +443,192 @@ fn.off = function(event, fn) {
});
}
});
+ },
+
+ /**
+ * Execute all handlers and behaviors attached to the matched elements for the given event type.
+ * @param {Node} el - Events will be triggered for thie DOM Node
+ * @param {String} event - One or more space-separated event types and optional namespaces
+ */
+ trigger: function(el, event) {
+ var events = [];
+
+ if (isString(event)) {
+ events = event.split(" ").map(function(event) {
+ return jBone.Event(event);
+ });
+ } else {
+ event = event instanceof Event ? event : jBone.Event(event);
+ events = [event];
+ }
+
+ events.forEach(function(event) {
+ if (!event.type) {
+ return;
+ }
+
+ el.dispatchEvent && el.dispatchEvent(event);
+ });
+ },
+
+ dispatch: function(e) {
+ var i = 0,
+ j = 0,
+ el = this,
+ handlers = jBone.getData(el).events[e.type],
+ length = handlers.length,
+ handlerQueue = [],
+ targets = [],
+ l,
+ expectedTarget,
+ handler,
+ event,
+ eventOptions;
+
+ // cache all events handlers, fix issue with multiple handlers (issue #45)
+ for (; i < length; i++) {
+ handlerQueue.push(handlers[i]);
+ }
+
+ i = 0;
+ length = handlerQueue.length;
+
+ for (;
+ // if event exists
+ i < length &&
+ // if handler is not removed from stack
+ ~handlers.indexOf(handlerQueue[i]) &&
+ // if propagation is not stopped
+ !(event && event.isImmediatePropagationStopped());
+ i++) {
+ expectedTarget = null;
+ eventOptions = {};
+ handler = handlerQueue[i];
+ handler.data && (eventOptions.data = handler.data);
+
+ // event handler without selector
+ if (!handler.selector) {
+ event = new BoneEvent(e, eventOptions);
+
+ if (!(e.namespace && e.namespace !== handler.namespace)) {
+ handler.originfn.call(el, event);
+ }
+ }
+ // event handler with selector
+ else if (
+ // if target and selected element the same
+ ~(targets = jBone(el).find(handler.selector)).indexOf(e.target) && (expectedTarget = e.target) ||
+ // if one of element matched with selector contains target
+ (el !== e.target && el.contains(e.target))
+ ) {
+ // get element matched with selector
+ if (!expectedTarget) {
+ l = targets.length;
+ j = 0;
+
+ for (; j < l; j++) {
+ if (targets[j] && targets[j].contains(e.target)) {
+ expectedTarget = targets[j];
+ }
+ }
+ }
+
+ if (!expectedTarget) {
+ continue;
+ }
+
+ eventOptions.currentTarget = expectedTarget;
+ event = new BoneEvent(e, eventOptions);
+
+ if (!(e.namespace && e.namespace !== handler.namespace)) {
+ handler.originfn.call(expectedTarget, event);
+ }
+ }
+ }
+ }
+};
+
+fn.on = function(types, selector, data, fn) {
+ var length = this.length,
+ i = 0;
+
+ if (data == null && fn == null) {
+ // (types, fn)
+ fn = selector;
+ data = selector = undefined;
+ } else if (fn == null) {
+ if (typeof selector === "string") {
+ // (types, selector, fn)
+ fn = data;
+ data = undefined;
+ } else {
+ // (types, data, fn)
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+
+ if (!fn) {
+ return this;
+ }
+
+ for (; i < length; i++) {
+ jBone.event.add(this[i], types, fn, data, selector);
+ }
+
+ return this;
+};
+
+fn.one = function(event) {
+ var args = arguments,
+ i = 0,
+ length = this.length,
+ oneArgs = slice.call(args, 1, args.length - 1),
+ callback = slice.call(args, -1)[0],
+ addListener;
+
+ addListener = function(el) {
+ var $el = jBone(el);
+
+ event.split(" ").forEach(function(event) {
+ var fn = function(e) {
+ $el.off(event, fn);
+ callback.call(el, e);
+ };
+
+ $el.on.apply($el, [event].concat(oneArgs, fn));
+ });
};
for (; i < length; i++) {
- removeListeners(this[i]);
+ addListener(this[i]);
+ }
+
+ return this;
+};
+
+fn.trigger = function(event) {
+ var i = 0,
+ length = this.length;
+
+ if (!event) {
+ return this;
+ }
+
+ for (; i < length; i++) {
+ jBone.event.trigger(this[i], event);
+ }
+
+ return this;
+};
+
+fn.off = function(types, handler) {
+ var i = 0,
+ length = this.length;
+
+ for (; i < length; i++) {
+ jBone.event.remove(this[i], types, handler);
}
return this;
@@ -533,7 +654,13 @@ fn.find = function(selector) {
};
fn.get = function(index) {
- return this[index];
+ return index != null ?
+
+ // Return just one element from the set
+ (index < 0 ? this[index + this.length] : this[index]) :
+
+ // Return all the elements in a clean array
+ slice.call(this);
};
fn.eq = function(index) {
@@ -575,6 +702,14 @@ fn.has = function() {
});
};
+fn.add = function(selector, context) {
+ return this.pushStack(
+ jBone.unique(
+ jBone.merge(this.get(), jBone(selector, context))
+ )
+ );
+};
+
fn.attr = function(key, value) {
var args = arguments,
i = 0,
@@ -745,6 +880,70 @@ fn.removeData = function(key) {
return this;
};
+fn.addClass = function(className) {
+ var i = 0,
+ j = 0,
+ length = this.length,
+ classes = className ? className.trim().split(/\s+/) : [];
+
+ for (; i < length; i++) {
+ j = 0;
+
+ for (j = 0; j < classes.length; j++) {
+ this[i].classList.add(classes[j]);
+ }
+ }
+
+ return this;
+};
+
+fn.removeClass = function(className) {
+ var i = 0,
+ j = 0,
+ length = this.length,
+ classes = className ? className.trim().split(/\s+/) : [];
+
+ for (; i < length; i++) {
+ j = 0;
+
+ for (j = 0; j < classes.length; j++) {
+ this[i].classList.remove(classes[j]);
+ }
+ }
+
+ return this;
+};
+
+fn.toggleClass = function(className, force) {
+ var i = 0,
+ length = this.length,
+ method = "toggle";
+
+ force === true && (method = "add") || force === false && (method = "remove");
+
+ if (className) {
+ for (; i < length; i++) {
+ this[i].classList[method](className);
+ }
+ }
+
+ return this;
+};
+
+fn.hasClass = function(className) {
+ var i = 0, length = this.length;
+
+ if (className) {
+ for (; i < length; i++) {
+ if (this[i].classList.contains(className)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+};
+
fn.html = function(value) {
var args = arguments,
el;
@@ -770,7 +969,7 @@ fn.append = function(appended) {
if (isString(appended) && rquickExpr.exec(appended)) {
appended = jBone(appended);
}
- // create text node for inserting
+ // create text node for insertion
else if (!isObject(appended)) {
appended = document.createTextNode(appended);
}
@@ -821,7 +1020,7 @@ fn.remove = function() {
length = this.length,
el;
- // remove all listners
+ // remove all listeners
this.off();
for (; i < length; i++) {
diff --git a/vendor/jbone/dist/jbone.min.js b/vendor/jbone/dist/jbone.min.js
index b755d51..3e5c664 100644
--- a/vendor/jbone/dist/jbone.min.js
+++ b/vendor/jbone/dist/jbone.min.js
@@ -1,10 +1,10 @@
/*!
- * jBone v1.0.20 - 2014-11-27 - Library for DOM manipulation
+ * jBone v1.1.2 - 2015-10-09 - Library for DOM manipulation
*
- * https://github.com/kupriyanenko/jbone
+ * http://jbone.js.org
*
- * Copyright 2014 Alexey Kupriyanenko
+ * Copyright 2015 Alexey Kupriyanenko
* Released under the MIT license.
*/
-!function(a){function b(b){var c=b.length,d=typeof b;return o(d)||b===a?!1:1===b.nodeType&&c?!0:p(d)||0===c||"number"==typeof c&&c>0&&c-1 in b}function c(a,b){var c,d;this.originalEvent=a,d=function(a,b){this[a]="preventDefault"===a?function(){return this.defaultPrevented=!0,b[a]()}:o(b[a])?function(){return b[a]()}:b[a]};for(c in a)(a[c]||"function"==typeof a[c])&&d.call(this,c,a);q.extend(this,b)}var d,e=a.$,f=a.jBone,g=/^<(\w+)\s*\/?>$/,h=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,i=[].slice,j=[].splice,k=Object.keys,l=document,m=function(a){return"string"==typeof a},n=function(a){return a instanceof Object},o=function(a){var b={};return a&&"[object Function]"===b.toString.call(a)},p=function(a){return Array.isArray(a)},q=function(a,b){return new d.init(a,b)};q.noConflict=function(){return a.$=e,a.jBone=f,q},d=q.fn=q.prototype={init:function(a,b){var c,d,e,f;if(!a)return this;if(m(a)){if(d=g.exec(a))return this[0]=l.createElement(d[1]),this.length=1,n(b)&&this.attr(b),this;if((d=h.exec(a))&&d[1]){for(f=l.createDocumentFragment(),e=l.createElement("div"),e.innerHTML=a;e.lastChild;)f.appendChild(e.firstChild);return c=i.call(f.childNodes),q.merge(this,c)}if(q.isElement(b))return q(b).find(a);try{return c=l.querySelectorAll(a),q.merge(this,c)}catch(j){return this}}return a.nodeType?(this[0]=a,this.length=1,this):o(a)?a():a instanceof q?a:q.makeArray(a,this)},pop:[].pop,push:[].push,reverse:[].reverse,shift:[].shift,sort:[].sort,splice:[].splice,slice:[].slice,indexOf:[].indexOf,forEach:[].forEach,unshift:[].unshift,concat:[].concat,join:[].join,every:[].every,some:[].some,filter:[].filter,map:[].map,reduce:[].reduce,reduceRight:[].reduceRight,length:0},d.constructor=q,d.init.prototype=d,q.setId=function(b){var c=b.jid;b===a?c="window":void 0===b.jid&&(b.jid=c=++q._cache.jid),q._cache.events[c]||(q._cache.events[c]={})},q.getData=function(b){b=b instanceof q?b[0]:b;var c=b===a?"window":b.jid;return{jid:c,events:q._cache.events[c]}},q.isElement=function(a){return a&&a instanceof q||a instanceof HTMLElement||m(a)},q._cache={events:{},jid:0},q.merge=function(a,b){for(var c=b.length,d=a.length,e=0;c>e;)a[d++]=b[e++];return a.length=d,a},q.contains=function(a,b){var c;return a.reverse().some(function(a){return a.contains(b)?c=a:void 0}),c},q.extend=function(a){var b,c,d,e;return j.call(arguments,1).forEach(function(f){if(f)for(b=k(f),c=b.length,d=0,e=a;c>d;d++)e[b[d]]=f[b[d]]}),a},q.makeArray=function(a,c){var d=c||[];return null!==a&&(b(a)?q.merge(d,m(a)?[a]:a):d.push(a)),d},q.Event=function(a,b){var c,d;return a.type&&!b&&(b=a,a=a.type),c=a.split(".").splice(1).join("."),d=a.split(".")[0],a=l.createEvent("Event"),a.initEvent(d,!0,!0),q.extend(a,{namespace:c,isDefaultPrevented:function(){return a.defaultPrevented}},b)},d.on=function(a){var b,d,e,f,g,h,i,j,k=arguments,l=this.length,m=0;for(2===k.length?b=k[1]:(d=k[1],b=k[2]),j=function(j){q.setId(j),g=q.getData(j).events,a.split(" ").forEach(function(a){h=a.split(".")[0],e=a.split(".").splice(1).join("."),g[h]=g[h]||[],f=function(a){a.namespace&&a.namespace!==e||(i=null,d?(~q(j).find(d).indexOf(a.target)||(i=q.contains(q(j).find(d),a.target)))&&(i=i||a.target,a=new c(a,{currentTarget:i}),b.call(i,a)):b.call(j,a))},g[h].push({namespace:e,fn:f,originfn:b}),j.addEventListener&&j.addEventListener(h,f,!1)})};l>m;m++)j(this[m]);return this},d.one=function(a){var b,c,d,e=arguments,f=0,g=this.length;for(2===e.length?b=e[1]:(c=e[1],b=e[2]),d=function(d){a.split(" ").forEach(function(a){var e=function(c){q(d).off(a,e),b.call(d,c)};c?q(d).on(a,c,e):q(d).on(a,e)})};g>f;f++)d(this[f]);return this},d.trigger=function(a){var b,c=[],d=0,e=this.length;if(!a)return this;for(m(a)?c=a.split(" ").map(function(a){return q.Event(a)}):(a=a instanceof Event?a:q.Event(a),c=[a]),b=function(a){c.forEach(function(b){b.type&&a.dispatchEvent&&a.dispatchEvent(b)})};e>d;d++)b(this[d]);return this},d.off=function(a,b){var c,d,e,f,g=0,h=this.length,i=function(a,c,d,e,f){var g;(b&&f.originfn===b||!b)&&(g=f.fn),a[c][d].fn===g&&(e.removeEventListener(c,g),q._cache.events[q.getData(e).jid][c].splice(d,1))};for(e=function(b){var e,g,h;return(c=q.getData(b).events)?!a&&c?k(c).forEach(function(a){for(g=c[a],e=g.length;e--;)i(c,a,e,b,g[e])}):void a.split(" ").forEach(function(a){if(f=a.split(".")[0],d=a.split(".").splice(1).join("."),c[f])for(g=c[f],e=g.length;e--;)h=g[e],(!d||d&&h.namespace===d)&&i(c,f,e,b,h);else d&&k(c).forEach(function(a){for(g=c[a],e=g.length;e--;)h=g[e],h.namespace.split(".")[0]===d.split(".")[0]&&i(c,a,e,b,h)})}):void 0};h>g;g++)e(this[g]);return this},d.find=function(a){for(var b=[],c=0,d=this.length,e=function(c){o(c.querySelectorAll)&&[].forEach.call(c.querySelectorAll(a),function(a){b.push(a)})};d>c;c++)e(this[c]);return q(b)},d.get=function(a){return this[a]},d.eq=function(a){return q(this[a])},d.parent=function(){for(var a,b=[],c=0,d=this.length;d>c;c++)!~b.indexOf(a=this[c].parentElement)&&a&&b.push(a);return q(b)},d.toArray=function(){return i.call(this)},d.is=function(){var a=arguments;return this.some(function(b){return b.tagName.toLowerCase()===a[0]})},d.has=function(){var a=arguments;return this.some(function(b){return b.querySelectorAll(a[0]).length})},d.attr=function(a,b){var c,d=arguments,e=0,f=this.length;if(m(a)&&1===d.length)return this[0]&&this[0].getAttribute(a);for(2===d.length?c=function(c){c.setAttribute(a,b)}:n(a)&&(c=function(b){k(a).forEach(function(c){b.setAttribute(c,a[c])})});f>e;e++)c(this[e]);return this},d.removeAttr=function(a){for(var b=0,c=this.length;c>b;b++)this[b].removeAttribute(a);return this},d.val=function(a){var b=0,c=this.length;if(0===arguments.length)return this[0]&&this[0].value;for(;c>b;b++)this[b].value=a;return this},d.css=function(b,c){var d,e=arguments,f=0,g=this.length;if(m(b)&&1===e.length)return this[0]&&a.getComputedStyle(this[0])[b];for(2===e.length?d=function(a){a.style[b]=c}:n(b)&&(d=function(a){k(b).forEach(function(c){a.style[c]=b[c]})});g>f;f++)d(this[f]);return this},d.data=function(a,b){var c,d=arguments,e={},f=0,g=this.length,h=function(a,b,c){n(c)?(a.jdata=a.jdata||{},a.jdata[b]=c):a.dataset[b]=c},i=function(a){return"true"===a?!0:"false"===a?!1:a};if(0===d.length)return this[0].jdata&&(e=this[0].jdata),k(this[0].dataset).forEach(function(a){e[a]=i(this[0].dataset[a])},this),e;if(1===d.length&&m(a))return this[0]&&i(this[0].dataset[a]||this[0].jdata&&this[0].jdata[a]);for(1===d.length&&n(a)?c=function(b){k(a).forEach(function(c){h(b,c,a[c])})}:2===d.length&&(c=function(c){h(c,a,b)});g>f;f++)c(this[f]);return this},d.removeData=function(a){for(var b,c,d=0,e=this.length;e>d;d++)if(b=this[d].jdata,c=this[d].dataset,a)b&&b[a]&&delete b[a],delete c[a];else{for(a in b)delete b[a];for(a in c)delete c[a]}return this},d.html=function(a){var b,c=arguments;return 1===c.length&&void 0!==a?this.empty().append(a):0===c.length&&(b=this[0])?b.innerHTML:this},d.append=function(a){var b,c=0,d=this.length;for(m(a)&&h.exec(a)?a=q(a):n(a)||(a=document.createTextNode(a)),a=a instanceof q?a:q(a),b=function(b,c){a.forEach(function(a){b.appendChild(c?a.cloneNode(!0):a)})};d>c;c++)b(this[c],c);return this},d.appendTo=function(a){return q(a).append(this),this},d.empty=function(){for(var a,b=0,c=this.length;c>b;b++)for(a=this[b];a.lastChild;)a.removeChild(a.lastChild);return this},d.remove=function(){var a,b=0,c=this.length;for(this.off();c>b;b++)a=this[b],delete a.jdata,a.parentNode&&a.parentNode.removeChild(a);return this},"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=q:"function"==typeof define&&define.amd?(define(function(){return q}),a.jBone=a.$=q):"object"==typeof a&&"object"==typeof a.document&&(a.jBone=a.$=q)}(window);
\ No newline at end of file
+!function(a){function b(b){var c=b.length,d=typeof b;return o(d)||b===a?!1:1===b.nodeType&&c?!0:p(d)||0===c||"number"==typeof c&&c>0&&c-1 in b}function c(a,b){var c,d;this.originalEvent=a,d=function(a,b){this[a]="preventDefault"===a?function(){return this.defaultPrevented=!0,b[a]()}:"stopImmediatePropagation"===a?function(){return this.immediatePropagationStopped=!0,b[a]()}:o(b[a])?function(){return b[a]()}:b[a]};for(c in a)(a[c]||"function"==typeof a[c])&&d.call(this,c,a);q.extend(this,b,{isImmediatePropagationStopped:function(){return!!this.immediatePropagationStopped}})}var d,e=a.$,f=a.jBone,g=/^<(\w+)\s*\/?>$/,h=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,i=[].slice,j=[].splice,k=Object.keys,l=document,m=function(a){return"string"==typeof a},n=function(a){return a instanceof Object},o=function(a){return"[object Function]"==={}.toString.call(a)},p=function(a){return Array.isArray(a)},q=function(a,b){return new d.init(a,b)};q.noConflict=function(){return a.$=e,a.jBone=f,q},d=q.fn=q.prototype={init:function(a,b){var c,d,e,f;if(!a)return this;if(m(a)){if(d=g.exec(a))return this[0]=l.createElement(d[1]),this.length=1,n(b)&&this.attr(b),this;if((d=h.exec(a))&&d[1]){for(f=l.createDocumentFragment(),e=l.createElement("div"),e.innerHTML=a;e.lastChild;)f.appendChild(e.firstChild);return c=i.call(f.childNodes),q.merge(this,c)}if(q.isElement(b))return q(b).find(a);try{return c=l.querySelectorAll(a),q.merge(this,c)}catch(j){return this}}return a.nodeType?(this[0]=a,this.length=1,this):o(a)?a():a instanceof q?a:q.makeArray(a,this)},pop:[].pop,push:[].push,reverse:[].reverse,shift:[].shift,sort:[].sort,splice:[].splice,slice:[].slice,indexOf:[].indexOf,forEach:[].forEach,unshift:[].unshift,concat:[].concat,join:[].join,every:[].every,some:[].some,filter:[].filter,map:[].map,reduce:[].reduce,reduceRight:[].reduceRight,length:0},d.constructor=q,d.init.prototype=d,q.setId=function(b){var c=b.jid;b===a?c="window":void 0===b.jid&&(b.jid=c=++q._cache.jid),q._cache.events[c]||(q._cache.events[c]={})},q.getData=function(b){b=b instanceof q?b[0]:b;var c=b===a?"window":b.jid;return{jid:c,events:q._cache.events[c]}},q.isElement=function(a){return a&&a instanceof q||a instanceof HTMLElement||m(a)},q._cache={events:{},jid:0},d.pushStack=function(a){var b=q.merge(this.constructor(),a);return b},q.merge=function(a,b){for(var c=b.length,d=a.length,e=0;c>e;)a[d++]=b[e++];return a.length=d,a},q.contains=function(a,b){return a.contains(b)},q.extend=function(a){var b;return j.call(arguments,1).forEach(function(c){if(b=a,c)for(var d in c)b[d]=c[d]}),a},q.makeArray=function(a,c){var d=c||[];return null!==a&&(b(a)?q.merge(d,m(a)?[a]:a):d.push(a)),d},q.unique=function(a){if(null==a)return[];for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c];b.indexOf(e)<0&&b.push(e)}return b},q.Event=function(a,b){var c,d;return a.type&&!b&&(b=a,a=a.type),c=a.split(".").splice(1).join("."),d=a.split(".")[0],a=l.createEvent("Event"),a.initEvent(d,!0,!0),q.extend(a,{namespace:c,isDefaultPrevented:function(){return a.defaultPrevented}},b)},q.event={add:function(a,b,c,d,e){q.setId(a);var f,g,h,i=function(b){q.event.dispatch.call(a,b)},j=q.getData(a).events;for(b=b.split(" "),g=b.length;g--;)h=b[g],f=h.split(".")[0],j[f]=j[f]||[],j[f].length?i=j[f][0].fn:a.addEventListener&&a.addEventListener(f,i,!1),j[f].push({namespace:h.split(".").splice(1).join("."),fn:i,selector:e,data:d,originfn:c})},remove:function(a,b,c){var d,e,f=function(a,b,d,e,f){var g;(c&&f.originfn===c||!c)&&(g=f.fn),a[b][d].fn===g&&(a[b].splice(d,1),a[b].length||e.removeEventListener(b,g))},g=q.getData(a).events;if(g)return!b&&g?k(g).forEach(function(b){for(e=g[b],d=e.length;d--;)f(g,b,d,a,e[d])}):void b.split(" ").forEach(function(b){var c,h=b.split(".")[0],i=b.split(".").splice(1).join(".");if(g[h])for(e=g[h],d=e.length;d--;)c=e[d],(!i||i&&c.namespace===i)&&f(g,h,d,a,c);else i&&k(g).forEach(function(b){for(e=g[b],d=e.length;d--;)c=e[d],c.namespace.split(".")[0]===i.split(".")[0]&&f(g,b,d,a,c)})})},trigger:function(a,b){var c=[];m(b)?c=b.split(" ").map(function(a){return q.Event(a)}):(b=b instanceof Event?b:q.Event(b),c=[b]),c.forEach(function(b){b.type&&a.dispatchEvent&&a.dispatchEvent(b)})},dispatch:function(a){for(var b,d,e,f,g,h=0,i=0,j=this,k=q.getData(j).events[a.type],l=k.length,m=[],n=[];l>h;h++)m.push(k[h]);for(h=0,l=m.length;l>h&&~k.indexOf(m[h])&&(!f||!f.isImmediatePropagationStopped());h++)if(d=null,g={},e=m[h],e.data&&(g.data=e.data),e.selector){if(~(n=q(j).find(e.selector)).indexOf(a.target)&&(d=a.target)||j!==a.target&&j.contains(a.target)){if(!d)for(b=n.length,i=0;b>i;i++)n[i]&&n[i].contains(a.target)&&(d=n[i]);if(!d)continue;g.currentTarget=d,f=new c(a,g),a.namespace&&a.namespace!==e.namespace||e.originfn.call(d,f)}}else f=new c(a,g),a.namespace&&a.namespace!==e.namespace||e.originfn.call(j,f)}},d.on=function(a,b,c,d){var e=this.length,f=0;if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),!d)return this;for(;e>f;f++)q.event.add(this[f],a,d,c,b);return this},d.one=function(a){var b,c=arguments,d=0,e=this.length,f=i.call(c,1,c.length-1),g=i.call(c,-1)[0];for(b=function(b){var c=q(b);a.split(" ").forEach(function(a){var d=function(e){c.off(a,d),g.call(b,e)};c.on.apply(c,[a].concat(f,d))})};e>d;d++)b(this[d]);return this},d.trigger=function(a){var b=0,c=this.length;if(!a)return this;for(;c>b;b++)q.event.trigger(this[b],a);return this},d.off=function(a,b){for(var c=0,d=this.length;d>c;c++)q.event.remove(this[c],a,b);return this},d.find=function(a){for(var b=[],c=0,d=this.length,e=function(c){o(c.querySelectorAll)&&[].forEach.call(c.querySelectorAll(a),function(a){b.push(a)})};d>c;c++)e(this[c]);return q(b)},d.get=function(a){return null!=a?0>a?this[a+this.length]:this[a]:i.call(this)},d.eq=function(a){return q(this[a])},d.parent=function(){for(var a,b=[],c=0,d=this.length;d>c;c++)!~b.indexOf(a=this[c].parentElement)&&a&&b.push(a);return q(b)},d.toArray=function(){return i.call(this)},d.is=function(){var a=arguments;return this.some(function(b){return b.tagName.toLowerCase()===a[0]})},d.has=function(){var a=arguments;return this.some(function(b){return b.querySelectorAll(a[0]).length})},d.add=function(a,b){return this.pushStack(q.unique(q.merge(this.get(),q(a,b))))},d.attr=function(a,b){var c,d=arguments,e=0,f=this.length;if(m(a)&&1===d.length)return this[0]&&this[0].getAttribute(a);for(2===d.length?c=function(c){c.setAttribute(a,b)}:n(a)&&(c=function(b){k(a).forEach(function(c){b.setAttribute(c,a[c])})});f>e;e++)c(this[e]);return this},d.removeAttr=function(a){for(var b=0,c=this.length;c>b;b++)this[b].removeAttribute(a);return this},d.val=function(a){var b=0,c=this.length;if(0===arguments.length)return this[0]&&this[0].value;for(;c>b;b++)this[b].value=a;return this},d.css=function(b,c){var d,e=arguments,f=0,g=this.length;if(m(b)&&1===e.length)return this[0]&&a.getComputedStyle(this[0])[b];for(2===e.length?d=function(a){a.style[b]=c}:n(b)&&(d=function(a){k(b).forEach(function(c){a.style[c]=b[c]})});g>f;f++)d(this[f]);return this},d.data=function(a,b){var c,d=arguments,e={},f=0,g=this.length,h=function(a,b,c){n(c)?(a.jdata=a.jdata||{},a.jdata[b]=c):a.dataset[b]=c},i=function(a){return"true"===a?!0:"false"===a?!1:a};if(0===d.length)return this[0].jdata&&(e=this[0].jdata),k(this[0].dataset).forEach(function(a){e[a]=i(this[0].dataset[a])},this),e;if(1===d.length&&m(a))return this[0]&&i(this[0].dataset[a]||this[0].jdata&&this[0].jdata[a]);for(1===d.length&&n(a)?c=function(b){k(a).forEach(function(c){h(b,c,a[c])})}:2===d.length&&(c=function(c){h(c,a,b)});g>f;f++)c(this[f]);return this},d.removeData=function(a){for(var b,c,d=0,e=this.length;e>d;d++)if(b=this[d].jdata,c=this[d].dataset,a)b&&b[a]&&delete b[a],delete c[a];else{for(a in b)delete b[a];for(a in c)delete c[a]}return this},d.addClass=function(a){for(var b=0,c=0,d=this.length,e=a?a.trim().split(/\s+/):[];d>b;b++)for(c=0,c=0;cb;b++)for(c=0,c=0;cc;c++)this[c].classList[e](a);return this},d.hasClass=function(a){var b=0,c=this.length;if(a)for(;c>b;b++)if(this[b].classList.contains(a))return!0;return!1},d.html=function(a){var b,c=arguments;return 1===c.length&&void 0!==a?this.empty().append(a):0===c.length&&(b=this[0])?b.innerHTML:this},d.append=function(a){var b,c=0,d=this.length;for(m(a)&&h.exec(a)?a=q(a):n(a)||(a=document.createTextNode(a)),a=a instanceof q?a:q(a),b=function(b,c){a.forEach(function(a){b.appendChild(c?a.cloneNode(!0):a)})};d>c;c++)b(this[c],c);return this},d.appendTo=function(a){return q(a).append(this),this},d.empty=function(){for(var a,b=0,c=this.length;c>b;b++)for(a=this[b];a.lastChild;)a.removeChild(a.lastChild);return this},d.remove=function(){var a,b=0,c=this.length;for(this.off();c>b;b++)a=this[b],delete a.jdata,a.parentNode&&a.parentNode.removeChild(a);return this},"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=q:"function"==typeof define&&define.amd?(define(function(){return q}),a.jBone=a.$=q):"object"==typeof a&&"object"==typeof a.document&&(a.jBone=a.$=q)}(window);
\ No newline at end of file
diff --git a/vendor/jbone/package.json b/vendor/jbone/package.json
deleted file mode 100644
index ba0d349..0000000
--- a/vendor/jbone/package.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "name": "jbone",
- "title": "jBone",
- "version": "1.0.20",
- "description": "Library for DOM manipulation",
- "main": "dist/jbone.js",
- "homepage": "https://github.com/kupriyanenko/jbone",
- "directories": {
- "test": "test"
- },
- "devDependencies": {
- "grunt": "0.4.4",
- "grunt-mocha": "0.4.10",
- "grunt-contrib-watch": "0.6.1",
- "grunt-contrib-jshint": "0.10.0",
- "grunt-contrib-uglify": "0.4.0",
- "grunt-contrib-concat": "0.4.0",
- "which": "1.0.5"
- },
- "keywords": [
- "jquery",
- "jbone",
- "backbone",
- "javascript",
- "library"
- ],
- "scripts": {
- "pretest": "node build/bower-install",
- "test": "grunt"
- },
- "author": "Alexey Kupriyanenko",
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "https://github.com/kupriyanenko/jbone"
- }
-}
diff --git a/vendor/jbone/perf/attributes.js b/vendor/jbone/perf/attributes.js
deleted file mode 100644
index 774583a..0000000
--- a/vendor/jbone/perf/attributes.js
+++ /dev/null
@@ -1,153 +0,0 @@
-suite("Set attribute", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.attr('name', 'value');
- });
-
- bench("jQuery", function() {
- suite.jqEl.attr('name', 'value');
- });
-});
-
-suite("Get attribute", function(suite) {
- setup(function() {
- suite.jbEl = jBone('', {
- name: 'value'
- });
- suite.jqEl = jQuery('', {
- name: 'value'
- });
- });
-
- bench("jBone", function() {
- suite.jbEl.attr('name');
- });
-
- bench("jQuery", function() {
- suite.jqEl.attr('name');
- });
-});
-
-suite("Set value", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.val('name', 'value');
- });
-
- bench("jQuery", function() {
- suite.jqEl.val('name', 'value');
- });
-});
-
-suite("Get value", function(suite) {
- setup(function() {
- suite.jbEl = jBone('').val('name', 'value');
- suite.jqEl = jQuery('').val('name', 'value');
- });
-
- bench("jBone", function() {
- suite.jbEl.val('name');
- });
-
- bench("jQuery", function() {
- suite.jqEl.val('name');
- });
-});
-
-suite("Set css", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.css('color', 'red');
- });
-
- bench("jQuery", function() {
- suite.jqEl.css('color', 'red');
- });
-});
-
-suite("Get css", function(suite) {
- setup(function() {
- suite.jbEl = jBone('').css('color', 'red').appendTo('#suite');
- suite.jqEl = jQuery('').css('color', 'red').appendTo('#suite');
- });
-
- bench("jBone", function() {
- suite.jbEl.css('color');
- });
-
- bench("jQuery", function() {
- suite.jqEl.css('color');
- });
-});
-
-suite("Set normal data", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.data('key', 'value');
- });
-
- bench("jQuery", function() {
- suite.jqEl.data('key', 'value');
- });
-});
-
-suite("Set object data", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.data('key', {});
- });
-
- bench("jQuery", function() {
- suite.jqEl.data('key', {});
- });
-});
-
-suite("Get normal data", function(suite) {
- setup(function() {
- suite.jbEl = jBone('').data('key', 'value');
- suite.jqEl = jQuery('').data('key', 'value');
- });
-
- bench("jBone", function() {
- suite.jbEl.data('key');
- });
-
- bench("jQuery", function() {
- suite.jqEl.data('key');
- });
-});
-
-suite("Get object data", function(suite) {
- setup(function() {
- suite.jbEl = jBone('').data('key', {});
- suite.jqEl = jQuery('').data('key', {});
- });
-
- bench("jBone", function() {
- suite.jbEl.data('key');
- });
-
- bench("jQuery", function() {
- suite.jqEl.data('key');
- });
-});
diff --git a/vendor/jbone/perf/backbone.js b/vendor/jbone/perf/backbone.js
deleted file mode 100644
index 0fd8b81..0000000
--- a/vendor/jbone/perf/backbone.js
+++ /dev/null
@@ -1,25 +0,0 @@
-var jbBackbone = Backbone.noConflict();
-jbBackbone.$ = jBone;
-
-var jqBackbone = Backbone.noConflict();
-jqBackbone.$ = jQuery;
-
-suite("Backbone View", function(suite) {
- setup(function() {
- suite.jbView = jbBackbone.View.extend({
- events: { click: function() {} }
- });
-
- suite.jqView = jqBackbone.View.extend({
- events: { click: function() {} }
- });
- });
-
- bench("jBone", function() {
- (new suite.jbView()).remove();
- });
-
- bench("jQuery", function() {
- (new suite.jqView()).remove();
- });
-});
diff --git a/vendor/jbone/perf/core.js b/vendor/jbone/perf/core.js
deleted file mode 100644
index 935ad58..0000000
--- a/vendor/jbone/perf/core.js
+++ /dev/null
@@ -1,65 +0,0 @@
-suite("Init", function() {
- bench("jBone", function() {
- jBone();
- });
-
- bench("jQuery", function() {
- jQuery();
- });
-});
-
-suite("Wrap DOM Node", function() {
- bench("jBone", function() {
- jBone(document.createElement('div'));
- });
-
- bench("jQuery", function() {
- jQuery(document.createElement('div'));
- });
-});
-
-suite("Create single Node", function() {
- bench("jBone", function() {
- jBone('');
- });
-
- bench("jQuery", function() {
- jQuery('');
- });
-});
-
-suite("Create multiple Nodes", function() {
- bench("jBone", function() {
- jBone('
');
- });
-
- bench("jQuery", function() {
- jQuery('
');
- });
-});
-
-suite("Create Node and define attributes", function() {
- bench("jBone", function() {
- jBone('', {
- 'class': 'test',
- 'name': 'value'
- });
- });
-
- bench("jQuery", function() {
- jQuery('', {
- 'class': 'test',
- 'name': 'value'
- });
- });
-});
-
-suite("Search by selector", function() {
- bench("jBone", function() {
- jBone('div');
- });
-
- bench("jQuery", function() {
- jQuery('div');
- });
-});
diff --git a/vendor/jbone/perf/events.js b/vendor/jbone/perf/events.js
deleted file mode 100644
index 97ecf25..0000000
--- a/vendor/jbone/perf/events.js
+++ /dev/null
@@ -1,44 +0,0 @@
-suite("on/off events", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.on('click', function() {}).off();
- });
-
- bench("jQuery", function() {
- suite.jqEl.on('click', function() {}).off();
- });
-});
-
-suite("off with eventType", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.on('click', function() {}).off('click');
- });
-
- bench("jQuery", function() {
- suite.jqEl.on('click', function() {}).off('click');
- });
-});
-
-suite("off with namespace", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.on('click.space', function() {}).off('.space');
- });
-
- bench("jQuery", function() {
- suite.jqEl.on('click.space', function() {}).off('.space');
- });
-});
diff --git a/vendor/jbone/perf/manipulation.js b/vendor/jbone/perf/manipulation.js
deleted file mode 100644
index a2208db..0000000
--- a/vendor/jbone/perf/manipulation.js
+++ /dev/null
@@ -1,14 +0,0 @@
-suite("Remove Element", function(suite) {
- setup(function() {
- suite.jbEl = jBone('');
- suite.jqEl = jQuery('');
- });
-
- bench("jBone", function() {
- suite.jbEl.remove();
- });
-
- bench("jQuery", function() {
- suite.jqEl.remove();
- });
-});
diff --git a/vendor/jbone/perf/perf.html b/vendor/jbone/perf/perf.html
deleted file mode 100644
index c904a48..0000000
--- a/vendor/jbone/perf/perf.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
- Performance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/vendor/jbone/perf/vendors/backbone.js b/vendor/jbone/perf/vendors/backbone.js
deleted file mode 100644
index 0a4b06c..0000000
--- a/vendor/jbone/perf/vendors/backbone.js
+++ /dev/null
@@ -1,1700 +0,0 @@
-// Backbone.js 1.1.2
-
-// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-// Backbone may be freely distributed under the MIT license.
-// For all details and documentation:
-// http://backbonejs.org
-
-(function(root, factory) {
-
- // Set up Backbone appropriately for the environment. Start with AMD.
- if (typeof define === 'function' && define.amd) {
- define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
- // Export global even in AMD case in case this script is loaded with
- // others that may still expect a global Backbone.
- root.Backbone = factory(root, exports, _, $);
- });
-
- // Next for Node.js or CommonJS. jQuery may not be needed as a module.
- } else if (typeof exports !== 'undefined') {
- var _ = require('underscore');
- factory(root, exports, _);
-
- // Finally, as a browser global.
- } else {
- root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
- }
-
-}(this, function(root, Backbone, _, $) {
-
- // Initial Setup
- // -------------
-
- // Save the previous value of the `Backbone` variable, so that it can be
- // restored later on, if `noConflict` is used.
- var previousBackbone = root.Backbone;
-
- // Create local references to array methods we'll want to use later.
- var array = [];
- var slice = array.slice;
-
- // Current version of the library. Keep in sync with `package.json`.
- Backbone.VERSION = '1.1.2';
-
- // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
- // the `$` variable.
- Backbone.$ = $;
-
- // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
- // to its previous owner. Returns a reference to this Backbone object.
- Backbone.noConflict = function() {
- root.Backbone = previousBackbone;
- return this;
- };
-
- // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
- // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
- // set a `X-Http-Method-Override` header.
- Backbone.emulateHTTP = false;
-
- // Turn on `emulateJSON` to support legacy servers that can't deal with direct
- // `application/json` requests ... will encode the body as
- // `application/x-www-form-urlencoded` instead and will send the model in a
- // form param named `model`.
- Backbone.emulateJSON = false;
-
- // Backbone.Events
- // ---------------
-
- // A module that can be mixed in to *any object* in order to provide it with
- // custom events. You may bind with `on` or remove with `off` callback
- // functions to an event; `trigger`-ing an event fires all callbacks in
- // succession.
- //
- // var object = {};
- // _.extend(object, Backbone.Events);
- // object.on('expand', function(){ alert('expanded'); });
- // object.trigger('expand');
- //
- var Events = Backbone.Events = {
-
- // Bind an event to a `callback` function. Passing `"all"` will bind
- // the callback to all events fired.
- on: function(name, callback, context) {
- if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
- this._events || (this._events = {});
- var events = this._events[name] || (this._events[name] = []);
- events.push({callback: callback, context: context, ctx: context || this});
- return this;
- },
-
- // Bind an event to only be triggered a single time. After the first time
- // the callback is invoked, it will be removed.
- once: function(name, callback, context) {
- if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
- var self = this;
- var once = _.once(function() {
- self.off(name, once);
- callback.apply(this, arguments);
- });
- once._callback = callback;
- return this.on(name, once, context);
- },
-
- // Remove one or many callbacks. If `context` is null, removes all
- // callbacks with that function. If `callback` is null, removes all
- // callbacks for the event. If `name` is null, removes all bound
- // callbacks for all events.
- off: function(name, callback, context) {
- if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
-
- // Remove all callbacks for all events.
- if (!name && !callback && !context) {
- this._events = void 0;
- return this;
- }
-
- var names = name ? [name] : _.keys(this._events);
- for (var i = 0, length = names.length; i < length; i++) {
- name = names[i];
-
- // Bail out if there are no events stored.
- var events = this._events[name];
- if (!events) continue;
-
- // Remove all callbacks for this event.
- if (!callback && !context) {
- delete this._events[name];
- continue;
- }
-
- // Find any remaining events.
- var remaining = [];
- for (var j = 0, k = events.length; j < k; j++) {
- var event = events[j];
- if (
- callback && callback !== event.callback &&
- callback !== event.callback._callback ||
- context && context !== event.context
- ) {
- remaining.push(event);
- }
- }
-
- // Replace events if there are any remaining. Otherwise, clean up.
- if (remaining.length) {
- this._events[name] = remaining;
- } else {
- delete this._events[name];
- }
- }
-
- return this;
- },
-
- // Trigger one or many events, firing all bound callbacks. Callbacks are
- // passed the same arguments as `trigger` is, apart from the event name
- // (unless you're listening on `"all"`, which will cause your callback to
- // receive the true name of the event as the first argument).
- trigger: function(name) {
- if (!this._events) return this;
- var args = slice.call(arguments, 1);
- if (!eventsApi(this, 'trigger', name, args)) return this;
- var events = this._events[name];
- var allEvents = this._events.all;
- if (events) triggerEvents(events, args);
- if (allEvents) triggerEvents(allEvents, arguments);
- return this;
- },
-
- // Tell this object to stop listening to either specific events ... or
- // to every object it's currently listening to.
- stopListening: function(obj, name, callback) {
- var listeningTo = this._listeningTo;
- if (!listeningTo) return this;
- var remove = !name && !callback;
- if (!callback && typeof name === 'object') callback = this;
- if (obj) (listeningTo = {})[obj._listenId] = obj;
- for (var id in listeningTo) {
- obj = listeningTo[id];
- obj.off(name, callback, this);
- if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id];
- }
- return this;
- }
-
- };
-
- // Regular expression used to split event strings.
- var eventSplitter = /\s+/;
-
- // Implement fancy features of the Events API such as multiple event
- // names `"change blur"` and jQuery-style event maps `{change: action}`
- // in terms of the existing API.
- var eventsApi = function(obj, action, name, rest) {
- if (!name) return true;
-
- // Handle event maps.
- if (typeof name === 'object') {
- for (var key in name) {
- obj[action].apply(obj, [key, name[key]].concat(rest));
- }
- return false;
- }
-
- // Handle space separated event names.
- if (eventSplitter.test(name)) {
- var names = name.split(eventSplitter);
- for (var i = 0, length = names.length; i < length; i++) {
- obj[action].apply(obj, [names[i]].concat(rest));
- }
- return false;
- }
-
- return true;
- };
-
- // A difficult-to-believe, but optimized internal dispatch function for
- // triggering events. Tries to keep the usual cases speedy (most internal
- // Backbone events have 3 arguments).
- var triggerEvents = function(events, args) {
- var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
- switch (args.length) {
- case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
- case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
- case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
- case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
- default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
- }
- };
-
- var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
-
- // Inversion-of-control versions of `on` and `once`. Tell *this* object to
- // listen to an event in another object ... keeping track of what it's
- // listening to.
- _.each(listenMethods, function(implementation, method) {
- Events[method] = function(obj, name, callback) {
- var listeningTo = this._listeningTo || (this._listeningTo = {});
- var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
- listeningTo[id] = obj;
- if (!callback && typeof name === 'object') callback = this;
- obj[implementation](name, callback, this);
- return this;
- };
- });
-
- // Aliases for backwards compatibility.
- Events.bind = Events.on;
- Events.unbind = Events.off;
-
- // Allow the `Backbone` object to serve as a global event bus, for folks who
- // want global "pubsub" in a convenient place.
- _.extend(Backbone, Events);
-
- // Backbone.Model
- // --------------
-
- // Backbone **Models** are the basic data object in the framework --
- // frequently representing a row in a table in a database on your server.
- // A discrete chunk of data and a bunch of useful, related methods for
- // performing computations and transformations on that data.
-
- // Create a new model with the specified attributes. A client id (`cid`)
- // is automatically generated and assigned for you.
- var Model = Backbone.Model = function(attributes, options) {
- var attrs = attributes || {};
- options || (options = {});
- this.cid = _.uniqueId('c');
- this.attributes = {};
- if (options.collection) this.collection = options.collection;
- if (options.parse) attrs = this.parse(attrs, options) || {};
- attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
- this.set(attrs, options);
- this.changed = {};
- this.initialize.apply(this, arguments);
- };
-
- // Attach all inheritable methods to the Model prototype.
- _.extend(Model.prototype, Events, {
-
- // A hash of attributes whose current and previous value differ.
- changed: null,
-
- // The value returned during the last failed validation.
- validationError: null,
-
- // The default name for the JSON `id` attribute is `"id"`. MongoDB and
- // CouchDB users may want to set this to `"_id"`.
- idAttribute: 'id',
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Return a copy of the model's `attributes` object.
- toJSON: function(options) {
- return _.clone(this.attributes);
- },
-
- // Proxy `Backbone.sync` by default -- but override this if you need
- // custom syncing semantics for *this* particular model.
- sync: function() {
- return Backbone.sync.apply(this, arguments);
- },
-
- // Get the value of an attribute.
- get: function(attr) {
- return this.attributes[attr];
- },
-
- // Get the HTML-escaped value of an attribute.
- escape: function(attr) {
- return _.escape(this.get(attr));
- },
-
- // Returns `true` if the attribute contains a value that is not null
- // or undefined.
- has: function(attr) {
- return this.get(attr) != null;
- },
-
- // Set a hash of model attributes on the object, firing `"change"`. This is
- // the core primitive operation of a model, updating the data and notifying
- // anyone who needs to know about the change in state. The heart of the beast.
- set: function(key, val, options) {
- var attr, attrs, unset, changes, silent, changing, prev, current;
- if (key == null) return this;
-
- // Handle both `"key", value` and `{key: value}` -style arguments.
- if (typeof key === 'object') {
- attrs = key;
- options = val;
- } else {
- (attrs = {})[key] = val;
- }
-
- options || (options = {});
-
- // Run validation.
- if (!this._validate(attrs, options)) return false;
-
- // Extract attributes and options.
- unset = options.unset;
- silent = options.silent;
- changes = [];
- changing = this._changing;
- this._changing = true;
-
- if (!changing) {
- this._previousAttributes = _.clone(this.attributes);
- this.changed = {};
- }
- current = this.attributes, prev = this._previousAttributes;
-
- // Check for changes of `id`.
- if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
-
- // For each `set` attribute, update or delete the current value.
- for (attr in attrs) {
- val = attrs[attr];
- if (!_.isEqual(current[attr], val)) changes.push(attr);
- if (!_.isEqual(prev[attr], val)) {
- this.changed[attr] = val;
- } else {
- delete this.changed[attr];
- }
- unset ? delete current[attr] : current[attr] = val;
- }
-
- // Trigger all relevant attribute changes.
- if (!silent) {
- if (changes.length) this._pending = options;
- for (var i = 0, length = changes.length; i < length; i++) {
- this.trigger('change:' + changes[i], this, current[changes[i]], options);
- }
- }
-
- // You might be wondering why there's a `while` loop here. Changes can
- // be recursively nested within `"change"` events.
- if (changing) return this;
- if (!silent) {
- while (this._pending) {
- options = this._pending;
- this._pending = false;
- this.trigger('change', this, options);
- }
- }
- this._pending = false;
- this._changing = false;
- return this;
- },
-
- // Remove an attribute from the model, firing `"change"`. `unset` is a noop
- // if the attribute doesn't exist.
- unset: function(attr, options) {
- return this.set(attr, void 0, _.extend({}, options, {unset: true}));
- },
-
- // Clear all attributes on the model, firing `"change"`.
- clear: function(options) {
- var attrs = {};
- for (var key in this.attributes) attrs[key] = void 0;
- return this.set(attrs, _.extend({}, options, {unset: true}));
- },
-
- // Determine if the model has changed since the last `"change"` event.
- // If you specify an attribute name, determine if that attribute has changed.
- hasChanged: function(attr) {
- if (attr == null) return !_.isEmpty(this.changed);
- return _.has(this.changed, attr);
- },
-
- // Return an object containing all the attributes that have changed, or
- // false if there are no changed attributes. Useful for determining what
- // parts of a view need to be updated and/or what attributes need to be
- // persisted to the server. Unset attributes will be set to undefined.
- // You can also pass an attributes object to diff against the model,
- // determining if there *would be* a change.
- changedAttributes: function(diff) {
- if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
- var val, changed = false;
- var old = this._changing ? this._previousAttributes : this.attributes;
- for (var attr in diff) {
- if (_.isEqual(old[attr], (val = diff[attr]))) continue;
- (changed || (changed = {}))[attr] = val;
- }
- return changed;
- },
-
- // Get the previous value of an attribute, recorded at the time the last
- // `"change"` event was fired.
- previous: function(attr) {
- if (attr == null || !this._previousAttributes) return null;
- return this._previousAttributes[attr];
- },
-
- // Get all of the attributes of the model at the time of the previous
- // `"change"` event.
- previousAttributes: function() {
- return _.clone(this._previousAttributes);
- },
-
- // Fetch the model from the server. If the server's representation of the
- // model differs from its current attributes, they will be overridden,
- // triggering a `"change"` event.
- fetch: function(options) {
- options = options ? _.clone(options) : {};
- if (options.parse === void 0) options.parse = true;
- var model = this;
- var success = options.success;
- options.success = function(resp) {
- if (!model.set(model.parse(resp, options), options)) return false;
- if (success) success(model, resp, options);
- model.trigger('sync', model, resp, options);
- };
- wrapError(this, options);
- return this.sync('read', this, options);
- },
-
- // Set a hash of model attributes, and sync the model to the server.
- // If the server returns an attributes hash that differs, the model's
- // state will be `set` again.
- save: function(key, val, options) {
- var attrs, method, xhr, attributes = this.attributes;
-
- // Handle both `"key", value` and `{key: value}` -style arguments.
- if (key == null || typeof key === 'object') {
- attrs = key;
- options = val;
- } else {
- (attrs = {})[key] = val;
- }
-
- options = _.extend({validate: true}, options);
-
- // If we're not waiting and attributes exist, save acts as
- // `set(attr).save(null, opts)` with validation. Otherwise, check if
- // the model will be valid when the attributes, if any, are set.
- if (attrs && !options.wait) {
- if (!this.set(attrs, options)) return false;
- } else {
- if (!this._validate(attrs, options)) return false;
- }
-
- // Set temporary attributes if `{wait: true}`.
- if (attrs && options.wait) {
- this.attributes = _.extend({}, attributes, attrs);
- }
-
- // After a successful server-side save, the client is (optionally)
- // updated with the server-side state.
- if (options.parse === void 0) options.parse = true;
- var model = this;
- var success = options.success;
- options.success = function(resp) {
- // Ensure attributes are restored during synchronous saves.
- model.attributes = attributes;
- var serverAttrs = model.parse(resp, options);
- if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
- if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
- return false;
- }
- if (success) success(model, resp, options);
- model.trigger('sync', model, resp, options);
- };
- wrapError(this, options);
-
- method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
- if (method === 'patch') options.attrs = attrs;
- xhr = this.sync(method, this, options);
-
- // Restore attributes.
- if (attrs && options.wait) this.attributes = attributes;
-
- return xhr;
- },
-
- // Destroy this model on the server if it was already persisted.
- // Optimistically removes the model from its collection, if it has one.
- // If `wait: true` is passed, waits for the server to respond before removal.
- destroy: function(options) {
- options = options ? _.clone(options) : {};
- var model = this;
- var success = options.success;
-
- var destroy = function() {
- model.trigger('destroy', model, model.collection, options);
- };
-
- options.success = function(resp) {
- if (options.wait || model.isNew()) destroy();
- if (success) success(model, resp, options);
- if (!model.isNew()) model.trigger('sync', model, resp, options);
- };
-
- if (this.isNew()) {
- options.success();
- return false;
- }
- wrapError(this, options);
-
- var xhr = this.sync('delete', this, options);
- if (!options.wait) destroy();
- return xhr;
- },
-
- // Default URL for the model's representation on the server -- if you're
- // using Backbone's restful methods, override this to change the endpoint
- // that will be called.
- url: function() {
- var base =
- _.result(this, 'urlRoot') ||
- _.result(this.collection, 'url') ||
- urlError();
- if (this.isNew()) return base;
- return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id);
- },
-
- // **parse** converts a response into the hash of attributes to be `set` on
- // the model. The default implementation is just to pass the response along.
- parse: function(resp, options) {
- return resp;
- },
-
- // Create a new model with identical attributes to this one.
- clone: function() {
- return new this.constructor(this.attributes);
- },
-
- // A model is new if it has never been saved to the server, and lacks an id.
- isNew: function() {
- return !this.has(this.idAttribute);
- },
-
- // Check if the model is currently in a valid state.
- isValid: function(options) {
- return this._validate({}, _.extend(options || {}, { validate: true }));
- },
-
- // Run validation against the next complete set of model attributes,
- // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
- _validate: function(attrs, options) {
- if (!options.validate || !this.validate) return true;
- attrs = _.extend({}, this.attributes, attrs);
- var error = this.validationError = this.validate(attrs, options) || null;
- if (!error) return true;
- this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
- return false;
- }
-
- });
-
- // Underscore methods that we want to implement on the Model.
- var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
-
- // Mix in each Underscore method as a proxy to `Model#attributes`.
- _.each(modelMethods, function(method) {
- if (!_[method]) return;
- Model.prototype[method] = function() {
- var args = slice.call(arguments);
- args.unshift(this.attributes);
- return _[method].apply(_, args);
- };
- });
-
- // Backbone.Collection
- // -------------------
-
- // If models tend to represent a single row of data, a Backbone Collection is
- // more analogous to a table full of data ... or a small slice or page of that
- // table, or a collection of rows that belong together for a particular reason
- // -- all of the messages in this particular folder, all of the documents
- // belonging to this particular author, and so on. Collections maintain
- // indexes of their models, both in order, and for lookup by `id`.
-
- // Create a new **Collection**, perhaps to contain a specific type of `model`.
- // If a `comparator` is specified, the Collection will maintain
- // its models in sort order, as they're added and removed.
- var Collection = Backbone.Collection = function(models, options) {
- options || (options = {});
- if (options.model) this.model = options.model;
- if (options.comparator !== void 0) this.comparator = options.comparator;
- this._reset();
- this.initialize.apply(this, arguments);
- if (models) this.reset(models, _.extend({silent: true}, options));
- };
-
- // Default options for `Collection#set`.
- var setOptions = {add: true, remove: true, merge: true};
- var addOptions = {add: true, remove: false};
-
- // Define the Collection's inheritable methods.
- _.extend(Collection.prototype, Events, {
-
- // The default model for a collection is just a **Backbone.Model**.
- // This should be overridden in most cases.
- model: Model,
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // The JSON representation of a Collection is an array of the
- // models' attributes.
- toJSON: function(options) {
- return this.map(function(model){ return model.toJSON(options); });
- },
-
- // Proxy `Backbone.sync` by default.
- sync: function() {
- return Backbone.sync.apply(this, arguments);
- },
-
- // Add a model, or list of models to the set.
- add: function(models, options) {
- return this.set(models, _.extend({merge: false}, options, addOptions));
- },
-
- // Remove a model, or a list of models from the set.
- remove: function(models, options) {
- var singular = !_.isArray(models);
- models = singular ? [models] : _.clone(models);
- options || (options = {});
- for (var i = 0, length = models.length; i < length; i++) {
- var model = models[i] = this.get(models[i]);
- if (!model) continue;
- delete this._byId[model.id];
- delete this._byId[model.cid];
- var index = this.indexOf(model);
- this.models.splice(index, 1);
- this.length--;
- if (!options.silent) {
- options.index = index;
- model.trigger('remove', model, this, options);
- }
- this._removeReference(model, options);
- }
- return singular ? models[0] : models;
- },
-
- // Update a collection by `set`-ing a new list of models, adding new ones,
- // removing models that are no longer present, and merging models that
- // already exist in the collection, as necessary. Similar to **Model#set**,
- // the core operation for updating the data contained by the collection.
- set: function(models, options) {
- options = _.defaults({}, options, setOptions);
- if (options.parse) models = this.parse(models, options);
- var singular = !_.isArray(models);
- models = singular ? (models ? [models] : []) : models.slice();
- var id, model, attrs, existing, sort;
- var at = options.at;
- var sortable = this.comparator && (at == null) && options.sort !== false;
- var sortAttr = _.isString(this.comparator) ? this.comparator : null;
- var toAdd = [], toRemove = [], modelMap = {};
- var add = options.add, merge = options.merge, remove = options.remove;
- var order = !sortable && add && remove ? [] : false;
-
- // Turn bare objects into model references, and prevent invalid models
- // from being added.
- for (var i = 0, length = models.length; i < length; i++) {
- attrs = models[i] || {};
- if (this._isModel(attrs)) {
- id = model = attrs;
- } else {
- id = attrs[this.model.prototype.idAttribute || 'id'];
- }
-
- // If a duplicate is found, prevent it from being added and
- // optionally merge it into the existing model.
- if (existing = this.get(id)) {
- if (remove) modelMap[existing.cid] = true;
- if (merge) {
- attrs = attrs === model ? model.attributes : attrs;
- if (options.parse) attrs = existing.parse(attrs, options);
- existing.set(attrs, options);
- if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
- }
- models[i] = existing;
-
- // If this is a new, valid model, push it to the `toAdd` list.
- } else if (add) {
- model = models[i] = this._prepareModel(attrs, options);
- if (!model) continue;
- toAdd.push(model);
- this._addReference(model, options);
- }
-
- // Do not add multiple models with the same `id`.
- model = existing || model;
- if (!model) continue;
- if (order && (model.isNew() || !modelMap[model.id])) order.push(model);
- modelMap[model.id] = true;
- }
-
- // Remove nonexistent models if appropriate.
- if (remove) {
- for (var i = 0, length = this.length; i < length; i++) {
- if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
- }
- if (toRemove.length) this.remove(toRemove, options);
- }
-
- // See if sorting is needed, update `length` and splice in new models.
- if (toAdd.length || (order && order.length)) {
- if (sortable) sort = true;
- this.length += toAdd.length;
- if (at != null) {
- for (var i = 0, length = toAdd.length; i < length; i++) {
- this.models.splice(at + i, 0, toAdd[i]);
- }
- } else {
- if (order) this.models.length = 0;
- var orderedModels = order || toAdd;
- for (var i = 0, length = orderedModels.length; i < length; i++) {
- this.models.push(orderedModels[i]);
- }
- }
- }
-
- // Silently sort the collection if appropriate.
- if (sort) this.sort({silent: true});
-
- // Unless silenced, it's time to fire all appropriate add/sort events.
- if (!options.silent) {
- for (var i = 0, length = toAdd.length; i < length; i++) {
- (model = toAdd[i]).trigger('add', model, this, options);
- }
- if (sort || (order && order.length)) this.trigger('sort', this, options);
- }
-
- // Return the added (or merged) model (or models).
- return singular ? models[0] : models;
- },
-
- // When you have more items than you want to add or remove individually,
- // you can reset the entire set with a new list of models, without firing
- // any granular `add` or `remove` events. Fires `reset` when finished.
- // Useful for bulk operations and optimizations.
- reset: function(models, options) {
- options || (options = {});
- for (var i = 0, length = this.models.length; i < length; i++) {
- this._removeReference(this.models[i], options);
- }
- options.previousModels = this.models;
- this._reset();
- models = this.add(models, _.extend({silent: true}, options));
- if (!options.silent) this.trigger('reset', this, options);
- return models;
- },
-
- // Add a model to the end of the collection.
- push: function(model, options) {
- return this.add(model, _.extend({at: this.length}, options));
- },
-
- // Remove a model from the end of the collection.
- pop: function(options) {
- var model = this.at(this.length - 1);
- this.remove(model, options);
- return model;
- },
-
- // Add a model to the beginning of the collection.
- unshift: function(model, options) {
- return this.add(model, _.extend({at: 0}, options));
- },
-
- // Remove a model from the beginning of the collection.
- shift: function(options) {
- var model = this.at(0);
- this.remove(model, options);
- return model;
- },
-
- // Slice out a sub-array of models from the collection.
- slice: function() {
- return slice.apply(this.models, arguments);
- },
-
- // Get a model from the set by id.
- get: function(obj) {
- if (obj == null) return void 0;
- return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid];
- },
-
- // Get the model at the given index.
- at: function(index) {
- return this.models[index];
- },
-
- // Return models with matching attributes. Useful for simple cases of
- // `filter`.
- where: function(attrs, first) {
- if (_.isEmpty(attrs)) return first ? void 0 : [];
- return this[first ? 'find' : 'filter'](function(model) {
- for (var key in attrs) {
- if (attrs[key] !== model.get(key)) return false;
- }
- return true;
- });
- },
-
- // Return the first model with matching attributes. Useful for simple cases
- // of `find`.
- findWhere: function(attrs) {
- return this.where(attrs, true);
- },
-
- // Force the collection to re-sort itself. You don't need to call this under
- // normal circumstances, as the set will maintain sort order as each item
- // is added.
- sort: function(options) {
- if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
- options || (options = {});
-
- // Run sort based on type of `comparator`.
- if (_.isString(this.comparator) || this.comparator.length === 1) {
- this.models = this.sortBy(this.comparator, this);
- } else {
- this.models.sort(_.bind(this.comparator, this));
- }
-
- if (!options.silent) this.trigger('sort', this, options);
- return this;
- },
-
- // Pluck an attribute from each model in the collection.
- pluck: function(attr) {
- return _.invoke(this.models, 'get', attr);
- },
-
- // Fetch the default set of models for this collection, resetting the
- // collection when they arrive. If `reset: true` is passed, the response
- // data will be passed through the `reset` method instead of `set`.
- fetch: function(options) {
- options = options ? _.clone(options) : {};
- if (options.parse === void 0) options.parse = true;
- var success = options.success;
- var collection = this;
- options.success = function(resp) {
- var method = options.reset ? 'reset' : 'set';
- collection[method](resp, options);
- if (success) success(collection, resp, options);
- collection.trigger('sync', collection, resp, options);
- };
- wrapError(this, options);
- return this.sync('read', this, options);
- },
-
- // Create a new instance of a model in this collection. Add the model to the
- // collection immediately, unless `wait: true` is passed, in which case we
- // wait for the server to agree.
- create: function(model, options) {
- options = options ? _.clone(options) : {};
- if (!(model = this._prepareModel(model, options))) return false;
- if (!options.wait) this.add(model, options);
- var collection = this;
- var success = options.success;
- options.success = function(model, resp) {
- if (options.wait) collection.add(model, options);
- if (success) success(model, resp, options);
- };
- model.save(null, options);
- return model;
- },
-
- // **parse** converts a response into a list of models to be added to the
- // collection. The default implementation is just to pass it through.
- parse: function(resp, options) {
- return resp;
- },
-
- // Create a new collection with an identical list of models as this one.
- clone: function() {
- return new this.constructor(this.models, {
- model: this.model,
- comparator: this.comparator
- });
- },
-
- // Private method to reset all internal state. Called when the collection
- // is first initialized or reset.
- _reset: function() {
- this.length = 0;
- this.models = [];
- this._byId = {};
- },
-
- // Prepare a hash of attributes (or other model) to be added to this
- // collection.
- _prepareModel: function(attrs, options) {
- if (this._isModel(attrs)) {
- if (!attrs.collection) attrs.collection = this;
- return attrs;
- }
- options = options ? _.clone(options) : {};
- options.collection = this;
- var model = new this.model(attrs, options);
- if (!model.validationError) return model;
- this.trigger('invalid', this, model.validationError, options);
- return false;
- },
-
- // Method for checking whether an object should be considered a model for
- // the purposes of adding to the collection.
- _isModel: function (model) {
- return model instanceof Model;
- },
-
- // Internal method to create a model's ties to a collection.
- _addReference: function(model, options) {
- this._byId[model.cid] = model;
- if (model.id != null) this._byId[model.id] = model;
- model.on('all', this._onModelEvent, this);
- },
-
- // Internal method to sever a model's ties to a collection.
- _removeReference: function(model, options) {
- if (this === model.collection) delete model.collection;
- model.off('all', this._onModelEvent, this);
- },
-
- // Internal method called every time a model in the set fires an event.
- // Sets need to update their indexes when models change ids. All other
- // events simply proxy through. "add" and "remove" events that originate
- // in other collections are ignored.
- _onModelEvent: function(event, model, collection, options) {
- if ((event === 'add' || event === 'remove') && collection !== this) return;
- if (event === 'destroy') this.remove(model, options);
- if (model && event === 'change:' + model.idAttribute) {
- delete this._byId[model.previous(model.idAttribute)];
- if (model.id != null) this._byId[model.id] = model;
- }
- this.trigger.apply(this, arguments);
- }
-
- });
-
- // Underscore methods that we want to implement on the Collection.
- // 90% of the core usefulness of Backbone Collections is actually implemented
- // right here:
- var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
- 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
- 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
- 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
- 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
- 'lastIndexOf', 'isEmpty', 'chain', 'sample', 'partition'];
-
- // Mix in each Underscore method as a proxy to `Collection#models`.
- _.each(methods, function(method) {
- if (!_[method]) return;
- Collection.prototype[method] = function() {
- var args = slice.call(arguments);
- args.unshift(this.models);
- return _[method].apply(_, args);
- };
- });
-
- // Underscore methods that take a property name as an argument.
- var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
-
- // Use attributes instead of properties.
- _.each(attributeMethods, function(method) {
- if (!_[method]) return;
- Collection.prototype[method] = function(value, context) {
- var iterator = _.isFunction(value) ? value : function(model) {
- return model.get(value);
- };
- return _[method](this.models, iterator, context);
- };
- });
-
- // Backbone.View
- // -------------
-
- // Backbone Views are almost more convention than they are actual code. A View
- // is simply a JavaScript object that represents a logical chunk of UI in the
- // DOM. This might be a single item, an entire list, a sidebar or panel, or
- // even the surrounding frame which wraps your whole app. Defining a chunk of
- // UI as a **View** allows you to define your DOM events declaratively, without
- // having to worry about render order ... and makes it easy for the view to
- // react to specific changes in the state of your models.
-
- // Creating a Backbone.View creates its initial element outside of the DOM,
- // if an existing element is not provided...
- var View = Backbone.View = function(options) {
- this.cid = _.uniqueId('view');
- options || (options = {});
- _.extend(this, _.pick(options, viewOptions));
- this._ensureElement();
- this.initialize.apply(this, arguments);
- };
-
- // Cached regex to split keys for `delegate`.
- var delegateEventSplitter = /^(\S+)\s*(.*)$/;
-
- // List of view options to be merged as properties.
- var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
-
- // Set up all inheritable **Backbone.View** properties and methods.
- _.extend(View.prototype, Events, {
-
- // The default `tagName` of a View's element is `"div"`.
- tagName: 'div',
-
- // jQuery delegate for element lookup, scoped to DOM elements within the
- // current view. This should be preferred to global lookups where possible.
- $: function(selector) {
- return this.$el.find(selector);
- },
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // **render** is the core function that your view should override, in order
- // to populate its element (`this.el`), with the appropriate HTML. The
- // convention is for **render** to always return `this`.
- render: function() {
- return this;
- },
-
- // Remove this view by taking the element out of the DOM, and removing any
- // applicable Backbone.Events listeners.
- remove: function() {
- this._removeElement();
- this.stopListening();
- return this;
- },
-
- // Remove this view's element from the document and all event listeners
- // attached to it. Exposed for subclasses using an alternative DOM
- // manipulation API.
- _removeElement: function() {
- this.$el.remove();
- },
-
- // Change the view's element (`this.el` property) and re-delegate the
- // view's events on the new element.
- setElement: function(element) {
- this.undelegateEvents();
- this._setElement(element);
- this.delegateEvents();
- return this;
- },
-
- // Creates the `this.el` and `this.$el` references for this view using the
- // given `el` and a hash of `attributes`. `el` can be a CSS selector or an
- // HTML string, a jQuery context or an element. Subclasses can override
- // this to utilize an alternative DOM manipulation API and are only required
- // to set the `this.el` property.
- _setElement: function(el) {
- this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
- this.el = this.$el[0];
- },
-
- // Set callbacks, where `this.events` is a hash of
- //
- // *{"event selector": "callback"}*
- //
- // {
- // 'mousedown .title': 'edit',
- // 'click .button': 'save',
- // 'click .open': function(e) { ... }
- // }
- //
- // pairs. Callbacks will be bound to the view, with `this` set properly.
- // Uses event delegation for efficiency.
- // Omitting the selector binds the event to `this.el`.
- delegateEvents: function(events) {
- if (!(events || (events = _.result(this, 'events')))) return this;
- this.undelegateEvents();
- for (var key in events) {
- var method = events[key];
- if (!_.isFunction(method)) method = this[events[key]];
- if (!method) continue;
- var match = key.match(delegateEventSplitter);
- this.delegate(match[1], match[2], _.bind(method, this));
- }
- return this;
- },
-
- // Add a single event listener to the view's element (or a child element
- // using `selector`). This only works for delegate-able events: not `focus`,
- // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
- delegate: function(eventName, selector, listener) {
- this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
- },
-
- // Clears all callbacks previously bound to the view by `delegateEvents`.
- // You usually don't need to use this, but may wish to if you have multiple
- // Backbone views attached to the same DOM element.
- undelegateEvents: function() {
- if (this.$el) this.$el.off('.delegateEvents' + this.cid);
- return this;
- },
-
- // A finer-grained `undelegateEvents` for removing a single delegated event.
- // `selector` and `listener` are both optional.
- undelegate: function(eventName, selector, listener) {
- this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
- },
-
- // Produces a DOM element to be assigned to your view. Exposed for
- // subclasses using an alternative DOM manipulation API.
- _createElement: function(tagName) {
- return document.createElement(tagName);
- },
-
- // Ensure that the View has a DOM element to render into.
- // If `this.el` is a string, pass it through `$()`, take the first
- // matching element, and re-assign it to `el`. Otherwise, create
- // an element from the `id`, `className` and `tagName` properties.
- _ensureElement: function() {
- if (!this.el) {
- var attrs = _.extend({}, _.result(this, 'attributes'));
- if (this.id) attrs.id = _.result(this, 'id');
- if (this.className) attrs['class'] = _.result(this, 'className');
- this.setElement(this._createElement(_.result(this, 'tagName')));
- this._setAttributes(attrs);
- } else {
- this.setElement(_.result(this, 'el'));
- }
- },
-
- // Set attributes from a hash on this view's element. Exposed for
- // subclasses using an alternative DOM manipulation API.
- _setAttributes: function(attributes) {
- this.$el.attr(attributes);
- }
-
- });
-
- // Backbone.sync
- // -------------
-
- // Override this function to change the manner in which Backbone persists
- // models to the server. You will be passed the type of request, and the
- // model in question. By default, makes a RESTful Ajax request
- // to the model's `url()`. Some possible customizations could be:
- //
- // * Use `setTimeout` to batch rapid-fire updates into a single request.
- // * Send up the models as XML instead of JSON.
- // * Persist models via WebSockets instead of Ajax.
- //
- // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
- // as `POST`, with a `_method` parameter containing the true HTTP method,
- // as well as all requests with the body as `application/x-www-form-urlencoded`
- // instead of `application/json` with the model in a param named `model`.
- // Useful when interfacing with server-side languages like **PHP** that make
- // it difficult to read the body of `PUT` requests.
- Backbone.sync = function(method, model, options) {
- var type = methodMap[method];
-
- // Default options, unless specified.
- _.defaults(options || (options = {}), {
- emulateHTTP: Backbone.emulateHTTP,
- emulateJSON: Backbone.emulateJSON
- });
-
- // Default JSON-request options.
- var params = {type: type, dataType: 'json'};
-
- // Ensure that we have a URL.
- if (!options.url) {
- params.url = _.result(model, 'url') || urlError();
- }
-
- // Ensure that we have the appropriate request data.
- if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
- params.contentType = 'application/json';
- params.data = JSON.stringify(options.attrs || model.toJSON(options));
- }
-
- // For older servers, emulate JSON by encoding the request into an HTML-form.
- if (options.emulateJSON) {
- params.contentType = 'application/x-www-form-urlencoded';
- params.data = params.data ? {model: params.data} : {};
- }
-
- // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
- // And an `X-HTTP-Method-Override` header.
- if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
- params.type = 'POST';
- if (options.emulateJSON) params.data._method = type;
- var beforeSend = options.beforeSend;
- options.beforeSend = function(xhr) {
- xhr.setRequestHeader('X-HTTP-Method-Override', type);
- if (beforeSend) return beforeSend.apply(this, arguments);
- };
- }
-
- // Don't process data on a non-GET request.
- if (params.type !== 'GET' && !options.emulateJSON) {
- params.processData = false;
- }
-
- // If we're sending a `PATCH` request, and we're in an old Internet Explorer
- // that still has ActiveX enabled by default, override jQuery to use that
- // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
- if (params.type === 'PATCH' && noXhrPatch) {
- params.xhr = function() {
- return new ActiveXObject("Microsoft.XMLHTTP");
- };
- }
-
- // Pass along `textStatus` and `errorThrown` from jQuery.
- var error = options.error;
- options.error = function(xhr, textStatus, errorThrown) {
- options.textStatus = textStatus;
- options.errorThrown = errorThrown;
- if (error) error.apply(this, arguments);
- };
-
- // Make the request, allowing the user to override any Ajax options.
- var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
- model.trigger('request', model, xhr, options);
- return xhr;
- };
-
- var noXhrPatch =
- typeof window !== 'undefined' && !!window.ActiveXObject &&
- !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
-
- // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
- var methodMap = {
- 'create': 'POST',
- 'update': 'PUT',
- 'patch': 'PATCH',
- 'delete': 'DELETE',
- 'read': 'GET'
- };
-
- // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
- // Override this if you'd like to use a different library.
- Backbone.ajax = function() {
- return Backbone.$.ajax.apply(Backbone.$, arguments);
- };
-
- // Backbone.Router
- // ---------------
-
- // Routers map faux-URLs to actions, and fire events when routes are
- // matched. Creating a new one sets its `routes` hash, if not set statically.
- var Router = Backbone.Router = function(options) {
- options || (options = {});
- if (options.routes) this.routes = options.routes;
- this._bindRoutes();
- this.initialize.apply(this, arguments);
- };
-
- // Cached regular expressions for matching named param parts and splatted
- // parts of route strings.
- var optionalParam = /\((.*?)\)/g;
- var namedParam = /(\(\?)?:\w+/g;
- var splatParam = /\*\w+/g;
- var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
-
- // Set up all inheritable **Backbone.Router** properties and methods.
- _.extend(Router.prototype, Events, {
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Manually bind a single named route to a callback. For example:
- //
- // this.route('search/:query/p:num', 'search', function(query, num) {
- // ...
- // });
- //
- route: function(route, name, callback) {
- if (!_.isRegExp(route)) route = this._routeToRegExp(route);
- if (_.isFunction(name)) {
- callback = name;
- name = '';
- }
- if (!callback) callback = this[name];
- var router = this;
- Backbone.history.route(route, function(fragment) {
- var args = router._extractParameters(route, fragment);
- if (router.execute(callback, args, name) !== false) {
- router.trigger.apply(router, ['route:' + name].concat(args));
- router.trigger('route', name, args);
- Backbone.history.trigger('route', router, name, args);
- }
- });
- return this;
- },
-
- // Execute a route handler with the provided parameters. This is an
- // excellent place to do pre-route setup or post-route cleanup.
- execute: function(callback, args, name) {
- if (callback) callback.apply(this, args);
- },
-
- // Simple proxy to `Backbone.history` to save a fragment into the history.
- navigate: function(fragment, options) {
- Backbone.history.navigate(fragment, options);
- return this;
- },
-
- // Bind all defined routes to `Backbone.history`. We have to reverse the
- // order of the routes here to support behavior where the most general
- // routes can be defined at the bottom of the route map.
- _bindRoutes: function() {
- if (!this.routes) return;
- this.routes = _.result(this, 'routes');
- var route, routes = _.keys(this.routes);
- while ((route = routes.pop()) != null) {
- this.route(route, this.routes[route]);
- }
- },
-
- // Convert a route string into a regular expression, suitable for matching
- // against the current location hash.
- _routeToRegExp: function(route) {
- route = route.replace(escapeRegExp, '\\$&')
- .replace(optionalParam, '(?:$1)?')
- .replace(namedParam, function(match, optional) {
- return optional ? match : '([^/?]+)';
- })
- .replace(splatParam, '([^?]*?)');
- return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
- },
-
- // Given a route, and a URL fragment that it matches, return the array of
- // extracted decoded parameters. Empty or unmatched parameters will be
- // treated as `null` to normalize cross-browser behavior.
- _extractParameters: function(route, fragment) {
- var params = route.exec(fragment).slice(1);
- return _.map(params, function(param, i) {
- // Don't decode the search params.
- if (i === params.length - 1) return param || null;
- return param ? decodeURIComponent(param) : null;
- });
- }
-
- });
-
- // Backbone.History
- // ----------------
-
- // Handles cross-browser history management, based on either
- // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
- // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
- // and URL fragments. If the browser supports neither (old IE, natch),
- // falls back to polling.
- var History = Backbone.History = function() {
- this.handlers = [];
- _.bindAll(this, 'checkUrl');
-
- // Ensure that `History` can be used outside of the browser.
- if (typeof window !== 'undefined') {
- this.location = window.location;
- this.history = window.history;
- }
- };
-
- // Cached regex for stripping a leading hash/slash and trailing space.
- var routeStripper = /^[#\/]|\s+$/g;
-
- // Cached regex for stripping leading and trailing slashes.
- var rootStripper = /^\/+|\/+$/g;
-
- // Cached regex for stripping urls of hash.
- var pathStripper = /#.*$/;
-
- // Has the history handling already been started?
- History.started = false;
-
- // Set up all inheritable **Backbone.History** properties and methods.
- _.extend(History.prototype, Events, {
-
- // The default interval to poll for hash changes, if necessary, is
- // twenty times a second.
- interval: 50,
-
- // Are we at the app root?
- atRoot: function() {
- var path = this.location.pathname.replace(/[^\/]$/, '$&/');
- return path === this.root && !this.location.search;
- },
-
- // Gets the true hash value. Cannot use location.hash directly due to bug
- // in Firefox where location.hash will always be decoded.
- getHash: function(window) {
- var match = (window || this).location.href.match(/#(.*)$/);
- return match ? match[1] : '';
- },
-
- // Get the pathname and search params, without the root.
- getPath: function() {
- var path = decodeURI(this.location.pathname + this.location.search);
- var root = this.root.slice(0, -1);
- if (!path.indexOf(root)) path = path.slice(root.length);
- return path.slice(1);
- },
-
- // Get the cross-browser normalized URL fragment from the path or hash.
- getFragment: function(fragment) {
- if (fragment == null) {
- if (this._hasPushState || !this._wantsHashChange) {
- fragment = this.getPath();
- } else {
- fragment = this.getHash();
- }
- }
- return fragment.replace(routeStripper, '');
- },
-
- // Start the hash change handling, returning `true` if the current URL matches
- // an existing route, and `false` otherwise.
- start: function(options) {
- if (History.started) throw new Error("Backbone.history has already been started");
- History.started = true;
-
- // Figure out the initial configuration. Do we need an iframe?
- // Is pushState desired ... is it available?
- this.options = _.extend({root: '/'}, this.options, options);
- this.root = this.options.root;
- this._wantsHashChange = this.options.hashChange !== false;
- this._hasHashChange = 'onhashchange' in window;
- this._wantsPushState = !!this.options.pushState;
- this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);
- this.fragment = this.getFragment();
-
- // Add a cross-platform `addEventListener` shim for older browsers.
- var addEventListener = window.addEventListener || function (eventName, listener) {
- return attachEvent('on' + eventName, listener);
- };
-
- // Normalize root to always include a leading and trailing slash.
- this.root = ('/' + this.root + '/').replace(rootStripper, '/');
-
- // Proxy an iframe to handle location events if the browser doesn't
- // support the `hashchange` event, HTML5 history, or the user wants
- // `hashChange` but not `pushState`.
- if (!this._hasHashChange && this._wantsHashChange && (!this._wantsPushState || !this._hasPushState)) {
- var iframe = document.createElement('iframe');
- iframe.src = 'javascript:0';
- iframe.style.display = 'none';
- iframe.tabIndex = -1;
- var body = document.body;
- // Using `appendChild` will throw on IE < 9 if the document is not ready.
- this.iframe = body.insertBefore(iframe, body.firstChild).contentWindow;
- this.navigate(this.fragment);
- }
-
- // Depending on whether we're using pushState or hashes, and whether
- // 'onhashchange' is supported, determine how we check the URL state.
- if (this._hasPushState) {
- addEventListener('popstate', this.checkUrl, false);
- } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) {
- addEventListener('hashchange', this.checkUrl, false);
- } else if (this._wantsHashChange) {
- this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
- }
-
- // Transition from hashChange to pushState or vice versa if both are
- // requested.
- if (this._wantsHashChange && this._wantsPushState) {
-
- // If we've started off with a route from a `pushState`-enabled
- // browser, but we're currently in a browser that doesn't support it...
- if (!this._hasPushState && !this.atRoot()) {
- this.location.replace(this.root + '#' + this.getPath());
- // Return immediately as browser will do redirect to new url
- return true;
-
- // Or if we've started out with a hash-based route, but we're currently
- // in a browser where it could be `pushState`-based instead...
- } else if (this._hasPushState && this.atRoot()) {
- this.navigate(this.getHash(), {replace: true});
- }
-
- }
-
- if (!this.options.silent) return this.loadUrl();
- },
-
- // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
- // but possibly useful for unit testing Routers.
- stop: function() {
- // Add a cross-platform `removeEventListener` shim for older browsers.
- var removeEventListener = window.removeEventListener || function (eventName, listener) {
- return detachEvent('on' + eventName, listener);
- };
-
- // Remove window listeners.
- if (this._hasPushState) {
- removeEventListener('popstate', this.checkUrl, false);
- } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) {
- removeEventListener('hashchange', this.checkUrl, false);
- }
-
- // Clean up the iframe if necessary.
- if (this.iframe) {
- document.body.removeChild(this.iframe.frameElement);
- this.iframe = null;
- }
-
- // Some environments will throw when clearing an undefined interval.
- if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
- History.started = false;
- },
-
- // Add a route to be tested when the fragment changes. Routes added later
- // may override previous routes.
- route: function(route, callback) {
- this.handlers.unshift({route: route, callback: callback});
- },
-
- // Checks the current URL to see if it has changed, and if it has,
- // calls `loadUrl`, normalizing across the hidden iframe.
- checkUrl: function(e) {
- var current = this.getFragment();
- if (current === this.fragment && this.iframe) {
- current = this.getHash(this.iframe);
- }
- if (current === this.fragment) return false;
- if (this.iframe) this.navigate(current);
- this.loadUrl();
- },
-
- // Attempt to load the current URL fragment. If a route succeeds with a
- // match, returns `true`. If no defined routes matches the fragment,
- // returns `false`.
- loadUrl: function(fragment) {
- fragment = this.fragment = this.getFragment(fragment);
- return _.any(this.handlers, function(handler) {
- if (handler.route.test(fragment)) {
- handler.callback(fragment);
- return true;
- }
- });
- },
-
- // Save a fragment into the hash history, or replace the URL state if the
- // 'replace' option is passed. You are responsible for properly URL-encoding
- // the fragment in advance.
- //
- // The options object can contain `trigger: true` if you wish to have the
- // route callback be fired (not usually desirable), or `replace: true`, if
- // you wish to modify the current URL without adding an entry to the history.
- navigate: function(fragment, options) {
- if (!History.started) return false;
- if (!options || options === true) options = {trigger: !!options};
-
- var url = this.root + (fragment = this.getFragment(fragment || ''));
-
- // Strip the hash and decode for matching.
- fragment = decodeURI(fragment.replace(pathStripper, ''));
-
- if (this.fragment === fragment) return;
- this.fragment = fragment;
-
- // Don't include a trailing slash on the root.
- if (fragment === '' && url !== '/') url = url.slice(0, -1);
-
- // If pushState is available, we use it to set the fragment as a real URL.
- if (this._hasPushState) {
- this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
-
- // If hash changes haven't been explicitly disabled, update the hash
- // fragment to store history.
- } else if (this._wantsHashChange) {
- this._updateHash(this.location, fragment, options.replace);
- if (this.iframe && (fragment !== this.getHash(this.iframe))) {
- // Opening and closing the iframe tricks IE7 and earlier to push a
- // history entry on hash-tag change. When replace is true, we don't
- // want this.
- if(!options.replace) this.iframe.document.open().close();
- this._updateHash(this.iframe.location, fragment, options.replace);
- }
-
- // If you've told us that you explicitly don't want fallback hashchange-
- // based history, then `navigate` becomes a page refresh.
- } else {
- return this.location.assign(url);
- }
- if (options.trigger) return this.loadUrl(fragment);
- },
-
- // Update the hash location, either replacing the current entry, or adding
- // a new one to the browser history.
- _updateHash: function(location, fragment, replace) {
- if (replace) {
- var href = location.href.replace(/(javascript:|#).*$/, '');
- location.replace(href + '#' + fragment);
- } else {
- // Some browsers require that `hash` contains a leading #.
- location.hash = '#' + fragment;
- }
- }
-
- });
-
- // Create the default Backbone.history.
- Backbone.history = new History;
-
- // Helpers
- // -------
-
- // Helper function to correctly set up the prototype chain, for subclasses.
- // Similar to `goog.inherits`, but uses a hash of prototype properties and
- // class properties to be extended.
- var extend = function(protoProps, staticProps) {
- var parent = this;
- var child;
-
- // The constructor function for the new subclass is either defined by you
- // (the "constructor" property in your `extend` definition), or defaulted
- // by us to simply call the parent's constructor.
- if (protoProps && _.has(protoProps, 'constructor')) {
- child = protoProps.constructor;
- } else {
- child = function(){ return parent.apply(this, arguments); };
- }
-
- // Add static properties to the constructor function, if supplied.
- _.extend(child, parent, staticProps);
-
- // Set the prototype chain to inherit from `parent`, without calling
- // `parent`'s constructor function.
- var Surrogate = function(){ this.constructor = child; };
- Surrogate.prototype = parent.prototype;
- child.prototype = new Surrogate;
-
- // Add prototype properties (instance properties) to the subclass,
- // if supplied.
- if (protoProps) _.extend(child.prototype, protoProps);
-
- // Set a convenience property in case the parent's prototype is needed
- // later.
- child.__super__ = parent.prototype;
-
- return child;
- };
-
- // Set up inheritance for the model, collection, router, view and history.
- Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
-
- // Throw an error when a URL is needed, and none is supplied.
- var urlError = function() {
- throw new Error('A "url" property or function must be specified');
- };
-
- // Wrap an optional error callback with a fallback error event.
- var wrapError = function(model, options) {
- var error = options.error;
- options.error = function(resp) {
- if (error) error(model, resp, options);
- model.trigger('error', model, resp, options);
- };
- };
-
- return Backbone;
-
-}));
\ No newline at end of file
diff --git a/vendor/jbone/perf/vendors/jquery.js b/vendor/jbone/perf/vendors/jquery.js
deleted file mode 100644
index 008f678..0000000
--- a/vendor/jbone/perf/vendors/jquery.js
+++ /dev/null
@@ -1,9111 +0,0 @@
-/*!
- * jQuery JavaScript Library v2.1.0
- * http://jquery.com/
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- *
- * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-01-23T21:10Z
- */
-
-(function( global, factory ) {
-
- if ( typeof module === "object" && typeof module.exports === "object" ) {
- // For CommonJS and CommonJS-like environments where a proper window is present,
- // execute the factory and get jQuery
- // For environments that do not inherently posses a window with a document
- // (such as Node.js), expose a jQuery-making factory as module.exports
- // This accentuates the need for the creation of a real window
- // e.g. var jQuery = require("jquery")(window);
- // See ticket #14549 for more info
- module.exports = global.document ?
- factory( global, true ) :
- function( w ) {
- if ( !w.document ) {
- throw new Error( "jQuery requires a window with a document" );
- }
- return factory( w );
- };
- } else {
- factory( global );
- }
-
-// Pass this if window is not defined yet
-}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Can't do this because several apps including ASP.NET trace
-// the stack via arguments.caller.callee and Firefox dies if
-// you try to trace through "use strict" call chains. (#13335)
-// Support: Firefox 18+
-//
-
-var arr = [];
-
-var slice = arr.slice;
-
-var concat = arr.concat;
-
-var push = arr.push;
-
-var indexOf = arr.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var trim = "".trim;
-
-var support = {};
-
-
-
-var
- // Use the correct document accordingly with window argument (sandbox)
- document = window.document,
-
- version = "2.1.0",
-
- // Define a local copy of jQuery
- jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- // Need init if jQuery is called (just allow error to be thrown if not included)
- return new jQuery.fn.init( selector, context );
- },
-
- // Matches dashed string for camelizing
- rmsPrefix = /^-ms-/,
- rdashAlpha = /-([\da-z])/gi,
-
- // Used by jQuery.camelCase as callback to replace()
- fcamelCase = function( all, letter ) {
- return letter.toUpperCase();
- };
-
-jQuery.fn = jQuery.prototype = {
- // The current version of jQuery being used
- jquery: version,
-
- constructor: jQuery,
-
- // Start with an empty selector
- selector: "",
-
- // The default length of a jQuery object is 0
- length: 0,
-
- toArray: function() {
- return slice.call( this );
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num != null ?
-
- // Return a 'clean' array
- ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
-
- // Return just the object
- slice.call( this );
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems ) {
-
- // Build a new jQuery matched element set
- var ret = jQuery.merge( this.constructor(), elems );
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
- ret.context = this.context;
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function( elem, i ) {
- return callback.call( elem, i, elem );
- }));
- },
-
- slice: function() {
- return this.pushStack( slice.apply( this, arguments ) );
- },
-
- first: function() {
- return this.eq( 0 );
- },
-
- last: function() {
- return this.eq( -1 );
- },
-
- eq: function( i ) {
- var len = this.length,
- j = +i + ( i < 0 ? len : 0 );
- return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
- },
-
- end: function() {
- return this.prevObject || this.constructor(null);
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: arr.sort,
- splice: arr.splice
-};
-
-jQuery.extend = jQuery.fn.extend = function() {
- var options, name, src, copy, copyIsArray, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
-
- // skip the boolean and the target
- target = arguments[ i ] || {};
- i++;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
- target = {};
- }
-
- // extend jQuery itself if only one argument is passed
- if ( i === length ) {
- target = this;
- i--;
- }
-
- for ( ; i < length; i++ ) {
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging plain objects or arrays
- if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src && jQuery.isArray(src) ? src : [];
-
- } else {
- clone = src && jQuery.isPlainObject(src) ? src : {};
- }
-
- // Never move original objects, clone them
- target[ name ] = jQuery.extend( deep, clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
- }
-
- // Return the modified object
- return target;
-};
-
-jQuery.extend({
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
- // Assume jQuery is ready without the ready module
- isReady: true,
-
- error: function( msg ) {
- throw new Error( msg );
- },
-
- noop: function() {},
-
- // See test/unit/core.js for details concerning isFunction.
- // Since version 1.3, DOM methods and functions like alert
- // aren't supported. They return false on IE (#2968).
- isFunction: function( obj ) {
- return jQuery.type(obj) === "function";
- },
-
- isArray: Array.isArray,
-
- isWindow: function( obj ) {
- return obj != null && obj === obj.window;
- },
-
- isNumeric: function( obj ) {
- // parseFloat NaNs numeric-cast false positives (null|true|false|"")
- // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
- // subtraction forces infinities to NaN
- return obj - parseFloat( obj ) >= 0;
- },
-
- isPlainObject: function( obj ) {
- // Not plain objects:
- // - Any object or value whose internal [[Class]] property is not "[object Object]"
- // - DOM nodes
- // - window
- if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- // Support: Firefox <20
- // The try/catch suppresses exceptions thrown when attempting to access
- // the "constructor" property of certain host objects, ie. |window.location|
- // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
- try {
- if ( obj.constructor &&
- !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
- return false;
- }
- } catch ( e ) {
- return false;
- }
-
- // If the function hasn't returned already, we're confident that
- // |obj| is a plain object, created by {} or constructed with new Object
- return true;
- },
-
- isEmptyObject: function( obj ) {
- var name;
- for ( name in obj ) {
- return false;
- }
- return true;
- },
-
- type: function( obj ) {
- if ( obj == null ) {
- return obj + "";
- }
- // Support: Android < 4.0, iOS < 6 (functionish RegExp)
- return typeof obj === "object" || typeof obj === "function" ?
- class2type[ toString.call(obj) ] || "object" :
- typeof obj;
- },
-
- // Evaluates a script in a global context
- globalEval: function( code ) {
- var script,
- indirect = eval;
-
- code = jQuery.trim( code );
-
- if ( code ) {
- // If the code includes a valid, prologue position
- // strict mode pragma, execute code by injecting a
- // script tag into the document.
- if ( code.indexOf("use strict") === 1 ) {
- script = document.createElement("script");
- script.text = code;
- document.head.appendChild( script ).parentNode.removeChild( script );
- } else {
- // Otherwise, avoid the DOM node creation, insertion
- // and removal by using an indirect global eval
- indirect( code );
- }
- }
- },
-
- // Convert dashed to camelCase; used by the css and data modules
- // Microsoft forgot to hump their vendor prefix (#9572)
- camelCase: function( string ) {
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
- },
-
- // args is for internal usage only
- each: function( obj, callback, args ) {
- var value,
- i = 0,
- length = obj.length,
- isArray = isArraylike( obj );
-
- if ( args ) {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.apply( obj[ i ], args );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.apply( obj[ i ], args );
-
- if ( value === false ) {
- break;
- }
- }
- }
-
- // A special, fast, case for the most common use of each
- } else {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.call( obj[ i ], i, obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.call( obj[ i ], i, obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- }
- }
-
- return obj;
- },
-
- trim: function( text ) {
- return text == null ? "" : trim.call( text );
- },
-
- // results is for internal usage only
- makeArray: function( arr, results ) {
- var ret = results || [];
-
- if ( arr != null ) {
- if ( isArraylike( Object(arr) ) ) {
- jQuery.merge( ret,
- typeof arr === "string" ?
- [ arr ] : arr
- );
- } else {
- push.call( ret, arr );
- }
- }
-
- return ret;
- },
-
- inArray: function( elem, arr, i ) {
- return arr == null ? -1 : indexOf.call( arr, elem, i );
- },
-
- merge: function( first, second ) {
- var len = +second.length,
- j = 0,
- i = first.length;
-
- for ( ; j < len; j++ ) {
- first[ i++ ] = second[ j ];
- }
-
- first.length = i;
-
- return first;
- },
-
- grep: function( elems, callback, invert ) {
- var callbackInverse,
- matches = [],
- i = 0,
- length = elems.length,
- callbackExpect = !invert;
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( ; i < length; i++ ) {
- callbackInverse = !callback( elems[ i ], i );
- if ( callbackInverse !== callbackExpect ) {
- matches.push( elems[ i ] );
- }
- }
-
- return matches;
- },
-
- // arg is for internal usage only
- map: function( elems, callback, arg ) {
- var value,
- i = 0,
- length = elems.length,
- isArray = isArraylike( elems ),
- ret = [];
-
- // Go through the array, translating each of the items to their new values
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
-
- // Go through every key on the object,
- } else {
- for ( i in elems ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
- }
-
- // Flatten any nested arrays
- return concat.apply( [], ret );
- },
-
- // A global GUID counter for objects
- guid: 1,
-
- // Bind a function to a context, optionally partially applying any
- // arguments.
- proxy: function( fn, context ) {
- var tmp, args, proxy;
-
- if ( typeof context === "string" ) {
- tmp = fn[ context ];
- context = fn;
- fn = tmp;
- }
-
- // Quick check to determine if target is callable, in the spec
- // this throws a TypeError, but we will just return undefined.
- if ( !jQuery.isFunction( fn ) ) {
- return undefined;
- }
-
- // Simulated bind
- args = slice.call( arguments, 2 );
- proxy = function() {
- return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
- };
-
- // Set the guid of unique handler to the same of original handler, so it can be removed
- proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
- return proxy;
- },
-
- now: Date.now,
-
- // jQuery.support is not used in Core but other projects attach their
- // properties to it so it needs to exist.
- support: support
-});
-
-// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
-
-function isArraylike( obj ) {
- var length = obj.length,
- type = jQuery.type( obj );
-
- if ( type === "function" || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- if ( obj.nodeType === 1 && length ) {
- return true;
- }
-
- return type === "array" || length === 0 ||
- typeof length === "number" && length > 0 && ( length - 1 ) in obj;
-}
-var Sizzle =
-/*!
- * Sizzle CSS Selector Engine v1.10.16
- * http://sizzlejs.com/
- *
- * Copyright 2013 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-01-13
- */
-(function( window ) {
-
-var i,
- support,
- Expr,
- getText,
- isXML,
- compile,
- outermostContext,
- sortInput,
- hasDuplicate,
-
- // Local document vars
- setDocument,
- document,
- docElem,
- documentIsHTML,
- rbuggyQSA,
- rbuggyMatches,
- matches,
- contains,
-
- // Instance-specific data
- expando = "sizzle" + -(new Date()),
- preferredDoc = window.document,
- dirruns = 0,
- done = 0,
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- }
- return 0;
- },
-
- // General-purpose constants
- strundefined = typeof undefined,
- MAX_NEGATIVE = 1 << 31,
-
- // Instance methods
- hasOwn = ({}).hasOwnProperty,
- arr = [],
- pop = arr.pop,
- push_native = arr.push,
- push = arr.push,
- slice = arr.slice,
- // Use a stripped-down indexOf if we can't use a native one
- indexOf = arr.indexOf || function( elem ) {
- var i = 0,
- len = this.length;
- for ( ; i < len; i++ ) {
- if ( this[i] === elem ) {
- return i;
- }
- }
- return -1;
- },
-
- booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
-
- // Regular expressions
-
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
-
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
-
- // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
- "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
-
- // Prefer arguments quoted,
- // then not containing pseudos/brackets,
- // then attribute selectors/non-parenthetical expressions,
- // then anything else
- // These preferences are here to reduce the number of selectors
- // needing tokenize in the PSEUDO preFilter
- pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
-
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
-
- rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
-
- rpseudo = new RegExp( pseudos ),
- ridentifier = new RegExp( "^" + identifier + "$" ),
-
- matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
- // For use in libraries implementing .is()
- // We use this for POS matching in `select`
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
- whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
- },
-
- rinputs = /^(?:input|select|textarea|button)$/i,
- rheader = /^h\d$/i,
-
- rnative = /^[^{]+\{\s*\[native \w/,
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
- rsibling = /[+~]/,
- rescape = /'|\\/g,
-
- // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
- funescape = function( _, escaped, escapedWhitespace ) {
- var high = "0x" + escaped - 0x10000;
- // NaN means non-codepoint
- // Support: Firefox
- // Workaround erroneous numeric interpretation of +"0x"
- return high !== high || escapedWhitespace ?
- escaped :
- high < 0 ?
- // BMP codepoint
- String.fromCharCode( high + 0x10000 ) :
- // Supplemental Plane codepoint (surrogate pair)
- String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
- };
-
-// Optimize for push.apply( _, NodeList )
-try {
- push.apply(
- (arr = slice.call( preferredDoc.childNodes )),
- preferredDoc.childNodes
- );
- // Support: Android<4.0
- // Detect silently failing push.apply
- arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
- push = { apply: arr.length ?
-
- // Leverage slice if possible
- function( target, els ) {
- push_native.apply( target, slice.call(els) );
- } :
-
- // Support: IE<9
- // Otherwise append directly
- function( target, els ) {
- var j = target.length,
- i = 0;
- // Can't trust NodeList.length
- while ( (target[j++] = els[i++]) ) {}
- target.length = j - 1;
- }
- };
-}
-
-function Sizzle( selector, context, results, seed ) {
- var match, elem, m, nodeType,
- // QSA vars
- i, groups, old, nid, newContext, newSelector;
-
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
- setDocument( context );
- }
-
- context = context || document;
- results = results || [];
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
- return [];
- }
-
- if ( documentIsHTML && !seed ) {
-
- // Shortcuts
- if ( (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document (jQuery #6963)
- if ( elem && elem.parentNode ) {
- // Handle the case where IE, Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) && elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
-
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results, context.getElementsByTagName( selector ) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
- push.apply( results, context.getElementsByClassName( m ) );
- return results;
- }
- }
-
- // QSA path
- if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
- nid = old = expando;
- newContext = context;
- newSelector = nodeType === 9 && selector;
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- groups = tokenize( selector );
-
- if ( (old = context.getAttribute("id")) ) {
- nid = old.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
- nid = "[id='" + nid + "'] ";
-
- i = groups.length;
- while ( i-- ) {
- groups[i] = nid + toSelector( groups[i] );
- }
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
- newSelector = groups.join(",");
- }
-
- if ( newSelector ) {
- try {
- push.apply( results,
- newContext.querySelectorAll( newSelector )
- );
- return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
- }
- }
- }
- }
- }
-
- // All others
- return select( selector.replace( rtrim, "$1" ), context, results, seed );
-}
-
-/**
- * Create key-value caches of limited size
- * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
- * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- * deleting the oldest entry
- */
-function createCache() {
- var keys = [];
-
- function cache( key, value ) {
- // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
- if ( keys.push( key + " " ) > Expr.cacheLength ) {
- // Only keep the most recent entries
- delete cache[ keys.shift() ];
- }
- return (cache[ key + " " ] = value);
- }
- return cache;
-}
-
-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
- fn[ expando ] = true;
- return fn;
-}
-
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
- */
-function assert( fn ) {
- var div = document.createElement("div");
-
- try {
- return !!fn( div );
- } catch (e) {
- return false;
- } finally {
- // Remove from its parent by default
- if ( div.parentNode ) {
- div.parentNode.removeChild( div );
- }
- // release memory in IE
- div = null;
- }
-}
-
-/**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
-function addHandle( attrs, handler ) {
- var arr = attrs.split("|"),
- i = attrs.length;
-
- while ( i-- ) {
- Expr.attrHandle[ arr[i] ] = handler;
- }
-}
-
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
-function siblingCheck( a, b ) {
- var cur = b && a,
- diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
- ( ~b.sourceIndex || MAX_NEGATIVE ) -
- ( ~a.sourceIndex || MAX_NEGATIVE );
-
- // Use IE sourceIndex if available on both nodes
- if ( diff ) {
- return diff;
- }
-
- // Check if b follows a
- if ( cur ) {
- while ( (cur = cur.nextSibling) ) {
- if ( cur === b ) {
- return -1;
- }
- }
- }
-
- return a ? 1 : -1;
-}
-
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
-}
-
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
-}
-
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
- return markFunction(function( argument ) {
- argument = +argument;
- return markFunction(function( seed, matches ) {
- var j,
- matchIndexes = fn( [], seed.length, argument ),
- i = matchIndexes.length;
-
- // Match elements found at the specified indexes
- while ( i-- ) {
- if ( seed[ (j = matchIndexes[i]) ] ) {
- seed[j] = !(matches[j] = seed[j]);
- }
- }
- });
- });
-}
-
-/**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
-function testContext( context ) {
- return context && typeof context.getElementsByTagName !== strundefined && context;
-}
-
-// Expose support vars for convenience
-support = Sizzle.support = {};
-
-/**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
-isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
- var hasCompare,
- doc = node ? node.ownerDocument || node : preferredDoc,
- parent = doc.defaultView;
-
- // If no document and documentElement is available, return
- if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
- return document;
- }
-
- // Set our document
- document = doc;
- docElem = doc.documentElement;
-
- // Support tests
- documentIsHTML = !isXML( doc );
-
- // Support: IE>8
- // If iframe document is assigned to "document" variable and if iframe has been reloaded,
- // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
- // IE6-8 do not support the defaultView property so parent will be undefined
- if ( parent && parent !== parent.top ) {
- // IE11 does not have attachEvent, so all must suffer
- if ( parent.addEventListener ) {
- parent.addEventListener( "unload", function() {
- setDocument();
- }, false );
- } else if ( parent.attachEvent ) {
- parent.attachEvent( "onunload", function() {
- setDocument();
- });
- }
- }
-
- /* Attributes
- ---------------------------------------------------------------------- */
-
- // Support: IE<8
- // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
- support.attributes = assert(function( div ) {
- div.className = "i";
- return !div.getAttribute("className");
- });
-
- /* getElement(s)By*
- ---------------------------------------------------------------------- */
-
- // Check if getElementsByTagName("*") returns only elements
- support.getElementsByTagName = assert(function( div ) {
- div.appendChild( doc.createComment("") );
- return !div.getElementsByTagName("*").length;
- });
-
- // Check if getElementsByClassName can be trusted
- support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
- div.innerHTML = "";
-
- // Support: Safari<4
- // Catch class over-caching
- div.firstChild.className = "i";
- // Support: Opera<10
- // Catch gEBCN failure to find non-leading classes
- return div.getElementsByClassName("i").length === 2;
- });
-
- // Support: IE<10
- // Check if getElementById returns elements by name
- // The broken getElementById methods don't pick up programatically-set names,
- // so use a roundabout getElementsByName test
- support.getById = assert(function( div ) {
- docElem.appendChild( div ).id = expando;
- return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
- });
-
- // ID find and filter
- if ( support.getById ) {
- Expr.find["ID"] = function( id, context ) {
- if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
- var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [m] : [];
- }
- };
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- return elem.getAttribute("id") === attrId;
- };
- };
- } else {
- // Support: IE6/7
- // getElementById is not reliable as a find shortcut
- delete Expr.find["ID"];
-
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
- return node && node.value === attrId;
- };
- };
- }
-
- // Tag
- Expr.find["TAG"] = support.getElementsByTagName ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !== strundefined ) {
- return context.getElementsByTagName( tag );
- }
- } :
- function( tag, context ) {
- var elem,
- tmp = [],
- i = 0,
- results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- while ( (elem = results[i++]) ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- };
-
- // Class
- Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
- if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
- return context.getElementsByClassName( className );
- }
- };
-
- /* QSA/matchesSelector
- ---------------------------------------------------------------------- */
-
- // QSA and matchesSelector support
-
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- rbuggyMatches = [];
-
- // qSa(:focus) reports false when true (Chrome 21)
- // We allow this because of a bug in IE8/9 that throws an error
- // whenever `document.activeElement` is accessed on an iframe
- // So, we allow :focus to pass through QSA all the time to avoid the IE error
- // See http://bugs.jquery.com/ticket/13378
- rbuggyQSA = [];
-
- if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explicitly
- // setting a boolean content attribute,
- // since its presence should be enough
- // http://bugs.jquery.com/ticket/12359
- div.innerHTML = "";
-
- // Support: IE8, Opera 10-12
- // Nothing should be selected when empty strings follow ^= or $= or *=
- if ( div.querySelectorAll("[t^='']").length ) {
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
- }
-
- // Support: IE8
- // Boolean attributes and "value" are not treated correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
- }
-
- // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
- });
-
- assert(function( div ) {
- // Support: Windows 8 Native Apps
- // The type and name attributes are restricted during .innerHTML assignment
- var input = doc.createElement("input");
- input.setAttribute( "type", "hidden" );
- div.appendChild( input ).setAttribute( "name", "D" );
-
- // Support: IE8
- // Enforce case-sensitivity of name attribute
- if ( div.querySelectorAll("[name=d]").length ) {
- rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push( ":enabled", ":disabled" );
- }
-
- // Opera 10-11 does not throw on post-comma invalid pseudos
- div.querySelectorAll("*,:x");
- rbuggyQSA.push(",.*:");
- });
- }
-
- if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector) )) ) {
-
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- support.disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call( div, "[s!='']:x" );
- rbuggyMatches.push( "!=", pseudos );
- });
- }
-
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
- rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
-
- /* Contains
- ---------------------------------------------------------------------- */
- hasCompare = rnative.test( docElem.compareDocumentPosition );
-
- // Element contains another
- // Purposefully does not implement inclusive descendent
- // As in, an element does not contain itself
- contains = hasCompare || rnative.test( docElem.contains ) ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && (
- adown.contains ?
- adown.contains( bup ) :
- a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
- ));
- } :
- function( a, b ) {
- if ( b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- }
- return false;
- };
-
- /* Sorting
- ---------------------------------------------------------------------- */
-
- // Document order sorting
- sortOrder = hasCompare ?
- function( a, b ) {
-
- // Flag for duplicate removal
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- // Sort on method existence if only one input has compareDocumentPosition
- var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
- if ( compare ) {
- return compare;
- }
-
- // Calculate position if both inputs belong to the same document
- compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
- a.compareDocumentPosition( b ) :
-
- // Otherwise we know they are disconnected
- 1;
-
- // Disconnected nodes
- if ( compare & 1 ||
- (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
-
- // Choose the first element that is related to our preferred document
- if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
- return -1;
- }
- if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
- return 1;
- }
-
- // Maintain original order
- return sortInput ?
- ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
- 0;
- }
-
- return compare & 4 ? -1 : 1;
- } :
- function( a, b ) {
- // Exit early if the nodes are identical
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- var cur,
- i = 0,
- aup = a.parentNode,
- bup = b.parentNode,
- ap = [ a ],
- bp = [ b ];
-
- // Parentless nodes are either documents or disconnected
- if ( !aup || !bup ) {
- return a === doc ? -1 :
- b === doc ? 1 :
- aup ? -1 :
- bup ? 1 :
- sortInput ?
- ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
- 0;
-
- // If the nodes are siblings, we can do a quick check
- } else if ( aup === bup ) {
- return siblingCheck( a, b );
- }
-
- // Otherwise we need full lists of their ancestors for comparison
- cur = a;
- while ( (cur = cur.parentNode) ) {
- ap.unshift( cur );
- }
- cur = b;
- while ( (cur = cur.parentNode) ) {
- bp.unshift( cur );
- }
-
- // Walk down the tree looking for a discrepancy
- while ( ap[i] === bp[i] ) {
- i++;
- }
-
- return i ?
- // Do a sibling check if the nodes have a common ancestor
- siblingCheck( ap[i], bp[i] ) :
-
- // Otherwise nodes in our document sort first
- ap[i] === preferredDoc ? -1 :
- bp[i] === preferredDoc ? 1 :
- 0;
- };
-
- return doc;
-};
-
-Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- if ( support.matchesSelector && documentIsHTML &&
- ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
- ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
-
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || support.disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch(e) {}
- }
-
- return Sizzle( expr, document, null, [elem] ).length > 0;
-};
-
-Sizzle.contains = function( context, elem ) {
- // Set document vars if needed
- if ( ( context.ownerDocument || context ) !== document ) {
- setDocument( context );
- }
- return contains( context, elem );
-};
-
-Sizzle.attr = function( elem, name ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- var fn = Expr.attrHandle[ name.toLowerCase() ],
- // Don't get fooled by Object.prototype properties (jQuery #13807)
- val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
- fn( elem, name, !documentIsHTML ) :
- undefined;
-
- return val !== undefined ?
- val :
- support.attributes || !documentIsHTML ?
- elem.getAttribute( name ) :
- (val = elem.getAttributeNode(name)) && val.specified ?
- val.value :
- null;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
-Sizzle.uniqueSort = function( results ) {
- var elem,
- duplicates = [],
- j = 0,
- i = 0;
-
- // Unless we *know* we can detect duplicates, assume their presence
- hasDuplicate = !support.detectDuplicates;
- sortInput = !support.sortStable && results.slice( 0 );
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- while ( (elem = results[i++]) ) {
- if ( elem === results[ i ] ) {
- j = duplicates.push( i );
- }
- }
- while ( j-- ) {
- results.splice( duplicates[ j ], 1 );
- }
- }
-
- // Clear input after sorting to release objects
- // See https://github.com/jquery/sizzle/pull/225
- sortInput = null;
-
- return results;
-};
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( !nodeType ) {
- // If no nodeType, this is expected to be an array
- while ( (node = elem[i++]) ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (jQuery #11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
-
- return ret;
-};
-
-Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- createPseudo: markFunction,
-
- match: matchExpr,
-
- attrHandle: {},
-
- find: {},
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( runescape, funescape );
-
- // Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 what (child|of-type)
- 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 4 xn-component of xn+y argument ([+-]?\d*n|)
- 5 sign of xn-component
- 6 x of xn-component
- 7 sign of y-component
- 8 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1].slice( 0, 3 ) === "nth" ) {
- // nth-* requires argument
- if ( !match[3] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
- match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[3] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match ) {
- var excess,
- unquoted = !match[5] && match[2];
-
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- // Accept quoted arguments as-is
- if ( match[3] && match[4] !== undefined ) {
- match[2] = match[4];
-
- // Strip excess characters from unquoted arguments
- } else if ( unquoted && rpseudo.test( unquoted ) &&
- // Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, true )) &&
- // advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
- // excess is a negative index
- match[0] = match[0].slice( 0, excess );
- match[2] = unquoted.slice( 0, excess );
- }
-
- // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
-
- "TAG": function( nodeNameSelector ) {
- var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
- return nodeNameSelector === "*" ?
- function() { return true; } :
- function( elem ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ className + " " ];
-
- return pattern ||
- (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
- classCache( className, function( elem ) {
- return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
- });
- },
-
- "ATTR": function( name, operator, check ) {
- return function( elem ) {
- var result = Sizzle.attr( elem, name );
-
- if ( result == null ) {
- return operator === "!=";
- }
- if ( !operator ) {
- return true;
- }
-
- result += "";
-
- return operator === "=" ? result === check :
- operator === "!=" ? result !== check :
- operator === "^=" ? check && result.indexOf( check ) === 0 :
- operator === "*=" ? check && result.indexOf( check ) > -1 :
- operator === "$=" ? check && result.slice( -check.length ) === check :
- operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
- operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
- false;
- };
- },
-
- "CHILD": function( type, what, argument, first, last ) {
- var simple = type.slice( 0, 3 ) !== "nth",
- forward = type.slice( -4 ) !== "last",
- ofType = what === "of-type";
-
- return first === 1 && last === 0 ?
-
- // Shortcut for :nth-*(n)
- function( elem ) {
- return !!elem.parentNode;
- } :
-
- function( elem, context, xml ) {
- var cache, outerCache, node, diff, nodeIndex, start,
- dir = simple !== forward ? "nextSibling" : "previousSibling",
- parent = elem.parentNode,
- name = ofType && elem.nodeName.toLowerCase(),
- useCache = !xml && !ofType;
-
- if ( parent ) {
-
- // :(first|last|only)-(child|of-type)
- if ( simple ) {
- while ( dir ) {
- node = elem;
- while ( (node = node[ dir ]) ) {
- if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
- return false;
- }
- }
- // Reverse direction for :only-* (if we haven't yet done so)
- start = dir = type === "only" && !start && "nextSibling";
- }
- return true;
- }
-
- start = [ forward ? parent.firstChild : parent.lastChild ];
-
- // non-xml :nth-child(...) stores cache data on `parent`
- if ( forward && useCache ) {
- // Seek `elem` from a previously-cached index
- outerCache = parent[ expando ] || (parent[ expando ] = {});
- cache = outerCache[ type ] || [];
- nodeIndex = cache[0] === dirruns && cache[1];
- diff = cache[0] === dirruns && cache[2];
- node = nodeIndex && parent.childNodes[ nodeIndex ];
-
- while ( (node = ++nodeIndex && node && node[ dir ] ||
-
- // Fallback to seeking `elem` from the start
- (diff = nodeIndex = 0) || start.pop()) ) {
-
- // When found, cache indexes on `parent` and break
- if ( node.nodeType === 1 && ++diff && node === elem ) {
- outerCache[ type ] = [ dirruns, nodeIndex, diff ];
- break;
- }
- }
-
- // Use previously-cached element index if available
- } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
- diff = cache[1];
-
- // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
- } else {
- // Use the same loop as above to seek `elem` from the start
- while ( (node = ++nodeIndex && node && node[ dir ] ||
- (diff = nodeIndex = 0) || start.pop()) ) {
-
- if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
- // Cache the index of each encountered element
- if ( useCache ) {
- (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
- }
-
- if ( node === elem ) {
- break;
- }
- }
- }
- }
-
- // Incorporate the offset, then check against cycle size
- diff -= last;
- return diff === first || ( diff % first === 0 && diff / first >= 0 );
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
- Sizzle.error( "unsupported pseudo: " + pseudo );
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if ( fn[ expando ] ) {
- return fn( argument );
- }
-
- // But maintain support for old signatures
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
- markFunction(function( seed, matches ) {
- var idx,
- matched = fn( seed, argument ),
- i = matched.length;
- while ( i-- ) {
- idx = indexOf.call( seed, matched[i] );
- seed[ idx ] = !( matches[ idx ] = matched[i] );
- }
- }) :
- function( elem ) {
- return fn( elem, 0, args );
- };
- }
-
- return fn;
- }
- },
-
- pseudos: {
- // Potentially complex pseudos
- "not": markFunction(function( selector ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile( selector.replace( rtrim, "$1" ) );
-
- return matcher[ expando ] ?
- markFunction(function( seed, matches, context, xml ) {
- var elem,
- unmatched = matcher( seed, null, xml, [] ),
- i = seed.length;
-
- // Match elements unmatched by `matcher`
- while ( i-- ) {
- if ( (elem = unmatched[i]) ) {
- seed[i] = !(matches[i] = elem);
- }
- }
- }) :
- function( elem, context, xml ) {
- input[0] = elem;
- matcher( input, null, xml, results );
- return !results.pop();
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "contains": markFunction(function( text ) {
- return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- // "Whether an element is represented by a :lang() selector
- // is based solely on the element's language value
- // being equal to the identifier C,
- // or beginning with the identifier C immediately followed by "-".
- // The matching of C against the element's language value is performed case-insensitively.
- // The identifier C does not have to be a valid language name."
- // http://www.w3.org/TR/selectors/#lang-pseudo
- "lang": markFunction( function( lang ) {
- // lang value must be a valid identifier
- if ( !ridentifier.test(lang || "") ) {
- Sizzle.error( "unsupported lang: " + lang );
- }
- lang = lang.replace( runescape, funescape ).toLowerCase();
- return function( elem ) {
- var elemLang;
- do {
- if ( (elemLang = documentIsHTML ?
- elem.lang :
- elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
-
- elemLang = elemLang.toLowerCase();
- return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
- }
- } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
- return false;
- };
- }),
-
- // Miscellaneous
- "target": function( elem ) {
- var hash = window.location && window.location.hash;
- return hash && hash.slice( 1 ) === elem.id;
- },
-
- "root": function( elem ) {
- return elem === docElem;
- },
-
- "focus": function( elem ) {
- return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
- },
-
- // Boolean properties
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- // Contents
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
- // but not by others (comment: 8; processing instruction: 7; etc.)
- // nodeType < 6 works because attributes (2) do not appear as children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- if ( elem.nodeType < 6 ) {
- return false;
- }
- }
- return true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- // Element/input types
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
-
- "text": function( elem ) {
- var attr;
- return elem.nodeName.toLowerCase() === "input" &&
- elem.type === "text" &&
-
- // Support: IE<8
- // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
- },
-
- // Position-in-collection
- "first": createPositionalPseudo(function() {
- return [ 0 ];
- }),
-
- "last": createPositionalPseudo(function( matchIndexes, length ) {
- return [ length - 1 ];
- }),
-
- "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ argument < 0 ? argument + length : argument ];
- }),
-
- "even": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 0;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "odd": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 1;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; --i >= 0; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; ++i < length; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- })
- }
-};
-
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
- Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
- Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-function tokenize( selector, parseOnly ) {
- var matched, match, tokens, type,
- soFar, groups, preFilters,
- cached = tokenCache[ selector + " " ];
-
- if ( cached ) {
- return parseOnly ? 0 : cached.slice( 0 );
- }
-
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
- if ( match ) {
- // Don't consume trailing commas as valid
- soFar = soFar.slice( match[0].length ) || soFar;
- }
- groups.push( (tokens = []) );
- }
-
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- // Cast descendant combinators to space
- type: match[0].replace( rtrim, " " )
- });
- soFar = soFar.slice( matched.length );
- }
-
- // Filters
- for ( type in Expr.filter ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- (match = preFilters[ type ]( match ))) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- type: type,
- matches: match
- });
- soFar = soFar.slice( matched.length );
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ?
- soFar.length :
- soFar ?
- Sizzle.error( selector ) :
- // Cache the tokens
- tokenCache( selector, groups ).slice( 0 );
-}
-
-function toSelector( tokens ) {
- var i = 0,
- len = tokens.length,
- selector = "";
- for ( ; i < len; i++ ) {
- selector += tokens[i].value;
- }
- return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
- var dir = combinator.dir,
- checkNonElements = base && dir === "parentNode",
- doneName = done++;
-
- return combinator.first ?
- // Check against closest ancestor/preceding element
- function( elem, context, xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- return matcher( elem, context, xml );
- }
- }
- } :
-
- // Check against all ancestor/preceding elements
- function( elem, context, xml ) {
- var oldCache, outerCache,
- newCache = [ dirruns, doneName ];
-
- // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
- if ( xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- if ( matcher( elem, context, xml ) ) {
- return true;
- }
- }
- }
- } else {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- outerCache = elem[ expando ] || (elem[ expando ] = {});
- if ( (oldCache = outerCache[ dir ]) &&
- oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
- // Assign to newCache so results back-propagate to previous elements
- return (newCache[ 2 ] = oldCache[ 2 ]);
- } else {
- // Reuse newcache so results back-propagate to previous elements
- outerCache[ dir ] = newCache;
-
- // A match means we're done; a fail means we have to keep checking
- if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
- return true;
- }
- }
- }
- }
- }
- };
-}
-
-function elementMatcher( matchers ) {
- return matchers.length > 1 ?
- function( elem, context, xml ) {
- var i = matchers.length;
- while ( i-- ) {
- if ( !matchers[i]( elem, context, xml ) ) {
- return false;
- }
- }
- return true;
- } :
- matchers[0];
-}
-
-function condense( unmatched, map, filter, context, xml ) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
-
- for ( ; i < len; i++ ) {
- if ( (elem = unmatched[i]) ) {
- if ( !filter || filter( elem, context, xml ) ) {
- newUnmatched.push( elem );
- if ( mapped ) {
- map.push( i );
- }
- }
- }
- }
-
- return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
- if ( postFilter && !postFilter[ expando ] ) {
- postFilter = setMatcher( postFilter );
- }
- if ( postFinder && !postFinder[ expando ] ) {
- postFinder = setMatcher( postFinder, postSelector );
- }
- return markFunction(function( seed, results, context, xml ) {
- var temp, i, elem,
- preMap = [],
- postMap = [],
- preexisting = results.length,
-
- // Get initial elements from seed or context
- elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
-
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
- matcherIn = preFilter && ( seed || !selector ) ?
- condense( elems, preMap, preFilter, context, xml ) :
- elems,
-
- matcherOut = matcher ?
- // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
- postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
- // ...intermediate processing is necessary
- [] :
-
- // ...otherwise use results directly
- results :
- matcherIn;
-
- // Find primary matches
- if ( matcher ) {
- matcher( matcherIn, matcherOut, context, xml );
- }
-
- // Apply postFilter
- if ( postFilter ) {
- temp = condense( matcherOut, postMap );
- postFilter( temp, [], context, xml );
-
- // Un-match failing elements by moving them back to matcherIn
- i = temp.length;
- while ( i-- ) {
- if ( (elem = temp[i]) ) {
- matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
- }
- }
- }
-
- if ( seed ) {
- if ( postFinder || preFilter ) {
- if ( postFinder ) {
- // Get the final matcherOut by condensing this intermediate into postFinder contexts
- temp = [];
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) ) {
- // Restore matcherIn since elem is not yet a final match
- temp.push( (matcherIn[i] = elem) );
- }
- }
- postFinder( null, (matcherOut = []), temp, xml );
- }
-
- // Move matched elements from seed to results to keep them synchronized
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) &&
- (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
-
- seed[temp] = !(results[temp] = elem);
- }
- }
- }
-
- // Add elements to results, through postFinder if defined
- } else {
- matcherOut = condense(
- matcherOut === results ?
- matcherOut.splice( preexisting, matcherOut.length ) :
- matcherOut
- );
- if ( postFinder ) {
- postFinder( null, results, matcherOut, xml );
- } else {
- push.apply( results, matcherOut );
- }
- }
- });
-}
-
-function matcherFromTokens( tokens ) {
- var checkContext, matcher, j,
- len = tokens.length,
- leadingRelative = Expr.relative[ tokens[0].type ],
- implicitRelative = leadingRelative || Expr.relative[" "],
- i = leadingRelative ? 1 : 0,
-
- // The foundational matcher ensures that elements are reachable from top-level context(s)
- matchContext = addCombinator( function( elem ) {
- return elem === checkContext;
- }, implicitRelative, true ),
- matchAnyContext = addCombinator( function( elem ) {
- return indexOf.call( checkContext, elem ) > -1;
- }, implicitRelative, true ),
- matchers = [ function( elem, context, xml ) {
- return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
- (checkContext = context).nodeType ?
- matchContext( elem, context, xml ) :
- matchAnyContext( elem, context, xml ) );
- } ];
-
- for ( ; i < len; i++ ) {
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
- matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
- } else {
- matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
- // Return special upon seeing a positional matcher
- if ( matcher[ expando ] ) {
- // Find the next relative operator (if any) for proper handling
- j = ++i;
- for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[j].type ] ) {
- break;
- }
- }
- return setMatcher(
- i > 1 && elementMatcher( matchers ),
- i > 1 && toSelector(
- // If the preceding token was a descendant combinator, insert an implicit any-element `*`
- tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
- ).replace( rtrim, "$1" ),
- matcher,
- i < j && matcherFromTokens( tokens.slice( i, j ) ),
- j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
- j < len && toSelector( tokens )
- );
- }
- matchers.push( matcher );
- }
- }
-
- return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function( seed, context, xml, results, outermost ) {
- var elem, j, matcher,
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- setMatched = [],
- contextBackup = outermostContext,
- // We must always have either seed elements or outermost context
- elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
- // Use integer dirruns iff this is the outermost matcher
- dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
- len = elems.length;
-
- if ( outermost ) {
- outermostContext = context !== document && context;
- }
-
- // Add elements passing elementMatchers directly to results
- // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
- // Support: IE<9, Safari
- // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
- for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
- if ( byElement && elem ) {
- j = 0;
- while ( (matcher = elementMatchers[j++]) ) {
- if ( matcher( elem, context, xml ) ) {
- results.push( elem );
- break;
- }
- }
- if ( outermost ) {
- dirruns = dirrunsUnique;
- }
- }
-
- // Track unmatched elements for set filters
- if ( bySet ) {
- // They will have gone through all possible matchers
- if ( (elem = !matcher && elem) ) {
- matchedCount--;
- }
-
- // Lengthen the array for every element, matched or not
- if ( seed ) {
- unmatched.push( elem );
- }
- }
- }
-
- // Apply set filters to unmatched elements
- matchedCount += i;
- if ( bySet && i !== matchedCount ) {
- j = 0;
- while ( (matcher = setMatchers[j++]) ) {
- matcher( unmatched, setMatched, context, xml );
- }
-
- if ( seed ) {
- // Reintegrate element matches to eliminate the need for sorting
- if ( matchedCount > 0 ) {
- while ( i-- ) {
- if ( !(unmatched[i] || setMatched[i]) ) {
- setMatched[i] = pop.call( results );
- }
- }
- }
-
- // Discard index placeholder values to get only actual matches
- setMatched = condense( setMatched );
- }
-
- // Add matches to results
- push.apply( results, setMatched );
-
- // Seedless set matches succeeding multiple successful matchers stipulate sorting
- if ( outermost && !seed && setMatched.length > 0 &&
- ( matchedCount + setMatchers.length ) > 1 ) {
-
- Sizzle.uniqueSort( results );
- }
- }
-
- // Override manipulation of globals by nested matchers
- if ( outermost ) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
-
- return unmatched;
- };
-
- return bySet ?
- markFunction( superMatcher ) :
- superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[ selector + " " ];
-
- if ( !cached ) {
- // Generate a function of recursive functions that can be used to check each element
- if ( !group ) {
- group = tokenize( selector );
- }
- i = group.length;
- while ( i-- ) {
- cached = matcherFromTokens( group[i] );
- if ( cached[ expando ] ) {
- setMatchers.push( cached );
- } else {
- elementMatchers.push( cached );
- }
- }
-
- // Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
- }
- return cached;
-};
-
-function multipleContexts( selector, contexts, results ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results );
- }
- return results;
-}
-
-function select( selector, context, results, seed ) {
- var i, tokens, token, type, find,
- match = tokenize( selector );
-
- if ( !seed ) {
- // Try to minimize operations if there is only one group
- if ( match.length === 1 ) {
-
- // Take a shortcut and set the context if the root selector is an ID
- tokens = match[0] = match[0].slice( 0 );
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- support.getById && context.nodeType === 9 && documentIsHTML &&
- Expr.relative[ tokens[1].type ] ) {
-
- context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
- if ( !context ) {
- return results;
- }
- selector = selector.slice( tokens.shift().value.length );
- }
-
- // Fetch a seed set for right-to-left matching
- i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
- while ( i-- ) {
- token = tokens[i];
-
- // Abort if we hit a combinator
- if ( Expr.relative[ (type = token.type) ] ) {
- break;
- }
- if ( (find = Expr.find[ type ]) ) {
- // Search, expanding context for leading sibling combinators
- if ( (seed = find(
- token.matches[0].replace( runescape, funescape ),
- rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
- )) ) {
-
- // If seed is empty or no tokens remain, we can return early
- tokens.splice( i, 1 );
- selector = seed.length && toSelector( tokens );
- if ( !selector ) {
- push.apply( results, seed );
- return results;
- }
-
- break;
- }
- }
- }
- }
- }
-
- // Compile and execute a filtering function
- // Provide `match` to avoid retokenization if we modified the selector above
- compile( selector, match )(
- seed,
- context,
- !documentIsHTML,
- results,
- rsibling.test( selector ) && testContext( context.parentNode ) || context
- );
- return results;
-}
-
-// One-time assignments
-
-// Sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
-// Support: Chrome<14
-// Always assume duplicates if they aren't passed to the comparison function
-support.detectDuplicates = !!hasDuplicate;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( div1 ) {
- // Should return 1, but returns 4 (following)
- return div1.compareDocumentPosition( document.createElement("div") ) & 1;
-});
-
-// Support: IE<8
-// Prevent attribute/property "interpolation"
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( div ) {
- div.innerHTML = "";
- return div.firstChild.getAttribute("href") === "#" ;
-}) ) {
- addHandle( "type|href|height|width", function( elem, name, isXML ) {
- if ( !isXML ) {
- return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
- }
- });
-}
-
-// Support: IE<9
-// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( div ) {
- div.innerHTML = "";
- div.firstChild.setAttribute( "value", "" );
- return div.firstChild.getAttribute( "value" ) === "";
-}) ) {
- addHandle( "value", function( elem, name, isXML ) {
- if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
- return elem.defaultValue;
- }
- });
-}
-
-// Support: IE<9
-// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( div ) {
- return div.getAttribute("disabled") == null;
-}) ) {
- addHandle( booleans, function( elem, name, isXML ) {
- var val;
- if ( !isXML ) {
- return elem[ name ] === true ? name.toLowerCase() :
- (val = elem.getAttributeNode( name )) && val.specified ?
- val.value :
- null;
- }
- });
-}
-
-return Sizzle;
-
-})( window );
-
-
-
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.pseudos;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
-
-
-
-var risSimple = /^.[^:#\[\.,]*$/;
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
- if ( jQuery.isFunction( qualifier ) ) {
- return jQuery.grep( elements, function( elem, i ) {
- /* jshint -W018 */
- return !!qualifier.call( elem, i, elem ) !== not;
- });
-
- }
-
- if ( qualifier.nodeType ) {
- return jQuery.grep( elements, function( elem ) {
- return ( elem === qualifier ) !== not;
- });
-
- }
-
- if ( typeof qualifier === "string" ) {
- if ( risSimple.test( qualifier ) ) {
- return jQuery.filter( qualifier, elements, not );
- }
-
- qualifier = jQuery.filter( qualifier, elements );
- }
-
- return jQuery.grep( elements, function( elem ) {
- return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
- });
-}
-
-jQuery.filter = function( expr, elems, not ) {
- var elem = elems[ 0 ];
-
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- return elems.length === 1 && elem.nodeType === 1 ?
- jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
- jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
- return elem.nodeType === 1;
- }));
-};
-
-jQuery.fn.extend({
- find: function( selector ) {
- var i,
- len = this.length,
- ret = [],
- self = this;
-
- if ( typeof selector !== "string" ) {
- return this.pushStack( jQuery( selector ).filter(function() {
- for ( i = 0; i < len; i++ ) {
- if ( jQuery.contains( self[ i ], this ) ) {
- return true;
- }
- }
- }) );
- }
-
- for ( i = 0; i < len; i++ ) {
- jQuery.find( selector, self[ i ], ret );
- }
-
- // Needed because $( selector, context ) becomes $( context ).find( selector )
- ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
- ret.selector = this.selector ? this.selector + " " + selector : selector;
- return ret;
- },
- filter: function( selector ) {
- return this.pushStack( winnow(this, selector || [], false) );
- },
- not: function( selector ) {
- return this.pushStack( winnow(this, selector || [], true) );
- },
- is: function( selector ) {
- return !!winnow(
- this,
-
- // If this is a positional/relative selector, check membership in the returned set
- // so $("p:first").is("p:last") won't return true for a doc with two "p".
- typeof selector === "string" && rneedsContext.test( selector ) ?
- jQuery( selector ) :
- selector || [],
- false
- ).length;
- }
-});
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
- // A simple way to check for HTML strings
- // Prioritize #id over to avoid XSS via location.hash (#9521)
- // Strict HTML recognition (#11290: must start with <)
- rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
-
- init = jQuery.fn.init = function( selector, context ) {
- var match, elem;
-
- // HANDLE: $(""), $(null), $(undefined), $(false)
- if ( !selector ) {
- return this;
- }
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
- // Assume that strings that start and end with <> are HTML and skip the regex check
- match = [ null, selector, null ];
-
- } else {
- match = rquickExpr.exec( selector );
- }
-
- // Match html or make sure no context is specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] ) {
- context = context instanceof jQuery ? context[0] : context;
-
- // scripts is true for back-compat
- // Intentionally let the error be thrown if parseHTML is not present
- jQuery.merge( this, jQuery.parseHTML(
- match[1],
- context && context.nodeType ? context.ownerDocument || context : document,
- true
- ) );
-
- // HANDLE: $(html, props)
- if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
- for ( match in context ) {
- // Properties of context are called as methods if possible
- if ( jQuery.isFunction( this[ match ] ) ) {
- this[ match ]( context[ match ] );
-
- // ...and otherwise set as attributes
- } else {
- this.attr( match, context[ match ] );
- }
- }
- }
-
- return this;
-
- // HANDLE: $(#id)
- } else {
- elem = document.getElementById( match[2] );
-
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Inject the element directly into the jQuery object
- this.length = 1;
- this[0] = elem;
- }
-
- this.context = document;
- this.selector = selector;
- return this;
- }
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return ( context || rootjQuery ).find( selector );
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return this.constructor( context ).find( selector );
- }
-
- // HANDLE: $(DOMElement)
- } else if ( selector.nodeType ) {
- this.context = this[0] = selector;
- this.length = 1;
- return this;
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
- return typeof rootjQuery.ready !== "undefined" ?
- rootjQuery.ready( selector ) :
- // Execute immediately if ready is not present
- selector( jQuery );
- }
-
- if ( selector.selector !== undefined ) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return jQuery.makeArray( selector, this );
- };
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
- // methods guaranteed to produce a unique set when starting from a unique set
- guaranteedUnique = {
- children: true,
- contents: true,
- next: true,
- prev: true
- };
-
-jQuery.extend({
- dir: function( elem, dir, until ) {
- var matched = [],
- truncate = until !== undefined;
-
- while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
- if ( elem.nodeType === 1 ) {
- if ( truncate && jQuery( elem ).is( until ) ) {
- break;
- }
- matched.push( elem );
- }
- }
- return matched;
- },
-
- sibling: function( n, elem ) {
- var matched = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- matched.push( n );
- }
- }
-
- return matched;
- }
-});
-
-jQuery.fn.extend({
- has: function( target ) {
- var targets = jQuery( target, this ),
- l = targets.length;
-
- return this.filter(function() {
- var i = 0;
- for ( ; i < l; i++ ) {
- if ( jQuery.contains( this, targets[i] ) ) {
- return true;
- }
- }
- });
- },
-
- closest: function( selectors, context ) {
- var cur,
- i = 0,
- l = this.length,
- matched = [],
- pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
- jQuery( selectors, context || this.context ) :
- 0;
-
- for ( ; i < l; i++ ) {
- for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
- // Always skip document fragments
- if ( cur.nodeType < 11 && (pos ?
- pos.index(cur) > -1 :
-
- // Don't pass non-elements to Sizzle
- cur.nodeType === 1 &&
- jQuery.find.matchesSelector(cur, selectors)) ) {
-
- matched.push( cur );
- break;
- }
- }
- }
-
- return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
-
- // No argument, return index in parent
- if ( !elem ) {
- return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
- }
-
- // index in selector
- if ( typeof elem === "string" ) {
- return indexOf.call( jQuery( elem ), this[ 0 ] );
- }
-
- // Locate the position of the desired element
- return indexOf.call( this,
-
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[ 0 ] : elem
- );
- },
-
- add: function( selector, context ) {
- return this.pushStack(
- jQuery.unique(
- jQuery.merge( this.get(), jQuery( selector, context ) )
- )
- );
- },
-
- addBack: function( selector ) {
- return this.add( selector == null ?
- this.prevObject : this.prevObject.filter(selector)
- );
- }
-});
-
-function sibling( cur, dir ) {
- while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
- return cur;
-}
-
-jQuery.each({
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return jQuery.dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return sibling( elem, "nextSibling" );
- },
- prev: function( elem ) {
- return sibling( elem, "previousSibling" );
- },
- nextAll: function( elem ) {
- return jQuery.dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return jQuery.dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
- },
- children: function( elem ) {
- return jQuery.sibling( elem.firstChild );
- },
- contents: function( elem ) {
- return elem.contentDocument || jQuery.merge( [], elem.childNodes );
- }
-}, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var matched = jQuery.map( this, fn, until );
-
- if ( name.slice( -5 ) !== "Until" ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- matched = jQuery.filter( selector, matched );
- }
-
- if ( this.length > 1 ) {
- // Remove duplicates
- if ( !guaranteedUnique[ name ] ) {
- jQuery.unique( matched );
- }
-
- // Reverse order for parents* and prev-derivatives
- if ( rparentsprev.test( name ) ) {
- matched.reverse();
- }
- }
-
- return this.pushStack( matched );
- };
-});
-var rnotwhite = (/\S+/g);
-
-
-
-// String to Object options format cache
-var optionsCache = {};
-
-// Convert String-formatted options into Object-formatted ones and store in cache
-function createOptions( options ) {
- var object = optionsCache[ options ] = {};
- jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
- object[ flag ] = true;
- });
- return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- * options: an optional list of space-separated options that will change how
- * the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- * once: will ensure the callback list can only be fired once (like a Deferred)
- *
- * memory: will keep track of previous values and will call any callback added
- * after the list has been fired right away with the latest "memorized"
- * values (like a Deferred)
- *
- * unique: will ensure a callback can only be added once (no duplicate in the list)
- *
- * stopOnFalse: interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
- // Convert options from String-formatted to Object-formatted if needed
- // (we check in cache first)
- options = typeof options === "string" ?
- ( optionsCache[ options ] || createOptions( options ) ) :
- jQuery.extend( {}, options );
-
- var // Last fire value (for non-forgettable lists)
- memory,
- // Flag to know if list was already fired
- fired,
- // Flag to know if list is currently firing
- firing,
- // First callback to fire (used internally by add and fireWith)
- firingStart,
- // End of the loop when firing
- firingLength,
- // Index of currently firing callback (modified by remove if needed)
- firingIndex,
- // Actual callback list
- list = [],
- // Stack of fire calls for repeatable lists
- stack = !options.once && [],
- // Fire callbacks
- fire = function( data ) {
- memory = options.memory && data;
- fired = true;
- firingIndex = firingStart || 0;
- firingStart = 0;
- firingLength = list.length;
- firing = true;
- for ( ; list && firingIndex < firingLength; firingIndex++ ) {
- if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
- memory = false; // To prevent further calls using add
- break;
- }
- }
- firing = false;
- if ( list ) {
- if ( stack ) {
- if ( stack.length ) {
- fire( stack.shift() );
- }
- } else if ( memory ) {
- list = [];
- } else {
- self.disable();
- }
- }
- },
- // Actual Callbacks object
- self = {
- // Add a callback or a collection of callbacks to the list
- add: function() {
- if ( list ) {
- // First, we save the current length
- var start = list.length;
- (function add( args ) {
- jQuery.each( args, function( _, arg ) {
- var type = jQuery.type( arg );
- if ( type === "function" ) {
- if ( !options.unique || !self.has( arg ) ) {
- list.push( arg );
- }
- } else if ( arg && arg.length && type !== "string" ) {
- // Inspect recursively
- add( arg );
- }
- });
- })( arguments );
- // Do we need to add the callbacks to the
- // current firing batch?
- if ( firing ) {
- firingLength = list.length;
- // With memory, if we're not firing then
- // we should call right away
- } else if ( memory ) {
- firingStart = start;
- fire( memory );
- }
- }
- return this;
- },
- // Remove a callback from the list
- remove: function() {
- if ( list ) {
- jQuery.each( arguments, function( _, arg ) {
- var index;
- while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
- list.splice( index, 1 );
- // Handle firing indexes
- if ( firing ) {
- if ( index <= firingLength ) {
- firingLength--;
- }
- if ( index <= firingIndex ) {
- firingIndex--;
- }
- }
- }
- });
- }
- return this;
- },
- // Check if a given callback is in the list.
- // If no argument is given, return whether or not list has callbacks attached.
- has: function( fn ) {
- return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
- },
- // Remove all callbacks from the list
- empty: function() {
- list = [];
- firingLength = 0;
- return this;
- },
- // Have the list do nothing anymore
- disable: function() {
- list = stack = memory = undefined;
- return this;
- },
- // Is it disabled?
- disabled: function() {
- return !list;
- },
- // Lock the list in its current state
- lock: function() {
- stack = undefined;
- if ( !memory ) {
- self.disable();
- }
- return this;
- },
- // Is it locked?
- locked: function() {
- return !stack;
- },
- // Call all callbacks with the given context and arguments
- fireWith: function( context, args ) {
- if ( list && ( !fired || stack ) ) {
- args = args || [];
- args = [ context, args.slice ? args.slice() : args ];
- if ( firing ) {
- stack.push( args );
- } else {
- fire( args );
- }
- }
- return this;
- },
- // Call all the callbacks with the given arguments
- fire: function() {
- self.fireWith( this, arguments );
- return this;
- },
- // To know if the callbacks have already been called at least once
- fired: function() {
- return !!fired;
- }
- };
-
- return self;
-};
-
-
-jQuery.extend({
-
- Deferred: function( func ) {
- var tuples = [
- // action, add listener, listener list, final state
- [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
- [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
- [ "notify", "progress", jQuery.Callbacks("memory") ]
- ],
- state = "pending",
- promise = {
- state: function() {
- return state;
- },
- always: function() {
- deferred.done( arguments ).fail( arguments );
- return this;
- },
- then: function( /* fnDone, fnFail, fnProgress */ ) {
- var fns = arguments;
- return jQuery.Deferred(function( newDefer ) {
- jQuery.each( tuples, function( i, tuple ) {
- var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
- // deferred[ done | fail | progress ] for forwarding actions to newDefer
- deferred[ tuple[1] ](function() {
- var returned = fn && fn.apply( this, arguments );
- if ( returned && jQuery.isFunction( returned.promise ) ) {
- returned.promise()
- .done( newDefer.resolve )
- .fail( newDefer.reject )
- .progress( newDefer.notify );
- } else {
- newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
- }
- });
- });
- fns = null;
- }).promise();
- },
- // Get a promise for this deferred
- // If obj is provided, the promise aspect is added to the object
- promise: function( obj ) {
- return obj != null ? jQuery.extend( obj, promise ) : promise;
- }
- },
- deferred = {};
-
- // Keep pipe for back-compat
- promise.pipe = promise.then;
-
- // Add list-specific methods
- jQuery.each( tuples, function( i, tuple ) {
- var list = tuple[ 2 ],
- stateString = tuple[ 3 ];
-
- // promise[ done | fail | progress ] = list.add
- promise[ tuple[1] ] = list.add;
-
- // Handle state
- if ( stateString ) {
- list.add(function() {
- // state = [ resolved | rejected ]
- state = stateString;
-
- // [ reject_list | resolve_list ].disable; progress_list.lock
- }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
- }
-
- // deferred[ resolve | reject | notify ]
- deferred[ tuple[0] ] = function() {
- deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
- return this;
- };
- deferred[ tuple[0] + "With" ] = list.fireWith;
- });
-
- // Make the deferred a promise
- promise.promise( deferred );
-
- // Call given func if any
- if ( func ) {
- func.call( deferred, deferred );
- }
-
- // All done!
- return deferred;
- },
-
- // Deferred helper
- when: function( subordinate /* , ..., subordinateN */ ) {
- var i = 0,
- resolveValues = slice.call( arguments ),
- length = resolveValues.length,
-
- // the count of uncompleted subordinates
- remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
-
- // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
- deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
-
- // Update function for both resolve and progress values
- updateFunc = function( i, contexts, values ) {
- return function( value ) {
- contexts[ i ] = this;
- values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
- if ( values === progressValues ) {
- deferred.notifyWith( contexts, values );
- } else if ( !( --remaining ) ) {
- deferred.resolveWith( contexts, values );
- }
- };
- },
-
- progressValues, progressContexts, resolveContexts;
-
- // add listeners to Deferred subordinates; treat others as resolved
- if ( length > 1 ) {
- progressValues = new Array( length );
- progressContexts = new Array( length );
- resolveContexts = new Array( length );
- for ( ; i < length; i++ ) {
- if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
- resolveValues[ i ].promise()
- .done( updateFunc( i, resolveContexts, resolveValues ) )
- .fail( deferred.reject )
- .progress( updateFunc( i, progressContexts, progressValues ) );
- } else {
- --remaining;
- }
- }
- }
-
- // if we're not waiting on anything, resolve the master
- if ( !remaining ) {
- deferred.resolveWith( resolveContexts, resolveValues );
- }
-
- return deferred.promise();
- }
-});
-
-
-// The deferred used on DOM ready
-var readyList;
-
-jQuery.fn.ready = function( fn ) {
- // Add the callback
- jQuery.ready.promise().done( fn );
-
- return this;
-};
-
-jQuery.extend({
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
-
- // A counter to track how many items to wait for before
- // the ready event fires. See #6781
- readyWait: 1,
-
- // Hold (or release) the ready event
- holdReady: function( hold ) {
- if ( hold ) {
- jQuery.readyWait++;
- } else {
- jQuery.ready( true );
- }
- },
-
- // Handle when the DOM is ready
- ready: function( wait ) {
-
- // Abort if there are pending holds or we're already ready
- if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
- return;
- }
-
- // Remember that the DOM is ready
- jQuery.isReady = true;
-
- // If a normal DOM Ready event fired, decrement, and wait if need be
- if ( wait !== true && --jQuery.readyWait > 0 ) {
- return;
- }
-
- // If there are functions bound, to execute
- readyList.resolveWith( document, [ jQuery ] );
-
- // Trigger any bound ready events
- if ( jQuery.fn.trigger ) {
- jQuery( document ).trigger("ready").off("ready");
- }
- }
-});
-
-/**
- * The ready event handler and self cleanup method
- */
-function completed() {
- document.removeEventListener( "DOMContentLoaded", completed, false );
- window.removeEventListener( "load", completed, false );
- jQuery.ready();
-}
-
-jQuery.ready.promise = function( obj ) {
- if ( !readyList ) {
-
- readyList = jQuery.Deferred();
-
- // Catch cases where $(document).ready() is called after the browser event has already occurred.
- // we once tried to use readyState "interactive" here, but it caused issues like the one
- // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
- if ( document.readyState === "complete" ) {
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- setTimeout( jQuery.ready );
-
- } else {
-
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", completed, false );
-
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", completed, false );
- }
- }
- return readyList.promise( obj );
-};
-
-// Kick off the DOM ready check even if the user does not
-jQuery.ready.promise();
-
-
-
-
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
- var i = 0,
- len = elems.length,
- bulk = key == null;
-
- // Sets many values
- if ( jQuery.type( key ) === "object" ) {
- chainable = true;
- for ( i in key ) {
- jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
- }
-
- // Sets one value
- } else if ( value !== undefined ) {
- chainable = true;
-
- if ( !jQuery.isFunction( value ) ) {
- raw = true;
- }
-
- if ( bulk ) {
- // Bulk operations run against the entire set
- if ( raw ) {
- fn.call( elems, value );
- fn = null;
-
- // ...except when executing function values
- } else {
- bulk = fn;
- fn = function( elem, key, value ) {
- return bulk.call( jQuery( elem ), value );
- };
- }
- }
-
- if ( fn ) {
- for ( ; i < len; i++ ) {
- fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
- }
- }
- }
-
- return chainable ?
- elems :
-
- // Gets
- bulk ?
- fn.call( elems ) :
- len ? fn( elems[0], key ) : emptyGet;
-};
-
-
-/**
- * Determines whether an object can have data
- */
-jQuery.acceptData = function( owner ) {
- // Accepts only:
- // - Node
- // - Node.ELEMENT_NODE
- // - Node.DOCUMENT_NODE
- // - Object
- // - Any
- /* jshint -W018 */
- return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
-};
-
-
-function Data() {
- // Support: Android < 4,
- // Old WebKit does not have Object.preventExtensions/freeze method,
- // return new empty object instead with no [[set]] accessor
- Object.defineProperty( this.cache = {}, 0, {
- get: function() {
- return {};
- }
- });
-
- this.expando = jQuery.expando + Math.random();
-}
-
-Data.uid = 1;
-Data.accepts = jQuery.acceptData;
-
-Data.prototype = {
- key: function( owner ) {
- // We can accept data for non-element nodes in modern browsers,
- // but we should not, see #8335.
- // Always return the key for a frozen object.
- if ( !Data.accepts( owner ) ) {
- return 0;
- }
-
- var descriptor = {},
- // Check if the owner object already has a cache key
- unlock = owner[ this.expando ];
-
- // If not, create one
- if ( !unlock ) {
- unlock = Data.uid++;
-
- // Secure it in a non-enumerable, non-writable property
- try {
- descriptor[ this.expando ] = { value: unlock };
- Object.defineProperties( owner, descriptor );
-
- // Support: Android < 4
- // Fallback to a less secure definition
- } catch ( e ) {
- descriptor[ this.expando ] = unlock;
- jQuery.extend( owner, descriptor );
- }
- }
-
- // Ensure the cache object
- if ( !this.cache[ unlock ] ) {
- this.cache[ unlock ] = {};
- }
-
- return unlock;
- },
- set: function( owner, data, value ) {
- var prop,
- // There may be an unlock assigned to this node,
- // if there is no entry for this "owner", create one inline
- // and set the unlock as though an owner entry had always existed
- unlock = this.key( owner ),
- cache = this.cache[ unlock ];
-
- // Handle: [ owner, key, value ] args
- if ( typeof data === "string" ) {
- cache[ data ] = value;
-
- // Handle: [ owner, { properties } ] args
- } else {
- // Fresh assignments by object are shallow copied
- if ( jQuery.isEmptyObject( cache ) ) {
- jQuery.extend( this.cache[ unlock ], data );
- // Otherwise, copy the properties one-by-one to the cache object
- } else {
- for ( prop in data ) {
- cache[ prop ] = data[ prop ];
- }
- }
- }
- return cache;
- },
- get: function( owner, key ) {
- // Either a valid cache is found, or will be created.
- // New caches will be created and the unlock returned,
- // allowing direct access to the newly created
- // empty data object. A valid owner object must be provided.
- var cache = this.cache[ this.key( owner ) ];
-
- return key === undefined ?
- cache : cache[ key ];
- },
- access: function( owner, key, value ) {
- var stored;
- // In cases where either:
- //
- // 1. No key was specified
- // 2. A string key was specified, but no value provided
- //
- // Take the "read" path and allow the get method to determine
- // which value to return, respectively either:
- //
- // 1. The entire cache object
- // 2. The data stored at the key
- //
- if ( key === undefined ||
- ((key && typeof key === "string") && value === undefined) ) {
-
- stored = this.get( owner, key );
-
- return stored !== undefined ?
- stored : this.get( owner, jQuery.camelCase(key) );
- }
-
- // [*]When the key is not a string, or both a key and value
- // are specified, set or extend (existing objects) with either:
- //
- // 1. An object of properties
- // 2. A key and value
- //
- this.set( owner, key, value );
-
- // Since the "set" path can have two possible entry points
- // return the expected data based on which path was taken[*]
- return value !== undefined ? value : key;
- },
- remove: function( owner, key ) {
- var i, name, camel,
- unlock = this.key( owner ),
- cache = this.cache[ unlock ];
-
- if ( key === undefined ) {
- this.cache[ unlock ] = {};
-
- } else {
- // Support array or space separated string of keys
- if ( jQuery.isArray( key ) ) {
- // If "name" is an array of keys...
- // When data is initially created, via ("key", "val") signature,
- // keys will be converted to camelCase.
- // Since there is no way to tell _how_ a key was added, remove
- // both plain key and camelCase key. #12786
- // This will only penalize the array argument path.
- name = key.concat( key.map( jQuery.camelCase ) );
- } else {
- camel = jQuery.camelCase( key );
- // Try the string as a key before any manipulation
- if ( key in cache ) {
- name = [ key, camel ];
- } else {
- // If a key with the spaces exists, use it.
- // Otherwise, create an array by matching non-whitespace
- name = camel;
- name = name in cache ?
- [ name ] : ( name.match( rnotwhite ) || [] );
- }
- }
-
- i = name.length;
- while ( i-- ) {
- delete cache[ name[ i ] ];
- }
- }
- },
- hasData: function( owner ) {
- return !jQuery.isEmptyObject(
- this.cache[ owner[ this.expando ] ] || {}
- );
- },
- discard: function( owner ) {
- if ( owner[ this.expando ] ) {
- delete this.cache[ owner[ this.expando ] ];
- }
- }
-};
-var data_priv = new Data();
-
-var data_user = new Data();
-
-
-
-/*
- Implementation Summary
-
- 1. Enforce API surface and semantic compatibility with 1.9.x branch
- 2. Improve the module's maintainability by reducing the storage
- paths to a single mechanism.
- 3. Use the same single mechanism to support "private" and "user" data.
- 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
- 5. Avoid exposing implementation details on user objects (eg. expando properties)
- 6. Provide a clear path for implementation upgrade to WeakMap in 2014
-*/
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
- rmultiDash = /([A-Z])/g;
-
-function dataAttr( elem, key, data ) {
- var name;
-
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if ( data === undefined && elem.nodeType === 1 ) {
- name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
- data = elem.getAttribute( name );
-
- if ( typeof data === "string" ) {
- try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
- // Only convert to a number if it doesn't change the string
- +data + "" === data ? +data :
- rbrace.test( data ) ? jQuery.parseJSON( data ) :
- data;
- } catch( e ) {}
-
- // Make sure we set the data so it isn't changed later
- data_user.set( elem, key, data );
- } else {
- data = undefined;
- }
- }
- return data;
-}
-
-jQuery.extend({
- hasData: function( elem ) {
- return data_user.hasData( elem ) || data_priv.hasData( elem );
- },
-
- data: function( elem, name, data ) {
- return data_user.access( elem, name, data );
- },
-
- removeData: function( elem, name ) {
- data_user.remove( elem, name );
- },
-
- // TODO: Now that all calls to _data and _removeData have been replaced
- // with direct calls to data_priv methods, these can be deprecated.
- _data: function( elem, name, data ) {
- return data_priv.access( elem, name, data );
- },
-
- _removeData: function( elem, name ) {
- data_priv.remove( elem, name );
- }
-});
-
-jQuery.fn.extend({
- data: function( key, value ) {
- var i, name, data,
- elem = this[ 0 ],
- attrs = elem && elem.attributes;
-
- // Gets all values
- if ( key === undefined ) {
- if ( this.length ) {
- data = data_user.get( elem );
-
- if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
- i = attrs.length;
- while ( i-- ) {
- name = attrs[ i ].name;
-
- if ( name.indexOf( "data-" ) === 0 ) {
- name = jQuery.camelCase( name.slice(5) );
- dataAttr( elem, name, data[ name ] );
- }
- }
- data_priv.set( elem, "hasDataAttrs", true );
- }
- }
-
- return data;
- }
-
- // Sets multiple values
- if ( typeof key === "object" ) {
- return this.each(function() {
- data_user.set( this, key );
- });
- }
-
- return access( this, function( value ) {
- var data,
- camelKey = jQuery.camelCase( key );
-
- // The calling jQuery object (element matches) is not empty
- // (and therefore has an element appears at this[ 0 ]) and the
- // `value` parameter was not undefined. An empty jQuery object
- // will result in `undefined` for elem = this[ 0 ] which will
- // throw an exception if an attempt to read a data cache is made.
- if ( elem && value === undefined ) {
- // Attempt to get data from the cache
- // with the key as-is
- data = data_user.get( elem, key );
- if ( data !== undefined ) {
- return data;
- }
-
- // Attempt to get data from the cache
- // with the key camelized
- data = data_user.get( elem, camelKey );
- if ( data !== undefined ) {
- return data;
- }
-
- // Attempt to "discover" the data in
- // HTML5 custom data-* attrs
- data = dataAttr( elem, camelKey, undefined );
- if ( data !== undefined ) {
- return data;
- }
-
- // We tried really hard, but the data doesn't exist.
- return;
- }
-
- // Set the data...
- this.each(function() {
- // First, attempt to store a copy or reference of any
- // data that might've been store with a camelCased key.
- var data = data_user.get( this, camelKey );
-
- // For HTML5 data-* attribute interop, we have to
- // store property names with dashes in a camelCase form.
- // This might not apply to all properties...*
- data_user.set( this, camelKey, value );
-
- // *... In the case of properties that might _actually_
- // have dashes, we need to also store a copy of that
- // unchanged property.
- if ( key.indexOf("-") !== -1 && data !== undefined ) {
- data_user.set( this, key, value );
- }
- });
- }, null, value, arguments.length > 1, null, true );
- },
-
- removeData: function( key ) {
- return this.each(function() {
- data_user.remove( this, key );
- });
- }
-});
-
-
-jQuery.extend({
- queue: function( elem, type, data ) {
- var queue;
-
- if ( elem ) {
- type = ( type || "fx" ) + "queue";
- queue = data_priv.get( elem, type );
-
- // Speed up dequeue by getting out quickly if this is just a lookup
- if ( data ) {
- if ( !queue || jQuery.isArray( data ) ) {
- queue = data_priv.access( elem, type, jQuery.makeArray(data) );
- } else {
- queue.push( data );
- }
- }
- return queue || [];
- }
- },
-
- dequeue: function( elem, type ) {
- type = type || "fx";
-
- var queue = jQuery.queue( elem, type ),
- startLength = queue.length,
- fn = queue.shift(),
- hooks = jQuery._queueHooks( elem, type ),
- next = function() {
- jQuery.dequeue( elem, type );
- };
-
- // If the fx queue is dequeued, always remove the progress sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- startLength--;
- }
-
- if ( fn ) {
-
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift( "inprogress" );
- }
-
- // clear up the last queue stop function
- delete hooks.stop;
- fn.call( elem, next, hooks );
- }
-
- if ( !startLength && hooks ) {
- hooks.empty.fire();
- }
- },
-
- // not intended for public consumption - generates a queueHooks object, or returns the current one
- _queueHooks: function( elem, type ) {
- var key = type + "queueHooks";
- return data_priv.get( elem, key ) || data_priv.access( elem, key, {
- empty: jQuery.Callbacks("once memory").add(function() {
- data_priv.remove( elem, [ type + "queue", key ] );
- })
- });
- }
-});
-
-jQuery.fn.extend({
- queue: function( type, data ) {
- var setter = 2;
-
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- setter--;
- }
-
- if ( arguments.length < setter ) {
- return jQuery.queue( this[0], type );
- }
-
- return data === undefined ?
- this :
- this.each(function() {
- var queue = jQuery.queue( this, type, data );
-
- // ensure a hooks for this queue
- jQuery._queueHooks( this, type );
-
- if ( type === "fx" && queue[0] !== "inprogress" ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- dequeue: function( type ) {
- return this.each(function() {
- jQuery.dequeue( this, type );
- });
- },
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- },
- // Get a promise resolved when queues of a certain type
- // are emptied (fx is the type by default)
- promise: function( type, obj ) {
- var tmp,
- count = 1,
- defer = jQuery.Deferred(),
- elements = this,
- i = this.length,
- resolve = function() {
- if ( !( --count ) ) {
- defer.resolveWith( elements, [ elements ] );
- }
- };
-
- if ( typeof type !== "string" ) {
- obj = type;
- type = undefined;
- }
- type = type || "fx";
-
- while ( i-- ) {
- tmp = data_priv.get( elements[ i ], type + "queueHooks" );
- if ( tmp && tmp.empty ) {
- count++;
- tmp.empty.add( resolve );
- }
- }
- resolve();
- return defer.promise( obj );
- }
-});
-var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
-
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
-var isHidden = function( elem, el ) {
- // isHidden might be called from jQuery#filter function;
- // in that case, element will be second argument
- elem = el || elem;
- return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
- };
-
-var rcheckableType = (/^(?:checkbox|radio)$/i);
-
-
-
-(function() {
- var fragment = document.createDocumentFragment(),
- div = fragment.appendChild( document.createElement( "div" ) );
-
- // #11217 - WebKit loses check when the name is after the checked attribute
- div.innerHTML = "";
-
- // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
- // old WebKit doesn't clone checked state correctly in fragments
- support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- // Support: IE9-IE11+
- div.innerHTML = "";
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-})();
-var strundefined = typeof undefined;
-
-
-
-support.focusinBubbles = "onfocusin" in window;
-
-
-var
- rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|contextmenu)|click/,
- rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
-
-function returnTrue() {
- return true;
-}
-
-function returnFalse() {
- return false;
-}
-
-function safeActiveElement() {
- try {
- return document.activeElement;
- } catch ( err ) { }
-}
-
-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
-
- global: {},
-
- add: function( elem, types, handler, data, selector ) {
-
- var handleObjIn, eventHandle, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = data_priv.get( elem );
-
- // Don't attach events to noData or text/comment nodes (but allow plain objects)
- if ( !elemData ) {
- return;
- }
-
- // Caller can pass in an object of custom data in lieu of the handler
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- selector = handleObjIn.selector;
- }
-
- // Make sure that the handler has a unique ID, used to find/remove it later
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure and main handler, if this is the first
- if ( !(events = elemData.events) ) {
- events = elemData.events = {};
- }
- if ( !(eventHandle = elemData.handle) ) {
- eventHandle = elemData.handle = function( e ) {
- // Discard the second event of a jQuery.event.trigger() and
- // when an event is called after a page has unloaded
- return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
- jQuery.event.dispatch.apply( elem, arguments ) : undefined;
- };
- }
-
- // Handle multiple events separated by a space
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // There *must* be a type, no attaching namespace-only handlers
- if ( !type ) {
- continue;
- }
-
- // If event changes its type, use the special event handlers for the changed type
- special = jQuery.event.special[ type ] || {};
-
- // If selector defined, determine special event api type, otherwise given type
- type = ( selector ? special.delegateType : special.bindType ) || type;
-
- // Update special based on newly reset type
- special = jQuery.event.special[ type ] || {};
-
- // handleObj is passed to all event handlers
- handleObj = jQuery.extend({
- type: type,
- origType: origType,
- data: data,
- handler: handler,
- guid: handler.guid,
- selector: selector,
- needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
- namespace: namespaces.join(".")
- }, handleObjIn );
-
- // Init the event handler queue if we're the first
- if ( !(handlers = events[ type ]) ) {
- handlers = events[ type ] = [];
- handlers.delegateCount = 0;
-
- // Only use addEventListener if the special events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle, false );
- }
- }
- }
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
-
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add to the element's handler list, delegates in front
- if ( selector ) {
- handlers.splice( handlers.delegateCount++, 0, handleObj );
- } else {
- handlers.push( handleObj );
- }
-
- // Keep track of which events have ever been used, for event optimization
- jQuery.event.global[ type ] = true;
- }
-
- },
-
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, selector, mappedTypes ) {
-
- var j, origCount, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = data_priv.hasData( elem ) && data_priv.get( elem );
-
- if ( !elemData || !(events = elemData.events) ) {
- return;
- }
-
- // Once for each type.namespace in types; type may be omitted
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // Unbind all events (on this namespace, if provided) for the element
- if ( !type ) {
- for ( type in events ) {
- jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
- }
- continue;
- }
-
- special = jQuery.event.special[ type ] || {};
- type = ( selector ? special.delegateType : special.bindType ) || type;
- handlers = events[ type ] || [];
- tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
-
- // Remove matching events
- origCount = j = handlers.length;
- while ( j-- ) {
- handleObj = handlers[ j ];
-
- if ( ( mappedTypes || origType === handleObj.origType ) &&
- ( !handler || handler.guid === handleObj.guid ) &&
- ( !tmp || tmp.test( handleObj.namespace ) ) &&
- ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
- handlers.splice( j, 1 );
-
- if ( handleObj.selector ) {
- handlers.delegateCount--;
- }
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
- }
-
- // Remove generic event handler if we removed something and no more handlers exist
- // (avoids potential for endless recursion during removal of special event handlers)
- if ( origCount && !handlers.length ) {
- if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
- jQuery.removeEvent( elem, type, elemData.handle );
- }
-
- delete events[ type ];
- }
- }
-
- // Remove the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- delete elemData.handle;
- data_priv.remove( elem, "events" );
- }
- },
-
- trigger: function( event, data, elem, onlyHandlers ) {
-
- var i, cur, tmp, bubbleType, ontype, handle, special,
- eventPath = [ elem || document ],
- type = hasOwn.call( event, "type" ) ? event.type : event,
- namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
-
- cur = tmp = elem = elem || document;
-
- // Don't do events on text and comment nodes
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- // focus/blur morphs to focusin/out; ensure we're not firing them right now
- if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
- return;
- }
-
- if ( type.indexOf(".") >= 0 ) {
- // Namespaced trigger; create a regexp to match event type in handle()
- namespaces = type.split(".");
- type = namespaces.shift();
- namespaces.sort();
- }
- ontype = type.indexOf(":") < 0 && "on" + type;
-
- // Caller can pass in a jQuery.Event object, Object, or just an event type string
- event = event[ jQuery.expando ] ?
- event :
- new jQuery.Event( type, typeof event === "object" && event );
-
- // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
- event.isTrigger = onlyHandlers ? 2 : 3;
- event.namespace = namespaces.join(".");
- event.namespace_re = event.namespace ?
- new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
- null;
-
- // Clean up the event in case it is being reused
- event.result = undefined;
- if ( !event.target ) {
- event.target = elem;
- }
-
- // Clone any incoming data and prepend the event, creating the handler arg list
- data = data == null ?
- [ event ] :
- jQuery.makeArray( data, [ event ] );
-
- // Allow special events to draw outside the lines
- special = jQuery.event.special[ type ] || {};
- if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
- return;
- }
-
- // Determine event propagation path in advance, per W3C events spec (#9951)
- // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
- if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
-
- bubbleType = special.delegateType || type;
- if ( !rfocusMorph.test( bubbleType + type ) ) {
- cur = cur.parentNode;
- }
- for ( ; cur; cur = cur.parentNode ) {
- eventPath.push( cur );
- tmp = cur;
- }
-
- // Only add window if we got to document (e.g., not plain obj or detached DOM)
- if ( tmp === (elem.ownerDocument || document) ) {
- eventPath.push( tmp.defaultView || tmp.parentWindow || window );
- }
- }
-
- // Fire handlers on the event path
- i = 0;
- while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
-
- event.type = i > 1 ?
- bubbleType :
- special.bindType || type;
-
- // jQuery handler
- handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
- if ( handle ) {
- handle.apply( cur, data );
- }
-
- // Native handler
- handle = ontype && cur[ ontype ];
- if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
- event.result = handle.apply( cur, data );
- if ( event.result === false ) {
- event.preventDefault();
- }
- }
- }
- event.type = type;
-
- // If nobody prevented the default action, do it now
- if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
- if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
- jQuery.acceptData( elem ) ) {
-
- // Call a native DOM method on the target with the same name name as the event.
- // Don't do default actions on window, that's where global variables be (#6170)
- if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
-
- // Don't re-trigger an onFOO event when we call its FOO() method
- tmp = elem[ ontype ];
-
- if ( tmp ) {
- elem[ ontype ] = null;
- }
-
- // Prevent re-triggering of the same event, since we already bubbled it above
- jQuery.event.triggered = type;
- elem[ type ]();
- jQuery.event.triggered = undefined;
-
- if ( tmp ) {
- elem[ ontype ] = tmp;
- }
- }
- }
- }
-
- return event.result;
- },
-
- dispatch: function( event ) {
-
- // Make a writable jQuery.Event from the native event object
- event = jQuery.event.fix( event );
-
- var i, j, ret, matched, handleObj,
- handlerQueue = [],
- args = slice.call( arguments ),
- handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
- special = jQuery.event.special[ event.type ] || {};
-
- // Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[0] = event;
- event.delegateTarget = this;
-
- // Call the preDispatch hook for the mapped type, and let it bail if desired
- if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
- return;
- }
-
- // Determine handlers
- handlerQueue = jQuery.event.handlers.call( this, event, handlers );
-
- // Run delegates first; they may want to stop propagation beneath us
- i = 0;
- while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
- event.currentTarget = matched.elem;
-
- j = 0;
- while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
-
- // Triggered event must either 1) have no namespace, or
- // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
- if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
-
- event.handleObj = handleObj;
- event.data = handleObj.data;
-
- ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
- .apply( matched.elem, args );
-
- if ( ret !== undefined ) {
- if ( (event.result = ret) === false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- }
- }
-
- // Call the postDispatch hook for the mapped type
- if ( special.postDispatch ) {
- special.postDispatch.call( this, event );
- }
-
- return event.result;
- },
-
- handlers: function( event, handlers ) {
- var i, matches, sel, handleObj,
- handlerQueue = [],
- delegateCount = handlers.delegateCount,
- cur = event.target;
-
- // Find delegate handlers
- // Black-hole SVG