a";
-
- // var all = div.getElementsByTagName("*"),
- // a = div.getElementsByTagName("a")[0],
- // select = document.createElement("select"),
- // opt = select.appendChild( document.createElement("option") );
-
- // // Can't get basic test support
- // if ( !all || !all.length || !a ) {
- // return;
- // }
-
- jQuery.support = {
- // IE strips leading whitespace when .innerHTML is used
- leadingWhitespace: false,
-
- // Make sure that tbody elements aren't automatically inserted
- // IE will insert them into empty tables
- tbody: false,
-
- // Make sure that link elements get serialized correctly by innerHTML
- // This requires a wrapper element in IE
- htmlSerialize: false,
-
- // Get the style information from getAttribute
- // (IE uses .cssText insted)
- style: false,
-
- // Make sure that URLs aren't manipulated
- // (IE normalizes it by default)
- hrefNormalized: false,
-
- // Make sure that element opacity exists
- // (IE uses filter instead)
- // Use a regex to work around a WebKit issue. See #5145
- opacity: false,
-
- // Verify style float existence
- // (IE uses styleFloat instead of cssFloat)
- cssFloat: false,
-
- // Make sure that if no value is specified for a checkbox
- // that it defaults to "on".
- // (WebKit defaults to "" instead)
- checkOn: false,
-
- // Make sure that a selected-by-default option has a working selected property.
- // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
- optSelected: false,
-
- // Will be defined later
- deleteExpando: false,
- optDisabled: false,
- checkClone: false,
- scriptEval: false,
- noCloneEvent: false,
- boxModel: false,
- inlineBlockNeedsLayout: false,
- shrinkWrapBlocks: false,
- reliableHiddenOffsets: true
- };
-
- // // Make sure that the options inside disabled selects aren't marked as disabled
- // // (WebKit marks them as diabled)
- // select.disabled = true;
- // jQuery.support.optDisabled = !opt.disabled;
-
- // script.type = "text/javascript";
- // try {
- // script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
- // } catch(e) {}
-
- // root.insertBefore( script, root.firstChild );
-
- // // Make sure that the execution of code works by injecting a script
- // // tag with appendChild/createTextNode
- // // (IE doesn't support this, fails, and uses .text instead)
- // if ( window[ id ] ) {
- // jQuery.support.scriptEval = true;
- // delete window[ id ];
- // }
-
- // // Test to see if it's possible to delete an expando from an element
- // // Fails in Internet Explorer
- // try {
- // delete script.test;
-
- // } catch(e) {
- // jQuery.support.deleteExpando = false;
- // }
-
- // root.removeChild( script );
-
- // if ( div.attachEvent && div.fireEvent ) {
- // div.attachEvent("onclick", function click() {
- // // Cloning a node shouldn't copy over any
- // // bound event handlers (IE does this)
- // jQuery.support.noCloneEvent = false;
- // div.detachEvent("onclick", click);
- // });
- // div.cloneNode(true).fireEvent("onclick");
- // }
-
- // div = document.createElement("div");
- // div.innerHTML = "";
-
- // var fragment = document.createDocumentFragment();
- // fragment.appendChild( div.firstChild );
-
- // // WebKit doesn't clone checked state correctly in fragments
- // jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
-
- // // Figure out if the W3C box model works as expected
- // // document.body must exist before we can do this
- // jQuery(function() {
- // var div = document.createElement("div");
- // div.style.width = div.style.paddingLeft = "1px";
-
- // document.body.appendChild( div );
- // jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
-
- // if ( "zoom" in div.style ) {
- // // Check if natively block-level elements act like inline-block
- // // elements when setting their display to 'inline' and giving
- // // them layout
- // // (IE < 8 does this)
- // div.style.display = "inline";
- // div.style.zoom = 1;
- // jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
-
- // // Check if elements with layout shrink-wrap their children
- // // (IE 6 does this)
- // div.style.display = "";
- // div.innerHTML = "";
- // jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
- // }
-
- // div.innerHTML = "
t
";
- // var tds = div.getElementsByTagName("td");
-
- // // Check if table cells still have offsetWidth/Height when they are set
- // // to display:none and there are still other visible table cells in a
- // // table row; if so, offsetWidth/Height are not reliable for use when
- // // determining if an element has been hidden directly using
- // // display:none (it is still safe to use offsets if a parent element is
- // // hidden; don safety goggles and see bug #4512 for more information).
- // // (only IE 8 fails this test)
- // jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
-
- // tds[0].style.display = "";
- // tds[1].style.display = "none";
-
- // // Check if empty table cells still have offsetWidth/Height
- // // (IE < 8 fail this test)
- // jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
- // div.innerHTML = "";
-
- // document.body.removeChild( div ).style.display = "none";
- // div = tds = null;
- // });
-
- // // Technique from Juriy Zaytsev
- // // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
- // var eventSupported = function( eventName ) {
- // var el = document.createElement("div");
- // eventName = "on" + eventName;
-
- // var isSupported = (eventName in el);
- // if ( !isSupported ) {
- // el.setAttribute(eventName, "return;");
- // isSupported = typeof el[eventName] === "function";
- // }
- // el = null;
-
- // return isSupported;
- // };
-
- jQuery.support.submitBubbles = false;
- jQuery.support.changeBubbles = false;
-
- // // release memory in IE
- // root = script = div = all = a = null;
- })();
-
-
-
- var windowData = {},
- rbrace = /^(?:\{.*\}|\[.*\])$/;
-
- jQuery.extend({
- cache: {},
-
- // Please use with caution
- uuid: 0,
-
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + jQuery.now(),
-
- // The following elements throw uncatchable exceptions if you
- // attempt to add expando properties to them.
- noData: {
- "embed": true,
- // Ban all objects except for Flash (which handle expandos)
- "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
- "applet": true
- },
-
- data: function (elem, name, data) {
- ///
- ///
Store arbitrary data associated with the specified element.
- ///
- ///
- ///
The DOM element to associate with the data.
- ///
- ///
- ///
A string naming the piece of data to set.
- ///
- ///
- ///
The new data value.
- ///
- ///
-
- if (!jQuery.acceptData(elem)) {
- return;
- }
-
- elem = elem == window ?
- windowData :
- elem;
-
- var isNode = elem.nodeType,
- id = isNode ? elem[jQuery.expando] : null,
- cache = jQuery.cache, thisCache;
-
- if (isNode && !id && typeof name === "string" && data === undefined) {
- return;
- }
-
- // Get the data from the object directly
- if (!isNode) {
- cache = elem;
-
- // Compute a unique ID for the element
- } else if (!id) {
- elem[jQuery.expando] = id = ++jQuery.uuid;
- }
-
- // Avoid generating a new cache unless none exists and we
- // want to manipulate it.
- if (typeof name === "object") {
- if (isNode) {
- cache[id] = jQuery.extend(cache[id], name);
-
- } else {
- jQuery.extend(cache, name);
- }
-
- } else if (isNode && !cache[id]) {
- cache[id] = {};
- }
-
- thisCache = isNode ? cache[id] : cache;
-
- // Prevent overriding the named cache with undefined values
- if (data !== undefined) {
- thisCache[name] = data;
- }
-
- return typeof name === "string" ? thisCache[name] : thisCache;
- },
-
- removeData: function (elem, name) {
- if (!jQuery.acceptData(elem)) {
- return;
- }
-
- elem = elem == window ?
- windowData :
- elem;
-
- var isNode = elem.nodeType,
- id = isNode ? elem[jQuery.expando] : elem,
- cache = jQuery.cache,
- thisCache = isNode ? cache[id] : id;
-
- // If we want to remove a specific section of the element's data
- if (name) {
- if (thisCache) {
- // Remove the section of cache data
- delete thisCache[name];
-
- // If we've removed all the data, remove the element's cache
- if (isNode && jQuery.isEmptyObject(thisCache)) {
- jQuery.removeData(elem);
- }
- }
-
- // Otherwise, we want to remove all of the element's data
- } else {
- if (isNode && jQuery.support.deleteExpando) {
- delete elem[jQuery.expando];
-
- } else if (elem.removeAttribute) {
- elem.removeAttribute(jQuery.expando);
-
- // Completely remove the data cache
- } else if (isNode) {
- delete cache[id];
-
- // Remove all fields from the object
- } else {
- for (var n in elem) {
- delete elem[n];
- }
- }
- }
- },
-
- // A method for determining if a DOM node can handle the data expando
- acceptData: function (elem) {
- if (elem.nodeName) {
- var match = jQuery.noData[elem.nodeName.toLowerCase()];
-
- if (match) {
- return !(match === true || elem.getAttribute("classid") !== match);
- }
- }
-
- return true;
- }
- });
-
- jQuery.fn.extend({
- data: function (key, value) {
- ///
- ///
Store arbitrary data associated with the matched elements.
- ///
- ///
- ///
A string naming the piece of data to set.
- ///
- ///
- ///
The new data value.
- ///
- ///
-
- var data = null;
-
- if (typeof key === "undefined") {
- if (this.length) {
- var attr = this[0].attributes, name;
- data = jQuery.data(this[0]);
-
- for (var i = 0, l = attr.length; i < l; i++) {
- name = attr[i].name;
-
- if (name.indexOf("data-") === 0) {
- name = name.substr(5);
- dataAttr(this[0], name, data[name]);
- }
- }
- }
-
- return data;
-
- } else if (typeof key === "object") {
- return this.each(function () {
- jQuery.data(this, key);
- });
- }
-
- var parts = key.split(".");
- parts[1] = parts[1] ? "." + parts[1] : "";
-
- if (value === undefined) {
- data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
-
- // Try to fetch any internally stored data first
- if (data === undefined && this.length) {
- data = jQuery.data(this[0], key);
- data = dataAttr(this[0], key, data);
- }
-
- return data === undefined && parts[1] ?
- this.data(parts[0]) :
- data;
-
- } else {
- return this.each(function () {
- var $this = jQuery(this),
- args = [parts[0], value];
-
- $this.triggerHandler("setData" + parts[1] + "!", args);
- jQuery.data(this, key, value);
- $this.triggerHandler("changeData" + parts[1] + "!", args);
- });
- }
- },
-
- removeData: function (key) {
- return this.each(function () {
- jQuery.removeData(this, key);
- });
- }
- });
-
- function dataAttr(elem, key, data) {
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if (data === undefined && elem.nodeType === 1) {
- data = elem.getAttribute("data-" + key);
-
- if (typeof data === "string") {
- try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
- !jQuery.isNaN(data) ? parseFloat(data) :
- rbrace.test(data) ? jQuery.parseJSON(data) :
- data;
- } catch (e) { }
-
- // Make sure we set the data so it isn't changed later
- jQuery.data(elem, key, data);
-
- } else {
- data = undefined;
- }
- }
-
- return data;
- }
-
-
-
-
- jQuery.extend({
- queue: function (elem, type, data) {
- if (!elem) {
- return;
- }
-
- type = (type || "fx") + "queue";
- var q = jQuery.data(elem, type);
-
- // Speed up dequeue by getting out quickly if this is just a lookup
- if (!data) {
- return q || [];
- }
-
- if (!q || jQuery.isArray(data)) {
- q = jQuery.data(elem, type, jQuery.makeArray(data));
-
- } else {
- q.push(data);
- }
-
- return q;
- },
-
- dequeue: function (elem, type) {
- type = type || "fx";
-
- var queue = jQuery.queue(elem, type),
- fn = queue.shift();
-
- // If the fx queue is dequeued, always remove the progress sentinel
- if (fn === "inprogress") {
- fn = queue.shift();
- }
-
- if (fn) {
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if (type === "fx") {
- queue.unshift("inprogress");
- }
-
- fn.call(elem, function () {
- jQuery.dequeue(elem, type);
- });
- }
- }
- });
-
- jQuery.fn.extend({
- queue: function (type, data) {
- ///
- ///
1: queue() - Returns a reference to the first element's queue (which is an array of functions).
- ///
2: queue(callback) - Adds a new function, to be executed, onto the end of the queue of all matched elements.
- ///
3: queue(queue) - Replaces the queue of all matched element with this new queue (the array of functions).
- ///
- /// The function to add to the queue.
- ///
-
- if (typeof type !== "string") {
- data = type;
- type = "fx";
- }
-
- if (data === undefined) {
- return jQuery.queue(this[0], type);
- }
- return this.each(function (i) {
- var queue = jQuery.queue(this, type, data);
-
- if (type === "fx" && queue[0] !== "inprogress") {
- jQuery.dequeue(this, type);
- }
- });
- },
- dequeue: function (type) {
- ///
- ///
Removes a queued function from the front of the queue and executes it.
- ///
- /// The type of queue to access.
- ///
-
- return this.each(function () {
- jQuery.dequeue(this, type);
- });
- },
-
- // Based off of the plugin by Clint Helfers, with permission.
- // http://blindsignals.com/index.php/2009/07/jquery-delay/
- delay: function (time, type) {
- ///
- ///
Set a timer to delay execution of subsequent items in the queue.
- ///
- ///
- ///
An integer indicating the number of milliseconds to delay execution of the next item in the queue.
- ///
- ///
- ///
A string containing the name of the queue. Defaults to fx, the standard effects queue.
- ///
- ///
-
- time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
- type = type || "fx";
-
- return this.queue(type, function () {
- var elem = this;
- setTimeout(function () {
- jQuery.dequeue(elem, type);
- }, time);
- });
- },
-
- clearQueue: function (type) {
- ///
- ///
Remove from the queue all items that have not yet been run.
- ///
- ///
- ///
A string containing the name of the queue. Defaults to fx, the standard effects queue.
- ///
- ///
-
- return this.queue(type || "fx", []);
- }
- });
-
-
-
-
- var rclass = /[\n\t]/g,
- rspaces = /\s+/,
- rreturn = /\r/g,
- rspecialurl = /^(?:href|src|style)$/,
- rtype = /^(?:button|input)$/i,
- rfocusable = /^(?:button|input|object|select|textarea)$/i,
- rclickable = /^a(?:rea)?$/i,
- rradiocheck = /^(?:radio|checkbox)$/i;
-
- jQuery.props = {
- "for": "htmlFor",
- "class": "className",
- readonly: "readOnly",
- maxlength: "maxLength",
- cellspacing: "cellSpacing",
- rowspan: "rowSpan",
- colspan: "colSpan",
- tabindex: "tabIndex",
- usemap: "useMap",
- frameborder: "frameBorder"
- };
-
- jQuery.fn.extend({
- attr: function (name, value) {
- ///
- ///
Set a single property to a computed value, on all matched elements.
- ///
Instead of a value, a function is provided, that computes the value.
- ///
Part of DOM/Attributes
- ///
- ///
- ///
- ///
The name of the property to set.
- ///
- ///
- ///
A function returning the value to set.
- ///
-
- return jQuery.access(this, name, value, true, jQuery.attr);
- },
-
- removeAttr: function (name, fn) {
- ///
- ///
Remove an attribute from each of the matched elements.
- ///
Part of DOM/Attributes
- ///
- ///
- ///
An attribute to remove.
- ///
- ///
-
- return this.each(function () {
- jQuery.attr(this, name, "");
- if (this.nodeType === 1) {
- this.removeAttribute(name);
- }
- });
- },
-
- addClass: function (value) {
- ///
- ///
Adds the specified class(es) to each of the set of matched elements.
- ///
Part of DOM/Attributes
- ///
- ///
- ///
One or more class names to be added to the class attribute of each matched element.
- ///
- ///
-
- if (jQuery.isFunction(value)) {
- return this.each(function (i) {
- var self = jQuery(this);
- self.addClass(value.call(this, i, self.attr("class")));
- });
- }
-
- if (value && typeof value === "string") {
- var classNames = (value || "").split(rspaces);
-
- for (var i = 0, l = this.length; i < l; i++) {
- var elem = this[i];
-
- if (elem.nodeType === 1) {
- if (!elem.className) {
- elem.className = value;
-
- } else {
- var className = " " + elem.className + " ",
- setClass = elem.className;
-
- for (var c = 0, cl = classNames.length; c < cl; c++) {
- if (className.indexOf(" " + classNames[c] + " ") < 0) {
- setClass += " " + classNames[c];
- }
- }
- elem.className = jQuery.trim(setClass);
- }
- }
- }
- }
-
- return this;
- },
-
- removeClass: function (value) {
- ///
- ///
Removes all or the specified class(es) from the set of matched elements.
- ///
Part of DOM/Attributes
- ///
- ///
- ///
(Optional) A class name to be removed from the class attribute of each matched element.
- ///
- ///
-
- if (jQuery.isFunction(value)) {
- return this.each(function (i) {
- var self = jQuery(this);
- self.removeClass(value.call(this, i, self.attr("class")));
- });
- }
-
- if ((value && typeof value === "string") || value === undefined) {
- var classNames = (value || "").split(rspaces);
-
- for (var i = 0, l = this.length; i < l; i++) {
- var elem = this[i];
-
- if (elem.nodeType === 1 && elem.className) {
- if (value) {
- var className = (" " + elem.className + " ").replace(rclass, " ");
- for (var c = 0, cl = classNames.length; c < cl; c++) {
- className = className.replace(" " + classNames[c] + " ", " ");
- }
- elem.className = jQuery.trim(className);
-
- } else {
- elem.className = "";
- }
- }
- }
- }
-
- return this;
- },
-
- toggleClass: function (value, stateVal) {
- ///
- ///
Add or remove a class from each element in the set of matched elements, depending
- ///
on either the class's presence or the value of the switch argument.
- ///
- ///
- ///
A class name to be toggled for each element in the matched set.
- ///
- ///
- ///
A boolean value to determine whether the class should be added or removed.
- ///
- ///
-
- var type = typeof value,
- isBool = typeof stateVal === "boolean";
-
- if (jQuery.isFunction(value)) {
- return this.each(function (i) {
- var self = jQuery(this);
- self.toggleClass(value.call(this, i, self.attr("class"), stateVal), stateVal);
- });
- }
-
- return this.each(function () {
- if (type === "string") {
- // toggle individual class names
- var className,
- i = 0,
- self = jQuery(this),
- state = stateVal,
- classNames = value.split(rspaces);
-
- while ((className = classNames[i++])) {
- // check each className given, space seperated list
- state = isBool ? state : !self.hasClass(className);
- self[state ? "addClass" : "removeClass"](className);
- }
-
- } else if (type === "undefined" || type === "boolean") {
- if (this.className) {
- // store className if set
- jQuery.data(this, "__className__", this.className);
- }
-
- // toggle whole className
- this.className = this.className || value === false ? "" : jQuery.data(this, "__className__") || "";
- }
- });
- },
-
- hasClass: function (selector) {
- ///
- ///
Checks the current selection against a class and returns whether at least one selection has a given class.
- ///
- /// The class to check against
- /// True if at least one element in the selection has the class, otherwise false.
-
- var className = " " + selector + " ";
- for (var i = 0, l = this.length; i < l; i++) {
- if ((" " + this[i].className + " ").replace(rclass, " ").indexOf(className) > -1) {
- return true;
- }
- }
-
- return false;
- },
-
- val: function (value) {
- ///
- ///
Set the value of every matched element.
- ///
Part of DOM/Attributes
- ///
- ///
- ///
- ///
A string of text or an array of strings to set as the value property of each
- ///
matched element.
- ///
-
- if (!arguments.length) {
- var elem = this[0];
-
- if (elem) {
- if (jQuery.nodeName(elem, "option")) {
- // attributes.value is undefined in Blackberry 4.7 but
- // uses .value. See #6932
- var val = elem.attributes.value;
- return !val || val.specified ? elem.value : elem.text;
- }
-
- // We need to handle select boxes special
- if (jQuery.nodeName(elem, "select")) {
- var index = elem.selectedIndex,
- values = [],
- options = elem.options,
- one = elem.type === "select-one";
-
- // Nothing was selected
- if (index < 0) {
- return null;
- }
-
- // Loop through all the selected options
- for (var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++) {
- var option = options[i];
-
- // Don't return options that are disabled or in a disabled optgroup
- if (option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
- (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) {
-
- // Get the specific value for the option
- value = jQuery(option).val();
-
- // We don't need an array for one selects
- if (one) {
- return value;
- }
-
- // Multi-Selects return an array
- values.push(value);
- }
- }
-
- return values;
- }
-
- // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
- if (rradiocheck.test(elem.type) && !jQuery.support.checkOn) {
- return elem.getAttribute("value") === null ? "on" : elem.value;
- }
-
-
- // Everything else, we just grab the value
- return (elem.value || "").replace(rreturn, "");
-
- }
-
- return undefined;
- }
-
- var isFunction = jQuery.isFunction(value);
-
- return this.each(function (i) {
- var self = jQuery(this), val = value;
-
- if (this.nodeType !== 1) {
- return;
- }
-
- if (isFunction) {
- val = value.call(this, i, self.val());
- }
-
- // Treat null/undefined as ""; convert numbers to string
- if (val == null) {
- val = "";
- } else if (typeof val === "number") {
- val += "";
- } else if (jQuery.isArray(val)) {
- val = jQuery.map(val, function (value) {
- return value == null ? "" : value + "";
- });
- }
-
- if (jQuery.isArray(val) && rradiocheck.test(this.type)) {
- this.checked = jQuery.inArray(self.val(), val) >= 0;
-
- } else if (jQuery.nodeName(this, "select")) {
- var values = jQuery.makeArray(val);
-
- jQuery("option", this).each(function () {
- this.selected = jQuery.inArray(jQuery(this).val(), values) >= 0;
- });
-
- if (!values.length) {
- this.selectedIndex = -1;
- }
-
- } else {
- this.value = val;
- }
- });
- }
- });
-
- jQuery.extend({
- attrFn: {
- val: true,
- css: true,
- html: true,
- text: true,
- data: true,
- width: true,
- height: true,
- offset: true
- },
-
- attr: function (elem, name, value, pass) {
- ///
- ///
This method is internal.
- ///
- ///
-
- // don't set attributes on text and comment nodes
- if (!elem || elem.nodeType === 3 || elem.nodeType === 8) {
- return undefined;
- }
-
- if (pass && name in jQuery.attrFn) {
- return jQuery(elem)[name](value);
- }
-
- var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc(elem),
- // Whether we are setting (or getting)
- set = value !== undefined;
-
- // Try to normalize/fix the name
- name = notxml && jQuery.props[name] || name;
-
- // These attributes require special treatment
- var special = rspecialurl.test(name);
-
- // Safari mis-reports the default selected property of an option
- // Accessing the parent's selectedIndex property fixes it
- if (name === "selected" && !jQuery.support.optSelected) {
- var parent = elem.parentNode;
- if (parent) {
- parent.selectedIndex;
-
- // Make sure that it also works with optgroups, see #5701
- if (parent.parentNode) {
- parent.parentNode.selectedIndex;
- }
- }
- }
-
- // If applicable, access the attribute via the DOM 0 way
- // 'in' checks fail in Blackberry 4.7 #6931
- if ((name in elem || elem[name] !== undefined) && notxml && !special) {
- if (set) {
- // We can't allow the type property to be changed (since it causes problems in IE)
- if (name === "type" && rtype.test(elem.nodeName) && elem.parentNode) {
- jQuery.error("type property can't be changed");
- }
-
- if (value === null) {
- if (elem.nodeType === 1) {
- elem.removeAttribute(name);
- }
-
- } else {
- elem[name] = value;
- }
- }
-
- // browsers index elements by id/name on forms, give priority to attributes.
- if (jQuery.nodeName(elem, "form") && elem.getAttributeNode(name)) {
- return elem.getAttributeNode(name).nodeValue;
- }
-
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
- if (name === "tabIndex") {
- var attributeNode = elem.getAttributeNode("tabIndex");
-
- return attributeNode && attributeNode.specified ?
- attributeNode.value :
- rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href ?
- 0 :
- undefined;
- }
-
- return elem[name];
- }
-
- if (!jQuery.support.style && notxml && name === "style") {
- if (set) {
- elem.style.cssText = "" + value;
- }
-
- return elem.style.cssText;
- }
-
- if (set) {
- // convert the value to a string (all browsers do this but IE) see #1070
- elem.setAttribute(name, "" + value);
- }
-
- // Ensure that missing attributes return undefined
- // Blackberry 4.7 returns "" from getAttribute #6938
- if (!elem.attributes[name] && (elem.hasAttribute && !elem.hasAttribute(name))) {
- return undefined;
- }
-
- var attr = !jQuery.support.hrefNormalized && notxml && special ?
- // Some attributes require a special call on IE
- elem.getAttribute(name, 2) :
- elem.getAttribute(name);
-
- // Non-existent attributes return null, we normalize to undefined
- return attr === null ? undefined : attr;
- }
- });
-
-
-
-
- var rnamespaces = /\.(.*)$/,
- rformElems = /^(?:textarea|input|select)$/i,
- rperiod = /\./g,
- rspace = / /g,
- rescape = /[^\w\s.|`]/g,
- fcleanup = function (nm) {
- return nm.replace(rescape, "\\$&");
- },
- focusCounts = { focusin: 0, focusout: 0 };
-
- /*
- * A number of helper functions used for managing events.
- * Many of the ideas behind this code originated from
- * Dean Edwards' addEvent library.
- */
- jQuery.event = {
-
- // Bind an event to an element
- // Original by Dean Edwards
- add: function (elem, types, handler, data) {
- ///
- ///
This method is internal.
- ///
- ///
-
- if (elem.nodeType === 3 || elem.nodeType === 8) {
- return;
- }
-
- // For whatever reason, IE has trouble passing the window object
- // around, causing it to be cloned in the process
- if (jQuery.isWindow(elem) && (elem !== window && !elem.frameElement)) {
- elem = window;
- }
-
- if (handler === false) {
- handler = returnFalse;
- } else if (!handler) {
- // Fixes bug #7229. Fix recommended by jdalton
- return;
- }
-
- var handleObjIn, handleObj;
-
- if (handler.handler) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- }
-
- // Make sure that the function being executed has a unique ID
- if (!handler.guid) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure
- var elemData = jQuery.data(elem);
-
- // If no elemData is found then we must be trying to bind to one of the
- // banned noData elements
- if (!elemData) {
- return;
- }
-
- // Use a key less likely to result in collisions for plain JS objects.
- // Fixes bug #7150.
- var eventKey = elem.nodeType ? "events" : "__events__",
- events = elemData[eventKey],
- eventHandle = elemData.handle;
-
- if (typeof events === "function") {
- // On plain objects events is a fn that holds the the data
- // which prevents this data from being JSON serialized
- // the function does not need to be called, it just contains the data
- eventHandle = events.handle;
- events = events.events;
-
- } else if (!events) {
- if (!elem.nodeType) {
- // On plain objects, create a fn that acts as the holder
- // of the values to avoid JSON serialization of event data
- elemData[eventKey] = elemData = function () { };
- }
-
- elemData.events = events = {};
- }
-
- if (!eventHandle) {
- elemData.handle = eventHandle = function () {
- // Handle the second event of a trigger and when
- // an event is called after a page has unloaded
- return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
- jQuery.event.handle.apply(eventHandle.elem, arguments) :
- undefined;
- };
- }
-
- // Add elem as a property of the handle function
- // This is to prevent a memory leak with non-native events in IE.
- eventHandle.elem = elem;
-
- // Handle multiple events separated by a space
- // jQuery(...).bind("mouseover mouseout", fn);
- types = types.split(" ");
-
- var type, i = 0, namespaces;
-
- while ((type = types[i++])) {
- handleObj = handleObjIn ?
- jQuery.extend({}, handleObjIn) :
- { handler: handler, data: data };
-
- // Namespaced event handlers
- if (type.indexOf(".") > -1) {
- namespaces = type.split(".");
- type = namespaces.shift();
- handleObj.namespace = namespaces.slice(0).sort().join(".");
-
- } else {
- namespaces = [];
- handleObj.namespace = "";
- }
-
- handleObj.type = type;
- if (!handleObj.guid) {
- handleObj.guid = handler.guid;
- }
-
- // Get the current list of functions bound to this event
- var handlers = events[type],
- special = jQuery.event.special[type] || {};
-
- // Init the event handler queue
- if (!handlers) {
- handlers = events[type] = [];
-
- // Check for a special event handler
- // Only use addEventListener/attachEvent if the special
- // events handler returns false
- if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
- // Bind the global event handler to the element
- if (elem.addEventListener) {
- elem.addEventListener(type, eventHandle, false);
-
- } else if (elem.attachEvent) {
- elem.attachEvent("on" + type, eventHandle);
- }
- }
- }
-
- if (special.add) {
- special.add.call(elem, handleObj);
-
- if (!handleObj.handler.guid) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add the function to the element's handler list
- handlers.push(handleObj);
-
- // Keep track of which events have been used, for global triggering
- jQuery.event.global[type] = true;
- }
-
- // Nullify elem to prevent memory leaks in IE
- elem = null;
- },
-
- global: {},
-
- // Detach an event or set of events from an element
- remove: function (elem, types, handler) {
- ///
- ///
This method is internal.
- ///
- ///
-
- // don't do events on text and comment nodes
- if (elem.nodeType === 3 || elem.nodeType === 8) {
- return;
- }
-
- if (handler === false) {
- handler = returnFalse;
- }
-
- var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
- eventKey = elem.nodeType ? "events" : "__events__",
- elemData = jQuery.data(elem),
- events = elemData && elemData[eventKey];
-
- if (!elemData || !events) {
- return;
- }
-
- if (typeof events === "function") {
- elemData = events;
- events = events.events;
- }
-
- // types is actually an event object here
- if (types && types.type) {
- handler = types.handler;
- types = types.type;
- }
-
- // Unbind all events for the element
- if (!types || typeof types === "string" && types.charAt(0) === ".") {
- types = types || "";
-
- for (type in events) {
- jQuery.event.remove(elem, type + types);
- }
-
- return;
- }
-
- // Handle multiple events separated by a space
- // jQuery(...).unbind("mouseover mouseout", fn);
- types = types.split(" ");
-
- while ((type = types[i++])) {
- origType = type;
- handleObj = null;
- all = type.indexOf(".") < 0;
- namespaces = [];
-
- if (!all) {
- // Namespaced event handlers
- namespaces = type.split(".");
- type = namespaces.shift();
-
- namespace = new RegExp("(^|\\.)" +
- jQuery.map(namespaces.slice(0).sort(), fcleanup).join("\\.(?:.*\\.)?") + "(\\.|$)");
- }
-
- eventType = events[type];
-
- if (!eventType) {
- continue;
- }
-
- if (!handler) {
- for (j = 0; j < eventType.length; j++) {
- handleObj = eventType[j];
-
- if (all || namespace.test(handleObj.namespace)) {
- jQuery.event.remove(elem, origType, handleObj.handler, j);
- eventType.splice(j--, 1);
- }
- }
-
- continue;
- }
-
- special = jQuery.event.special[type] || {};
-
- for (j = pos || 0; j < eventType.length; j++) {
- handleObj = eventType[j];
-
- if (handler.guid === handleObj.guid) {
- // remove the given handler for the given type
- if (all || namespace.test(handleObj.namespace)) {
- if (pos == null) {
- eventType.splice(j--, 1);
- }
-
- if (special.remove) {
- special.remove.call(elem, handleObj);
- }
- }
-
- if (pos != null) {
- break;
- }
- }
- }
-
- // remove generic event handler if no more handlers exist
- if (eventType.length === 0 || pos != null && eventType.length === 1) {
- if (!special.teardown || special.teardown.call(elem, namespaces) === false) {
- jQuery.removeEvent(elem, type, elemData.handle);
- }
-
- ret = null;
- delete events[type];
- }
- }
-
- // Remove the expando if it's no longer used
- if (jQuery.isEmptyObject(events)) {
- var handle = elemData.handle;
- if (handle) {
- handle.elem = null;
- }
-
- delete elemData.events;
- delete elemData.handle;
-
- if (typeof elemData === "function") {
- jQuery.removeData(elem, eventKey);
-
- } else if (jQuery.isEmptyObject(elemData)) {
- jQuery.removeData(elem);
- }
- }
- },
-
- // bubbling is internal
- trigger: function (event, data, elem /*, bubbling */) {
- ///
- ///
This method is internal.
- ///
- ///
-
- // Event object or event type
- var type = event.type || event,
- bubbling = arguments[3];
-
- if (!bubbling) {
- event = typeof event === "object" ?
- // jQuery.Event object
- event[jQuery.expando] ? event :
- // Object literal
- jQuery.extend(jQuery.Event(type), event) :
- // Just the event type (string)
- jQuery.Event(type);
-
- if (type.indexOf("!") >= 0) {
- event.type = type = type.slice(0, -1);
- event.exclusive = true;
- }
-
- // Handle a global trigger
- if (!elem) {
- // Don't bubble custom events when global (to avoid too much overhead)
- event.stopPropagation();
-
- // Only trigger if we've ever bound an event for it
- if (jQuery.event.global[type]) {
- jQuery.each(jQuery.cache, function () {
- if (this.events && this.events[type]) {
- jQuery.event.trigger(event, data, this.handle.elem);
- }
- });
- }
- }
-
- // Handle triggering a single element
-
- // don't do events on text and comment nodes
- if (!elem || elem.nodeType === 3 || elem.nodeType === 8) {
- return undefined;
- }
-
- // Clean up in case it is reused
- event.result = undefined;
- event.target = elem;
-
- // Clone the incoming data, if any
- data = jQuery.makeArray(data);
- data.unshift(event);
- }
-
- event.currentTarget = elem;
-
- // Trigger the event, it is assumed that "handle" is a function
- var handle = elem.nodeType ?
- jQuery.data(elem, "handle") :
- (jQuery.data(elem, "__events__") || {}).handle;
-
- if (handle) {
- handle.apply(elem, data);
- }
-
- var parent = elem.parentNode || elem.ownerDocument;
-
- // Trigger an inline bound script
- try {
- if (!(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()])) {
- if (elem["on" + type] && elem["on" + type].apply(elem, data) === false) {
- event.result = false;
- event.preventDefault();
- }
- }
-
- // prevent IE from throwing an error for some elements with some event types, see #3533
- } catch (inlineError) { }
-
- if (!event.isPropagationStopped() && parent) {
- jQuery.event.trigger(event, data, parent, true);
-
- } else if (!event.isDefaultPrevented()) {
- var old,
- target = event.target,
- targetType = type.replace(rnamespaces, ""),
- isClick = jQuery.nodeName(target, "a") && targetType === "click",
- special = jQuery.event.special[targetType] || {};
-
- if ((!special._default || special._default.call(elem, event) === false) &&
- !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()])) {
-
- try {
- if (target[targetType]) {
- // Make sure that we don't accidentally re-trigger the onFOO events
- old = target["on" + targetType];
-
- if (old) {
- target["on" + targetType] = null;
- }
-
- jQuery.event.triggered = true;
- target[targetType]();
- }
-
- // prevent IE from throwing an error for some elements with some event types, see #3533
- } catch (triggerError) { }
-
- if (old) {
- target["on" + targetType] = old;
- }
-
- jQuery.event.triggered = false;
- }
- }
- },
-
- handle: function (event) {
- ///
- ///
This method is internal.
- ///
- ///
-
- var all, handlers, namespaces, namespace_re, events,
- namespace_sort = [],
- args = jQuery.makeArray(arguments);
-
- event = args[0] = jQuery.event.fix(event || window.event);
- event.currentTarget = this;
-
- // Namespaced event handlers
- all = event.type.indexOf(".") < 0 && !event.exclusive;
-
- if (!all) {
- namespaces = event.type.split(".");
- event.type = namespaces.shift();
- namespace_sort = namespaces.slice(0).sort();
- namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
- }
-
- event.namespace = event.namespace || namespace_sort.join(".");
-
- events = jQuery.data(this, this.nodeType ? "events" : "__events__");
-
- if (typeof events === "function") {
- events = events.events;
- }
-
- handlers = (events || {})[event.type];
-
- if (events && handlers) {
- // Clone the handlers to prevent manipulation
- handlers = handlers.slice(0);
-
- for (var j = 0, l = handlers.length; j < l; j++) {
- var handleObj = handlers[j];
-
- // Filter the functions by class
- if (all || namespace_re.test(handleObj.namespace)) {
- // Pass in a reference to the handler function itself
- // So that we can later remove it
- event.handler = handleObj.handler;
- event.data = handleObj.data;
- event.handleObj = handleObj;
-
- var ret = handleObj.handler.apply(this, args);
-
- if (ret !== undefined) {
- event.result = ret;
- if (ret === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
-
- if (event.isImmediatePropagationStopped()) {
- break;
- }
- }
- }
- }
-
- return event.result;
- },
-
- props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
-
- fix: function (event) {
- ///
- ///
This method is internal.
- ///
- ///
-
- if (event[jQuery.expando]) {
- return event;
- }
-
- // store a copy of the original event object
- // and "clone" to set read-only properties
- var originalEvent = event;
- event = jQuery.Event(originalEvent);
-
- for (var i = this.props.length, prop; i; ) {
- prop = this.props[--i];
- event[prop] = originalEvent[prop];
- }
-
- // Fix target property, if necessary
- if (!event.target) {
- // Fixes #1925 where srcElement might not be defined either
- event.target = event.srcElement || document;
- }
-
- // check if target is a textnode (safari)
- if (event.target.nodeType === 3) {
- event.target = event.target.parentNode;
- }
-
- // Add relatedTarget, if necessary
- if (!event.relatedTarget && event.fromElement) {
- event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
- }
-
- // Calculate pageX/Y if missing and clientX/Y available
- if (event.pageX == null && event.clientX != null) {
- var doc = document.documentElement,
- body = document.body;
-
- event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
- event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
- }
-
- // Add which for key events
- if (event.which == null && (event.charCode != null || event.keyCode != null)) {
- event.which = event.charCode != null ? event.charCode : event.keyCode;
- }
-
- // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
- if (!event.metaKey && event.ctrlKey) {
- event.metaKey = event.ctrlKey;
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if (!event.which && event.button !== undefined) {
- event.which = (event.button & 1 ? 1 : (event.button & 2 ? 3 : (event.button & 4 ? 2 : 0)));
- }
-
- return event;
- },
-
- // Deprecated, use jQuery.guid instead
- guid: 1E8,
-
- // Deprecated, use jQuery.proxy instead
- proxy: jQuery.proxy,
-
- special: {
- ready: {
- // Make sure the ready event is setup
- setup: jQuery.bindReady,
- teardown: jQuery.noop
- },
-
- live: {
- add: function (handleObj) {
- jQuery.event.add(this,
- liveConvert(handleObj.origType, handleObj.selector),
- jQuery.extend({}, handleObj, { handler: liveHandler, guid: handleObj.handler.guid }));
- },
-
- remove: function (handleObj) {
- jQuery.event.remove(this, liveConvert(handleObj.origType, handleObj.selector), handleObj);
- }
- },
-
- beforeunload: {
- setup: function (data, namespaces, eventHandle) {
- // We only want to do this special case on windows
- if (jQuery.isWindow(this)) {
- this.onbeforeunload = eventHandle;
- }
- },
-
- teardown: function (namespaces, eventHandle) {
- if (this.onbeforeunload === eventHandle) {
- this.onbeforeunload = null;
- }
- }
- }
- }
- };
-
- jQuery.removeEvent = document.removeEventListener ?
- function (elem, type, handle) {
- if (elem.removeEventListener) {
- elem.removeEventListener(type, handle, false);
- }
- } :
- function (elem, type, handle) {
- if (elem.detachEvent) {
- elem.detachEvent("on" + type, handle);
- }
- };
-
- jQuery.Event = function (src) {
- // Allow instantiation without the 'new' keyword
- if (!this.preventDefault) {
- return new jQuery.Event(src);
- }
-
- // Event object
- if (src && src.type) {
- this.originalEvent = src;
- this.type = src.type;
- // Event type
- } else {
- this.type = src;
- }
-
- // timeStamp is buggy for some events on Firefox(#3843)
- // So we won't rely on the native value
- this.timeStamp = jQuery.now();
-
- // Mark it as fixed
- this[jQuery.expando] = true;
- };
-
- function returnFalse() {
- return false;
- }
- function returnTrue() {
- return true;
- }
-
- // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
- // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
- jQuery.Event.prototype = {
- preventDefault: function () {
- this.isDefaultPrevented = returnTrue;
-
- var e = this.originalEvent;
- if (!e) {
- return;
- }
-
- // if preventDefault exists run it on the original event
- if (e.preventDefault) {
- e.preventDefault();
-
- // otherwise set the returnValue property of the original event to false (IE)
- } else {
- e.returnValue = false;
- }
- },
- stopPropagation: function () {
- this.isPropagationStopped = returnTrue;
-
- var e = this.originalEvent;
- if (!e) {
- return;
- }
- // if stopPropagation exists run it on the original event
- if (e.stopPropagation) {
- e.stopPropagation();
- }
- // otherwise set the cancelBubble property of the original event to true (IE)
- e.cancelBubble = true;
- },
- stopImmediatePropagation: function () {
- this.isImmediatePropagationStopped = returnTrue;
- this.stopPropagation();
- },
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse
- };
-
- // Checks if an event happened on an element within another element
- // Used in jQuery.event.special.mouseenter and mouseleave handlers
- var withinElement = function (event) {
- // Check if mouse(over|out) are still within the same parent element
- var parent = event.relatedTarget;
-
- // Firefox sometimes assigns relatedTarget a XUL element
- // which we cannot access the parentNode property of
- try {
- // Traverse up the tree
- while (parent && parent !== this) {
- parent = parent.parentNode;
- }
-
- if (parent !== this) {
- // set the correct event type
- event.type = event.data;
-
- // handle event if we actually just moused on to a non sub-element
- jQuery.event.handle.apply(this, arguments);
- }
-
- // assuming we've left the element since we most likely mousedover a xul element
- } catch (e) { }
- },
-
- // In case of event delegation, we only need to rename the event.type,
- // liveHandler will take care of the rest.
-delegate = function (event) {
- event.type = event.data;
- jQuery.event.handle.apply(this, arguments);
-};
-
- // Create mouseenter and mouseleave events
- jQuery.each({
- mouseenter: "mouseover",
- mouseleave: "mouseout"
- }, function (orig, fix) {
- jQuery.event.special[orig] = {
- setup: function (data) {
- jQuery.event.add(this, fix, data && data.selector ? delegate : withinElement, orig);
- },
- teardown: function (data) {
- jQuery.event.remove(this, fix, data && data.selector ? delegate : withinElement);
- }
- };
- });
-
- // submit delegation
- if (!jQuery.support.submitBubbles) {
-
- jQuery.event.special.submit = {
- setup: function (data, namespaces) {
- if (this.nodeName.toLowerCase() !== "form") {
- jQuery.event.add(this, "click.specialSubmit", function (e) {
- var elem = e.target,
- type = elem.type;
-
- if ((type === "submit" || type === "image") && jQuery(elem).closest("form").length) {
- e.liveFired = undefined;
- return trigger("submit", this, arguments);
- }
- });
-
- jQuery.event.add(this, "keypress.specialSubmit", function (e) {
- var elem = e.target,
- type = elem.type;
-
- if ((type === "text" || type === "password") && jQuery(elem).closest("form").length && e.keyCode === 13) {
- e.liveFired = undefined;
- return trigger("submit", this, arguments);
- }
- });
-
- } else {
- return false;
- }
- },
-
- teardown: function (namespaces) {
- jQuery.event.remove(this, ".specialSubmit");
- }
- };
-
- }
-
- // change delegation, happens here so we have bind.
- if (!jQuery.support.changeBubbles) {
-
- var changeFilters,
-
- getVal = function (elem) {
- var type = elem.type, val = elem.value;
-
- if (type === "radio" || type === "checkbox") {
- val = elem.checked;
-
- } else if (type === "select-multiple") {
- val = elem.selectedIndex > -1 ?
- jQuery.map(elem.options, function (elem) {
- return elem.selected;
- }).join("-") :
- "";
-
- } else if (elem.nodeName.toLowerCase() === "select") {
- val = elem.selectedIndex;
- }
-
- return val;
- },
-
- testChange = function testChange(e) {
- var elem = e.target, data, val;
-
- if (!rformElems.test(elem.nodeName) || elem.readOnly) {
- return;
- }
-
- data = jQuery.data(elem, "_change_data");
- val = getVal(elem);
-
- // the current data will be also retrieved by beforeactivate
- if (e.type !== "focusout" || elem.type !== "radio") {
- jQuery.data(elem, "_change_data", val);
- }
-
- if (data === undefined || val === data) {
- return;
- }
-
- if (data != null || val) {
- e.type = "change";
- e.liveFired = undefined;
- return jQuery.event.trigger(e, arguments[1], elem);
- }
- };
-
- jQuery.event.special.change = {
- filters: {
- focusout: testChange,
-
- beforedeactivate: testChange,
-
- click: function (e) {
- var elem = e.target, type = elem.type;
-
- if (type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select") {
- return testChange.call(this, e);
- }
- },
-
- // Change has to be called before submit
- // Keydown will be called before keypress, which is used in submit-event delegation
- keydown: function (e) {
- var elem = e.target, type = elem.type;
-
- if ((e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
- (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
- type === "select-multiple") {
- return testChange.call(this, e);
- }
- },
-
- // Beforeactivate happens also before the previous element is blurred
- // with this event you can't trigger a change event, but you can store
- // information
- beforeactivate: function (e) {
- var elem = e.target;
- jQuery.data(elem, "_change_data", getVal(elem));
- }
- },
-
- setup: function (data, namespaces) {
- if (this.type === "file") {
- return false;
- }
-
- for (var type in changeFilters) {
- jQuery.event.add(this, type + ".specialChange", changeFilters[type]);
- }
-
- return rformElems.test(this.nodeName);
- },
-
- teardown: function (namespaces) {
- jQuery.event.remove(this, ".specialChange");
-
- return rformElems.test(this.nodeName);
- }
- };
-
- changeFilters = jQuery.event.special.change.filters;
-
- // Handle when the input is .focus()'d
- changeFilters.focus = changeFilters.beforeactivate;
- }
-
- function trigger(type, elem, args) {
- args[0].type = type;
- return jQuery.event.handle.apply(elem, args);
- }
-
- // Create "bubbling" focus and blur events
- if (document.addEventListener) {
- jQuery.each({ focus: "focusin", blur: "focusout" }, function (orig, fix) {
- jQuery.event.special[fix] = {
- setup: function () {
- ///
- ///
This method is internal.
- ///
- ///
-
- if (focusCounts[fix]++ === 0) {
- document.addEventListener(orig, handler, true);
- }
- },
- teardown: function () {
- ///
- ///
This method is internal.
- ///
- ///
-
- if (--focusCounts[fix] === 0) {
- document.removeEventListener(orig, handler, true);
- }
- }
- };
-
- function handler(e) {
- e = jQuery.event.fix(e);
- e.type = fix;
- return jQuery.event.trigger(e, null, e.target);
- }
- });
- }
-
- // jQuery.each(["bind", "one"], function( i, name ) {
- // jQuery.fn[ name ] = function( type, data, fn ) {
- // // Handle object literals
- // if ( typeof type === "object" ) {
- // for ( var key in type ) {
- // this[ name ](key, data, type[key], fn);
- // }
- // return this;
- // }
-
- // if ( jQuery.isFunction( data ) || data === false ) {
- // fn = data;
- // data = undefined;
- // }
-
- // var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
- // jQuery( this ).unbind( event, handler );
- // return fn.apply( this, arguments );
- // }) : fn;
-
- // if ( type === "unload" && name !== "one" ) {
- // this.one( type, data, fn );
-
- // } else {
- // for ( var i = 0, l = this.length; i < l; i++ ) {
- // jQuery.event.add( this[i], type, handler, data );
- // }
- // }
-
- // return this;
- // };
- // });
-
- jQuery.fn["bind"] = function (type, data, fn) {
- ///
- ///
Binds a handler to one or more events for each matched element. Can also bind custom events.
- ///
- /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .
- /// Additional data passed to the event handler as event.data
- /// A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element.
-
- // Handle object literals
- if (typeof type === "object") {
- for (var key in type) {
- this["bind"](key, data, type[key], fn);
- }
- return this;
- }
-
- if (jQuery.isFunction(data)) {
- fn = data;
- data = undefined;
- }
-
- var handler = "bind" === "one" ? jQuery.proxy(fn, function (event) {
- jQuery(this).unbind(event, handler);
- return fn.apply(this, arguments);
- }) : fn;
-
- return type === "unload" && "bind" !== "one" ?
- this.one(type, data, fn) :
- this.each(function () {
- jQuery.event.add(this, type, handler, data);
- });
- };
-
- jQuery.fn["one"] = function (type, data, fn) {
- ///
- ///
Binds a handler to one or more events to be executed exactly once for each matched element.
- ///
- /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .
- /// Additional data passed to the event handler as event.data
- /// A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element.
-
- // Handle object literals
- if (typeof type === "object") {
- for (var key in type) {
- this["one"](key, data, type[key], fn);
- }
- return this;
- }
-
- if (jQuery.isFunction(data)) {
- fn = data;
- data = undefined;
- }
-
- var handler = "one" === "one" ? jQuery.proxy(fn, function (event) {
- jQuery(this).unbind(event, handler);
- return fn.apply(this, arguments);
- }) : fn;
-
- return type === "unload" && "one" !== "one" ?
- this.one(type, data, fn) :
- this.each(function () {
- jQuery.event.add(this, type, handler, data);
- });
- };
-
- jQuery.fn.extend({
- unbind: function (type, fn) {
- ///
- ///
Unbinds a handler from one or more events for each matched element.
- ///
- /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .
- /// A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element.
-
- // Handle object literals
- if (typeof type === "object" && !type.preventDefault) {
- for (var key in type) {
- this.unbind(key, type[key]);
- }
-
- } else {
- for (var i = 0, l = this.length; i < l; i++) {
- jQuery.event.remove(this[i], type, fn);
- }
- }
-
- return this;
- },
-
- delegate: function (selector, types, data, fn) {
- return this.live(types, data, fn, selector);
- },
-
- undelegate: function (selector, types, fn) {
- if (arguments.length === 0) {
- return this.unbind("live");
-
- } else {
- return this.die(types, null, fn, selector);
- }
- },
-
- trigger: function (type, data) {
- ///
- ///
Triggers a type of event on every matched element.
- ///
- /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .
- /// Additional data passed to the event handler as additional arguments.
- /// This parameter is undocumented.
-
- return this.each(function () {
- jQuery.event.trigger(type, data, this);
- });
- },
-
- triggerHandler: function (type, data) {
- ///
- ///
Triggers all bound event handlers on an element for a specific event type without executing the browser's default actions.
- ///
- /// One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .
- /// Additional data passed to the event handler as additional arguments.
- /// This parameter is undocumented.
-
- if (this[0]) {
- var event = jQuery.Event(type);
- event.preventDefault();
- event.stopPropagation();
- jQuery.event.trigger(event, data, this[0]);
- return event.result;
- }
- },
-
- toggle: function (fn) {
- ///
- ///
Toggles among two or more function calls every other click.
- ///
- /// The functions among which to toggle execution
-
- // Save reference to arguments for access in closure
- var args = arguments,
- i = 1;
-
- // link all the functions, so any of them can unbind this click handler
- while (i < args.length) {
- jQuery.proxy(fn, args[i++]);
- }
-
- return this.click(jQuery.proxy(fn, function (event) {
- // Figure out which function to execute
- var lastToggle = (jQuery.data(this, "lastToggle" + fn.guid) || 0) % i;
- jQuery.data(this, "lastToggle" + fn.guid, lastToggle + 1);
-
- // Make sure that clicks stop
- event.preventDefault();
-
- // and execute the function
- return args[lastToggle].apply(this, arguments) || false;
- }));
- },
-
- hover: function (fnOver, fnOut) {
- ///
- ///
Simulates hovering (moving the mouse on or off of an object).
- ///
- /// The function to fire when the mouse is moved over a matched element.
- /// The function to fire when the mouse is moved off of a matched element.
-
- return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
- }
- });
-
- var liveMap = {
- focus: "focusin",
- blur: "focusout",
- mouseenter: "mouseover",
- mouseleave: "mouseout"
- };
-
- // jQuery.each(["live", "die"], function( i, name ) {
- // jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
- // var type, i = 0, match, namespaces, preType,
- // selector = origSelector || this.selector,
- // context = origSelector ? this : jQuery( this.context );
-
- // if ( typeof types === "object" && !types.preventDefault ) {
- // for ( var key in types ) {
- // context[ name ]( key, data, types[key], selector );
- // }
-
- // return this;
- // }
-
- // if ( jQuery.isFunction( data ) ) {
- // fn = data;
- // data = undefined;
- // }
-
- // types = (types || "").split(" ");
-
- // while ( (type = types[ i++ ]) != null ) {
- // match = rnamespaces.exec( type );
- // namespaces = "";
-
- // if ( match ) {
- // namespaces = match[0];
- // type = type.replace( rnamespaces, "" );
- // }
-
- // if ( type === "hover" ) {
- // types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
- // continue;
- // }
-
- // preType = type;
-
- // if ( type === "focus" || type === "blur" ) {
- // types.push( liveMap[ type ] + namespaces );
- // type = type + namespaces;
-
- // } else {
- // type = (liveMap[ type ] || type) + namespaces;
- // }
-
- // if ( name === "live" ) {
- // // bind live handler
- // for ( var j = 0, l = context.length; j < l; j++ ) {
- // jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
- // { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
- // }
-
- // } else {
- // // unbind live handler
- // context.unbind( "live." + liveConvert( type, selector ), fn );
- // }
- // }
-
- // return this;
- // };
- // });
-
- jQuery.fn["live"] = function (types, data, fn) {
- ///
- ///
Attach a handler to the event for all elements which match the current selector, now or
- ///
in the future.
- ///
- ///
- ///
A string containing a JavaScript event type, such as "click" or "keydown".
- ///
- ///
- ///
A map of data that will be passed to the event handler.
- ///
- ///
- ///
A function to execute at the time the event is triggered.
- ///
- ///
-
- var type, i = 0;
-
- if (jQuery.isFunction(data)) {
- fn = data;
- data = undefined;
- }
-
- types = (types || "").split(/\s+/);
-
- while ((type = types[i++]) != null) {
- type = type === "focus" ? "focusin" : // focus --> focusin
- type === "blur" ? "focusout" : // blur --> focusout
- type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support
- type;
-
- if ("live" === "live") {
- // bind live handler
- jQuery(this.context).bind(liveConvert(type, this.selector), {
- data: data, selector: this.selector, live: type
- }, fn);
-
- } else {
- // unbind live handler
- jQuery(this.context).unbind(liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type} : null);
- }
- }
-
- return this;
- }
-
- jQuery.fn["die"] = function (types, data, fn) {
- ///
- ///
Remove all event handlers previously attached using .live() from the elements.
- ///
- ///
- ///
A string containing a JavaScript event type, such as click or keydown.
- ///
- ///
- ///
The function that is to be no longer executed.
- ///
- ///
-
- var type, i = 0;
-
- if (jQuery.isFunction(data)) {
- fn = data;
- data = undefined;
- }
-
- types = (types || "").split(/\s+/);
-
- while ((type = types[i++]) != null) {
- type = type === "focus" ? "focusin" : // focus --> focusin
- type === "blur" ? "focusout" : // blur --> focusout
- type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support
- type;
-
- if ("die" === "live") {
- // bind live handler
- jQuery(this.context).bind(liveConvert(type, this.selector), {
- data: data, selector: this.selector, live: type
- }, fn);
-
- } else {
- // unbind live handler
- jQuery(this.context).unbind(liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type} : null);
- }
- }
-
- return this;
- }
-
- function liveHandler(event) {
- var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
- elems = [],
- selectors = [],
- events = jQuery.data(this, this.nodeType ? "events" : "__events__");
-
- if (typeof events === "function") {
- events = events.events;
- }
-
- // Make sure we avoid non-left-click bubbling in Firefox (#3861)
- if (event.liveFired === this || !events || !events.live || event.button && event.type === "click") {
- return;
- }
-
- if (event.namespace) {
- namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
- }
-
- event.liveFired = this;
-
- var live = events.live.slice(0);
-
- for (j = 0; j < live.length; j++) {
- handleObj = live[j];
-
- if (handleObj.origType.replace(rnamespaces, "") === event.type) {
- selectors.push(handleObj.selector);
-
- } else {
- live.splice(j--, 1);
- }
- }
-
- match = jQuery(event.target).closest(selectors, event.currentTarget);
-
- for (i = 0, l = match.length; i < l; i++) {
- close = match[i];
-
- for (j = 0; j < live.length; j++) {
- handleObj = live[j];
-
- if (close.selector === handleObj.selector && (!namespace || namespace.test(handleObj.namespace))) {
- elem = close.elem;
- related = null;
-
- // Those two events require additional checking
- if (handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave") {
- event.type = handleObj.preType;
- related = jQuery(event.relatedTarget).closest(handleObj.selector)[0];
- }
-
- if (!related || related !== elem) {
- elems.push({ elem: elem, handleObj: handleObj, level: close.level });
- }
- }
- }
- }
-
- for (i = 0, l = elems.length; i < l; i++) {
- match = elems[i];
-
- if (maxLevel && match.level > maxLevel) {
- break;
- }
-
- event.currentTarget = match.elem;
- event.data = match.handleObj.data;
- event.handleObj = match.handleObj;
-
- ret = match.handleObj.origHandler.apply(match.elem, arguments);
-
- if (ret === false || event.isPropagationStopped()) {
- maxLevel = match.level;
-
- if (ret === false) {
- stop = false;
- }
- if (event.isImmediatePropagationStopped()) {
- break;
- }
- }
- }
-
- return stop;
- }
-
- function liveConvert(type, selector) {
- return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
- }
-
- // jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
- // "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
- // "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
-
- // // Handle event binding
- // jQuery.fn[ name ] = function( data, fn ) {
- // if ( fn == null ) {
- // fn = data;
- // data = null;
- // }
-
- // return arguments.length > 0 ?
- // this.bind( name, data, fn ) :
- // this.trigger( name );
- // };
-
- // if ( jQuery.attrFn ) {
- // jQuery.attrFn[ name ] = true;
- // }
- // });
-
- jQuery.fn["blur"] = function (fn) {
- ///
- ///
1: blur() - Triggers the blur event of each matched element.
- ///
2: blur(fn) - Binds a function to the blur event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("blur", fn) : this.trigger("blur");
- };
-
- jQuery.fn["focus"] = function (fn) {
- ///
- ///
1: focus() - Triggers the focus event of each matched element.
- ///
2: focus(fn) - Binds a function to the focus event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("focus", fn) : this.trigger("focus");
- };
-
- jQuery.fn["focusin"] = function (fn) {
- ///
- ///
Bind an event handler to the "focusin" JavaScript event.
- ///
- ///
- ///
A function to execute each time the event is triggered.
- ///
- ///
-
- return fn ? this.bind("focusin", fn) : this.trigger("focusin");
- };
-
- jQuery.fn["focusout"] = function (fn) {
- ///
- ///
Bind an event handler to the "focusout" JavaScript event.
- ///
- ///
- ///
A function to execute each time the event is triggered.
- ///
- ///
-
- return fn ? this.bind("focusout", fn) : this.trigger("focusout");
- };
-
- jQuery.fn["load"] = function (fn) {
- ///
- ///
1: load() - Triggers the load event of each matched element.
- ///
2: load(fn) - Binds a function to the load event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("load", fn) : this.trigger("load");
- };
-
- jQuery.fn["resize"] = function (fn) {
- ///
- ///
1: resize() - Triggers the resize event of each matched element.
- ///
2: resize(fn) - Binds a function to the resize event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("resize", fn) : this.trigger("resize");
- };
-
- jQuery.fn["scroll"] = function (fn) {
- ///
- ///
1: scroll() - Triggers the scroll event of each matched element.
- ///
2: scroll(fn) - Binds a function to the scroll event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("scroll", fn) : this.trigger("scroll");
- };
-
- jQuery.fn["unload"] = function (fn) {
- ///
- ///
1: unload() - Triggers the unload event of each matched element.
- ///
2: unload(fn) - Binds a function to the unload event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("unload", fn) : this.trigger("unload");
- };
-
- jQuery.fn["click"] = function (fn) {
- ///
- ///
1: click() - Triggers the click event of each matched element.
- ///
2: click(fn) - Binds a function to the click event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("click", fn) : this.trigger("click");
- };
-
- jQuery.fn["dblclick"] = function (fn) {
- ///
- ///
1: dblclick() - Triggers the dblclick event of each matched element.
- ///
2: dblclick(fn) - Binds a function to the dblclick event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("dblclick", fn) : this.trigger("dblclick");
- };
-
- jQuery.fn["mousedown"] = function (fn) {
- ///
- ///
Binds a function to the mousedown event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("mousedown", fn) : this.trigger("mousedown");
- };
-
- jQuery.fn["mouseup"] = function (fn) {
- ///
- ///
Bind a function to the mouseup event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("mouseup", fn) : this.trigger("mouseup");
- };
-
- jQuery.fn["mousemove"] = function (fn) {
- ///
- ///
Bind a function to the mousemove event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("mousemove", fn) : this.trigger("mousemove");
- };
-
- jQuery.fn["mouseover"] = function (fn) {
- ///
- ///
Bind a function to the mouseover event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("mouseover", fn) : this.trigger("mouseover");
- };
-
- jQuery.fn["mouseout"] = function (fn) {
- ///
- ///
Bind a function to the mouseout event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("mouseout", fn) : this.trigger("mouseout");
- };
-
- jQuery.fn["mouseenter"] = function (fn) {
- ///
- ///
Bind a function to the mouseenter event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("mouseenter", fn) : this.trigger("mouseenter");
- };
-
- jQuery.fn["mouseleave"] = function (fn) {
- ///
- ///
Bind a function to the mouseleave event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("mouseleave", fn) : this.trigger("mouseleave");
- };
-
- jQuery.fn["change"] = function (fn) {
- ///
- ///
1: change() - Triggers the change event of each matched element.
- ///
2: change(fn) - Binds a function to the change event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("change", fn) : this.trigger("change");
- };
-
- jQuery.fn["select"] = function (fn) {
- ///
- ///
1: select() - Triggers the select event of each matched element.
- ///
2: select(fn) - Binds a function to the select event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("select", fn) : this.trigger("select");
- };
-
- jQuery.fn["submit"] = function (fn) {
- ///
- ///
1: submit() - Triggers the submit event of each matched element.
- ///
2: submit(fn) - Binds a function to the submit event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("submit", fn) : this.trigger("submit");
- };
-
- jQuery.fn["keydown"] = function (fn) {
- ///
- ///
1: keydown() - Triggers the keydown event of each matched element.
- ///
2: keydown(fn) - Binds a function to the keydown event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("keydown", fn) : this.trigger("keydown");
- };
-
- jQuery.fn["keypress"] = function (fn) {
- ///
- ///
1: keypress() - Triggers the keypress event of each matched element.
- ///
2: keypress(fn) - Binds a function to the keypress event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("keypress", fn) : this.trigger("keypress");
- };
-
- jQuery.fn["keyup"] = function (fn) {
- ///
- ///
1: keyup() - Triggers the keyup event of each matched element.
- ///
2: keyup(fn) - Binds a function to the keyup event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("keyup", fn) : this.trigger("keyup");
- };
-
- jQuery.fn["error"] = function (fn) {
- ///
- ///
1: error() - Triggers the error event of each matched element.
- ///
2: error(fn) - Binds a function to the error event of each matched element.
- ///
- /// The function to execute.
- ///
-
- return fn ? this.bind("error", fn) : this.trigger("error");
- };
-
- // Prevent memory leaks in IE
- // Window isn't included so as not to unbind existing unload events
- // More info:
- // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
- if (window.attachEvent && !window.addEventListener) {
- jQuery(window).bind("unload", function () {
- for (var id in jQuery.cache) {
- if (jQuery.cache[id].handle) {
- // Try/Catch is to handle iframes being unloaded, see #4280
- try {
- jQuery.event.remove(jQuery.cache[id].handle.elem);
- } catch (e) { }
- }
- }
- });
- }
-
-
- (function () {
-
- var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
- done = 0,
- toString = Object.prototype.toString,
- hasDuplicate = false,
- baseHasDuplicate = true;
-
- // Here we check if the JavaScript engine is using some sort of
- // optimization where it does not always call our comparision
- // function. If that is the case, discard the hasDuplicate value.
- // Thus far that includes Google Chrome.
- [0, 0].sort(function () {
- baseHasDuplicate = false;
- return 0;
- });
-
- var Sizzle = function (selector, context, results, seed) {
- results = results || [];
- context = context || document;
-
- var origContext = context;
-
- if (context.nodeType !== 1 && context.nodeType !== 9) {
- return [];
- }
-
- if (!selector || typeof selector !== "string") {
- return results;
- }
-
- var m, set, checkSet, extra, ret, cur, pop, i,
- prune = true,
- contextXML = Sizzle.isXML(context),
- parts = [],
- soFar = selector;
-
- // Reset the position of the chunker regexp (start from head)
- do {
- chunker.exec("");
- m = chunker.exec(soFar);
-
- if (m) {
- soFar = m[3];
-
- parts.push(m[1]);
-
- if (m[2]) {
- extra = m[3];
- break;
- }
- }
- } while (m);
-
- if (parts.length > 1 && origPOS.exec(selector)) {
-
- if (parts.length === 2 && Expr.relative[parts[0]]) {
- set = posProcess(parts[0] + parts[1], context);
-
- } else {
- set = Expr.relative[parts[0]] ?
- [context] :
- Sizzle(parts.shift(), context);
-
- while (parts.length) {
- selector = parts.shift();
-
- if (Expr.relative[selector]) {
- selector += parts.shift();
- }
-
- set = posProcess(selector, set);
- }
- }
-
- } else {
- // Take a shortcut and set the context if the root selector is an ID
- // (but not if it'll be faster if the inner selector is an ID)
- if (!seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
- Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1])) {
-
- ret = Sizzle.find(parts.shift(), context, contextXML);
- context = ret.expr ?
- Sizzle.filter(ret.expr, ret.set)[0] :
- ret.set[0];
- }
-
- if (context) {
- ret = seed ?
- { expr: parts.pop(), set: makeArray(seed)} :
- Sizzle.find(parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML);
-
- set = ret.expr ?
- Sizzle.filter(ret.expr, ret.set) :
- ret.set;
-
- if (parts.length > 0) {
- checkSet = makeArray(set);
-
- } else {
- prune = false;
- }
-
- while (parts.length) {
- cur = parts.pop();
- pop = cur;
-
- if (!Expr.relative[cur]) {
- cur = "";
- } else {
- pop = parts.pop();
- }
-
- if (pop == null) {
- pop = context;
- }
-
- Expr.relative[cur](checkSet, pop, contextXML);
- }
-
- } else {
- checkSet = parts = [];
- }
- }
-
- if (!checkSet) {
- checkSet = set;
- }
-
- if (!checkSet) {
- Sizzle.error(cur || selector);
- }
-
- if (toString.call(checkSet) === "[object Array]") {
- if (!prune) {
- results.push.apply(results, checkSet);
-
- } else if (context && context.nodeType === 1) {
- for (i = 0; checkSet[i] != null; i++) {
- if (checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i]))) {
- results.push(set[i]);
- }
- }
-
- } else {
- for (i = 0; checkSet[i] != null; i++) {
- if (checkSet[i] && checkSet[i].nodeType === 1) {
- results.push(set[i]);
- }
- }
- }
-
- } else {
- makeArray(checkSet, results);
- }
-
- if (extra) {
- Sizzle(extra, origContext, results, seed);
- Sizzle.uniqueSort(results);
- }
-
- return results;
- };
-
- Sizzle.uniqueSort = function (results) {
- ///
- ///
Removes all duplicate elements from an array of elements.
- ///
- /// The array to translate
- /// The array after translation.
-
- if (sortOrder) {
- hasDuplicate = baseHasDuplicate;
- results.sort(sortOrder);
-
- if (hasDuplicate) {
- for (var i = 1; i < results.length; i++) {
- if (results[i] === results[i - 1]) {
- results.splice(i--, 1);
- }
- }
- }
- }
-
- return results;
- };
-
- Sizzle.matches = function (expr, set) {
- return Sizzle(expr, null, null, set);
- };
-
- Sizzle.matchesSelector = function (node, expr) {
- return Sizzle(expr, null, null, [node]).length > 0;
- };
-
- Sizzle.find = function (expr, context, isXML) {
- var set;
-
- if (!expr) {
- return [];
- }
-
- for (var i = 0, l = Expr.order.length; i < l; i++) {
- var match,
- type = Expr.order[i];
-
- if ((match = Expr.leftMatch[type].exec(expr))) {
- var left = match[1];
- match.splice(1, 1);
-
- if (left.substr(left.length - 1) !== "\\") {
- match[1] = (match[1] || "").replace(/\\/g, "");
- set = Expr.find[type](match, context, isXML);
-
- if (set != null) {
- expr = expr.replace(Expr.match[type], "");
- break;
- }
- }
- }
- }
-
- if (!set) {
- set = context.getElementsByTagName("*");
- }
-
- return { set: set, expr: expr };
- };
-
- Sizzle.filter = function (expr, set, inplace, not) {
- var match, anyFound,
- old = expr,
- result = [],
- curLoop = set,
- isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);
-
- while (expr && set.length) {
- for (var type in Expr.filter) {
- if ((match = Expr.leftMatch[type].exec(expr)) != null && match[2]) {
- var found, item,
- filter = Expr.filter[type],
- left = match[1];
-
- anyFound = false;
-
- match.splice(1, 1);
-
- if (left.substr(left.length - 1) === "\\") {
- continue;
- }
-
- if (curLoop === result) {
- result = [];
- }
-
- if (Expr.preFilter[type]) {
- match = Expr.preFilter[type](match, curLoop, inplace, result, not, isXMLFilter);
-
- if (!match) {
- anyFound = found = true;
-
- } else if (match === true) {
- continue;
- }
- }
-
- if (match) {
- for (var i = 0; (item = curLoop[i]) != null; i++) {
- if (item) {
- found = filter(item, match, i, curLoop);
- var pass = not ^ !!found;
-
- if (inplace && found != null) {
- if (pass) {
- anyFound = true;
-
- } else {
- curLoop[i] = false;
- }
-
- } else if (pass) {
- result.push(item);
- anyFound = true;
- }
- }
- }
- }
-
- if (found !== undefined) {
- if (!inplace) {
- curLoop = result;
- }
-
- expr = expr.replace(Expr.match[type], "");
-
- if (!anyFound) {
- return [];
- }
-
- break;
- }
- }
- }
-
- // Improper expression
- if (expr === old) {
- if (anyFound == null) {
- Sizzle.error(expr);
-
- } else {
- break;
- }
- }
-
- old = expr;
- }
-
- return curLoop;
- };
-
- Sizzle.error = function (msg) {
- throw "Syntax error, unrecognized expression: " + msg;
- };
-
- var Expr = Sizzle.selectors = {
- order: ["ID", "NAME", "TAG"],
-
- match: {
- ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
- CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
- NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
- ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
- TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
- CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
- POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
- PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
- },
-
- leftMatch: {},
-
- attrMap: {
- "class": "className",
- "for": "htmlFor"
- },
-
- attrHandle: {
- href: function (elem) {
- return elem.getAttribute("href");
- }
- },
-
- relative: {
- "+": function (checkSet, part) {
- var isPartStr = typeof part === "string",
- isTag = isPartStr && !/\W/.test(part),
- isPartStrNotTag = isPartStr && !isTag;
-
- if (isTag) {
- part = part.toLowerCase();
- }
-
- for (var i = 0, l = checkSet.length, elem; i < l; i++) {
- if ((elem = checkSet[i])) {
- while ((elem = elem.previousSibling) && elem.nodeType !== 1) { }
-
- checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
- elem || false :
- elem === part;
- }
- }
-
- if (isPartStrNotTag) {
- Sizzle.filter(part, checkSet, true);
- }
- },
-
- ">": function (checkSet, part) {
- var elem,
- isPartStr = typeof part === "string",
- i = 0,
- l = checkSet.length;
-
- if (isPartStr && !/\W/.test(part)) {
- part = part.toLowerCase();
-
- for (; i < l; i++) {
- elem = checkSet[i];
-
- if (elem) {
- var parent = elem.parentNode;
- checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
- }
- }
-
- } else {
- for (; i < l; i++) {
- elem = checkSet[i];
-
- if (elem) {
- checkSet[i] = isPartStr ?
- elem.parentNode :
- elem.parentNode === part;
- }
- }
-
- if (isPartStr) {
- Sizzle.filter(part, checkSet, true);
- }
- }
- },
-
- "": function (checkSet, part, isXML) {
- var nodeCheck,
- doneName = done++,
- checkFn = dirCheck;
-
- if (typeof part === "string" && !/\W/.test(part)) {
- part = part.toLowerCase();
- nodeCheck = part;
- checkFn = dirNodeCheck;
- }
-
- checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
- },
-
- "~": function (checkSet, part, isXML) {
- var nodeCheck,
- doneName = done++,
- checkFn = dirCheck;
-
- if (typeof part === "string" && !/\W/.test(part)) {
- part = part.toLowerCase();
- nodeCheck = part;
- checkFn = dirNodeCheck;
- }
-
- checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
- }
- },
-
- find: {
- ID: function (match, context, isXML) {
- if (typeof context.getElementById !== "undefined" && !isXML) {
- var m = context.getElementById(match[1]);
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [m] : [];
- }
- },
-
- NAME: function (match, context) {
- if (typeof context.getElementsByName !== "undefined") {
- var ret = [],
- results = context.getElementsByName(match[1]);
-
- for (var i = 0, l = results.length; i < l; i++) {
- if (results[i].getAttribute("name") === match[1]) {
- ret.push(results[i]);
- }
- }
-
- return ret.length === 0 ? null : ret;
- }
- },
-
- TAG: function (match, context) {
- return context.getElementsByTagName(match[1]);
- }
- },
- preFilter: {
- CLASS: function (match, curLoop, inplace, result, not, isXML) {
- match = " " + match[1].replace(/\\/g, "") + " ";
-
- if (isXML) {
- return match;
- }
-
- for (var i = 0, elem; (elem = curLoop[i]) != null; i++) {
- if (elem) {
- if (not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0)) {
- if (!inplace) {
- result.push(elem);
- }
-
- } else if (inplace) {
- curLoop[i] = false;
- }
- }
- }
-
- return false;
- },
-
- ID: function (match) {
- return match[1].replace(/\\/g, "");
- },
-
- TAG: function (match, curLoop) {
- return match[1].toLowerCase();
- },
-
- CHILD: function (match) {
- if (match[1] === "nth") {
- // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
- var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
- match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
- !/\D/.test(match[2]) && "0n+" + match[2] || match[2]);
-
- // calculate the numbers (first)n+(last) including if they are negative
- match[2] = (test[1] + (test[2] || 1)) - 0;
- match[3] = test[3] - 0;
- }
-
- // TODO: Move to normal caching system
- match[0] = done++;
-
- return match;
- },
-
- ATTR: function (match, curLoop, inplace, result, not, isXML) {
- var name = match[1].replace(/\\/g, "");
-
- if (!isXML && Expr.attrMap[name]) {
- match[1] = Expr.attrMap[name];
- }
-
- if (match[2] === "~=") {
- match[4] = " " + match[4] + " ";
- }
-
- return match;
- },
-
- PSEUDO: function (match, curLoop, inplace, result, not) {
- if (match[1] === "not") {
- // If we're dealing with a complex expression, or a simple one
- if ((chunker.exec(match[3]) || "").length > 1 || /^\w/.test(match[3])) {
- match[3] = Sizzle(match[3], null, null, curLoop);
-
- } else {
- var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
-
- if (!inplace) {
- result.push.apply(result, ret);
- }
-
- return false;
- }
-
- } else if (Expr.match.POS.test(match[0]) || Expr.match.CHILD.test(match[0])) {
- return true;
- }
-
- return match;
- },
-
- POS: function (match) {
- match.unshift(true);
-
- return match;
- }
- },
-
- filters: {
- enabled: function (elem) {
- return elem.disabled === false && elem.type !== "hidden";
- },
-
- disabled: function (elem) {
- return elem.disabled === true;
- },
-
- checked: function (elem) {
- return elem.checked === true;
- },
-
- selected: function (elem) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- elem.parentNode.selectedIndex;
-
- return elem.selected === true;
- },
-
- parent: function (elem) {
- return !!elem.firstChild;
- },
-
- empty: function (elem) {
- return !elem.firstChild;
- },
-
- has: function (elem, i, match) {
- ///
- ///
Internal use only; use hasClass('class')
- ///
- ///
-
- return !!Sizzle(match[3], elem).length;
- },
-
- header: function (elem) {
- return (/h\d/i).test(elem.nodeName);
- },
-
- text: function (elem) {
- return "text" === elem.type;
- },
- radio: function (elem) {
- return "radio" === elem.type;
- },
-
- checkbox: function (elem) {
- return "checkbox" === elem.type;
- },
-
- file: function (elem) {
- return "file" === elem.type;
- },
- password: function (elem) {
- return "password" === elem.type;
- },
-
- submit: function (elem) {
- return "submit" === elem.type;
- },
-
- image: function (elem) {
- return "image" === elem.type;
- },
-
- reset: function (elem) {
- return "reset" === elem.type;
- },
-
- button: function (elem) {
- return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
- },
-
- input: function (elem) {
- return (/input|select|textarea|button/i).test(elem.nodeName);
- }
- },
- setFilters: {
- first: function (elem, i) {
- return i === 0;
- },
-
- last: function (elem, i, match, array) {
- return i === array.length - 1;
- },
-
- even: function (elem, i) {
- return i % 2 === 0;
- },
-
- odd: function (elem, i) {
- return i % 2 === 1;
- },
-
- lt: function (elem, i, match) {
- return i < match[3] - 0;
- },
-
- gt: function (elem, i, match) {
- return i > match[3] - 0;
- },
-
- nth: function (elem, i, match) {
- return match[3] - 0 === i;
- },
-
- eq: function (elem, i, match) {
- return match[3] - 0 === i;
- }
- },
- filter: {
- PSEUDO: function (elem, match, i, array) {
- var name = match[1],
- filter = Expr.filters[name];
-
- if (filter) {
- return filter(elem, i, match, array);
-
- } else if (name === "contains") {
- return (elem.textContent || elem.innerText || Sizzle.getText([elem]) || "").indexOf(match[3]) >= 0;
-
- } else if (name === "not") {
- var not = match[3];
-
- for (var j = 0, l = not.length; j < l; j++) {
- if (not[j] === elem) {
- return false;
- }
- }
-
- return true;
-
- } else {
- Sizzle.error("Syntax error, unrecognized expression: " + name);
- }
- },
-
- CHILD: function (elem, match) {
- var type = match[1],
- node = elem;
-
- switch (type) {
- case "only":
- case "first":
- while ((node = node.previousSibling)) {
- if (node.nodeType === 1) {
- return false;
- }
- }
-
- if (type === "first") {
- return true;
- }
-
- node = elem;
-
- case "last":
- while ((node = node.nextSibling)) {
- if (node.nodeType === 1) {
- return false;
- }
- }
-
- return true;
-
- case "nth":
- var first = match[2],
- last = match[3];
-
- if (first === 1 && last === 0) {
- return true;
- }
-
- var doneName = match[0],
- parent = elem.parentNode;
-
- if (parent && (parent.sizcache !== doneName || !elem.nodeIndex)) {
- var count = 0;
-
- for (node = parent.firstChild; node; node = node.nextSibling) {
- if (node.nodeType === 1) {
- node.nodeIndex = ++count;
- }
- }
-
- parent.sizcache = doneName;
- }
-
- var diff = elem.nodeIndex - last;
-
- if (first === 0) {
- return diff === 0;
-
- } else {
- return (diff % first === 0 && diff / first >= 0);
- }
- }
- },
-
- ID: function (elem, match) {
- return elem.nodeType === 1 && elem.getAttribute("id") === match;
- },
-
- TAG: function (elem, match) {
- return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
- },
-
- CLASS: function (elem, match) {
- return (" " + (elem.className || elem.getAttribute("class")) + " ")
- .indexOf(match) > -1;
- },
-
- ATTR: function (elem, match) {
- var name = match[1],
- result = Expr.attrHandle[name] ?
- Expr.attrHandle[name](elem) :
- elem[name] != null ?
- elem[name] :
- elem.getAttribute(name),
- value = result + "",
- type = match[2],
- check = match[4];
-
- return result == null ?
- type === "!=" :
- type === "=" ?
- value === check :
- type === "*=" ?
- value.indexOf(check) >= 0 :
- type === "~=" ?
- (" " + value + " ").indexOf(check) >= 0 :
- !check ?
- value && result !== false :
- type === "!=" ?
- value !== check :
- type === "^=" ?
- value.indexOf(check) === 0 :
- type === "$=" ?
- value.substr(value.length - check.length) === check :
- type === "|=" ?
- value === check || value.substr(0, check.length + 1) === check + "-" :
- false;
- },
-
- POS: function (elem, match, i, array) {
- var name = match[2],
- filter = Expr.setFilters[name];
-
- if (filter) {
- return filter(elem, i, match, array);
- }
- }
- }
- };
-
- var origPOS = Expr.match.POS,
- fescape = function (all, num) {
- return "\\" + (num - 0 + 1);
- };
-
- for (var type in Expr.match) {
- Expr.match[type] = new RegExp(Expr.match[type].source + (/(?![^\[]*\])(?![^\(]*\))/.source));
- Expr.leftMatch[type] = new RegExp(/(^(?:.|\r|\n)*?)/.source + Expr.match[type].source.replace(/\\(\d+)/g, fescape));
- }
-
- var makeArray = function (array, results) {
- array = Array.prototype.slice.call(array, 0);
-
- if (results) {
- results.push.apply(results, array);
- return results;
- }
-
- return array;
- };
-
- // Perform a simple check to determine if the browser is capable of
- // converting a NodeList to an array using builtin methods.
- // Also verifies that the returned array holds DOM nodes
- // (which is not the case in the Blackberry browser)
- try {
- Array.prototype.slice.call(document.documentElement.childNodes, 0)[0].nodeType;
-
- // Provide a fallback method if it does not work
- } catch (e) {
- makeArray = function (array, results) {
- var i = 0,
- ret = results || [];
-
- if (toString.call(array) === "[object Array]") {
- Array.prototype.push.apply(ret, array);
-
- } else {
- if (typeof array.length === "number") {
- for (var l = array.length; i < l; i++) {
- ret.push(array[i]);
- }
-
- } else {
- for (; array[i]; i++) {
- ret.push(array[i]);
- }
- }
- }
-
- return ret;
- };
- }
-
- var sortOrder, siblingCheck;
-
- if (document.documentElement.compareDocumentPosition) {
- sortOrder = function (a, b) {
- if (a === b) {
- hasDuplicate = true;
- return 0;
- }
-
- if (!a.compareDocumentPosition || !b.compareDocumentPosition) {
- return a.compareDocumentPosition ? -1 : 1;
- }
-
- return a.compareDocumentPosition(b) & 4 ? -1 : 1;
- };
-
- } else {
- sortOrder = function (a, b) {
- var al, bl,
- ap = [],
- bp = [],
- aup = a.parentNode,
- bup = b.parentNode,
- cur = aup;
-
- // The nodes are identical, we can exit early
- if (a === b) {
- hasDuplicate = true;
- return 0;
-
- // If the nodes are siblings (or identical) we can do a quick check
- } else if (aup === bup) {
- return siblingCheck(a, b);
-
- // If no parents were found then the nodes are disconnected
- } else if (!aup) {
- return -1;
-
- } else if (!bup) {
- return 1;
- }
-
- // Otherwise they're somewhere else in the tree so we need
- // to build up a full list of the parentNodes for comparison
- while (cur) {
- ap.unshift(cur);
- cur = cur.parentNode;
- }
-
- cur = bup;
-
- while (cur) {
- bp.unshift(cur);
- cur = cur.parentNode;
- }
-
- al = ap.length;
- bl = bp.length;
-
- // Start walking down the tree looking for a discrepancy
- for (var i = 0; i < al && i < bl; i++) {
- if (ap[i] !== bp[i]) {
- return siblingCheck(ap[i], bp[i]);
- }
- }
-
- // We ended someplace up the tree so do a sibling check
- return i === al ?
- siblingCheck(a, bp[i], -1) :
- siblingCheck(ap[i], b, 1);
- };
-
- siblingCheck = function (a, b, ret) {
- if (a === b) {
- return ret;
- }
-
- var cur = a.nextSibling;
-
- while (cur) {
- if (cur === b) {
- return -1;
- }
-
- cur = cur.nextSibling;
- }
-
- return 1;
- };
- }
-
- // Utility function for retreiving the text value of an array of DOM nodes
- Sizzle.getText = function (elems) {
- var ret = "", elem;
-
- for (var i = 0; elems[i]; i++) {
- elem = elems[i];
-
- // Get the text from text nodes and CDATA nodes
- if (elem.nodeType === 3 || elem.nodeType === 4) {
- ret += elem.nodeValue;
-
- // Traverse everything else, except comment nodes
- } else if (elem.nodeType !== 8) {
- ret += Sizzle.getText(elem.childNodes);
- }
- }
-
- return ret;
- };
-
- // [vsdoc] The following function has been modified for IntelliSense.
- // Check to see if the browser returns elements by name when
- // querying by getElementById (and provide a workaround)
- (function () {
- // We're going to inject a fake input element with a specified name
- // var form = document.createElement("div"),
- // id = "script" + (new Date()).getTime(),
- // root = document.documentElement;
-
- // form.innerHTML = "";
-
- // // Inject it into the root element, check its status, and remove it quickly
- // root.insertBefore( form, root.firstChild );
-
- // // The workaround has to do additional checks after a getElementById
- // // Which slows things down for other browsers (hence the branching)
- // if ( document.getElementById( id ) ) {
- Expr.find.ID = function (match, context, isXML) {
- if (typeof context.getElementById !== "undefined" && !isXML) {
- var m = context.getElementById(match[1]);
-
- return m ?
- m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
- [m] :
- undefined :
- [];
- }
- };
-
- Expr.filter.ID = function (elem, match) {
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
-
- return elem.nodeType === 1 && node && node.nodeValue === match;
- };
- // }
-
- // root.removeChild( form );
-
- // release memory in IE
- root = form = null;
- })();
-
- // [vsdoc] The following function has been modified for IntelliSense.
- (function () {
- // Check to see if the browser returns only elements
- // when doing getElementsByTagName("*")
-
- // Create a fake element
- // var div = document.createElement("div");
- // div.appendChild( document.createComment("") );
-
- // Make sure no comments are found
- // if ( div.getElementsByTagName("*").length > 0 ) {
- Expr.find.TAG = function (match, context) {
- var results = context.getElementsByTagName(match[1]);
-
- // Filter out possible comments
- if (match[1] === "*") {
- var tmp = [];
-
- for (var i = 0; results[i]; i++) {
- if (results[i].nodeType === 1) {
- tmp.push(results[i]);
- }
- }
-
- results = tmp;
- }
-
- return results;
- };
- // }
-
- // Check to see if an attribute returns normalized href attributes
- // div.innerHTML = "";
-
- // if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
- // div.firstChild.getAttribute("href") !== "#" ) {
-
- // Expr.attrHandle.href = function( elem ) {
- // return elem.getAttribute( "href", 2 );
- // };
- // }
-
- // release memory in IE
- div = null;
- })();
-
- if (document.querySelectorAll) {
- (function () {
- var oldSizzle = Sizzle,
- div = document.createElement("div"),
- id = "__sizzle__";
-
- div.innerHTML = "";
-
- // Safari can't handle uppercase or unicode characters when
- // in quirks mode.
- if (div.querySelectorAll && div.querySelectorAll(".TEST").length === 0) {
- return;
- }
-
- Sizzle = function (query, context, extra, seed) {
- context = context || document;
-
- // Make sure that attribute selectors are quoted
- query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
-
- // Only use querySelectorAll on non-XML documents
- // (ID selectors don't work in non-HTML documents)
- if (!seed && !Sizzle.isXML(context)) {
- if (context.nodeType === 9) {
- try {
- return makeArray(context.querySelectorAll(query), extra);
- } catch (qsaError) { }
-
- // 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
- } else if (context.nodeType === 1 && context.nodeName.toLowerCase() !== "object") {
- var old = context.getAttribute("id"),
- nid = old || id;
-
- if (!old) {
- context.setAttribute("id", nid);
- }
-
- try {
- return makeArray(context.querySelectorAll("#" + nid + " " + query), extra);
-
- } catch (pseudoError) {
- } finally {
- if (!old) {
- context.removeAttribute("id");
- }
- }
- }
- }
-
- return oldSizzle(query, context, extra, seed);
- };
-
- for (var prop in oldSizzle) {
- Sizzle[prop] = oldSizzle[prop];
- }
-
- // release memory in IE
- div = null;
- })();
- }
-
- (function () {
- var html = document.documentElement,
- matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
- pseudoWorks = false;
-
- try {
- // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call(document.documentElement, "[test!='']:sizzle");
-
- } catch (pseudoError) {
- pseudoWorks = true;
- }
-
- if (matches) {
- Sizzle.matchesSelector = function (node, expr) {
- // Make sure that attribute selectors are quoted
- expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
-
- if (!Sizzle.isXML(node)) {
- try {
- if (pseudoWorks || !Expr.match.PSEUDO.test(expr) && !/!=/.test(expr)) {
- return matches.call(node, expr);
- }
- } catch (e) { }
- }
-
- return Sizzle(expr, null, null, [node]).length > 0;
- };
- }
- })();
-
- (function () {
- var div = document.createElement("div");
-
- div.innerHTML = "";
-
- // Opera can't find a second classname (in 9.6)
- // Also, make sure that getElementsByClassName actually exists
- if (!div.getElementsByClassName || div.getElementsByClassName("e").length === 0) {
- return;
- }
-
- // Safari caches class attributes, doesn't catch changes (in 3.2)
- div.lastChild.className = "e";
-
- if (div.getElementsByClassName("e").length === 1) {
- return;
- }
-
- Expr.order.splice(1, 0, "CLASS");
- Expr.find.CLASS = function (match, context, isXML) {
- if (typeof context.getElementsByClassName !== "undefined" && !isXML) {
- return context.getElementsByClassName(match[1]);
- }
- };
-
- // release memory in IE
- div = null;
- })();
-
- function dirNodeCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
- for (var i = 0, l = checkSet.length; i < l; i++) {
- var elem = checkSet[i];
-
- if (elem) {
- var match = false;
-
- elem = elem[dir];
-
- while (elem) {
- if (elem.sizcache === doneName) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if (elem.nodeType === 1 && !isXML) {
- elem.sizcache = doneName;
- elem.sizset = i;
- }
-
- if (elem.nodeName.toLowerCase() === cur) {
- match = elem;
- break;
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
- }
-
- function dirCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
- for (var i = 0, l = checkSet.length; i < l; i++) {
- var elem = checkSet[i];
-
- if (elem) {
- var match = false;
-
- elem = elem[dir];
-
- while (elem) {
- if (elem.sizcache === doneName) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if (elem.nodeType === 1) {
- if (!isXML) {
- elem.sizcache = doneName;
- elem.sizset = i;
- }
-
- if (typeof cur !== "string") {
- if (elem === cur) {
- match = true;
- break;
- }
-
- } else if (Sizzle.filter(cur, [elem]).length > 0) {
- match = elem;
- break;
- }
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
- }
-
- if (document.documentElement.contains) {
- Sizzle.contains = function (a, b) {
- ///
- ///
Check to see if a DOM node is within another DOM node.
- ///
- ///
- ///
The DOM element that may contain the other element.
- ///
- ///
- ///
The DOM node that may be contained by the other element.
- ///
- ///
-
- return a !== b && (a.contains ? a.contains(b) : true);
- };
-
- } else if (document.documentElement.compareDocumentPosition) {
- Sizzle.contains = function (a, b) {
- ///
- ///
Check to see if a DOM node is within another DOM node.
- ///
- ///
- ///
The DOM element that may contain the other element.
- ///
- ///
- ///
The DOM node that may be contained by the other element.
- ///
- ///
-
- return !!(a.compareDocumentPosition(b) & 16);
- };
-
- } else {
- Sizzle.contains = function () {
- return false;
- };
- }
-
- Sizzle.isXML = function (elem) {
- ///
- ///
Determines if the parameter passed is an XML document.
- ///
- /// The object to test
- /// True if the parameter is an XML document; otherwise false.
-
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
-
- return documentElement ? documentElement.nodeName !== "HTML" : false;
- };
-
- var posProcess = function (selector, context) {
- var match,
- tmpSet = [],
- later = "",
- root = context.nodeType ? [context] : context;
-
- // Position selectors must be done after the filter
- // And so must :not(positional) so we move all PSEUDOs to the end
- while ((match = Expr.match.PSEUDO.exec(selector))) {
- later += match[0];
- selector = selector.replace(Expr.match.PSEUDO, "");
- }
-
- selector = Expr.relative[selector] ? selector + "*" : selector;
-
- for (var i = 0, l = root.length; i < l; i++) {
- Sizzle(selector, root[i], tmpSet);
- }
-
- return Sizzle.filter(later, tmpSet);
- };
-
- // EXPOSE
- jQuery.find = Sizzle;
- jQuery.expr = Sizzle.selectors;
- jQuery.expr[":"] = jQuery.expr.filters;
- jQuery.unique = Sizzle.uniqueSort;
- jQuery.text = Sizzle.getText;
- jQuery.isXMLDoc = Sizzle.isXML;
- jQuery.contains = Sizzle.contains;
-
-
- })();
-
-
- var runtil = /Until$/,
- rparentsprev = /^(?:parents|prevUntil|prevAll)/,
- // Note: This RegExp should be improved, or likely pulled from Sizzle
- rmultiselector = /,/,
- isSimple = /^.[^:#\[\.,]*$/,
- slice = Array.prototype.slice,
- POS = jQuery.expr.match.POS;
-
- jQuery.fn.extend({
- find: function (selector) {
- ///
- ///
Searches for all elements that match the specified expression.
- ///
This method is a good way to find additional descendant
- ///
elements with which to process.
- ///
All searching is done using a jQuery expression. The expression can be
- ///
written using CSS 1-3 Selector syntax, or basic XPath.
- ///
Part of DOM/Traversing
- ///
- ///
- ///
- ///
An expression to search with.
- ///
- ///
-
- var ret = this.pushStack("", "find", selector),
- length = 0;
-
- for (var i = 0, l = this.length; i < l; i++) {
- length = ret.length;
- jQuery.find(selector, this[i], ret);
-
- if (i > 0) {
- // Make sure that the results are unique
- for (var n = length; n < ret.length; n++) {
- for (var r = 0; r < length; r++) {
- if (ret[r] === ret[n]) {
- ret.splice(n--, 1);
- break;
- }
- }
- }
- }
- }
-
- return ret;
- },
-
- has: function (target) {
- ///
- ///
Reduce the set of matched elements to those that have a descendant that matches the
- ///
selector or DOM element.
- ///
- ///
- ///
A string containing a selector expression to match elements against.
- ///
- ///
-
- var targets = jQuery(target);
- return this.filter(function () {
- for (var i = 0, l = targets.length; i < l; i++) {
- if (jQuery.contains(this, targets[i])) {
- return true;
- }
- }
- });
- },
-
- not: function (selector) {
- ///
- ///
Removes any elements inside the array of elements from the set
- ///
of matched elements. This method is used to remove one or more
- ///
elements from a jQuery object.
- ///
Part of DOM/Traversing
- ///
- ///
- ///
A set of elements to remove from the jQuery set of matched elements.
- ///
- ///
-
- return this.pushStack(winnow(this, selector, false), "not", selector);
- },
-
- filter: function (selector) {
- ///
- ///
Removes all elements from the set of matched elements that do not
- ///
pass the specified filter. This method is used to narrow down
- ///
the results of a search.
- ///
})
- ///
Part of DOM/Traversing
- ///
- ///
- ///
- ///
A function to use for filtering
- ///
- ///
-
- return this.pushStack(winnow(this, selector, true), "filter", selector);
- },
-
- is: function (selector) {
- ///
- ///
Checks the current selection against an expression and returns true,
- ///
if at least one element of the selection fits the given expression.
- ///
Does return false, if no element fits or the expression is not valid.
- ///
filter(String) is used internally, therefore all rules that apply there
- ///
apply here, too.
- ///
Part of DOM/Traversing
- ///
- ///
- ///
- ///
The expression with which to filter
- ///
-
- return !!selector && jQuery.filter(selector, this).length > 0;
- },
-
- closest: function (selectors, context) {
- ///
- ///
Get a set of elements containing the closest parent element that matches the specified selector, the starting element included.
- ///
- ///
- ///
A string containing a selector expression to match elements against.
- ///
- ///
- ///
A DOM element within which a matching element may be found. If no context is passed
- ///
in then the context of the jQuery set will be used instead.
- ///
- ///
-
- var ret = [], i, l, cur = this[0];
-
- if (jQuery.isArray(selectors)) {
- var match, selector,
- matches = {},
- level = 1;
-
- if (cur && selectors.length) {
- for (i = 0, l = selectors.length; i < l; i++) {
- selector = selectors[i];
-
- if (!matches[selector]) {
- matches[selector] = jQuery.expr.match.POS.test(selector) ?
- jQuery(selector, context || this.context) :
- selector;
- }
- }
-
- while (cur && cur.ownerDocument && cur !== context) {
- for (selector in matches) {
- match = matches[selector];
-
- if (match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match)) {
- ret.push({ selector: selector, elem: cur, level: level });
- }
- }
-
- cur = cur.parentNode;
- level++;
- }
- }
-
- return ret;
- }
-
- var pos = POS.test(selectors) ?
- jQuery(selectors, context || this.context) : null;
-
- for (i = 0, l = this.length; i < l; i++) {
- cur = this[i];
-
- while (cur) {
- if (pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors)) {
- ret.push(cur);
- break;
-
- } else {
- cur = cur.parentNode;
- if (!cur || !cur.ownerDocument || cur === context) {
- break;
- }
- }
- }
- }
-
- ret = ret.length > 1 ? jQuery.unique(ret) : ret;
-
- return this.pushStack(ret, "closest", selectors);
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function (elem) {
- ///
- ///
Searches every matched element for the object and returns
- ///
the index of the element, if found, starting with zero.
- ///
Returns -1 if the object wasn't found.
- ///
Part of Core
- ///
- ///
- ///
- ///
Object to search for
- ///
-
- if (!elem || typeof elem === "string") {
- return jQuery.inArray(this[0],
- // If it receives a string, the selector is used
- // If it receives nothing, the siblings are used
- elem ? jQuery(elem) : this.parent().children());
- }
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[0] : elem, this);
- },
-
- add: function (selector, context) {
- ///
- ///
Adds one or more Elements to the set of matched elements.
- ///
Part of DOM/Traversing
- ///
- ///
- ///
A string containing a selector expression to match additional elements against.
- ///
- ///
- ///
Add some elements rooted against the specified context.
- ///
- ///
-
- var set = typeof selector === "string" ?
- jQuery(selector, context || this.context) :
- jQuery.makeArray(selector),
- all = jQuery.merge(this.get(), set);
-
- return this.pushStack(isDisconnected(set[0]) || isDisconnected(all[0]) ?
- all :
- jQuery.unique(all));
- },
-
- andSelf: function () {
- ///
- ///
Adds the previous selection to the current selection.
- ///
- ///
-
- return this.add(this.prevObject);
- }
- });
-
- // A painfully simple check to see if an element is disconnected
- // from a document (should be improved, where feasible).
- function isDisconnected(node) {
- return !node || !node.parentNode || node.parentNode.nodeType === 11;
- }
-
- jQuery.fn.parents = function (until, selector) {
- ///
- /// Get the ancestors of each element in the current set of matched elements, optionally filtered by a selector.
- ///
- ///
- /// A string containing a selector expression to match elements against.
- ///
- ///
- return jQuery.dir(elem, "parentNode");
- };
-
- jQuery.fn.parentsUntil = function (until, selector) {
- ///
- /// Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector.
- ///
- ///
- /// A string containing a selector expression to indicate where to stop matching ancestor elements.
- ///
- ///
- return jQuery.dir(elem, "parentNode", until);
- };
-
- jQuery.each({
- parent: function (elem) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- next: function (elem) {
- return jQuery.nth(elem, 2, "nextSibling");
- },
- prev: function (elem) {
- return jQuery.nth(elem, 2, "previousSibling");
- },
- nextAll: function (elem) {
- return jQuery.dir(elem, "nextSibling");
- },
- prevAll: function (elem) {
- return jQuery.dir(elem, "previousSibling");
- },
- nextUntil: function (elem, i, until) {
- ///
- ///
Get all following siblings of each element up to but not including the element matched
- ///
by the selector.
- ///
- ///
- ///
A string containing a selector expression to indicate where to stop matching following
- ///
sibling elements.
- ///
- ///
-
- return jQuery.dir(elem, "nextSibling", until);
- },
- prevUntil: function (elem, i, until) {
- ///
- ///
Get all preceding siblings of each element up to but not including the element matched
- ///
by the selector.
- ///
- ///
- ///
A string containing a selector expression to indicate where to stop matching preceding
- ///
sibling elements.
- ///
- ///
-
- 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 jQuery.nodeName(elem, "iframe") ?
- elem.contentDocument || elem.contentWindow.document :
- jQuery.makeArray(elem.childNodes);
- }
- }, function (name, fn) {
- jQuery.fn[name] = function (until, selector) {
- var ret = jQuery.map(this, fn, until);
-
- if (!runtil.test(name)) {
- selector = until;
- }
-
- if (selector && typeof selector === "string") {
- ret = jQuery.filter(selector, ret);
- }
-
- ret = this.length > 1 ? jQuery.unique(ret) : ret;
-
- if ((this.length > 1 || rmultiselector.test(selector)) && rparentsprev.test(name)) {
- ret = ret.reverse();
- }
-
- return this.pushStack(ret, name, slice.call(arguments).join(","));
- };
- });
-
- jQuery.extend({
- filter: function (expr, elems, not) {
- if (not) {
- expr = ":not(" + expr + ")";
- }
-
- return elems.length === 1 ?
- jQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [] :
- jQuery.find.matches(expr, elems);
- },
-
- dir: function (elem, dir, until) {
- ///
- ///
This member is internal only.
- ///
- ///
-
- var matched = [],
- cur = elem[dir];
-
- while (cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery(cur).is(until))) {
- if (cur.nodeType === 1) {
- matched.push(cur);
- }
- cur = cur[dir];
- }
- return matched;
- },
-
- nth: function (cur, result, dir, elem) {
- ///
- ///
This member is internal only.
- ///
- ///
-
- result = result || 1;
- var num = 0;
-
- for (; cur; cur = cur[dir]) {
- if (cur.nodeType === 1 && ++num === result) {
- break;
- }
- }
-
- return cur;
- },
-
- sibling: function (n, elem) {
- ///
- ///
This member is internal only.
- ///
- ///
-
- var r = [];
-
- for (; n; n = n.nextSibling) {
- if (n.nodeType === 1 && n !== elem) {
- r.push(n);
- }
- }
-
- return r;
- }
- });
-
- // Implement the identical functionality for filter and not
- function winnow(elements, qualifier, keep) {
- if (jQuery.isFunction(qualifier)) {
- return jQuery.grep(elements, function (elem, i) {
- var retVal = !!qualifier.call(elem, i, elem);
- return retVal === keep;
- });
-
- } else if (qualifier.nodeType) {
- return jQuery.grep(elements, function (elem, i) {
- return (elem === qualifier) === keep;
- });
-
- } else if (typeof qualifier === "string") {
- var filtered = jQuery.grep(elements, function (elem) {
- return elem.nodeType === 1;
- });
-
- if (isSimple.test(qualifier)) {
- return jQuery.filter(qualifier, filtered, !keep);
- } else {
- qualifier = jQuery.filter(qualifier, filtered);
- }
- }
-
- return jQuery.grep(elements, function (elem, i) {
- return (jQuery.inArray(elem, qualifier) >= 0) === keep;
- });
- }
-
-
-
-
- var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
- rleadingWhitespace = /^\s+/,
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
- rtagName = /<([\w:]+)/,
- rtbody = /\s]+\/)>/g,
- wrapMap = {
- option: [1, ""],
- legend: [1, ""],
- thead: [1, "
", "
"],
- tr: [2, "
", "
"],
- td: [3, "
", "
"],
- col: [2, "
", "
"],
- area: [1, ""],
- _default: [0, "", ""]
- };
-
- wrapMap.optgroup = wrapMap.option;
- wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
- wrapMap.th = wrapMap.td;
-
- // IE can't serialize and ' );
-
- iframe_doc.close();
-
- // Update the Iframe's hash, for great justice.
- iframe.location.hash = hash;
- }
- };
-
- })();
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- return self;
- })();
-
-})(jQuery,this);
-/*
-* "page" plugin
-*/
-
-(function( $, undefined ) {
-
-$.widget( "mobile.page", $.mobile.widget, {
- options: {
- theme: "c",
- domCache: false,
- keepNativeDefault: ":jqmData(role='none'), :jqmData(role='nojs')"
- },
-
- _create: function() {
-
- this._trigger( "beforecreate" );
-
- this.element
- .attr( "tabindex", "0" )
- .addClass( "ui-page ui-body-" + this.options.theme );
- },
-
- keepNativeSelector: function() {
- var options = this.options,
- keepNativeDefined = options.keepNative && $.trim(options.keepNative);
-
- if( keepNativeDefined && options.keepNative !== options.keepNativeDefault ){
- return [options.keepNative, options.keepNativeDefault].join(", ");
- }
-
- return options.keepNativeDefault;
- }
-});
-})( jQuery );
-/*
-* "core" - The base file for jQm
-*/
-
-(function( $, window, undefined ) {
-
- var nsNormalizeDict = {};
-
- // jQuery.mobile configurable options
- $.extend( $.mobile, {
-
- // Namespace used framework-wide for data-attrs. Default is no namespace
- ns: "",
-
- // Define the url parameter used for referencing widget-generated sub-pages.
- // Translates to to example.html&ui-page=subpageIdentifier
- // hash segment before &ui-page= is used to make Ajax request
- subPageUrlKey: "ui-page",
-
- // Class assigned to page currently in view, and during transitions
- activePageClass: "ui-page-active",
-
- // Class used for "active" button state, from CSS framework
- activeBtnClass: "ui-btn-active",
-
- // Automatically handle clicks and form submissions through Ajax, when same-domain
- ajaxEnabled: true,
-
- // Automatically load and show pages based on location.hash
- hashListeningEnabled: true,
-
- // disable to prevent jquery from bothering with links
- linkBindingEnabled: true,
-
- // Set default page transition - 'none' for no transitions
- defaultPageTransition: "slide",
-
- // Minimum scroll distance that will be remembered when returning to a page
- minScrollBack: 250,
-
- // Set default dialog transition - 'none' for no transitions
- defaultDialogTransition: "pop",
-
- // Show loading message during Ajax requests
- // if false, message will not appear, but loading classes will still be toggled on html el
- loadingMessage: "loading",
-
- // Error response message - appears when an Ajax page request fails
- pageLoadErrorMessage: "Error Loading Page",
-
- //automatically initialize the DOM when it's ready
- autoInitializePage: true,
-
- pushStateEnabled: true,
-
- // turn of binding to the native orientationchange due to android orientation behavior
- orientationChangeEnabled: true,
-
- // Support conditions that must be met in order to proceed
- // default enhanced qualifications are media query support OR IE 7+
- gradeA: function(){
- return $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7;
- },
-
- // TODO might be useful upstream in jquery itself ?
- keyCode: {
- ALT: 18,
- BACKSPACE: 8,
- CAPS_LOCK: 20,
- COMMA: 188,
- COMMAND: 91,
- COMMAND_LEFT: 91, // COMMAND
- COMMAND_RIGHT: 93,
- CONTROL: 17,
- DELETE: 46,
- DOWN: 40,
- END: 35,
- ENTER: 13,
- ESCAPE: 27,
- HOME: 36,
- INSERT: 45,
- LEFT: 37,
- MENU: 93, // COMMAND_RIGHT
- NUMPAD_ADD: 107,
- NUMPAD_DECIMAL: 110,
- NUMPAD_DIVIDE: 111,
- NUMPAD_ENTER: 108,
- NUMPAD_MULTIPLY: 106,
- NUMPAD_SUBTRACT: 109,
- PAGE_DOWN: 34,
- PAGE_UP: 33,
- PERIOD: 190,
- RIGHT: 39,
- SHIFT: 16,
- SPACE: 32,
- TAB: 9,
- UP: 38,
- WINDOWS: 91 // COMMAND
- },
-
- // Scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value
- silentScroll: function( ypos ) {
- if ( $.type( ypos ) !== "number" ) {
- ypos = $.mobile.defaultHomeScroll;
- }
-
- // prevent scrollstart and scrollstop events
- $.event.special.scrollstart.enabled = false;
-
- setTimeout(function() {
- window.scrollTo( 0, ypos );
- $( document ).trigger( "silentscroll", { x: 0, y: ypos });
- }, 20 );
-
- setTimeout(function() {
- $.event.special.scrollstart.enabled = true;
- }, 150 );
- },
-
- // Expose our cache for testing purposes.
- nsNormalizeDict: nsNormalizeDict,
-
- // Take a data attribute property, prepend the namespace
- // and then camel case the attribute string. Add the result
- // to our nsNormalizeDict so we don't have to do this again.
- nsNormalize: function( prop ) {
- if ( !prop ) {
- return;
- }
-
- return nsNormalizeDict[ prop ] || ( nsNormalizeDict[ prop ] = $.camelCase( $.mobile.ns + prop ) );
- },
-
- getInheritedTheme: function( el, defaultTheme ) {
-
- // Find the closest parent with a theme class on it. Note that
- // we are not using $.fn.closest() on purpose here because this
- // method gets called quite a bit and we need it to be as fast
- // as possible.
-
- var e = el[ 0 ],
- ltr = "",
- re = /ui-(bar|body)-([a-z])\b/,
- c, m;
-
- while ( e ) {
- var c = e.className || "";
- if ( ( m = re.exec( c ) ) && ( ltr = m[ 2 ] ) ) {
- // We found a parent with a theme class
- // on it so bail from this loop.
- break;
- }
- e = e.parentNode;
- }
-
- // Return the theme letter we found, if none, return the
- // specified default.
-
- return ltr || defaultTheme || "a";
- }
- });
-
- // Mobile version of data and removeData and hasData methods
- // ensures all data is set and retrieved using jQuery Mobile's data namespace
- $.fn.jqmData = function( prop, value ) {
- var result;
- if ( typeof prop != "undefined" ) {
- result = this.data( prop ? $.mobile.nsNormalize( prop ) : prop, value );
- }
- return result;
- };
-
- $.jqmData = function( elem, prop, value ) {
- var result;
- if ( typeof prop != "undefined" ) {
- result = $.data( elem, prop ? $.mobile.nsNormalize( prop ) : prop, value );
- }
- return result;
- };
-
- $.fn.jqmRemoveData = function( prop ) {
- return this.removeData( $.mobile.nsNormalize( prop ) );
- };
-
- $.jqmRemoveData = function( elem, prop ) {
- return $.removeData( elem, $.mobile.nsNormalize( prop ) );
- };
-
- $.fn.removeWithDependents = function() {
- $.removeWithDependents( this );
- };
-
- $.removeWithDependents = function( elem ) {
- var $elem = $( elem );
-
- ( $elem.jqmData('dependents') || $() ).remove();
- $elem.remove();
- };
-
- $.fn.addDependents = function( newDependents ) {
- $.addDependents( $(this), newDependents );
- };
-
- $.addDependents = function( elem, newDependents ) {
- var dependents = $(elem).jqmData( 'dependents' ) || $();
-
- $(elem).jqmData( 'dependents', $.merge(dependents, newDependents) );
- };
-
- // note that this helper doesn't attempt to handle the callback
- // or setting of an html elements text, its only purpose is
- // to return the html encoded version of the text in all cases. (thus the name)
- $.fn.getEncodedText = function() {
- return $( "" ).text( $(this).text() ).html();
- };
-
- // Monkey-patching Sizzle to filter the :jqmData selector
- var oldFind = $.find,
- jqmDataRE = /:jqmData\(([^)]*)\)/g;
-
- $.find = function( selector, context, ret, extra ) {
- selector = selector.replace( jqmDataRE, "[data-" + ( $.mobile.ns || "" ) + "$1]" );
-
- return oldFind.call( this, selector, context, ret, extra );
- };
-
- $.extend( $.find, oldFind );
-
- $.find.matches = function( expr, set ) {
- return $.find( expr, null, null, set );
- };
-
- $.find.matchesSelector = function( node, expr ) {
- return $.find( expr, null, null, [ node ] ).length > 0;
- };
-})( jQuery, this );
-
-/*
-* core utilities for auto ajax navigation, base tag mgmt,
-*/
-
-( function( $, undefined ) {
-
- //define vars for interal use
- var $window = $( window ),
- $html = $( 'html' ),
- $head = $( 'head' ),
-
- //url path helpers for use in relative url management
- path = {
-
- // This scary looking regular expression parses an absolute URL or its relative
- // variants (protocol, site, document, query, and hash), into the various
- // components (protocol, host, path, query, fragment, etc that make up the
- // URL as well as some other commonly used sub-parts. When used with RegExp.exec()
- // or String.match, it parses the URL into a results array that looks like this:
- //
- // [0]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content
- // [1]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread
- // [2]: http://jblas:password@mycompany.com:8080/mail/inbox
- // [3]: http://jblas:password@mycompany.com:8080
- // [4]: http:
- // [5]: //
- // [6]: jblas:password@mycompany.com:8080
- // [7]: jblas:password
- // [8]: jblas
- // [9]: password
- // [10]: mycompany.com:8080
- // [11]: mycompany.com
- // [12]: 8080
- // [13]: /mail/inbox
- // [14]: /mail/
- // [15]: inbox
- // [16]: ?msg=1234&type=unread
- // [17]: #msg-content
- //
- urlParseRE: /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
-
- //Parse a URL into a structure that allows easy access to
- //all of the URL components by name.
- parseUrl: function( url ) {
- // If we're passed an object, we'll assume that it is
- // a parsed url object and just return it back to the caller.
- if ( $.type( url ) === "object" ) {
- return url;
- }
-
- var matches = path.urlParseRE.exec( url || "" ) || [];
-
- // Create an object that allows the caller to access the sub-matches
- // by name. Note that IE returns an empty string instead of undefined,
- // like all other browsers do, so we normalize everything so its consistent
- // no matter what browser we're running on.
- return {
- href: matches[ 0 ] || "",
- hrefNoHash: matches[ 1 ] || "",
- hrefNoSearch: matches[ 2 ] || "",
- domain: matches[ 3 ] || "",
- protocol: matches[ 4 ] || "",
- doubleSlash: matches[ 5 ] || "",
- authority: matches[ 6 ] || "",
- username: matches[ 8 ] || "",
- password: matches[ 9 ] || "",
- host: matches[ 10 ] || "",
- hostname: matches[ 11 ] || "",
- port: matches[ 12 ] || "",
- pathname: matches[ 13 ] || "",
- directory: matches[ 14 ] || "",
- filename: matches[ 15 ] || "",
- search: matches[ 16 ] || "",
- hash: matches[ 17 ] || ""
- };
- },
-
- //Turn relPath into an asbolute path. absPath is
- //an optional absolute path which describes what
- //relPath is relative to.
- makePathAbsolute: function( relPath, absPath ) {
- if ( relPath && relPath.charAt( 0 ) === "/" ) {
- return relPath;
- }
-
- relPath = relPath || "";
- absPath = absPath ? absPath.replace( /^\/|(\/[^\/]*|[^\/]+)$/g, "" ) : "";
-
- var absStack = absPath ? absPath.split( "/" ) : [],
- relStack = relPath.split( "/" );
- for ( var i = 0; i < relStack.length; i++ ) {
- var d = relStack[ i ];
- switch ( d ) {
- case ".":
- break;
- case "..":
- if ( absStack.length ) {
- absStack.pop();
- }
- break;
- default:
- absStack.push( d );
- break;
- }
- }
- return "/" + absStack.join( "/" );
- },
-
- //Returns true if both urls have the same domain.
- isSameDomain: function( absUrl1, absUrl2 ) {
- return path.parseUrl( absUrl1 ).domain === path.parseUrl( absUrl2 ).domain;
- },
-
- //Returns true for any relative variant.
- isRelativeUrl: function( url ) {
- // All relative Url variants have one thing in common, no protocol.
- return path.parseUrl( url ).protocol === "";
- },
-
- //Returns true for an absolute url.
- isAbsoluteUrl: function( url ) {
- return path.parseUrl( url ).protocol !== "";
- },
-
- //Turn the specified realtive URL into an absolute one. This function
- //can handle all relative variants (protocol, site, document, query, fragment).
- makeUrlAbsolute: function( relUrl, absUrl ) {
- if ( !path.isRelativeUrl( relUrl ) ) {
- return relUrl;
- }
-
- var relObj = path.parseUrl( relUrl ),
- absObj = path.parseUrl( absUrl ),
- protocol = relObj.protocol || absObj.protocol,
- doubleSlash = relObj.protocol ? relObj.doubleSlash : ( relObj.doubleSlash || absObj.doubleSlash ),
- authority = relObj.authority || absObj.authority,
- hasPath = relObj.pathname !== "",
- pathname = path.makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname ),
- search = relObj.search || ( !hasPath && absObj.search ) || "",
- hash = relObj.hash;
-
- return protocol + doubleSlash + authority + pathname + search + hash;
- },
-
- //Add search (aka query) params to the specified url.
- addSearchParams: function( url, params ) {
- var u = path.parseUrl( url ),
- p = ( typeof params === "object" ) ? $.param( params ) : params,
- s = u.search || "?";
- return u.hrefNoSearch + s + ( s.charAt( s.length - 1 ) !== "?" ? "&" : "" ) + p + ( u.hash || "" );
- },
-
- convertUrlToDataUrl: function( absUrl ) {
- var u = path.parseUrl( absUrl );
- if ( path.isEmbeddedPage( u ) ) {
- // For embedded pages, remove the dialog hash key as in getFilePath(),
- // otherwise the Data Url won't match the id of the embedded Page.
- return u.hash.split( dialogHashKey )[0].replace( /^#/, "" );
- } else if ( path.isSameDomain( u, documentBase ) ) {
- return u.hrefNoHash.replace( documentBase.domain, "" );
- }
- return absUrl;
- },
-
- //get path from current hash, or from a file path
- get: function( newPath ) {
- if( newPath === undefined ) {
- newPath = location.hash;
- }
- return path.stripHash( newPath ).replace( /[^\/]*\.[^\/*]+$/, '' );
- },
-
- //return the substring of a filepath before the sub-page key, for making a server request
- getFilePath: function( path ) {
- var splitkey = '&' + $.mobile.subPageUrlKey;
- return path && path.split( splitkey )[0].split( dialogHashKey )[0];
- },
-
- //set location hash to path
- set: function( path ) {
- location.hash = path;
- },
-
- //test if a given url (string) is a path
- //NOTE might be exceptionally naive
- isPath: function( url ) {
- return ( /\// ).test( url );
- },
-
- //return a url path with the window's location protocol/hostname/pathname removed
- clean: function( url ) {
- return url.replace( documentBase.domain, "" );
- },
-
- //just return the url without an initial #
- stripHash: function( url ) {
- return url.replace( /^#/, "" );
- },
-
- //remove the preceding hash, any query params, and dialog notations
- cleanHash: function( hash ) {
- return path.stripHash( hash.replace( /\?.*$/, "" ).replace( dialogHashKey, "" ) );
- },
-
- //check whether a url is referencing the same domain, or an external domain or different protocol
- //could be mailto, etc
- isExternal: function( url ) {
- var u = path.parseUrl( url );
- return u.protocol && u.domain !== documentUrl.domain ? true : false;
- },
-
- hasProtocol: function( url ) {
- return ( /^(:?\w+:)/ ).test( url );
- },
-
- //check if the specified url refers to the first page in the main application document.
- isFirstPageUrl: function( url ) {
- // We only deal with absolute paths.
- var u = path.parseUrl( path.makeUrlAbsolute( url, documentBase ) ),
-
- // Does the url have the same path as the document?
- samePath = u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ),
-
- // Get the first page element.
- fp = $.mobile.firstPage,
-
- // Get the id of the first page element if it has one.
- fpId = fp && fp[0] ? fp[0].id : undefined;
-
- // The url refers to the first page if the path matches the document and
- // it either has no hash value, or the hash is exactly equal to the id of the
- // first page element.
- return samePath && ( !u.hash || u.hash === "#" || ( fpId && u.hash.replace( /^#/, "" ) === fpId ) );
- },
-
- isEmbeddedPage: function( url ) {
- var u = path.parseUrl( url );
-
- //if the path is absolute, then we need to compare the url against
- //both the documentUrl and the documentBase. The main reason for this
- //is that links embedded within external documents will refer to the
- //application document, whereas links embedded within the application
- //document will be resolved against the document base.
- if ( u.protocol !== "" ) {
- return ( u.hash && ( u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ) ) );
- }
- return (/^#/).test( u.href );
- }
- },
-
- //will be defined when a link is clicked and given an active class
- $activeClickedLink = null,
-
- //urlHistory is purely here to make guesses at whether the back or forward button was clicked
- //and provide an appropriate transition
- urlHistory = {
- // Array of pages that are visited during a single page load.
- // Each has a url and optional transition, title, and pageUrl (which represents the file path, in cases where URL is obscured, such as dialogs)
- stack: [],
-
- //maintain an index number for the active page in the stack
- activeIndex: 0,
-
- //get active
- getActive: function() {
- return urlHistory.stack[ urlHistory.activeIndex ];
- },
-
- getPrev: function() {
- return urlHistory.stack[ urlHistory.activeIndex - 1 ];
- },
-
- getNext: function() {
- return urlHistory.stack[ urlHistory.activeIndex + 1 ];
- },
-
- // addNew is used whenever a new page is added
- addNew: function( url, transition, title, pageUrl, role ) {
- //if there's forward history, wipe it
- if( urlHistory.getNext() ) {
- urlHistory.clearForward();
- }
-
- urlHistory.stack.push( {url : url, transition: transition, title: title, pageUrl: pageUrl, role: role } );
-
- urlHistory.activeIndex = urlHistory.stack.length - 1;
- },
-
- //wipe urls ahead of active index
- clearForward: function() {
- urlHistory.stack = urlHistory.stack.slice( 0, urlHistory.activeIndex + 1 );
- },
-
- directHashChange: function( opts ) {
- var back , forward, newActiveIndex, prev = this.getActive();
-
- // check if url isp in history and if it's ahead or behind current page
- $.each( urlHistory.stack, function( i, historyEntry ) {
-
- //if the url is in the stack, it's a forward or a back
- if( opts.currentUrl === historyEntry.url ) {
- //define back and forward by whether url is older or newer than current page
- back = i < urlHistory.activeIndex;
- forward = !back;
- newActiveIndex = i;
- }
- });
-
- // save new page index, null check to prevent falsey 0 result
- this.activeIndex = newActiveIndex !== undefined ? newActiveIndex : this.activeIndex;
-
- if( back ) {
- ( opts.either || opts.isBack )( true );
- } else if( forward ) {
- ( opts.either || opts.isForward )( false );
- }
- },
-
- //disable hashchange event listener internally to ignore one change
- //toggled internally when location.hash is updated to match the url of a successful page load
- ignoreNextHashChange: false
- },
-
- //define first selector to receive focus when a page is shown
- focusable = "[tabindex],a,button:visible,select:visible,input",
-
- //queue to hold simultanious page transitions
- pageTransitionQueue = [],
-
- //indicates whether or not page is in process of transitioning
- isPageTransitioning = false,
-
- //nonsense hash change key for dialogs, so they create a history entry
- dialogHashKey = "&ui-state=dialog",
-
- //existing base tag?
- $base = $head.children( "base" ),
-
- //tuck away the original document URL minus any fragment.
- documentUrl = path.parseUrl( location.href ),
-
- //if the document has an embedded base tag, documentBase is set to its
- //initial value. If a base tag does not exist, then we default to the documentUrl.
- documentBase = $base.length ? path.parseUrl( path.makeUrlAbsolute( $base.attr( "href" ), documentUrl.href ) ) : documentUrl,
-
- //cache the comparison once.
- documentBaseDiffers = ( documentUrl.hrefNoHash !== documentBase.hrefNoHash );
-
- //base element management, defined depending on dynamic base tag support
- var base = $.support.dynamicBaseTag ? {
-
- //define base element, for use in routing asset urls that are referenced in Ajax-requested markup
- element: ( $base.length ? $base : $( "", { href: documentBase.hrefNoHash } ).prependTo( $head ) ),
-
- //set the generated BASE element's href attribute to a new page's base path
- set: function( href ) {
- base.element.attr( "href", path.makeUrlAbsolute( href, documentBase ) );
- },
-
- //set the generated BASE element's href attribute to a new page's base path
- reset: function() {
- base.element.attr( "href", documentBase.hrefNoHash );
- }
-
- } : undefined;
-
-/*
- internal utility functions
---------------------------------------*/
-
-
- //direct focus to the page title, or otherwise first focusable element
- function reFocus( page ) {
- var pageTitle = page.find( ".ui-title:eq(0)" );
-
- if( pageTitle.length ) {
- pageTitle.focus();
- }
- else{
- page.focus();
- }
- }
-
- //remove active classes after page transition or error
- function removeActiveLinkClass( forceRemoval ) {
- if( !!$activeClickedLink && ( !$activeClickedLink.closest( '.ui-page-active' ).length || forceRemoval ) ) {
- $activeClickedLink.removeClass( $.mobile.activeBtnClass );
- }
- $activeClickedLink = null;
- }
-
- function releasePageTransitionLock() {
- isPageTransitioning = false;
- if( pageTransitionQueue.length > 0 ) {
- $.mobile.changePage.apply( null, pageTransitionQueue.pop() );
- }
- }
-
- // Save the last scroll distance per page, before it is hidden
- var setLastScrollEnabled = true,
- firstScrollElem, getScrollElem, setLastScroll, delayedSetLastScroll;
-
- getScrollElem = function() {
- var scrollElem = $window, activePage,
- touchOverflow = $.support.touchOverflow && $.mobile.touchOverflowEnabled;
-
- if( touchOverflow ){
- activePage = $( ".ui-page-active" );
- scrollElem = activePage.is( ".ui-native-fixed" ) ? activePage.find( ".ui-content" ) : activePage;
- }
-
- return scrollElem;
- };
-
- setLastScroll = function( scrollElem ) {
- // this barrier prevents setting the scroll value based on the browser
- // scrolling the window based on a hashchange
- if( !setLastScrollEnabled ) {
- return;
- }
-
- var active = $.mobile.urlHistory.getActive();
-
- if( active ) {
- var lastScroll = scrollElem && scrollElem.scrollTop();
-
- // Set active page's lastScroll prop.
- // If the location we're scrolling to is less than minScrollBack, let it go.
- active.lastScroll = lastScroll < $.mobile.minScrollBack ? $.mobile.defaultHomeScroll : lastScroll;
- }
- };
-
- // bind to scrollstop to gather scroll position. The delay allows for the hashchange
- // event to fire and disable scroll recording in the case where the browser scrolls
- // to the hash targets location (sometimes the top of the page). once pagechange fires
- // getLastScroll is again permitted to operate
- delayedSetLastScroll = function() {
- setTimeout( setLastScroll, 100, $(this) );
- };
-
- // disable an scroll setting when a hashchange has been fired, this only works
- // because the recording of the scroll position is delayed for 100ms after
- // the browser might have changed the position because of the hashchange
- $window.bind( $.support.pushState ? "popstate" : "hashchange", function() {
- setLastScrollEnabled = false;
- });
-
- // handle initial hashchange from chrome :(
- $window.one( $.support.pushState ? "popstate" : "hashchange", function() {
- setLastScrollEnabled = true;
- });
-
- // wait until the mobile page container has been determined to bind to pagechange
- $window.one( "pagecontainercreate", function(){
- // once the page has changed, re-enable the scroll recording
- $.mobile.pageContainer.bind( "pagechange", function() {
- var scrollElem = getScrollElem();
-
- setLastScrollEnabled = true;
-
- // remove any binding that previously existed on the get scroll
- // which may or may not be different than the scroll element determined for
- // this page previously
- scrollElem.unbind( "scrollstop", delayedSetLastScroll );
-
- // determine and bind to the current scoll element which may be the window
- // or in the case of touch overflow the element with touch overflow
- scrollElem.bind( "scrollstop", delayedSetLastScroll );
- });
- });
-
- // bind to scrollstop for the first page as "pagechange" won't be fired in that case
- getScrollElem().bind( "scrollstop", delayedSetLastScroll );
-
- // Make the iOS clock quick-scroll work again if we're using native overflow scrolling
- /*
- if( $.support.touchOverflow ){
- if( $.mobile.touchOverflowEnabled ){
- $( window ).bind( "scrollstop", function(){
- if( $( this ).scrollTop() === 0 ){
- $.mobile.activePage.scrollTop( 0 );
- }
- });
- }
- }
- */
-
- //function for transitioning between two existing pages
- function transitionPages( toPage, fromPage, transition, reverse ) {
-
- //get current scroll distance
- var active = $.mobile.urlHistory.getActive(),
- touchOverflow = $.support.touchOverflow && $.mobile.touchOverflowEnabled,
- toScroll = active.lastScroll || ( touchOverflow ? 0 : $.mobile.defaultHomeScroll ),
- screenHeight = getScreenHeight();
-
- // Scroll to top, hide addr bar
- window.scrollTo( 0, $.mobile.defaultHomeScroll );
-
- if( fromPage ) {
- //trigger before show/hide events
- fromPage.data( "page" )._trigger( "beforehide", null, { nextPage: toPage } );
- }
-
- if( !touchOverflow){
- toPage.height( screenHeight + toScroll );
- }
-
- toPage.data( "page" )._trigger( "beforeshow", null, { prevPage: fromPage || $( "" ) } );
-
- //clear page loader
- $.mobile.hidePageLoadingMsg();
-
- if( touchOverflow && toScroll ){
-
- toPage.addClass( "ui-mobile-pre-transition" );
- // Send focus to page as it is now display: block
- reFocus( toPage );
-
- //set page's scrollTop to remembered distance
- if( toPage.is( ".ui-native-fixed" ) ){
- toPage.find( ".ui-content" ).scrollTop( toScroll );
- }
- else{
- toPage.scrollTop( toScroll );
- }
- }
-
- //find the transition handler for the specified transition. If there
- //isn't one in our transitionHandlers dictionary, use the default one.
- //call the handler immediately to kick-off the transition.
- var th = $.mobile.transitionHandlers[transition || "none"] || $.mobile.defaultTransitionHandler,
- promise = th( transition, reverse, toPage, fromPage );
-
- promise.done(function() {
- //reset toPage height back
- if( !touchOverflow ){
- toPage.height( "" );
- // Send focus to the newly shown page
- reFocus( toPage );
- }
-
- // Jump to top or prev scroll, sometimes on iOS the page has not rendered yet.
- if( !touchOverflow ){
- $.mobile.silentScroll( toScroll );
- }
-
- //trigger show/hide events
- if( fromPage ) {
- if( !touchOverflow ){
- fromPage.height( "" );
- }
-
- fromPage.data( "page" )._trigger( "hide", null, { nextPage: toPage } );
- }
-
- //trigger pageshow, define prevPage as either fromPage or empty jQuery obj
- toPage.data( "page" )._trigger( "show", null, { prevPage: fromPage || $( "" ) } );
- });
-
- return promise;
- }
-
- //simply set the active page's minimum height to screen height, depending on orientation
- function getScreenHeight(){
- var orientation = $.event.special.orientationchange.orientation(),
- port = orientation === "portrait",
- winMin = port ? 480 : 320,
- screenHeight = port ? screen.availHeight : screen.availWidth,
- winHeight = Math.max( winMin, $( window ).height() ),
- pageMin = Math.min( screenHeight, winHeight );
-
- return pageMin;
- }
-
- $.mobile.getScreenHeight = getScreenHeight;
-
- //simply set the active page's minimum height to screen height, depending on orientation
- function resetActivePageHeight(){
- // Don't apply this height in touch overflow enabled mode
- if( $.support.touchOverflow && $.mobile.touchOverflowEnabled ){
- return;
- }
- $( "." + $.mobile.activePageClass ).css( "min-height", getScreenHeight() );
- }
-
- //shared page enhancements
- function enhancePage( $page, role ) {
- // If a role was specified, make sure the data-role attribute
- // on the page element is in sync.
- if( role ) {
- $page.attr( "data-" + $.mobile.ns + "role", role );
- }
-
- //run page plugin
- $page.page();
- }
-
-/* exposed $.mobile methods */
-
- //animation complete callback
- $.fn.animationComplete = function( callback ) {
- if( $.support.cssTransitions ) {
- return $( this ).one( 'webkitAnimationEnd', callback );
- }
- else{
- // defer execution for consistency between webkit/non webkit
- setTimeout( callback, 0 );
- return $( this );
- }
- };
-
- //expose path object on $.mobile
- $.mobile.path = path;
-
- //expose base object on $.mobile
- $.mobile.base = base;
-
- //history stack
- $.mobile.urlHistory = urlHistory;
-
- $.mobile.dialogHashKey = dialogHashKey;
-
- //default non-animation transition handler
- $.mobile.noneTransitionHandler = function( name, reverse, $toPage, $fromPage ) {
- if ( $fromPage ) {
- $fromPage.removeClass( $.mobile.activePageClass );
- }
- $toPage.addClass( $.mobile.activePageClass );
-
- return $.Deferred().resolve( name, reverse, $toPage, $fromPage ).promise();
- };
-
- //default handler for unknown transitions
- $.mobile.defaultTransitionHandler = $.mobile.noneTransitionHandler;
-
- //transition handler dictionary for 3rd party transitions
- $.mobile.transitionHandlers = {
- none: $.mobile.defaultTransitionHandler
- };
-
- //enable cross-domain page support
- $.mobile.allowCrossDomainPages = false;
-
- //return the original document url
- $.mobile.getDocumentUrl = function(asParsedObject) {
- return asParsedObject ? $.extend( {}, documentUrl ) : documentUrl.href;
- };
-
- //return the original document base url
- $.mobile.getDocumentBase = function(asParsedObject) {
- return asParsedObject ? $.extend( {}, documentBase ) : documentBase.href;
- };
-
- $.mobile._bindPageRemove = function() {
- var page = $(this);
-
- // when dom caching is not enabled or the page is embedded bind to remove the page on hide
- if( !page.data("page").options.domCache
- && page.is(":jqmData(external-page='true')") ) {
-
- page.bind( 'pagehide.remove', function() {
- var $this = $( this ),
- prEvent = new $.Event( "pageremove" );
-
- $this.trigger( prEvent );
-
- if( !prEvent.isDefaultPrevented() ){
- $this.removeWithDependents();
- }
- });
- }
- };
-
- // Load a page into the DOM.
- $.mobile.loadPage = function( url, options ) {
- // This function uses deferred notifications to let callers
- // know when the page is done loading, or if an error has occurred.
- var deferred = $.Deferred(),
-
- // The default loadPage options with overrides specified by
- // the caller.
- settings = $.extend( {}, $.mobile.loadPage.defaults, options ),
-
- // The DOM element for the page after it has been loaded.
- page = null,
-
- // If the reloadPage option is true, and the page is already
- // in the DOM, dupCachedPage will be set to the page element
- // so that it can be removed after the new version of the
- // page is loaded off the network.
- dupCachedPage = null,
-
- // determine the current base url
- findBaseWithDefault = function(){
- var closestBase = ( $.mobile.activePage && getClosestBaseUrl( $.mobile.activePage ) );
- return closestBase || documentBase.hrefNoHash;
- },
-
- // The absolute version of the URL passed into the function. This
- // version of the URL may contain dialog/subpage params in it.
- absUrl = path.makeUrlAbsolute( url, findBaseWithDefault() );
-
-
- // If the caller provided data, and we're using "get" request,
- // append the data to the URL.
- if ( settings.data && settings.type === "get" ) {
- absUrl = path.addSearchParams( absUrl, settings.data );
- settings.data = undefined;
- }
-
- // If the caller is using a "post" request, reloadPage must be true
- if( settings.data && settings.type === "post" ){
- settings.reloadPage = true;
- }
-
- // The absolute version of the URL minus any dialog/subpage params.
- // In otherwords the real URL of the page to be loaded.
- var fileUrl = path.getFilePath( absUrl ),
-
- // The version of the Url actually stored in the data-url attribute of
- // the page. For embedded pages, it is just the id of the page. For pages
- // within the same domain as the document base, it is the site relative
- // path. For cross-domain pages (Phone Gap only) the entire absolute Url
- // used to load the page.
- dataUrl = path.convertUrlToDataUrl( absUrl );
-
- // Make sure we have a pageContainer to work with.
- settings.pageContainer = settings.pageContainer || $.mobile.pageContainer;
-
- // Check to see if the page already exists in the DOM.
- page = settings.pageContainer.children( ":jqmData(url='" + dataUrl + "')" );
-
- // If we failed to find the page, check to see if the url is a
- // reference to an embedded page. If so, it may have been dynamically
- // injected by a developer, in which case it would be lacking a data-url
- // attribute and in need of enhancement.
- if ( page.length === 0 && dataUrl && !path.isPath( dataUrl ) ) {
- page = settings.pageContainer.children( "#" + dataUrl )
- .attr( "data-" + $.mobile.ns + "url", dataUrl );
- }
-
- // If we failed to find a page in the DOM, check the URL to see if it
- // refers to the first page in the application. If it isn't a reference
- // to the first page and refers to non-existent embedded page, error out.
- if ( page.length === 0 ) {
- if ( $.mobile.firstPage && path.isFirstPageUrl( fileUrl ) ) {
- // Check to make sure our cached-first-page is actually
- // in the DOM. Some user deployed apps are pruning the first
- // page from the DOM for various reasons, we check for this
- // case here because we don't want a first-page with an id
- // falling through to the non-existent embedded page error
- // case. If the first-page is not in the DOM, then we let
- // things fall through to the ajax loading code below so
- // that it gets reloaded.
- if ( $.mobile.firstPage.parent().length ) {
- page = $( $.mobile.firstPage );
- }
- } else if ( path.isEmbeddedPage( fileUrl ) ) {
- deferred.reject( absUrl, options );
- return deferred.promise();
- }
- }
-
- // Reset base to the default document base.
- if ( base ) {
- base.reset();
- }
-
- // If the page we are interested in is already in the DOM,
- // and the caller did not indicate that we should force a
- // reload of the file, we are done. Otherwise, track the
- // existing page as a duplicated.
- if ( page.length ) {
- if ( !settings.reloadPage ) {
- enhancePage( page, settings.role );
- deferred.resolve( absUrl, options, page );
- return deferred.promise();
- }
- dupCachedPage = page;
- }
-
- var mpc = settings.pageContainer,
- pblEvent = new $.Event( "pagebeforeload" ),
- triggerData = { url: url, absUrl: absUrl, dataUrl: dataUrl, deferred: deferred, options: settings };
-
- // Let listeners know we're about to load a page.
- mpc.trigger( pblEvent, triggerData );
-
- // If the default behavior is prevented, stop here!
- if( pblEvent.isDefaultPrevented() ){
- return deferred.promise();
- }
-
- if ( settings.showLoadMsg ) {
-
- // This configurable timeout allows cached pages a brief delay to load without showing a message
- var loadMsgDelay = setTimeout(function(){
- $.mobile.showPageLoadingMsg();
- }, settings.loadMsgDelay ),
-
- // Shared logic for clearing timeout and removing message.
- hideMsg = function(){
-
- // Stop message show timer
- clearTimeout( loadMsgDelay );
-
- // Hide loading message
- $.mobile.hidePageLoadingMsg();
- };
- }
-
- if ( !( $.mobile.allowCrossDomainPages || path.isSameDomain( documentUrl, absUrl ) ) ) {
- deferred.reject( absUrl, options );
- } else {
- // Load the new page.
- $.ajax({
- url: fileUrl,
- type: settings.type,
- data: settings.data,
- dataType: "html",
- success: function( html, textStatus, xhr ) {
- //pre-parse html to check for a data-url,
- //use it as the new fileUrl, base path, etc
- var all = $( "" ),
-
- //page title regexp
- newPageTitle = html.match( /]*>([^<]*)/ ) && RegExp.$1,
-
- // TODO handle dialogs again
- pageElemRegex = new RegExp( "(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>)" ),
- dataUrlRegex = new RegExp( "\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?" );
-
-
- // data-url must be provided for the base tag so resource requests can be directed to the
- // correct url. loading into a temprorary element makes these requests immediately
- if( pageElemRegex.test( html )
- && RegExp.$1
- && dataUrlRegex.test( RegExp.$1 )
- && RegExp.$1 ) {
- url = fileUrl = path.getFilePath( RegExp.$1 );
- }
-
- if ( base ) {
- base.set( fileUrl );
- }
-
- //workaround to allow scripts to execute when included in page divs
- all.get( 0 ).innerHTML = html;
- page = all.find( ":jqmData(role='page'), :jqmData(role='dialog')" ).first();
-
- //if page elem couldn't be found, create one and insert the body element's contents
- if( !page.length ){
- page = $( "
" ).text();
- }
- page.jqmData( "title", newPageTitle );
- }
-
- //rewrite src and href attrs to use a base url
- if( !$.support.dynamicBaseTag ) {
- var newPath = path.get( fileUrl );
- page.find( "[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]" ).each(function() {
- var thisAttr = $( this ).is( '[href]' ) ? 'href' :
- $(this).is('[src]') ? 'src' : 'action',
- thisUrl = $( this ).attr( thisAttr );
-
- // XXX_jblas: We need to fix this so that it removes the document
- // base URL, and then prepends with the new page URL.
- //if full path exists and is same, chop it - helps IE out
- thisUrl = thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' );
-
- if( !/^(\w+:|#|\/)/.test( thisUrl ) ) {
- $( this ).attr( thisAttr, newPath + thisUrl );
- }
- });
- }
-
- //append to page and enhance
- // TODO taging a page with external to make sure that embedded pages aren't removed
- // by the various page handling code is bad. Having page handling code in many
- // places is bad. Solutions post 1.0
- page
- .attr( "data-" + $.mobile.ns + "url", path.convertUrlToDataUrl( fileUrl ) )
- .attr( "data-" + $.mobile.ns + "external-page", true )
- .appendTo( settings.pageContainer );
-
- // wait for page creation to leverage options defined on widget
- page.one( 'pagecreate', $.mobile._bindPageRemove );
-
- enhancePage( page, settings.role );
-
- // Enhancing the page may result in new dialogs/sub pages being inserted
- // into the DOM. If the original absUrl refers to a sub-page, that is the
- // real page we are interested in.
- if ( absUrl.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ) {
- page = settings.pageContainer.children( ":jqmData(url='" + dataUrl + "')" );
- }
-
- //bind pageHide to removePage after it's hidden, if the page options specify to do so
-
- // Remove loading message.
- if ( settings.showLoadMsg ) {
- hideMsg();
- }
-
- // Add the page reference and xhr to our triggerData.
- triggerData.xhr = xhr;
- triggerData.textStatus = textStatus;
- triggerData.page = page;
-
- // Let listeners know the page loaded successfully.
- settings.pageContainer.trigger( "pageload", triggerData );
-
- deferred.resolve( absUrl, options, page, dupCachedPage );
- },
- error: function( xhr, textStatus, errorThrown ) {
- //set base back to current path
- if( base ) {
- base.set( path.get() );
- }
-
- // Add error info to our triggerData.
- triggerData.xhr = xhr;
- triggerData.textStatus = textStatus;
- triggerData.errorThrown = errorThrown;
-
- var plfEvent = new $.Event( "pageloadfailed" );
-
- // Let listeners know the page load failed.
- settings.pageContainer.trigger( plfEvent, triggerData );
-
- // If the default behavior is prevented, stop here!
- // Note that it is the responsibility of the listener/handler
- // that called preventDefault(), to resolve/reject the
- // deferred object within the triggerData.
- if( plfEvent.isDefaultPrevented() ){
- return;
- }
-
- // Remove loading message.
- if ( settings.showLoadMsg ) {
-
- // Remove loading message.
- hideMsg();
-
- //show error message
- $( "
"+ $.mobile.pageLoadErrorMessage +"
" )
- .css({ "display": "block", "opacity": 0.96, "top": $window.scrollTop() + 100 })
- .appendTo( settings.pageContainer )
- .delay( 800 )
- .fadeOut( 400, function() {
- $( this ).remove();
- });
- }
-
- deferred.reject( absUrl, options );
- }
- });
- }
-
- return deferred.promise();
- };
-
- $.mobile.loadPage.defaults = {
- type: "get",
- data: undefined,
- reloadPage: false,
- role: undefined, // By default we rely on the role defined by the @data-role attribute.
- showLoadMsg: false,
- pageContainer: undefined,
- loadMsgDelay: 50 // This delay allows loads that pull from browser cache to occur without showing the loading message.
- };
-
- // Show a specific page in the page container.
- $.mobile.changePage = function( toPage, options ) {
- // If we are in the midst of a transition, queue the current request.
- // We'll call changePage() once we're done with the current transition to
- // service the request.
- if( isPageTransitioning ) {
- pageTransitionQueue.unshift( arguments );
- return;
- }
-
- var settings = $.extend( {}, $.mobile.changePage.defaults, options );
-
- // Make sure we have a pageContainer to work with.
- settings.pageContainer = settings.pageContainer || $.mobile.pageContainer;
-
- // Make sure we have a fromPage.
- settings.fromPage = settings.fromPage || $.mobile.activePage;
-
- var mpc = settings.pageContainer,
- pbcEvent = new $.Event( "pagebeforechange" ),
- triggerData = { toPage: toPage, options: settings };
-
- // Let listeners know we're about to change the current page.
- mpc.trigger( pbcEvent, triggerData );
-
- // If the default behavior is prevented, stop here!
- if( pbcEvent.isDefaultPrevented() ){
- return;
- }
-
- // We allow "pagebeforechange" observers to modify the toPage in the trigger
- // data to allow for redirects. Make sure our toPage is updated.
-
- toPage = triggerData.toPage;
-
- // Set the isPageTransitioning flag to prevent any requests from
- // entering this method while we are in the midst of loading a page
- // or transitioning.
-
- isPageTransitioning = true;
-
- // If the caller passed us a url, call loadPage()
- // to make sure it is loaded into the DOM. We'll listen
- // to the promise object it returns so we know when
- // it is done loading or if an error ocurred.
- if ( typeof toPage == "string" ) {
- $.mobile.loadPage( toPage, settings )
- .done(function( url, options, newPage, dupCachedPage ) {
- isPageTransitioning = false;
- options.duplicateCachedPage = dupCachedPage;
- $.mobile.changePage( newPage, options );
- })
- .fail(function( url, options ) {
- isPageTransitioning = false;
-
- //clear out the active button state
- removeActiveLinkClass( true );
-
- //release transition lock so navigation is free again
- releasePageTransitionLock();
- settings.pageContainer.trigger( "pagechangefailed", triggerData );
- });
- return;
- }
-
- // If we are going to the first-page of the application, we need to make
- // sure settings.dataUrl is set to the application document url. This allows
- // us to avoid generating a document url with an id hash in the case where the
- // first-page of the document has an id attribute specified.
- if ( toPage[ 0 ] === $.mobile.firstPage[ 0 ] && !settings.dataUrl ) {
- settings.dataUrl = documentUrl.hrefNoHash;
- }
-
- // The caller passed us a real page DOM element. Update our
- // internal state and then trigger a transition to the page.
- var fromPage = settings.fromPage,
- url = ( settings.dataUrl && path.convertUrlToDataUrl( settings.dataUrl ) ) || toPage.jqmData( "url" ),
- // The pageUrl var is usually the same as url, except when url is obscured as a dialog url. pageUrl always contains the file path
- pageUrl = url,
- fileUrl = path.getFilePath( url ),
- active = urlHistory.getActive(),
- activeIsInitialPage = urlHistory.activeIndex === 0,
- historyDir = 0,
- pageTitle = document.title,
- isDialog = settings.role === "dialog" || toPage.jqmData( "role" ) === "dialog";
-
- // By default, we prevent changePage requests when the fromPage and toPage
- // are the same element, but folks that generate content manually/dynamically
- // and reuse pages want to be able to transition to the same page. To allow
- // this, they will need to change the default value of allowSamePageTransition
- // to true, *OR*, pass it in as an option when they manually call changePage().
- // It should be noted that our default transition animations assume that the
- // formPage and toPage are different elements, so they may behave unexpectedly.
- // It is up to the developer that turns on the allowSamePageTransitiona option
- // to either turn off transition animations, or make sure that an appropriate
- // animation transition is used.
- if( fromPage && fromPage[0] === toPage[0] && !settings.allowSamePageTransition ) {
- isPageTransitioning = false;
- mpc.trigger( "pagechange", triggerData );
- return;
- }
-
- // We need to make sure the page we are given has already been enhanced.
- enhancePage( toPage, settings.role );
-
- // If the changePage request was sent from a hashChange event, check to see if the
- // page is already within the urlHistory stack. If so, we'll assume the user hit
- // the forward/back button and will try to match the transition accordingly.
- if( settings.fromHashChange ) {
- urlHistory.directHashChange({
- currentUrl: url,
- isBack: function() { historyDir = -1; },
- isForward: function() { historyDir = 1; }
- });
- }
-
- // Kill the keyboard.
- // XXX_jblas: We need to stop crawling the entire document to kill focus. Instead,
- // we should be tracking focus with a live() handler so we already have
- // the element in hand at this point.
- // Wrap this in a try/catch block since IE9 throw "Unspecified error" if document.activeElement
- // is undefined when we are in an IFrame.
- try {
- if(document.activeElement && document.activeElement.nodeName.toLowerCase() != 'body') {
- $(document.activeElement).blur();
- } else {
- $( "input:focus, textarea:focus, select:focus" ).blur();
- }
- } catch(e) {}
-
- // If we're displaying the page as a dialog, we don't want the url
- // for the dialog content to be used in the hash. Instead, we want
- // to append the dialogHashKey to the url of the current page.
- if ( isDialog && active ) {
- // on the initial page load active.url is undefined and in that case should
- // be an empty string. Moving the undefined -> empty string back into
- // urlHistory.addNew seemed imprudent given undefined better represents
- // the url state
- url = ( active.url || "" ) + dialogHashKey;
- }
-
- // Set the location hash.
- if( settings.changeHash !== false && url ) {
- //disable hash listening temporarily
- urlHistory.ignoreNextHashChange = true;
- //update hash and history
- path.set( url );
- }
-
- // if title element wasn't found, try the page div data attr too
- // If this is a deep-link or a reload ( active === undefined ) then just use pageTitle
- var newPageTitle = ( !active )? pageTitle : toPage.jqmData( "title" ) || toPage.children(":jqmData(role='header')").find(".ui-title" ).getEncodedText();
- if( !!newPageTitle && pageTitle == document.title ) {
- pageTitle = newPageTitle;
- }
- if ( !toPage.jqmData( "title" ) ) {
- toPage.jqmData( "title", pageTitle );
- }
-
- // Make sure we have a transition defined.
- settings.transition = settings.transition
- || ( ( historyDir && !activeIsInitialPage ) ? active.transition : undefined )
- || ( isDialog ? $.mobile.defaultDialogTransition : $.mobile.defaultPageTransition );
-
- //add page to history stack if it's not back or forward
- if( !historyDir ) {
- urlHistory.addNew( url, settings.transition, pageTitle, pageUrl, settings.role );
- }
-
- //set page title
- document.title = urlHistory.getActive().title;
-
- //set "toPage" as activePage
- $.mobile.activePage = toPage;
-
- // If we're navigating back in the URL history, set reverse accordingly.
- settings.reverse = settings.reverse || historyDir < 0;
-
- transitionPages( toPage, fromPage, settings.transition, settings.reverse )
- .done(function() {
- removeActiveLinkClass();
-
- //if there's a duplicateCachedPage, remove it from the DOM now that it's hidden
- if ( settings.duplicateCachedPage ) {
- settings.duplicateCachedPage.remove();
- }
-
- //remove initial build class (only present on first pageshow)
- $html.removeClass( "ui-mobile-rendering" );
-
- releasePageTransitionLock();
-
- // Let listeners know we're all done changing the current page.
- mpc.trigger( "pagechange", triggerData );
- });
- };
-
- $.mobile.changePage.defaults = {
- transition: undefined,
- reverse: false,
- changeHash: true,
- fromHashChange: false,
- role: undefined, // By default we rely on the role defined by the @data-role attribute.
- duplicateCachedPage: undefined,
- pageContainer: undefined,
- showLoadMsg: true, //loading message shows by default when pages are being fetched during changePage
- dataUrl: undefined,
- fromPage: undefined,
- allowSamePageTransition: false
- };
-
-/* Event Bindings - hashchange, submit, and click */
- function findClosestLink( ele )
- {
- while ( ele ) {
- // Look for the closest element with a nodeName of "a".
- // Note that we are checking if we have a valid nodeName
- // before attempting to access it. This is because the
- // node we get called with could have originated from within
- // an embedded SVG document where some symbol instance elements
- // don't have nodeName defined on them, or strings are of type
- // SVGAnimatedString.
- if ( ( typeof ele.nodeName === "string" ) && ele.nodeName.toLowerCase() == "a" ) {
- break;
- }
- ele = ele.parentNode;
- }
- return ele;
- }
-
- // The base URL for any given element depends on the page it resides in.
- function getClosestBaseUrl( ele )
- {
- // Find the closest page and extract out its url.
- var url = $( ele ).closest( ".ui-page" ).jqmData( "url" ),
- base = documentBase.hrefNoHash;
-
- if ( !url || !path.isPath( url ) ) {
- url = base;
- }
-
- return path.makeUrlAbsolute( url, base);
- }
-
-
- //The following event bindings should be bound after mobileinit has been triggered
- //the following function is called in the init file
- $.mobile._registerInternalEvents = function(){
-
- //bind to form submit events, handle with Ajax
- $( "form" ).live('submit', function( event ) {
- var $this = $( this );
- if( !$.mobile.ajaxEnabled ||
- $this.is( ":jqmData(ajax='false')" ) ) {
- return;
- }
-
- var type = $this.attr( "method" ),
- target = $this.attr( "target" ),
- url = $this.attr( "action" );
-
- // If no action is specified, browsers default to using the
- // URL of the document containing the form. Since we dynamically
- // pull in pages from external documents, the form should submit
- // to the URL for the source document of the page containing
- // the form.
- if ( !url ) {
- // Get the @data-url for the page containing the form.
- url = getClosestBaseUrl( $this );
- if ( url === documentBase.hrefNoHash ) {
- // The url we got back matches the document base,
- // which means the page must be an internal/embedded page,
- // so default to using the actual document url as a browser
- // would.
- url = documentUrl.hrefNoSearch;
- }
- }
-
- url = path.makeUrlAbsolute( url, getClosestBaseUrl($this) );
-
- //external submits use regular HTTP
- if( path.isExternal( url ) || target ) {
- return;
- }
-
- $.mobile.changePage(
- url,
- {
- type: type && type.length && type.toLowerCase() || "get",
- data: $this.serialize(),
- transition: $this.jqmData( "transition" ),
- direction: $this.jqmData( "direction" ),
- reloadPage: true
- }
- );
- event.preventDefault();
- });
-
- //add active state on vclick
- $( document ).bind( "vclick", function( event ) {
- // if this isn't a left click we don't care. Its important to note
- // that when the virtual event is generated it will create
- if ( event.which > 1 || !$.mobile.linkBindingEnabled ){
- return;
- }
-
- var link = findClosestLink( event.target );
- if ( link ) {
- if ( path.parseUrl( link.getAttribute( "href" ) || "#" ).hash !== "#" ) {
- removeActiveLinkClass( true );
- $activeClickedLink = $( link ).closest( ".ui-btn" ).not( ".ui-disabled" );
- $activeClickedLink.addClass( $.mobile.activeBtnClass );
- $( "." + $.mobile.activePageClass + " .ui-btn" ).not( link ).blur();
- }
- }
- });
-
- // click routing - direct to HTTP or Ajax, accordingly
- $( document ).bind( "click", function( event ) {
- if( !$.mobile.linkBindingEnabled ){
- return;
- }
-
- var link = findClosestLink( event.target );
-
- // If there is no link associated with the click or its not a left
- // click we want to ignore the click
- if ( !link || event.which > 1) {
- return;
- }
-
- var $link = $( link ),
- //remove active link class if external (then it won't be there if you come back)
- httpCleanup = function(){
- window.setTimeout( function() { removeActiveLinkClass( true ); }, 200 );
- };
-
- //if there's a data-rel=back attr, go back in history
- if( $link.is( ":jqmData(rel='back')" ) ) {
- window.history.back();
- return false;
- }
-
- var baseUrl = getClosestBaseUrl( $link ),
-
- //get href, if defined, otherwise default to empty hash
- href = path.makeUrlAbsolute( $link.attr( "href" ) || "#", baseUrl );
-
- //if ajax is disabled, exit early
- if( !$.mobile.ajaxEnabled && !path.isEmbeddedPage( href ) ){
- httpCleanup();
- //use default click handling
- return;
- }
-
- // XXX_jblas: Ideally links to application pages should be specified as
- // an url to the application document with a hash that is either
- // the site relative path or id to the page. But some of the
- // internal code that dynamically generates sub-pages for nested
- // lists and select dialogs, just write a hash in the link they
- // create. This means the actual URL path is based on whatever
- // the current value of the base tag is at the time this code
- // is called. For now we are just assuming that any url with a
- // hash in it is an application page reference.
- if ( href.search( "#" ) != -1 ) {
- href = href.replace( /[^#]*#/, "" );
- if ( !href ) {
- //link was an empty hash meant purely
- //for interaction, so we ignore it.
- event.preventDefault();
- return;
- } else if ( path.isPath( href ) ) {
- //we have apath so make it the href we want to load.
- href = path.makeUrlAbsolute( href, baseUrl );
- } else {
- //we have a simple id so use the documentUrl as its base.
- href = path.makeUrlAbsolute( "#" + href, documentUrl.hrefNoHash );
- }
- }
-
- // Should we handle this link, or let the browser deal with it?
- var useDefaultUrlHandling = $link.is( "[rel='external']" ) || $link.is( ":jqmData(ajax='false')" ) || $link.is( "[target]" ),
-
- // Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR
- // requests if the document doing the request was loaded via the file:// protocol.
- // This is usually to allow the application to "phone home" and fetch app specific
- // data. We normally let the browser handle external/cross-domain urls, but if the
- // allowCrossDomainPages option is true, we will allow cross-domain http/https
- // requests to go through our page loading logic.
- isCrossDomainPageLoad = ( $.mobile.allowCrossDomainPages && documentUrl.protocol === "file:" && href.search( /^https?:/ ) != -1 ),
-
- //check for protocol or rel and its not an embedded page
- //TODO overlap in logic from isExternal, rel=external check should be
- // moved into more comprehensive isExternalLink
- isExternal = useDefaultUrlHandling || ( path.isExternal( href ) && !isCrossDomainPageLoad );
-
- if( isExternal ) {
- httpCleanup();
- //use default click handling
- return;
- }
-
- //use ajax
- var transition = $link.jqmData( "transition" ),
- direction = $link.jqmData( "direction" ),
- reverse = ( direction && direction === "reverse" ) ||
- // deprecated - remove by 1.0
- $link.jqmData( "back" ),
-
- //this may need to be more specific as we use data-rel more
- role = $link.attr( "data-" + $.mobile.ns + "rel" ) || undefined;
-
- $.mobile.changePage( href, { transition: transition, reverse: reverse, role: role } );
- event.preventDefault();
- });
-
- //prefetch pages when anchors with data-prefetch are encountered
- $( ".ui-page" ).live( "pageshow.prefetch", function() {
- var urls = [];
- $( this ).find( "a:jqmData(prefetch)" ).each(function(){
- var $link = $(this),
- url = $link.attr( "href" );
-
- if ( url && $.inArray( url, urls ) === -1 ) {
- urls.push( url );
-
- $.mobile.loadPage( url, {role: $link.attr("data-" + $.mobile.ns + "rel")} );
- }
- });
- });
-
- $.mobile._handleHashChange = function( hash ) {
- //find first page via hash
- var to = path.stripHash( hash ),
- //transition is false if it's the first page, undefined otherwise (and may be overridden by default)
- transition = $.mobile.urlHistory.stack.length === 0 ? "none" : undefined,
-
- // default options for the changPage calls made after examining the current state
- // of the page and the hash
- changePageOptions = {
- transition: transition,
- changeHash: false,
- fromHashChange: true
- };
-
- //if listening is disabled (either globally or temporarily), or it's a dialog hash
- if( !$.mobile.hashListeningEnabled || urlHistory.ignoreNextHashChange ) {
- urlHistory.ignoreNextHashChange = false;
- return;
- }
-
- // special case for dialogs
- if( urlHistory.stack.length > 1 && to.indexOf( dialogHashKey ) > -1 ) {
-
- // If current active page is not a dialog skip the dialog and continue
- // in the same direction
- if(!$.mobile.activePage.is( ".ui-dialog" )) {
- //determine if we're heading forward or backward and continue accordingly past
- //the current dialog
- urlHistory.directHashChange({
- currentUrl: to,
- isBack: function() { window.history.back(); },
- isForward: function() { window.history.forward(); }
- });
-
- // prevent changePage()
- return;
- } else {
- // if the current active page is a dialog and we're navigating
- // to a dialog use the dialog objected saved in the stack
- urlHistory.directHashChange({
- currentUrl: to,
-
- // regardless of the direction of the history change
- // do the following
- either: function( isBack ) {
- var active = $.mobile.urlHistory.getActive();
-
- to = active.pageUrl;
-
- // make sure to set the role, transition and reversal
- // as most of this is lost by the domCache cleaning
- $.extend( changePageOptions, {
- role: active.role,
- transition: active.transition,
- reverse: isBack
- });
- }
- });
- }
- }
-
- //if to is defined, load it
- if ( to ) {
- // At this point, 'to' can be one of 3 things, a cached page element from
- // a history stack entry, an id, or site-relative/absolute URL. If 'to' is
- // an id, we need to resolve it against the documentBase, not the location.href,
- // since the hashchange could've been the result of a forward/backward navigation
- // that crosses from an external page/dialog to an internal page/dialog.
- to = ( typeof to === "string" && !path.isPath( to ) ) ? ( path.makeUrlAbsolute( '#' + to, documentBase ) ) : to;
- $.mobile.changePage( to, changePageOptions );
- } else {
- //there's no hash, go to the first page in the dom
- $.mobile.changePage( $.mobile.firstPage, changePageOptions );
- }
- };
-
- //hashchange event handler
- $window.bind( "hashchange", function( e, triggered ) {
- $.mobile._handleHashChange( location.hash );
- });
-
- //set page min-heights to be device specific
- $( document ).bind( "pageshow", resetActivePageHeight );
- $( window ).bind( "throttledresize", resetActivePageHeight );
-
- };//_registerInternalEvents callback
-
-})( jQuery );
-/*
-* history.pushState support, layered on top of hashchange
-*/
-
-( function( $, window ) {
- // For now, let's Monkeypatch this onto the end of $.mobile._registerInternalEvents
- // Scope self to pushStateHandler so we can reference it sanely within the
- // methods handed off as event handlers
- var pushStateHandler = {},
- self = pushStateHandler,
- $win = $( window ),
- url = $.mobile.path.parseUrl( location.href );
-
- $.extend( pushStateHandler, {
- // TODO move to a path helper, this is rather common functionality
- initialFilePath: (function() {
- return url.pathname + url.search;
- })(),
-
- initialHref: url.hrefNoHash,
-
- // Flag for tracking if a Hashchange naturally occurs after each popstate + replace
- hashchangeFired: false,
-
- state: function() {
- return {
- hash: location.hash || "#" + self.initialFilePath,
- title: document.title,
-
- // persist across refresh
- initialHref: self.initialHref
- };
- },
-
- resetUIKeys: function( url ) {
- var dialog = $.mobile.dialogHashKey,
- subkey = "&" + $.mobile.subPageUrlKey,
- dialogIndex = url.indexOf( dialog );
-
- if( dialogIndex > -1 ) {
- url = url.slice( 0, dialogIndex ) + "#" + url.slice( dialogIndex );
- } else if( url.indexOf( subkey ) > -1 ) {
- url = url.split( subkey ).join( "#" + subkey );
- }
-
- return url;
- },
-
- // TODO sort out a single barrier to hashchange functionality
- nextHashChangePrevented: function( value ) {
- $.mobile.urlHistory.ignoreNextHashChange = value;
- self.onHashChangeDisabled = value;
- },
-
- // on hash change we want to clean up the url
- // NOTE this takes place *after* the vanilla navigation hash change
- // handling has taken place and set the state of the DOM
- onHashChange: function( e ) {
- // disable this hash change
- if( self.onHashChangeDisabled ){
- return;
- }
-
- var href, state,
- hash = location.hash,
- isPath = $.mobile.path.isPath( hash ),
- resolutionUrl = isPath ? location.href : $.mobile.getDocumentUrl();
- hash = isPath ? hash.replace( "#", "" ) : hash;
-
- // propulate the hash when its not available
- state = self.state();
-
- // make the hash abolute with the current href
- href = $.mobile.path.makeUrlAbsolute( hash, resolutionUrl );
-
- if ( isPath ) {
- href = self.resetUIKeys( href );
- }
-
- // replace the current url with the new href and store the state
- // Note that in some cases we might be replacing an url with the
- // same url. We do this anyways because we need to make sure that
- // all of our history entries have a state object associated with
- // them. This allows us to work around the case where window.history.back()
- // is called to transition from an external page to an embedded page.
- // In that particular case, a hashchange event is *NOT* generated by the browser.
- // Ensuring each history entry has a state object means that onPopState()
- // will always trigger our hashchange callback even when a hashchange event
- // is not fired.
- history.replaceState( state, document.title, href );
- },
-
- // on popstate (ie back or forward) we need to replace the hash that was there previously
- // cleaned up by the additional hash handling
- onPopState: function( e ) {
- var poppedState = e.originalEvent.state, holdnexthashchange = false;
-
- // if there's no state its not a popstate we care about, ie chrome's initial popstate
- // or forward popstate
- if( poppedState ) {
- // disable any hashchange triggered by the browser
- self.nextHashChangePrevented( true );
-
- // defer our manual hashchange until after the browser fired
- // version has come and gone
- setTimeout(function() {
- // make sure that the manual hash handling takes place
- self.nextHashChangePrevented( false );
-
- // change the page based on the hash
- $.mobile._handleHashChange( poppedState.hash );
- }, 100);
- }
- },
-
- init: function() {
- $win.bind( "hashchange", self.onHashChange );
-
- // Handle popstate events the occur through history changes
- $win.bind( "popstate", self.onPopState );
-
- // if there's no hash, we need to replacestate for returning to home
- if ( location.hash === "" ) {
- history.replaceState( self.state(), document.title, location.href );
- }
- }
- });
-
- $( function() {
- if( $.mobile.pushStateEnabled && $.support.pushState ){
- pushStateHandler.init();
- }
- });
-})( jQuery, this );
-/*
-* "transitions" plugin - Page change tranistions
-*/
-
-(function( $, window, undefined ) {
-
-function css3TransitionHandler( name, reverse, $to, $from ) {
-
- var deferred = new $.Deferred(),
- reverseClass = reverse ? " reverse" : "",
- viewportClass = "ui-mobile-viewport-transitioning viewport-" + name,
- doneFunc = function() {
-
- $to.add( $from ).removeClass( "out in reverse " + name );
-
- if ( $from && $from[ 0 ] !== $to[ 0 ] ) {
- $from.removeClass( $.mobile.activePageClass );
- }
-
- $to.parent().removeClass( viewportClass );
-
- deferred.resolve( name, reverse, $to, $from );
- };
-
- $to.animationComplete( doneFunc );
-
- $to.parent().addClass( viewportClass );
-
- if ( $from ) {
- $from.addClass( name + " out" + reverseClass );
- }
- $to.addClass( $.mobile.activePageClass + " " + name + " in" + reverseClass );
-
- return deferred.promise();
-}
-
-// Make our transition handler public.
-$.mobile.css3TransitionHandler = css3TransitionHandler;
-
-// If the default transition handler is the 'none' handler, replace it with our handler.
-if ( $.mobile.defaultTransitionHandler === $.mobile.noneTransitionHandler ) {
- $.mobile.defaultTransitionHandler = css3TransitionHandler;
-}
-
-})( jQuery, this );
-/*
-* "degradeInputs" plugin - degrades inputs to another type after custom enhancements are made.
-*/
-
-(function( $, undefined ) {
-
-$.mobile.page.prototype.options.degradeInputs = {
- color: false,
- date: false,
- datetime: false,
- "datetime-local": false,
- email: false,
- month: false,
- number: false,
- range: "number",
- search: "text",
- tel: false,
- time: false,
- url: false,
- week: false
-};
-
-
-//auto self-init widgets
-$( document ).bind( "pagecreate create", function( e ){
-
- var page = $(e.target).closest(':jqmData(role="page")').data("page"), options;
-
- if( !page ) {
- return;
- }
-
- options = page.options;
-
- // degrade inputs to avoid poorly implemented native functionality
- $( e.target ).find( "input" ).not( page.keepNativeSelector() ).each(function() {
- var $this = $( this ),
- type = this.getAttribute( "type" ),
- optType = options.degradeInputs[ type ] || "text";
-
- if ( options.degradeInputs[ type ] ) {
- var html = $( "
" ).html( $this.clone() ).html(),
- // In IE browsers, the type sometimes doesn't exist in the cloned markup, so we replace the closing tag instead
- hasType = html.indexOf( " type=" ) > -1,
- findstr = hasType ? /\s+type=["']?\w+['"]?/ : /\/?>/,
- repstr = " type=\"" + optType + "\" data-" + $.mobile.ns + "type=\"" + type + "\"" + ( hasType ? "" : ">" );
-
- $this.replaceWith( html.replace( findstr, repstr ) );
- }
- });
-
-});
-
-})( jQuery );/*
-* "dialog" plugin.
-*/
-
-(function( $, window, undefined ) {
-
-$.widget( "mobile.dialog", $.mobile.widget, {
- options: {
- closeBtnText : "Close",
- overlayTheme : "a",
- initSelector : ":jqmData(role='dialog')"
- },
- _create: function() {
- var self = this,
- $el = this.element,
- headerCloseButton = $( ""+ this.options.closeBtnText + "" );
-
- $el.addClass( "ui-overlay-" + this.options.overlayTheme );
-
- // Class the markup for dialog styling
- // Set aria role
- $el.attr( "role", "dialog" )
- .addClass( "ui-dialog" )
- .find( ":jqmData(role='header')" )
- .addClass( "ui-corner-top ui-overlay-shadow" )
- .prepend( headerCloseButton )
- .end()
- .find( ":jqmData(role='content'),:jqmData(role='footer')" )
- .addClass( "ui-overlay-shadow" )
- .last()
- .addClass( "ui-corner-bottom" );
-
- // this must be an anonymous function so that select menu dialogs can replace
- // the close method. This is a change from previously just defining data-rel=back
- // on the button and letting nav handle it
- headerCloseButton.bind( "vclick", function() {
- self.close();
- });
-
- /* bind events
- - clicks and submits should use the closing transition that the dialog opened with
- unless a data-transition is specified on the link/form
- - if the click was on the close button, or the link has a data-rel="back" it'll go back in history naturally
- */
- $el.bind( "vclick submit", function( event ) {
- var $target = $( event.target ).closest( event.type === "vclick" ? "a" : "form" ),
- active;
-
- if ( $target.length && !$target.jqmData( "transition" ) ) {
-
- active = $.mobile.urlHistory.getActive() || {};
-
- $target.attr( "data-" + $.mobile.ns + "transition", ( active.transition || $.mobile.defaultDialogTransition ) )
- .attr( "data-" + $.mobile.ns + "direction", "reverse" );
- }
- })
- .bind( "pagehide", function() {
- $( this ).find( "." + $.mobile.activeBtnClass ).removeClass( $.mobile.activeBtnClass );
- });
- },
-
- // Close method goes back in history
- close: function() {
- window.history.back();
- }
-});
-
-//auto self-init widgets
-$( $.mobile.dialog.prototype.options.initSelector ).live( "pagecreate", function(){
- $( this ).dialog();
-});
-
-})( jQuery, this );
-/*
-* This plugin handles theming and layout of headers, footers, and content areas
-*/
-
-(function( $, undefined ) {
-
-$.mobile.page.prototype.options.backBtnText = "Back";
-$.mobile.page.prototype.options.addBackBtn = false;
-$.mobile.page.prototype.options.backBtnTheme = null;
-$.mobile.page.prototype.options.headerTheme = "a";
-$.mobile.page.prototype.options.footerTheme = "a";
-$.mobile.page.prototype.options.contentTheme = null;
-
-$( ":jqmData(role='page'), :jqmData(role='dialog')" ).live( "pagecreate", function( e ) {
-
- var $page = $( this ),
- o = $page.data( "page" ).options,
- pageRole = $page.jqmData( "role" ),
- pageTheme = o.theme;
-
- $( ":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')", this ).each(function() {
- var $this = $( this ),
- role = $this.jqmData( "role" ),
- theme = $this.jqmData( "theme" ),
- contentTheme = theme || o.contentTheme || ( pageRole === "dialog" && pageTheme ),
- $headeranchors,
- leftbtn,
- rightbtn,
- backBtn;
-
- $this.addClass( "ui-" + role );
-
- //apply theming and markup modifications to page,header,content,footer
- if ( role === "header" || role === "footer" ) {
-
- var thisTheme = theme || ( role === "header" ? o.headerTheme : o.footerTheme ) || pageTheme;
-
- $this
- //add theme class
- .addClass( "ui-bar-" + thisTheme )
- // Add ARIA role
- .attr( "role", role === "header" ? "banner" : "contentinfo" );
-
- // Right,left buttons
- $headeranchors = $this.children( "a" );
- leftbtn = $headeranchors.hasClass( "ui-btn-left" );
- rightbtn = $headeranchors.hasClass( "ui-btn-right" );
-
- leftbtn = leftbtn || $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length;
-
- rightbtn = rightbtn || $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length;
-
- // Auto-add back btn on pages beyond first view
- if ( o.addBackBtn &&
- role === "header" &&
- $( ".ui-page" ).length > 1 &&
- $this.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) &&
- !leftbtn ) {
-
- backBtn = $( ""+ o.backBtnText +"" )
- // If theme is provided, override default inheritance
- .attr( "data-"+ $.mobile.ns +"theme", o.backBtnTheme || thisTheme )
- .prependTo( $this );
- }
-
- // Page title
- $this.children( "h1, h2, h3, h4, h5, h6" )
- .addClass( "ui-title" )
- // Regardless of h element number in src, it becomes h1 for the enhanced page
- .attr({
- "tabindex": "0",
- "role": "heading",
- "aria-level": "1"
- });
-
- } else if ( role === "content" ) {
- if ( contentTheme ) {
- $this.addClass( "ui-body-" + ( contentTheme ) );
- }
-
- // Add ARIA role
- $this.attr( "role", "main" );
- }
- });
-});
-
-})( jQuery );/*
-* "collapsible" plugin
-*/
-
-(function( $, undefined ) {
-
-$.widget( "mobile.collapsible", $.mobile.widget, {
- options: {
- expandCueText: " click to expand contents",
- collapseCueText: " click to collapse contents",
- collapsed: true,
- heading: "h1,h2,h3,h4,h5,h6,legend",
- theme: null,
- contentTheme: null,
- iconTheme: "d",
- initSelector: ":jqmData(role='collapsible')"
- },
- _create: function() {
-
- var $el = this.element,
- o = this.options,
- collapsible = $el.addClass( "ui-collapsible" ),
- collapsibleHeading = $el.children( o.heading ).first(),
- collapsibleContent = collapsible.wrapInner( "" ).find( ".ui-collapsible-content" ),
- collapsibleSet = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" );
-
- // Replace collapsibleHeading if it's a legend
- if ( collapsibleHeading.is( "legend" ) ) {
- collapsibleHeading = $( "
"+ collapsibleHeading.html() +"
" ).insertBefore( collapsibleHeading );
- collapsibleHeading.next().remove();
- }
-
- // If we are in a collapsible set
- if ( collapsibleSet.length ) {
- // Inherit the theme from collapsible-set
- if ( !o.theme ) {
- o.theme = collapsibleSet.jqmData( "theme" );
- }
- // Inherit the content-theme from collapsible-set
- if ( !o.contentTheme ) {
- o.contentTheme = collapsibleSet.jqmData( "content-theme" );
- }
- }
-
- collapsibleContent.addClass( ( o.contentTheme ) ? ( "ui-body-" + o.contentTheme ) : "");
-
- collapsibleHeading
- //drop heading in before content
- .insertBefore( collapsibleContent )
- //modify markup & attributes
- .addClass( "ui-collapsible-heading" )
- .append( "" )
- .wrapInner( "" )
- .find( "a" )
- .first()
- .buttonMarkup({
- shadow: false,
- corners: false,
- iconPos: "left",
- icon: "plus",
- theme: o.theme
- })
- .add( ".ui-btn-inner" )
- .addClass( "ui-corner-top ui-corner-bottom" );
-
- //events
- collapsible
- .bind( "expand collapse", function( event ) {
- if ( !event.isDefaultPrevented() ) {
-
- event.preventDefault();
-
- var $this = $( this ),
- isCollapse = ( event.type === "collapse" ),
- contentTheme = o.contentTheme;
-
- collapsibleHeading
- .toggleClass( "ui-collapsible-heading-collapsed", isCollapse)
- .find( ".ui-collapsible-heading-status" )
- .text( isCollapse ? o.expandCueText : o.collapseCueText )
- .end()
- .find( ".ui-icon" )
- .toggleClass( "ui-icon-minus", !isCollapse )
- .toggleClass( "ui-icon-plus", isCollapse );
-
- $this.toggleClass( "ui-collapsible-collapsed", isCollapse );
- collapsibleContent.toggleClass( "ui-collapsible-content-collapsed", isCollapse ).attr( "aria-hidden", isCollapse );
-
- if ( contentTheme && ( !collapsibleSet.length || collapsible.jqmData( "collapsible-last" ) ) ) {
- collapsibleHeading
- .find( "a" ).first().add( collapsibleHeading.find( ".ui-btn-inner" ) )
- .toggleClass( "ui-corner-bottom", isCollapse );
- collapsibleContent.toggleClass( "ui-corner-bottom", !isCollapse );
- }
- collapsibleContent.trigger( "updatelayout" );
- }
- })
- .trigger( o.collapsed ? "collapse" : "expand" );
-
- collapsibleHeading
- .bind( "click", function( event ) {
-
- var type = collapsibleHeading.is( ".ui-collapsible-heading-collapsed" ) ?
- "expand" : "collapse";
-
- collapsible.trigger( type );
-
- event.preventDefault();
- });
- }
-});
-
-//auto self-init widgets
-$( document ).bind( "pagecreate create", function( e ){
- $( $.mobile.collapsible.prototype.options.initSelector, e.target ).collapsible();
-});
-
-})( jQuery );
-/*
-* "fieldcontain" plugin - simple class additions to make form row separators
-*/
-
-(function( $, undefined ) {
-
-$.fn.fieldcontain = function( options ) {
- return this.addClass( "ui-field-contain ui-body ui-br" );
-};
-
-//auto self-init widgets
-$( document ).bind( "pagecreate create", function( e ){
- $( ":jqmData(role='fieldcontain')", e.target ).fieldcontain();
-});
-
-})( jQuery );/*
-* plugin for creating CSS grids
-*/
-
-(function( $, undefined ) {
-
-$.fn.grid = function( options ) {
- return this.each(function() {
-
- var $this = $( this ),
- o = $.extend({
- grid: null
- },options),
- $kids = $this.children(),
- gridCols = {solo:1, a:2, b:3, c:4, d:5},
- grid = o.grid,
- iterator;
-
- if ( !grid ) {
- if ( $kids.length <= 5 ) {
- for ( var letter in gridCols ) {
- if ( gridCols[ letter ] === $kids.length ) {
- grid = letter;
- }
- }
- } else {
- grid = "a";
- }
- }
- iterator = gridCols[grid];
-
- $this.addClass( "ui-grid-" + grid );
-
- $kids.filter( ":nth-child(" + iterator + "n+1)" ).addClass( "ui-block-a" );
-
- if ( iterator > 1 ) {
- $kids.filter( ":nth-child(" + iterator + "n+2)" ).addClass( "ui-block-b" );
- }
- if ( iterator > 2 ) {
- $kids.filter( ":nth-child(3n+3)" ).addClass( "ui-block-c" );
- }
- if ( iterator > 3 ) {
- $kids.filter( ":nth-child(4n+4)" ).addClass( "ui-block-d" );
- }
- if ( iterator > 4 ) {
- $kids.filter( ":nth-child(5n+5)" ).addClass( "ui-block-e" );
- }
- });
-};
-})( jQuery );/*
-* "navbar" plugin
-*/
-
-(function( $, undefined ) {
-
-$.widget( "mobile.navbar", $.mobile.widget, {
- options: {
- iconpos: "top",
- grid: null,
- initSelector: ":jqmData(role='navbar')"
- },
-
- _create: function(){
-
- var $navbar = this.element,
- $navbtns = $navbar.find( "a" ),
- iconpos = $navbtns.filter( ":jqmData(icon)" ).length ?
- this.options.iconpos : undefined;
-
- $navbar.addClass( "ui-navbar" )
- .attr( "role","navigation" )
- .find( "ul" )
- .grid({ grid: this.options.grid });
-
- if ( !iconpos ) {
- $navbar.addClass( "ui-navbar-noicons" );
- }
-
- $navbtns.buttonMarkup({
- corners: false,
- shadow: false,
- iconpos: iconpos
- });
-
- $navbar.delegate( "a", "vclick", function( event ) {
- $navbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass );
- $( this ).addClass( $.mobile.activeBtnClass );
- });
- }
-});
-
-//auto self-init widgets
-$( document ).bind( "pagecreate create", function( e ){
- $( $.mobile.navbar.prototype.options.initSelector, e.target ).navbar();
-});
-
-})( jQuery );
-/*
-* "listview" plugin
-*/
-
-(function( $, undefined ) {
-
-//Keeps track of the number of lists per page UID
-//This allows support for multiple nested list in the same page
-//https://github.com/jquery/jquery-mobile/issues/1617
-var listCountPerPage = {};
-
-$.widget( "mobile.listview", $.mobile.widget, {
- options: {
- theme: null,
- countTheme: "c",
- headerTheme: "b",
- dividerTheme: "b",
- splitIcon: "arrow-r",
- splitTheme: "b",
- inset: false,
- initSelector: ":jqmData(role='listview')"
- },
-
- _create: function() {
- var t = this;
-
- // create listview markup
- t.element.addClass(function( i, orig ) {
- return orig + " ui-listview " + ( t.options.inset ? " ui-listview-inset ui-corner-all ui-shadow " : "" );
- });
-
- t.refresh( true );
- },
-
- _removeCorners: function( li, which ) {
- var top = "ui-corner-top ui-corner-tr ui-corner-tl",
- bot = "ui-corner-bottom ui-corner-br ui-corner-bl";
-
- li = li.add( li.find( ".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb" ) );
-
- if ( which === "top" ) {
- li.removeClass( top );
- } else if ( which === "bottom" ) {
- li.removeClass( bot );
- } else {
- li.removeClass( top + " " + bot );
- }
- },
-
- _refreshCorners: function( create ) {
- var $li,
- $visibleli,
- $topli,
- $bottomli;
-
- if ( this.options.inset ) {
- $li = this.element.children( "li" );
- // at create time the li are not visible yet so we need to rely on .ui-screen-hidden
- $visibleli = create?$li.not( ".ui-screen-hidden" ):$li.filter( ":visible" );
-
- this._removeCorners( $li );
-
- // Select the first visible li element
- $topli = $visibleli.first()
- .addClass( "ui-corner-top" );
-
- $topli.add( $topli.find( ".ui-btn-inner" )
- .not( ".ui-li-link-alt span:first-child" ) )
- .addClass( "ui-corner-top" )
- .end()
- .find( ".ui-li-link-alt, .ui-li-link-alt span:first-child" )
- .addClass( "ui-corner-tr" )
- .end()
- .find( ".ui-li-thumb" )
- .not(".ui-li-icon")
- .addClass( "ui-corner-tl" );
-
- // Select the last visible li element
- $bottomli = $visibleli.last()
- .addClass( "ui-corner-bottom" );
-
- $bottomli.add( $bottomli.find( ".ui-btn-inner" ) )
- .find( ".ui-li-link-alt" )
- .addClass( "ui-corner-br" )
- .end()
- .find( ".ui-li-thumb" )
- .not(".ui-li-icon")
- .addClass( "ui-corner-bl" );
- }
- if ( !create ) {
- this.element.trigger( "updatelayout" );
- }
- },
-
- // This is a generic utility method for finding the first
- // node with a given nodeName. It uses basic DOM traversal
- // to be fast and is meant to be a substitute for simple
- // $.fn.closest() and $.fn.children() calls on a single
- // element. Note that callers must pass both the lowerCase
- // and upperCase version of the nodeName they are looking for.
- // The main reason for this is that this function will be
- // called many times and we want to avoid having to lowercase
- // the nodeName from the element every time to ensure we have
- // a match. Note that this function lives here for now, but may
- // be moved into $.mobile if other components need a similar method.
- _findFirstElementByTagName: function( ele, nextProp, lcName, ucName )
- {
- var dict = {};
- dict[ lcName ] = dict[ ucName ] = true;
- while ( ele ) {
- if ( dict[ ele.nodeName ] ) {
- return ele;
- }
- ele = ele[ nextProp ];
- }
- return null;
- },
- _getChildrenByTagName: function( ele, lcName, ucName )
- {
- var results = [],
- dict = {};
- dict[ lcName ] = dict[ ucName ] = true;
- ele = ele.firstChild;
- while ( ele ) {
- if ( dict[ ele.nodeName ] ) {
- results.push( ele );
- }
- ele = ele.nextSibling;
- }
- return $( results );
- },
-
- _addThumbClasses: function( containers )
- {
- var i, img, len = containers.length;
- for ( i = 0; i < len; i++ ) {
- img = $( this._findFirstElementByTagName( containers[ i ].firstChild, "nextSibling", "img", "IMG" ) );
- if ( img.length ) {
- img.addClass( "ui-li-thumb" );
- $( this._findFirstElementByTagName( img[ 0 ].parentNode, "parentNode", "li", "LI" ) ).addClass( img.is( ".ui-li-icon" ) ? "ui-li-has-icon" : "ui-li-has-thumb" );
- }
- }
- },
-
- refresh: function( create ) {
- this.parentPage = this.element.closest( ".ui-page" );
- this._createSubPages();
-
- var o = this.options,
- $list = this.element,
- self = this,
- dividertheme = $list.jqmData( "dividertheme" ) || o.dividerTheme,
- listsplittheme = $list.jqmData( "splittheme" ),
- listspliticon = $list.jqmData( "spliticon" ),
- li = this._getChildrenByTagName( $list[ 0 ], "li", "LI" ),
- counter = $.support.cssPseudoElement || !$.nodeName( $list[ 0 ], "ol" ) ? 0 : 1,
- itemClassDict = {},
- item, itemClass, itemTheme,
- a, last, splittheme, countParent, icon, imgParents, img;
-
- if ( counter ) {
- $list.find( ".ui-li-dec" ).remove();
- }
-
- if ( !o.theme ) {
- o.theme = $.mobile.getInheritedTheme( this.element, "c" );
- }
-
- for ( var pos = 0, numli = li.length; pos < numli; pos++ ) {
- item = li.eq( pos );
- itemClass = "ui-li";
-
- // If we're creating the element, we update it regardless
- if ( create || !item.hasClass( "ui-li" ) ) {
- itemTheme = item.jqmData("theme") || o.theme;
- a = this._getChildrenByTagName( item[ 0 ], "a", "A" );
-
- if ( a.length ) {
- icon = item.jqmData("icon");
-
- item.buttonMarkup({
- wrapperEls: "div",
- shadow: false,
- corners: false,
- iconpos: "right",
- icon: a.length > 1 || icon === false ? false : icon || "arrow-r",
- theme: itemTheme
- });
-
- if ( ( icon != false ) && ( a.length == 1 ) ) {
- item.addClass( "ui-li-has-arrow" );
- }
-
- a.first().addClass( "ui-link-inherit" );
-
- if ( a.length > 1 ) {
- itemClass += " ui-li-has-alt";
-
- last = a.last();
- splittheme = listsplittheme || last.jqmData( "theme" ) || o.splitTheme;
-
- last.appendTo(item)
- .attr( "title", last.getEncodedText() )
- .addClass( "ui-li-link-alt" )
- .empty()
- .buttonMarkup({
- shadow: false,
- corners: false,
- theme: itemTheme,
- icon: false,
- iconpos: false
- })
- .find( ".ui-btn-inner" )
- .append(
- $( document.createElement( "span" ) ).buttonMarkup({
- shadow: true,
- corners: true,
- theme: splittheme,
- iconpos: "notext",
- icon: listspliticon || last.jqmData( "icon" ) || o.splitIcon
- })
- );
- }
- } else if ( item.jqmData( "role" ) === "list-divider" ) {
-
- itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme;
- item.attr( "role", "heading" );
-
- //reset counter when a divider heading is encountered
- if ( counter ) {
- counter = 1;
- }
-
- } else {
- itemClass += " ui-li-static ui-body-" + itemTheme;
- }
- }
-
- if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) {
- countParent = item.is( ".ui-li-static:first" ) ? item : item.find( ".ui-link-inherit" );
-
- countParent.addClass( "ui-li-jsnumbering" )
- .prepend( "" + (counter++) + ". " );
- }
-
- // Instead of setting item class directly on the list item and its
- // btn-inner at this point in time, push the item into a dictionary
- // that tells us what class to set on it so we can do this after this
- // processing loop is finished.
-
- if ( !itemClassDict[ itemClass ] ) {
- itemClassDict[ itemClass ] = [];
- }
-
- itemClassDict[ itemClass ].push( item[ 0 ] );
- }
-
- // Set the appropriate listview item classes on each list item
- // and their btn-inner elements. The main reason we didn't do this
- // in the for-loop above is because we can eliminate per-item function overhead
- // by calling addClass() and children() once or twice afterwards. This
- // can give us a significant boost on platforms like WP7.5.
-
- for ( itemClass in itemClassDict ) {
- $( itemClassDict[ itemClass ] ).addClass( itemClass ).children( ".ui-btn-inner" ).addClass( itemClass );
- }
-
- $list.find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" )
- .end()
-
- .find( "p, dl" ).addClass( "ui-li-desc" )
- .end()
-
- .find( ".ui-li-aside" ).each(function() {
- var $this = $(this);
- $this.prependTo( $this.parent() ); //shift aside to front for css float
- })
- .end()
-
- .find( ".ui-li-count" ).each( function() {
- $( this ).closest( "li" ).addClass( "ui-li-has-count" );
- }).addClass( "ui-btn-up-" + ( $list.jqmData( "counttheme" ) || this.options.countTheme) + " ui-btn-corner-all" );
-
- // The idea here is to look at the first image in the list item
- // itself, and any .ui-link-inherit element it may contain, so we
- // can place the appropriate classes on the image and list item.
- // Note that we used to use something like:
- //
- // li.find(">img:eq(0), .ui-link-inherit>img:eq(0)").each( ... );
- //
- // But executing a find() like that on Windows Phone 7.5 took a
- // really long time. Walking things manually with the code below
- // allows the 400 listview item page to load in about 3 seconds as
- // opposed to 30 seconds.
-
- this._addThumbClasses( li );
- this._addThumbClasses( $list.find( ".ui-link-inherit" ) );
-
- this._refreshCorners( create );
- },
-
- //create a string for ID/subpage url creation
- _idStringEscape: function( str ) {
- return str.replace(/[^a-zA-Z0-9]/g, '-');
- },
-
- _createSubPages: function() {
- var parentList = this.element,
- parentPage = parentList.closest( ".ui-page" ),
- parentUrl = parentPage.jqmData( "url" ),
- parentId = parentUrl || parentPage[ 0 ][ $.expando ],
- parentListId = parentList.attr( "id" ),
- o = this.options,
- dns = "data-" + $.mobile.ns,
- self = this,
- persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" ),
- hasSubPages;
-
- if ( typeof listCountPerPage[ parentId ] === "undefined" ) {
- listCountPerPage[ parentId ] = -1;
- }
-
- parentListId = parentListId || ++listCountPerPage[ parentId ];
-
- $( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function( i ) {
- var self = this,
- list = $( this ),
- listId = list.attr( "id" ) || parentListId + "-" + i,
- parent = list.parent(),
- nodeEls = $( list.prevAll().toArray().reverse() ),
- nodeEls = nodeEls.length ? nodeEls : $( "" + $.trim(parent.contents()[ 0 ].nodeValue) + "" ),
- title = nodeEls.first().getEncodedText(),//url limits to first 30 chars of text
- id = ( parentUrl || "" ) + "&" + $.mobile.subPageUrlKey + "=" + listId,
- theme = list.jqmData( "theme" ) || o.theme,
- countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme,
- newPage, anchor;
-
- //define hasSubPages for use in later removal
- hasSubPages = true;
-
- newPage = list.detach()
- .wrap( "
" )
- .parent()
- .before( "
" + title + "
" )
- .after( persistentFooterID ? $( "
") : "" )
- .parent()
- .appendTo( $.mobile.pageContainer );
-
- newPage.page();
-
- anchor = parent.find('a:first');
-
- if ( !anchor.length ) {
- anchor = $( "" ).html( nodeEls || title ).prependTo( parent.empty() );
- }
-
- anchor.attr( "href", "#" + id );
-
- }).listview();
-
- // on pagehide, remove any nested pages along with the parent page, as long as they aren't active
- // and aren't embedded
- if( hasSubPages &&
- parentPage.is( ":jqmData(external-page='true')" ) &&
- parentPage.data("page").options.domCache === false ) {
-
- var newRemove = function( e, ui ){
- var nextPage = ui.nextPage, npURL;
-
- if( ui.nextPage ){
- npURL = nextPage.jqmData( "url" );
- if( npURL.indexOf( parentUrl + "&" + $.mobile.subPageUrlKey ) !== 0 ){
- self.childPages().remove();
- parentPage.remove();
- }
- }
- };
-
- // unbind the original page remove and replace with our specialized version
- parentPage
- .unbind( "pagehide.remove" )
- .bind( "pagehide.remove", newRemove);
- }
- },
-
- // TODO sort out a better way to track sub pages of the listview this is brittle
- childPages: function(){
- var parentUrl = this.parentPage.jqmData( "url" );
-
- return $( ":jqmData(url^='"+ parentUrl + "&" + $.mobile.subPageUrlKey +"')");
- }
-});
-
-//auto self-init widgets
-$( document ).bind( "pagecreate create", function( e ){
- $( $.mobile.listview.prototype.options.initSelector, e.target ).listview();
-});
-
-})( jQuery );
-/*
-* "listview" filter extension
-*/
-
-(function( $, undefined ) {
-
-$.mobile.listview.prototype.options.filter = false;
-$.mobile.listview.prototype.options.filterPlaceholder = "Filter items...";
-$.mobile.listview.prototype.options.filterTheme = "c";
-$.mobile.listview.prototype.options.filterCallback = function( text, searchValue ){
- return text.toLowerCase().indexOf( searchValue ) === -1;
-};
-
-$( ":jqmData(role='listview')" ).live( "listviewcreate", function() {
-
- var list = $( this ),
- listview = list.data( "listview" );
-
- if ( !listview.options.filter ) {
- return;
- }
-
- var wrapper = $( "