* $Rev$
*/
-// Global undefined variable
-window.undefined = window.undefined;
-
/**
* Create a new jQuery Object
*
* @param jQuery|Element|Array<Element> c context
* @cat Core
*/
-var jQuery = function(a,c) {
+
+// Map over jQuery in case of overwrite
+if ( typeof jQuery != "undefined" )
+ var _jQuery = jQuery;
+
+var jQuery = window.jQuery = function(a,c) {
// If the context is global, return a new object
if ( window == this || !this.init )
return new jQuery(a,c);
// Map over the $ in case of overwrite
if ( typeof $ != "undefined" )
- jQuery._$ = $;
+ var _$ = $;
// Map the jQuery namespace to the '$' one
-var $ = jQuery;
+window.$ = jQuery;
+
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
/**
* This function accepts a string containing a CSS or
// Make sure that a selection was provided
a = a || document;
- // HANDLE: $(function)
- // Shortcut for document ready
- if ( jQuery.isFunction(a) )
- return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( a );
-
// Handle HTML strings
if ( typeof a == "string" ) {
- // HANDLE: $(html) -> $(array)
- var m = /^[^<]*(<(.|\s)+>)[^>]*$/.exec(a);
- if ( m )
- a = jQuery.clean( [ m[1] ] );
+ var m = quickExpr.exec(a);
+ if ( m && (m[1] || !c) ) {
+ // HANDLE: $(html) -> $(array)
+ if ( m[1] )
+ a = jQuery.clean( [ m[1] ] );
+
+ // HANDLE: $("#id")
+ else {
+ var tmp = document.getElementById( m[3] );
+ if ( tmp )
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( tmp.id != m[3] )
+ return jQuery().find( a );
+ else {
+ this[0] = tmp;
+ this.length = 1;
+ return this;
+ }
+ else
+ a = [];
+ }
// HANDLE: $(expr)
- else
+ } else
return new jQuery( c ).find( a );
- }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction(a) )
+ return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( a );
return this.setArray(
// HANDLE: $(array)
*/
setArray: function( a ) {
this.length = 0;
- [].push.apply( this, a );
+ Array.prototype.push.apply( this, a );
return this;
},
* @cat DOM/Manipulation
*/
clone: function(deep) {
- // Need to remove events on the element and its descendants
+ deep = deep != undefined ? deep : true;
var $this = this.add(this.find("*"));
- $this.each(function() {
- this._$events = {};
- for (var type in this.$events)
- this._$events[type] = jQuery.extend({},this.$events[type]);
- }).unbind();
+ if (jQuery.browser.msie) {
+ // Need to remove events on the element and its descendants
+ $this.each(function() {
+ this._$events = {};
+ for (var type in this.$events)
+ this._$events[type] = jQuery.extend({},this.$events[type]);
+ }).unbind();
+ }
// Do the clone
var r = this.pushStack( jQuery.map( this, function(a){
- return a.cloneNode( deep != undefined ? deep : true );
+ return a.cloneNode( deep );
}) );
- // Add the events back to the original and its descendants
- $this.each(function() {
- var events = this._$events;
- for (var type in events)
- for (var handler in events[type])
- jQuery.event.add(this, type, events[type][handler], events[type][handler].data);
- this._$events = null;
- });
+ if (jQuery.browser.msie) {
+ $this.each(function() {
+ // Add the events back to the original and its descendants
+ var events = this._$events;
+ for (var type in events)
+ for (var handler in events[type])
+ jQuery.event.add(this, type, events[type][handler], events[type][handler].data);
+ this._$events = null;
+ });
+ }
+
+ // copy form values over
+ if (deep) {
+ var inputs = r.add(r.find('*')).filter('select,input[@type=checkbox]');
+ $this.filter('select,input[@type=checkbox]').each(function(i) {
+ if (this.selectedIndex)
+ inputs[i].selectedIndex = this.selectedIndex;
+ if (this.checked)
+ inputs[i].checked = true;
+ });
+ }
// Return the cloned set
return r;
return this.pushStack(
jQuery.isFunction( t ) &&
jQuery.grep(this, function(el, index){
- return t.apply(el, [index])
+ return t.apply(el, [index]);
}) ||
jQuery.multiFilter(t,this) );
( this.length ? this[0].innerHTML : null ) :
this.empty().append( val );
},
+
+ replaceWith: function( val ) {
+ return this.after( val ).remove();
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+ },
/**
* @private
if ( this.src )
jQuery.ajax({ url: this.src, async: false, dataType: "script" });
else
- (new Function( this.text || this.textContent || this.innerHTML || "" ))();
+ jQuery.globalEval( this.text || this.textContent || this.innerHTML || "" );
} else
fn.apply( obj, [ clone ? this.cloneNode(true) : this ] );
});
*/
jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
- var target = arguments[0], a = 1;
+ var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;
+
+ // Handle a deep copy situation
+ if ( target.constructor == Boolean ) {
+ deep = target;
+ target = arguments[1] || {};
+ }
// extend jQuery itself if only one argument is passed
- if ( arguments.length == 1 ) {
+ if ( al == 1 ) {
target = this;
a = 0;
}
+
var prop;
- while ( (prop = arguments[a++]) != null )
- // Extend the base object
- for ( var i in prop ) target[i] = prop[i];
+
+ for ( ; a < al; a++ )
+ // Only deal with non-null/undefined values
+ if ( (prop = arguments[a]) != null )
+ // Extend the base object
+ for ( var i in prop ) {
+ // Prevent never-ending loop
+ if ( target == prop[i] )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && typeof prop[i] == 'object' && target[i] )
+ jQuery.extend( target[i], prop[i] );
+
+ // Don't bring in undefined values
+ else if ( prop[i] != undefined )
+ target[i] = prop[i];
+ }
// Return the modified object
return target;
* @type undefined
* @cat Core
*/
- noConflict: function() {
- if ( jQuery._$ )
- $ = jQuery._$;
+ noConflict: function(deep) {
+ window.$ = _$;
+ if ( deep )
+ window.jQuery = _jQuery;
return jQuery;
},
// check if an element is in a XML document
isXMLDoc: function(elem) {
- return elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ return elem.documentElement && !elem.body ||
+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ // Evalulates a script in a global context
+ // Evaluates Async. in Safari 2 :-(
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+ if ( data ) {
+ if ( window.execScript )
+ window.execScript( data );
+ else if ( jQuery.browser.safari )
+ // safari doesn't provide a synchronous global eval
+ window.setTimeout( data, 0 );
+ else
+ eval.call( window, data );
+ }
},
nodeName: function( elem, name ) {
*/
// args is for internal usage only
each: function( obj, fn, args ) {
- if ( obj.length == undefined )
- for ( var i in obj )
- fn.apply( obj[i], args || [i, obj[i]] );
- else
- for ( var i = 0, ol = obj.length; i < ol; i++ )
- if ( fn.apply( obj[i], args || [i, obj[i]] ) === false ) break;
+ if ( args ) {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.apply( obj[i], args );
+ else
+ for ( var i = 0, ol = obj.length; i < ol; i++ )
+ if ( fn.apply( obj[i], args ) === false ) break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.call( obj[i], i, obj[i] );
+ else
+ for ( var i = 0, ol = obj.length, val = obj[0];
+ i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){}
+ }
+
return obj;
},
className: {
// internal only, use addClass("class")
add: function( elem, c ){
- jQuery.each( c.split(/\s+/), function(i, cur){
+ jQuery.each( (c || "").split(/\s+/), function(i, cur){
if ( !jQuery.className.has( elem.className, cur ) )
elem.className += ( elem.className ? " " : "" ) + cur;
});
},
curCSS: function(elem, prop, force) {
- var ret;
+ var ret, stack = [], swap = [];
+
+ // A helper method for determining if an element's values are broken
+ function color(a){
+ if ( !jQuery.browser.safari )
+ return false;
+
+ var ret = document.defaultView.getComputedStyle(a,null);
+ return !ret || ret.getPropertyValue("color") == "";
+ }
if (prop == "opacity" && jQuery.browser.msie) {
ret = jQuery.attr(elem.style, "opacity");
}
if (prop.match(/float/i))
- prop = jQuery.styleFloat;
+ prop = styleFloat;
if (!force && elem.style[prop])
ret = elem.style[prop];
prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
var cur = document.defaultView.getComputedStyle(elem, null);
- if ( cur )
+ if ( cur && !color(elem) )
ret = cur.getPropertyValue(prop);
- else if ( prop == "display" )
- ret = "none";
- else
- jQuery.swap(elem, { display: "block" }, function() {
- var c = document.defaultView.getComputedStyle(this, "");
- ret = c && c.getPropertyValue(prop) || "";
- });
+
+ // If the element isn't reporting its values properly in Safari
+ // then some display: none elements are involved
+ else {
+ // Locate all of the parent display: none elements
+ for ( var a = elem; a && color(a); a = a.parentNode )
+ stack.unshift(a);
+
+ // Go through and make them visible, but in reverse
+ // (It would be better if we knew the exact display type that they had)
+ for ( a = 0; a < stack.length; a++ )
+ if ( color(stack[a]) ) {
+ swap[a] = stack[a].style.display;
+ stack[a].style.display = "block";
+ }
+
+ // Since we flip the display style, we have to handle that
+ // one special, otherwise get the value
+ ret = prop == "display" && swap[stack.length-1] != null ?
+ "none" :
+ document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || "";
+
+ // Finally, revert the display styles back
+ for ( a = 0; a < swap.length; a++ )
+ if ( swap[a] != null )
+ stack[a].style.display = swap[a];
+ }
if ( prop == "opacity" && ret == "" )
ret = "1";
!s.indexOf("<leg") &&
[1, "<fieldset>", "</fieldset>"] ||
- (!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot") || !s.indexOf("<colg")) &&
+ s.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
[1, "<table>", "</table>"] ||
!s.indexOf("<tr") &&
[3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
!s.indexOf("<col") &&
- [2, "<table><colgroup>", "</colgroup></table>"] ||
+ [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ jQuery.browser.msie &&
+ [1, "div<div>", "</div>"] ||
[0,"",""];
// Move to the right depth
while ( wrap[0]-- )
- div = div.firstChild;
+ div = div.lastChild;
// Remove IE's autoinserted <tbody> from table fragments
if ( jQuery.browser.msie ) {
for ( var n = tb.length-1; n >= 0 ; --n )
if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
tb[n].parentNode.removeChild(tb[n]);
-
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( /^\s/.test(arg) )
+ div.insertBefore( doc.createTextNode( arg.match(/^\s*/)[0] ), div.firstChild );
+
}
arg = jQuery.makeArray( div.childNodes );
attr: function(elem, name, value){
var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props;
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && jQuery.browser.safari )
+ elem.parentNode.selectedIndex;
// Certain attributes only work when accessed via the old DOM 0 way
if ( fix[name] ) {
merge: function(first, second) {
// We have to loop this way because IE & Opera overwrite the length
// expando of getElementsByTagName
- for ( var i = 0; second[i]; i++ )
- first.push(second[i]);
+
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( jQuery.browser.msie ) {
+ for ( var i = 0; second[i]; i++ )
+ if ( second[i].nodeType != 8 )
+ first.push(second[i]);
+ } else
+ for ( var i = 0; second[i]; i++ )
+ first.push(second[i]);
+
return first;
},
// If a string is passed in for the function, make a function
// for it (a handy shortcut)
if ( typeof fn == "string" )
- fn = new Function("a","i","return " + fn);
+ fn = eval("false||function(a,i){return " + fn + "}");
var result = [];
// If a string is passed in for the function, make a function
// for it (a handy shortcut)
if ( typeof fn == "string" )
- fn = new Function("a","return " + fn);
+ fn = eval("false||function(a){return " + fn + "}");
var result = [];
* @type Boolean
* @cat JavaScript
*/
-new function() {
- var b = navigator.userAgent.toLowerCase();
-
- // Figure out what browser is being used
- jQuery.browser = {
- version: (b.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
- safari: /webkit/.test(b),
- opera: /opera/.test(b),
- msie: /msie/.test(b) && !/opera/.test(b),
- mozilla: /mozilla/.test(b) && !/(compatible|webkit)/.test(b)
- };
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
+ safari: /webkit/.test(userAgent),
+ opera: /opera/.test(userAgent),
+ msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
+ mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
+};
+var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
+
+jQuery.extend({
// Check to see if the W3C box model is being used
- jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";
-
- jQuery.styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat",
-
- jQuery.props = {
+ boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+
+ styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
+
+ props: {
"for": "htmlFor",
"class": "className",
- "float": jQuery.styleFloat,
- cssFloat: jQuery.styleFloat,
- styleFloat: jQuery.styleFloat,
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
innerHTML: "innerHTML",
className: "className",
value: "value",
readonly: "readOnly",
selected: "selected",
maxlength: "maxLength"
- };
-
-};
+ }
+});
/**
* Get a set of elements containing the unique parents of the matched
var ret = jQuery.map(this,n);
if ( a && typeof a == "string" )
ret = jQuery.multiFilter(a,ret);
- return this.pushStack( ret );
+ return this.pushStack( jQuery.unique(ret) );
};
});
appendTo: "append",
prependTo: "prepend",
insertBefore: "before",
- insertAfter: "after"
+ insertAfter: "after",
+ replaceAll: "replaceWith"
}, function(i,n){
jQuery.fn[ i ] = function(){
var a = arguments;
* @param String str The string that will be contained within the text of an element.
* @cat DOM/Traversing
*/
+// DEPRECATED
jQuery.each( [ "eq", "lt", "gt", "contains" ], function(i,n){
jQuery.fn[ n ] = function(num,fn) {
return this.filter( ":" + n + "(" + num + ")", fn );