diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | build.xml | 3 | ||||
-rw-r--r-- | src/attributes.js | 390 | ||||
-rw-r--r-- | src/core.js | 856 | ||||
-rw-r--r-- | src/manipulation.js | 350 | ||||
-rw-r--r-- | src/traversing.js | 120 | ||||
-rw-r--r-- | test/index.html | 3 | ||||
-rw-r--r-- | test/unit/attributes.js | 458 | ||||
-rw-r--r-- | test/unit/core.js | 1361 | ||||
-rw-r--r-- | test/unit/fx.js | 35 | ||||
-rw-r--r-- | test/unit/manipulation.js | 596 | ||||
-rw-r--r-- | test/unit/traversing.js | 246 |
12 files changed, 2221 insertions, 2200 deletions
@@ -11,6 +11,9 @@ PLUG_DIR = ../plugins BASE_FILES = ${SRC_DIR}/core.js\ ${SRC_DIR}/data.js\ ${SRC_DIR}/selector.js\ + ${SRC_DIR}/traversing.js\ + ${SRC_DIR}/attributes.js\ + ${SRC_DIR}/manipulation.js\ ${SRC_DIR}/event.js\ ${SRC_DIR}/support.js\ ${SRC_DIR}/ajax.js\ @@ -55,6 +55,9 @@ <fileset dir="${SRC_DIR}" includes="core.js" /> <fileset dir="${SRC_DIR}" includes="data.js" /> <fileset dir="${SRC_DIR}" includes="selector.js" /> + <fileset dir="${SRC_DIR}" includes="traversing.js" /> + <fileset dir="${SRC_DIR}" includes="attributes.js" /> + <fileset dir="${SRC_DIR}" includes="manipulation.js" /> <fileset dir="${SRC_DIR}" includes="event.js" /> <fileset dir="${SRC_DIR}" includes="support.js" /> <fileset dir="${SRC_DIR}" includes="ajax.js" /> diff --git a/src/attributes.js b/src/attributes.js new file mode 100644 index 000000000..8d5c2229c --- /dev/null +++ b/src/attributes.js @@ -0,0 +1,390 @@ +jQuery.fn.extend({ + attr: function( name, value, type ) { + var options = name, isFunction = jQuery.isFunction( value ); + + // Look for the case where we're accessing a style value + if ( typeof name === "string" ) { + if ( value === undefined ) { + return this.length ? + jQuery[ type || "attr" ]( this[0], name ) : + null; + + } else { + options = {}; + options[ name ] = value; + } + } + + // Check to see if we're setting style values + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; + + // Set all the styles + for ( var prop in options ) { + value = options[prop]; + + if ( isFunction ) { + value = value.call( elem, i ); + } + + if ( typeof value === "number" && type === "curCSS" && !exclude.test(prop) ) { + value = value + "px"; + } + + jQuery.attr( type ? elem.style : elem, prop, value ); + } + } + + return this; + }, + + css: function( key, value ) { + // ignore negative width and height values + if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) + value = undefined; + return this.attr( key, value, "curCSS" ); + }, + + hasClass: function( selector ) { + return !!selector && this.is( "." + selector ); + }, + + val: function( value ) { + if ( value === undefined ) { + var elem = this[0]; + + if ( elem ) { + if( jQuery.nodeName( elem, 'option' ) ) + return (elem.attributes.value || {}).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 ]; + + if ( option.selected ) { + // Get the specifc 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; + } + + // Everything else, we just grab the value + return (elem.value || "").replace(/\r/g, ""); + + } + + return undefined; + } + + if ( typeof value === "number" ) + value += ''; + + return this.each(function(){ + if ( this.nodeType != 1 ) + return; + + if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) + this.checked = (jQuery.inArray(this.value, value) >= 0 || + jQuery.inArray(this.name, value) >= 0); + + else if ( jQuery.nodeName( this, "select" ) ) { + var values = jQuery.makeArray(value); + + jQuery( "option", this ).each(function(){ + this.selected = (jQuery.inArray( this.value, values ) >= 0 || + jQuery.inArray( this.text, values ) >= 0); + }); + + if ( !values.length ) + this.selectedIndex = -1; + + } else + this.value = value; + }); + } +}); + +jQuery.each({ + removeAttr: function( name ) { + jQuery.attr( this, name, "" ); + if (this.nodeType == 1) + this.removeAttribute( name ); + }, + + addClass: function( classNames ) { + jQuery.className.add( this, classNames ); + }, + + removeClass: function( classNames ) { + jQuery.className.remove( this, classNames ); + }, + + toggleClass: function( classNames, state ) { + if( typeof state !== "boolean" ) + state = !jQuery.className.has( this, classNames ); + jQuery.className[ state ? "add" : "remove" ]( this, classNames ); + } +}, function(name, fn){ + jQuery.fn[ name ] = function(){ + return this.each( fn, arguments ); + }; +}); + +jQuery.extend({ + className: { + // internal only, use addClass("class") + add: function( elem, classNames ) { + jQuery.each((classNames || "").split(/\s+/), function(i, className){ + if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) + elem.className += (elem.className ? " " : "") + className; + }); + }, + + // internal only, use removeClass("class") + remove: function( elem, classNames ) { + if (elem.nodeType == 1) + elem.className = classNames !== undefined ? + jQuery.grep(elem.className.split(/\s+/), function(className){ + return !jQuery.className.has( classNames, className ); + }).join(" ") : + ""; + }, + + // internal only, use hasClass("class") + has: function( elem, className ) { + return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; + } + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var old = {}; + // Remember the old values, and insert the new ones + for ( var name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + callback.call( elem ); + + // Revert the old values + for ( var name in options ) + elem.style[ name ] = old[ name ]; + }, + + css: function( elem, name, force, extra ) { + if ( name == "width" || name == "height" ) { + var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; + + function getWH() { + val = name == "width" ? elem.offsetWidth : elem.offsetHeight; + + if ( extra === "border" ) + return; + + jQuery.each( which, function() { + if ( !extra ) + val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; + if ( extra === "margin" ) + val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; + else + val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; + }); + } + + if ( elem.offsetWidth !== 0 ) + getWH(); + else + jQuery.swap( elem, props, getWH ); + + return Math.max(0, Math.round(val)); + } + + return jQuery.curCSS( elem, name, force ); + }, + + curCSS: function( elem, name, force ) { + var ret, style = elem.style; + + // We need to handle opacity special in IE + if ( name == "opacity" && !jQuery.support.opacity ) { + ret = jQuery.attr( style, "opacity" ); + + return ret == "" ? + "1" : + ret; + } + + // Make sure we're using the right name for getting the float value + if ( name.match( /float/i ) ) + name = styleFloat; + + if ( !force && style && style[ name ] ) + ret = style[ name ]; + + else if ( defaultView.getComputedStyle ) { + + // Only "float" is needed here + if ( name.match( /float/i ) ) + name = "float"; + + name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); + + var computedStyle = defaultView.getComputedStyle( elem, null ); + + if ( computedStyle ) + ret = computedStyle.getPropertyValue( name ); + + // We should always get a number back from opacity + if ( name == "opacity" && ret == "" ) + ret = "1"; + + } else if ( elem.currentStyle ) { + var camelCase = name.replace(/\-(\w)/g, function(all, letter){ + return letter.toUpperCase(); + }); + + ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { + // Remember the original values + var left = style.left, rsLeft = elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + elem.runtimeStyle.left = elem.currentStyle.left; + style.left = ret || 0; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + elem.runtimeStyle.left = rsLeft; + } + } + + return ret; + }, + + attr: function( elem, name, value ) { + // don't set attributes on text and comment nodes + if (!elem || elem.nodeType == 3 || elem.nodeType == 8) + return undefined; + + var notxml = !elem.tagName || !jQuery.isXMLDoc( elem ), + // Whether we are setting (or getting) + set = value !== undefined; + + // Try to normalize/fix the name + name = notxml && jQuery.props[ name ] || name; + + // Only do all the following if this is a node (faster for style) + // IE elem.getAttribute passes even for style + if ( elem.tagName ) { + + // These attributes require special treatment + var special = /href|src|style/.test( name ); + + // Safari mis-reports the default selected property of a hidden option + // Accessing the parent's selectedIndex property fixes it + if ( name == "selected" && elem.parentNode ) + elem.parentNode.selectedIndex; + + // If applicable, access the attribute via the DOM 0 way + if ( name in elem && notxml && !special ) { + if ( set ){ + // We can't allow the type property to be changed (since it causes problems in IE) + if ( name == "type" && elem.nodeName.match(/(button|input)/i) && elem.parentNode ) + throw "type property can't be changed"; + + 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 + : elem.nodeName.match(/(button|input|object|select|textarea)/i) + ? 0 + : elem.nodeName.match(/^(a|area)$/i) && elem.href + ? 0 + : undefined; + } + + return elem[ name ]; + } + + if ( !jQuery.support.style && notxml && name == "style" ) + return jQuery.attr( elem.style, "cssText", value ); + + if ( set ) + // convert the value to a string (all browsers do this but IE) see #1070 + elem.setAttribute( name, "" + value ); + + 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; + } + + // elem is actually elem.style ... set the style + + // IE uses filters for opacity + if ( !jQuery.support.opacity && name == "opacity" ) { + if ( set ) { + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + elem.zoom = 1; + + // Set the alpha filter to set the opacity + elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + + (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); + } + + return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? + (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '': + ""; + } + + name = name.replace(/-([a-z])/ig, function(all, letter){ + return letter.toUpperCase(); + }); + + if ( set ) + elem[ name ] = value; + + return elem[ name ]; + } +});
\ No newline at end of file diff --git a/src/core.js b/src/core.js index 56fbbde1c..9c3526152 100644 --- a/src/core.js +++ b/src/core.js @@ -165,399 +165,15 @@ jQuery.fn = jQuery.prototype = { , this ); }, - attr: function( name, value, type ) { - var options = name, isFunction = jQuery.isFunction( value ); - - // Look for the case where we're accessing a style value - if ( typeof name === "string" ) { - if ( value === undefined ) { - return this.length ? - jQuery[ type || "attr" ]( this[0], name ) : - null; - - } else { - options = {}; - options[ name ] = value; - } - } - - // Check to see if we're setting style values - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; - - // Set all the styles - for ( var prop in options ) { - value = options[prop]; - - if ( isFunction ) { - value = value.call( elem, i ); - } - - if ( typeof value === "number" && type === "curCSS" && !exclude.test(prop) ) { - value = value + "px"; - } - - jQuery.attr( type ? elem.style : elem, prop, value ); - } - } - - return this; - }, - - css: function( key, value ) { - // ignore negative width and height values - if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) - value = undefined; - return this.attr( key, value, "curCSS" ); - }, - - text: function( text ) { - if ( typeof text !== "object" && text != null ) - return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); - - var ret = ""; - - jQuery.each( text || this, function(){ - jQuery.each( this.childNodes, function(){ - if ( this.nodeType != 8 ) - ret += this.nodeType != 1 ? - this.nodeValue : - jQuery.fn.text( [ this ] ); - }); - }); - - return ret; - }, - - wrapAll: function( html ) { - if ( this[0] ) { - // The elements to wrap the target around - var wrap = jQuery( html, this[0].ownerDocument ).clone(); - - if ( this[0].parentNode ) - wrap.insertBefore( this[0] ); - - wrap.map(function(){ - var elem = this; - - while ( elem.firstChild ) - elem = elem.firstChild; - - return elem; - }).append(this); - } - - return this; - }, - - wrapInner: function( html ) { - return this.each(function(){ - jQuery( this ).contents().wrapAll( html ); - }); - }, - - wrap: function( html ) { - return this.each(function(){ - jQuery( this ).wrapAll( html ); - }); - }, - - append: function() { - return this.domManip(arguments, true, function(elem){ - if (this.nodeType == 1) - this.appendChild( elem ); - }); - }, - - prepend: function() { - return this.domManip(arguments, true, function(elem){ - if (this.nodeType == 1) - this.insertBefore( elem, this.firstChild ); - }); - }, - - before: function() { - return this.domManip(arguments, false, function(elem){ - this.parentNode.insertBefore( elem, this ); - }); - }, - - after: function() { - return this.domManip(arguments, false, function(elem){ - this.parentNode.insertBefore( elem, this.nextSibling ); - }); - }, - - end: function() { - return this.prevObject || jQuery(null); + is: function( selector ) { + return !!selector && jQuery.multiFilter( selector, this ).length > 0; }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: [].push, sort: [].sort, - splice: [].splice, - - find: function( selector ) { - 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; - }, - - clone: function( events ) { - // Do the clone - var ret = this.map(function(){ - if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { - // IE copies events bound via attachEvent when - // using cloneNode. Calling detachEvent on the - // clone will also remove the events from the orignal - // In order to get around this, we use innerHTML. - // Unfortunately, this means some modifications to - // attributes in IE that are actually only stored - // as properties will not be copied (such as the - // the name attribute on an input). - var html = this.outerHTML, ownerDocument = this.ownerDocument; - if ( !html ) { - var div = ownerDocument.createElement("div"); - div.appendChild( this.cloneNode(true) ); - html = div.innerHTML; - } - - return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")], ownerDocument)[0]; - } else - return this.cloneNode(true); - }); - - // Copy the events from the original to the clone - if ( events === true ) { - var orig = this.find("*").andSelf(), i = 0; - - ret.find("*").andSelf().each(function(){ - if ( this.nodeName !== orig[i].nodeName ) - return; - - var events = jQuery.data( orig[i], "events" ); - - for ( var type in events ) { - for ( var handler in events[ type ] ) { - jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); - } - } - - i++; - }); - } - - // Return the cloned set - return ret; - }, - - filter: function( selector ) { - return this.pushStack( - jQuery.isFunction( selector ) && - jQuery.grep(this, function(elem, i){ - return selector.call( elem, i ); - }) || - - jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ - return elem.nodeType === 1; - }) ), "filter", selector ); - }, - - closest: function( selector ) { - var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null, - closer = 0; - - return this.map(function(){ - var cur = this; - while ( cur && cur.ownerDocument ) { - if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) { - jQuery.data(cur, "closest", closer); - return cur; - } - cur = cur.parentNode; - closer++; - } - }); - }, - - not: function( selector ) { - if ( typeof selector === "string" ) - // test special case where just one selector is passed in - if ( isSimple.test( selector ) ) - return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); - else - selector = jQuery.multiFilter( selector, this ); - - var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; - return this.filter(function() { - return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; - }); - }, - - add: function( selector ) { - return this.pushStack( jQuery.unique( jQuery.merge( - this.get(), - typeof selector === "string" ? - jQuery( selector ) : - jQuery.makeArray( selector ) - ))); - }, - - is: function( selector ) { - return !!selector && jQuery.multiFilter( selector, this ).length > 0; - }, - - hasClass: function( selector ) { - return !!selector && this.is( "." + selector ); - }, - - val: function( value ) { - if ( value === undefined ) { - var elem = this[0]; - - if ( elem ) { - if( jQuery.nodeName( elem, 'option' ) ) - return (elem.attributes.value || {}).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 ]; - - if ( option.selected ) { - // Get the specifc 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; - } - - // Everything else, we just grab the value - return (elem.value || "").replace(/\r/g, ""); - - } - - return undefined; - } - - if ( typeof value === "number" ) - value += ''; - - return this.each(function(){ - if ( this.nodeType != 1 ) - return; - - if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) - this.checked = (jQuery.inArray(this.value, value) >= 0 || - jQuery.inArray(this.name, value) >= 0); - - else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(value); - - jQuery( "option", this ).each(function(){ - this.selected = (jQuery.inArray( this.value, values ) >= 0 || - jQuery.inArray( this.text, values ) >= 0); - }); - - if ( !values.length ) - this.selectedIndex = -1; - - } else - this.value = value; - }); - }, - - html: function( value ) { - return value === undefined ? - (this[0] ? - this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : - null) : - this.empty().append( value ); - }, - - replaceWith: function( value ) { - return this.after( value ).remove(); - }, - - eq: function( i ) { - return this.slice( i, +i + 1 ); - }, - - slice: function() { - return this.pushStack( Array.prototype.slice.apply( this, arguments ), - "slice", Array.prototype.slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function(elem, i){ - return callback.call( elem, i, elem ); - })); - }, - - andSelf: function() { - return this.add( this.prevObject ); - }, - - domManip: function( args, table, callback ) { - if ( this[0] ) { - var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), - scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), - first = fragment.firstChild; - - if ( first ) - for ( var i = 0, l = this.length; i < l; i++ ) - callback.call( root(this[i], first), this.length > 1 || i > 0 ? - fragment.cloneNode(true) : fragment ); - - if ( scripts ) - jQuery.each( scripts, evalScript ); - } - - return this; - - function root( elem, cur ) { - return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? - (elem.getElementsByTagName("tbody")[0] || - elem.appendChild(elem.ownerDocument.createElement("tbody"))) : - elem; - } - } + splice: [].splice }; // Give the init function the jQuery prototype for later instantiation @@ -632,11 +248,7 @@ jQuery.extend = jQuery.fn.extend = function() { return target; }; -// exclude the following css properties to add px -var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, - // cache defaultView - defaultView = document.defaultView || {}, - toString = Object.prototype.toString; +var toString = Object.prototype.toString; jQuery.extend({ noConflict: function( deep ) { @@ -718,363 +330,6 @@ jQuery.extend({ return object; }, - className: { - // internal only, use addClass("class") - add: function( elem, classNames ) { - jQuery.each((classNames || "").split(/\s+/), function(i, className){ - if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) - elem.className += (elem.className ? " " : "") + className; - }); - }, - - // internal only, use removeClass("class") - remove: function( elem, classNames ) { - if (elem.nodeType == 1) - elem.className = classNames !== undefined ? - jQuery.grep(elem.className.split(/\s+/), function(className){ - return !jQuery.className.has( classNames, className ); - }).join(" ") : - ""; - }, - - // internal only, use hasClass("class") - has: function( elem, className ) { - return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; - } - }, - - // A method for quickly swapping in/out CSS properties to get correct calculations - swap: function( elem, options, callback ) { - var old = {}; - // Remember the old values, and insert the new ones - for ( var name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - callback.call( elem ); - - // Revert the old values - for ( var name in options ) - elem.style[ name ] = old[ name ]; - }, - - css: function( elem, name, force, extra ) { - if ( name == "width" || name == "height" ) { - var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; - - function getWH() { - val = name == "width" ? elem.offsetWidth : elem.offsetHeight; - - if ( extra === "border" ) - return; - - jQuery.each( which, function() { - if ( !extra ) - val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; - if ( extra === "margin" ) - val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; - else - val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; - }); - } - - if ( elem.offsetWidth !== 0 ) - getWH(); - else - jQuery.swap( elem, props, getWH ); - - return Math.max(0, Math.round(val)); - } - - return jQuery.curCSS( elem, name, force ); - }, - - curCSS: function( elem, name, force ) { - var ret, style = elem.style; - - // We need to handle opacity special in IE - if ( name == "opacity" && !jQuery.support.opacity ) { - ret = jQuery.attr( style, "opacity" ); - - return ret == "" ? - "1" : - ret; - } - - // Make sure we're using the right name for getting the float value - if ( name.match( /float/i ) ) - name = styleFloat; - - if ( !force && style && style[ name ] ) - ret = style[ name ]; - - else if ( defaultView.getComputedStyle ) { - - // Only "float" is needed here - if ( name.match( /float/i ) ) - name = "float"; - - name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); - - var computedStyle = defaultView.getComputedStyle( elem, null ); - - if ( computedStyle ) - ret = computedStyle.getPropertyValue( name ); - - // We should always get a number back from opacity - if ( name == "opacity" && ret == "" ) - ret = "1"; - - } else if ( elem.currentStyle ) { - var camelCase = name.replace(/\-(\w)/g, function(all, letter){ - return letter.toUpperCase(); - }); - - ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; - - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - - // If we're not dealing with a regular pixel number - // but a number that has a weird ending, we need to convert it to pixels - if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { - // Remember the original values - var left = style.left, rsLeft = elem.runtimeStyle.left; - - // Put in the new values to get a computed value out - elem.runtimeStyle.left = elem.currentStyle.left; - style.left = ret || 0; - ret = style.pixelLeft + "px"; - - // Revert the changed values - style.left = left; - elem.runtimeStyle.left = rsLeft; - } - } - - return ret; - }, - - clean: function( elems, context, fragment ) { - context = context || document; - - // !context.createElement fails in IE with an error but returns typeof 'object' - if ( typeof context.createElement === "undefined" ) - context = context.ownerDocument || context[0] && context[0].ownerDocument || document; - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { - var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); - if ( match ) - return [ context.createElement( match[1] ) ]; - } - - var ret = [], scripts = [], div = context.createElement("div"); - - jQuery.each(elems, function(i, elem){ - if ( typeof elem === "number" ) - elem += ''; - - if ( !elem ) - return; - - // Convert html string into DOM nodes - if ( typeof elem === "string" ) { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ - return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? - all : - front + "></" + tag + ">"; - }); - - // Trim whitespace, otherwise indexOf won't work as expected - var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); - - var wrap = - // option or optgroup - !tags.indexOf("<opt") && - [ 1, "<select multiple='multiple'>", "</select>" ] || - - !tags.indexOf("<leg") && - [ 1, "<fieldset>", "</fieldset>" ] || - - tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && - [ 1, "<table>", "</table>" ] || - - !tags.indexOf("<tr") && - [ 2, "<table><tbody>", "</tbody></table>" ] || - - // <thead> matched above - (!tags.indexOf("<td") || !tags.indexOf("<th")) && - [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || - - !tags.indexOf("<col") && - [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || - - // IE can't serialize <link> and <script> tags normally - !jQuery.support.htmlSerialize && - [ 1, "div<div>", "</div>" ] || - - [ 0, "", "" ]; - - // Go to html and back, then peel off extra wrappers - div.innerHTML = wrap[1] + elem + wrap[2]; - - // Move to the right depth - while ( wrap[0]-- ) - div = div.lastChild; - - // Remove IE's autoinserted <tbody> from table fragments - if ( !jQuery.support.tbody ) { - - // String was a <table>, *may* have spurious <tbody> - var hasBody = /<tbody/i.test(elem), - tbody = !tags.indexOf("<table") && !hasBody ? - div.firstChild && div.firstChild.childNodes : - - // String was a bare <thead> or <tfoot> - wrap[1] == "<table>" && !hasBody ? - div.childNodes : - []; - - for ( var j = tbody.length - 1; j >= 0 ; --j ) - if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) - tbody[ j ].parentNode.removeChild( tbody[ j ] ); - - } - - // IE completely kills leading whitespace when innerHTML is used - if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) ) - div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); - - elem = jQuery.makeArray( div.childNodes ); - } - - if ( elem.nodeType ) - ret.push( elem ); - else - ret = jQuery.merge( ret, elem ); - - }); - - if ( fragment ) { - for ( var i = 0; ret[i]; i++ ) { - if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { - scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); - } else { - if ( ret[i].nodeType === 1 ) - ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); - fragment.appendChild( ret[i] ); - } - } - - return scripts; - } - - return ret; - }, - - attr: function( elem, name, value ) { - // don't set attributes on text and comment nodes - if (!elem || elem.nodeType == 3 || elem.nodeType == 8) - return undefined; - - var notxml = !elem.tagName || !jQuery.isXMLDoc( elem ), - // Whether we are setting (or getting) - set = value !== undefined; - - // Try to normalize/fix the name - name = notxml && jQuery.props[ name ] || name; - - // Only do all the following if this is a node (faster for style) - // IE elem.getAttribute passes even for style - if ( elem.tagName ) { - - // These attributes require special treatment - var special = /href|src|style/.test( name ); - - // Safari mis-reports the default selected property of a hidden option - // Accessing the parent's selectedIndex property fixes it - if ( name == "selected" && elem.parentNode ) - elem.parentNode.selectedIndex; - - // If applicable, access the attribute via the DOM 0 way - if ( name in elem && notxml && !special ) { - if ( set ){ - // We can't allow the type property to be changed (since it causes problems in IE) - if ( name == "type" && elem.nodeName.match(/(button|input)/i) && elem.parentNode ) - throw "type property can't be changed"; - - 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 - : elem.nodeName.match(/(button|input|object|select|textarea)/i) - ? 0 - : elem.nodeName.match(/^(a|area)$/i) && elem.href - ? 0 - : undefined; - } - - return elem[ name ]; - } - - if ( !jQuery.support.style && notxml && name == "style" ) - return jQuery.attr( elem.style, "cssText", value ); - - if ( set ) - // convert the value to a string (all browsers do this but IE) see #1070 - elem.setAttribute( name, "" + value ); - - 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; - } - - // elem is actually elem.style ... set the style - - // IE uses filters for opacity - if ( !jQuery.support.opacity && name == "opacity" ) { - if ( set ) { - // IE has trouble with opacity if it does not have layout - // Force it by setting the zoom level - elem.zoom = 1; - - // Set the alpha filter to set the opacity - elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + - (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); - } - - return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? - (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '': - ""; - } - - name = name.replace(/-([a-z])/ig, function(all, letter){ - return letter.toUpperCase(); - }); - - if ( set ) - elem[ name ] = value; - - return elem[ name ]; - }, - trim: function( text ) { return (text || "").replace( /^\s+|\s+$/g, "" ); }, @@ -1187,105 +442,4 @@ jQuery.browser = { opera: /opera/.test( userAgent ), msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) -}; - -jQuery.each({ - parent: function(elem){return elem.parentNode;}, - parents: function(elem){return jQuery.dir(elem,"parentNode");}, - 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");}, - 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( selector ) { - var ret = jQuery.map( this, fn ); - - if ( selector && typeof selector == "string" ) - ret = jQuery.multiFilter( selector, ret ); - - return this.pushStack( jQuery.unique( ret ), name, selector ); - }; -}); - -jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function(name, original){ - jQuery.fn[ name ] = function( selector ) { - var ret = [], insert = jQuery( selector ); - - for ( var i = 0, l = insert.length; i < l; i++ ) { - var elems = (i > 0 ? this.clone(true) : this).get(); - jQuery.fn[ original ].apply( jQuery(insert[i]), elems ); - ret = ret.concat( elems ); - } - - return this.pushStack( ret, name, selector ); - }; -}); - -jQuery.each({ - removeAttr: function( name ) { - jQuery.attr( this, name, "" ); - if (this.nodeType == 1) - this.removeAttribute( name ); - }, - - addClass: function( classNames ) { - jQuery.className.add( this, classNames ); - }, - - removeClass: function( classNames ) { - jQuery.className.remove( this, classNames ); - }, - - toggleClass: function( classNames, state ) { - if( typeof state !== "boolean" ) - state = !jQuery.className.has( this, classNames ); - jQuery.className[ state ? "add" : "remove" ]( this, classNames ); - }, - - remove: function( selector ) { - if ( !selector || jQuery.multiFilter( selector, [ this ] ).length ) { - if ( this.nodeType === 1 ) { - cleanData( this.getElementsByTagName("*") ); - cleanData( [this] ); - } - - if ( this.parentNode ) { - this.parentNode.removeChild( this ); - } - } - }, - - empty: function() { - // Remove element nodes and prevent memory leaks - if ( this.nodeType === 1 ) { - cleanData( this.getElementsByTagName("*") ); - } - - // Remove any remaining nodes - while ( this.firstChild ) { - this.removeChild( this.firstChild ); - } - } -}, function(name, fn){ - jQuery.fn[ name ] = function(){ - return this.each( fn, arguments ); - }; -}); - -function cleanData( elems ) { - for ( var i = 0, l = elems.length; i < l; i++ ) { - var id = elems[i][expando]; - if ( id ) { - delete jQuery.cache[ id ]; - } - } -} +};
\ No newline at end of file diff --git a/src/manipulation.js b/src/manipulation.js new file mode 100644 index 000000000..c2c0ff2a7 --- /dev/null +++ b/src/manipulation.js @@ -0,0 +1,350 @@ +// exclude the following css properties to add px +var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, + // cache defaultView + defaultView = document.defaultView || {}; + +jQuery.fn.extend({ + text: function( text ) { + if ( typeof text !== "object" && text != null ) + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); + + var ret = ""; + + jQuery.each( text || this, function(){ + jQuery.each( this.childNodes, function(){ + if ( this.nodeType != 8 ) + ret += this.nodeType != 1 ? + this.nodeValue : + jQuery.fn.text( [ this ] ); + }); + }); + + return ret; + }, + + wrapAll: function( html ) { + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).clone(); + + if ( this[0].parentNode ) + wrap.insertBefore( this[0] ); + + wrap.map(function(){ + var elem = this; + + while ( elem.firstChild ) + elem = elem.firstChild; + + return elem; + }).append(this); + } + + return this; + }, + + wrapInner: function( html ) { + return this.each(function(){ + jQuery( this ).contents().wrapAll( html ); + }); + }, + + wrap: function( html ) { + return this.each(function(){ + jQuery( this ).wrapAll( html ); + }); + }, + + append: function() { + return this.domManip(arguments, true, function(elem){ + if (this.nodeType == 1) + this.appendChild( elem ); + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function(elem){ + if (this.nodeType == 1) + this.insertBefore( elem, this.firstChild ); + }); + }, + + before: function() { + return this.domManip(arguments, false, function(elem){ + this.parentNode.insertBefore( elem, this ); + }); + }, + + after: function() { + return this.domManip(arguments, false, function(elem){ + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + }, + + clone: function( events ) { + // Do the clone + var ret = this.map(function(){ + if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { + // IE copies events bound via attachEvent when + // using cloneNode. Calling detachEvent on the + // clone will also remove the events from the orignal + // In order to get around this, we use innerHTML. + // Unfortunately, this means some modifications to + // attributes in IE that are actually only stored + // as properties will not be copied (such as the + // the name attribute on an input). + var html = this.outerHTML, ownerDocument = this.ownerDocument; + if ( !html ) { + var div = ownerDocument.createElement("div"); + div.appendChild( this.cloneNode(true) ); + html = div.innerHTML; + } + + return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")], ownerDocument)[0]; + } else + return this.cloneNode(true); + }); + + // Copy the events from the original to the clone + if ( events === true ) { + var orig = this.find("*").andSelf(), i = 0; + + ret.find("*").andSelf().each(function(){ + if ( this.nodeName !== orig[i].nodeName ) + return; + + var events = jQuery.data( orig[i], "events" ); + + for ( var type in events ) { + for ( var handler in events[ type ] ) { + jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); + } + } + + i++; + }); + } + + // Return the cloned set + return ret; + }, + + html: function( value ) { + return value === undefined ? + (this[0] ? + this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : + null) : + this.empty().append( value ); + }, + + replaceWith: function( value ) { + return this.after( value ).remove(); + }, + + domManip: function( args, table, callback ) { + if ( this[0] ) { + var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), + scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), + first = fragment.firstChild; + + if ( first ) + for ( var i = 0, l = this.length; i < l; i++ ) + callback.call( root(this[i], first), this.length > 1 || i > 0 ? + fragment.cloneNode(true) : fragment ); + + if ( scripts ) + jQuery.each( scripts, evalScript ); + } + + return this; + + function root( elem, cur ) { + return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? + (elem.getElementsByTagName("tbody")[0] || + elem.appendChild(elem.ownerDocument.createElement("tbody"))) : + elem; + } + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function(name, original){ + jQuery.fn[ name ] = function( selector ) { + var ret = [], insert = jQuery( selector ); + + for ( var i = 0, l = insert.length; i < l; i++ ) { + var elems = (i > 0 ? this.clone(true) : this).get(); + jQuery.fn[ original ].apply( jQuery(insert[i]), elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, selector ); + }; +}); + +jQuery.each({ + remove: function( selector ) { + if ( !selector || jQuery.multiFilter( selector, [ this ] ).length ) { + if ( this.nodeType === 1 ) { + cleanData( this.getElementsByTagName("*") ); + cleanData( [this] ); + } + + if ( this.parentNode ) { + this.parentNode.removeChild( this ); + } + } + }, + + empty: function() { + // Remove element nodes and prevent memory leaks + if ( this.nodeType === 1 ) { + cleanData( this.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( this.firstChild ) { + this.removeChild( this.firstChild ); + } + } +}, function(name, fn){ + jQuery.fn[ name ] = function(){ + return this.each( fn, arguments ); + }; +}); + +jQuery.extend({ + clean: function( elems, context, fragment ) { + context = context || document; + + // !context.createElement fails in IE with an error but returns typeof 'object' + if ( typeof context.createElement === "undefined" ) + context = context.ownerDocument || context[0] && context[0].ownerDocument || document; + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { + var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); + if ( match ) + return [ context.createElement( match[1] ) ]; + } + + var ret = [], scripts = [], div = context.createElement("div"); + + jQuery.each(elems, function(i, elem){ + if ( typeof elem === "number" ) + elem += ''; + + if ( !elem ) + return; + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ + return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? + all : + front + "></" + tag + ">"; + }); + + // Trim whitespace, otherwise indexOf won't work as expected + var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); + + var wrap = + // option or optgroup + !tags.indexOf("<opt") && + [ 1, "<select multiple='multiple'>", "</select>" ] || + + !tags.indexOf("<leg") && + [ 1, "<fieldset>", "</fieldset>" ] || + + tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && + [ 1, "<table>", "</table>" ] || + + !tags.indexOf("<tr") && + [ 2, "<table><tbody>", "</tbody></table>" ] || + + // <thead> matched above + (!tags.indexOf("<td") || !tags.indexOf("<th")) && + [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || + + !tags.indexOf("<col") && + [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || + + // IE can't serialize <link> and <script> tags normally + !jQuery.support.htmlSerialize && + [ 1, "div<div>", "</div>" ] || + + [ 0, "", "" ]; + + // Go to html and back, then peel off extra wrappers + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( wrap[0]-- ) + div = div.lastChild; + + // Remove IE's autoinserted <tbody> from table fragments + if ( !jQuery.support.tbody ) { + + // String was a <table>, *may* have spurious <tbody> + var hasBody = /<tbody/i.test(elem), + tbody = !tags.indexOf("<table") && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare <thead> or <tfoot> + wrap[1] == "<table>" && !hasBody ? + div.childNodes : + []; + + for ( var j = tbody.length - 1; j >= 0 ; --j ) + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) ) + div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); + + elem = jQuery.makeArray( div.childNodes ); + } + + if ( elem.nodeType ) + ret.push( elem ); + else + ret = jQuery.merge( ret, elem ); + + }); + + if ( fragment ) { + for ( var i = 0; ret[i]; i++ ) { + if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { + scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); + } else { + if ( ret[i].nodeType === 1 ) + ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); + fragment.appendChild( ret[i] ); + } + } + + return scripts; + } + + return ret; + } +}); + +function cleanData( elems ) { + for ( var i = 0, l = elems.length; i < l; i++ ) { + var id = elems[i][expando]; + if ( id ) { + delete jQuery.cache[ id ]; + } + } +} diff --git a/src/traversing.js b/src/traversing.js new file mode 100644 index 000000000..d78884798 --- /dev/null +++ b/src/traversing.js @@ -0,0 +1,120 @@ +jQuery.fn.extend({ + find: function( selector ) { + 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; + }, + + filter: function( selector ) { + return this.pushStack( + jQuery.isFunction( selector ) && + jQuery.grep(this, function(elem, i){ + return selector.call( elem, i ); + }) || + + jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ + return elem.nodeType === 1; + }) ), "filter", selector ); + }, + + closest: function( selector ) { + var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null, + closer = 0; + + return this.map(function(){ + var cur = this; + while ( cur && cur.ownerDocument ) { + if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) { + jQuery.data(cur, "closest", closer); + return cur; + } + cur = cur.parentNode; + closer++; + } + }); + }, + + not: function( selector ) { + if ( typeof selector === "string" ) + // test special case where just one selector is passed in + if ( isSimple.test( selector ) ) + return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); + else + selector = jQuery.multiFilter( selector, this ); + + var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; + return this.filter(function() { + return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; + }); + }, + + add: function( selector ) { + return this.pushStack( jQuery.unique( jQuery.merge( + this.get(), + typeof selector === "string" ? + jQuery( selector ) : + jQuery.makeArray( selector ) + ))); + }, + + eq: function( i ) { + return this.slice( i, +i + 1 ); + }, + + slice: function() { + return this.pushStack( Array.prototype.slice.apply( this, arguments ), + "slice", Array.prototype.slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function(elem, i){ + return callback.call( elem, i, elem ); + })); + }, + + andSelf: function() { + return this.add( this.prevObject ); + }, + + end: function() { + return this.prevObject || jQuery(null); + } +}); + +jQuery.each({ + parent: function(elem){return elem.parentNode;}, + parents: function(elem){return jQuery.dir(elem,"parentNode");}, + 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");}, + 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( selector ) { + var ret = jQuery.map( this, fn ); + + if ( selector && typeof selector == "string" ) + ret = jQuery.multiFilter( selector, ret ); + + return this.pushStack( jQuery.unique( ret ), name, selector ); + }; +});
\ No newline at end of file diff --git a/test/index.html b/test/index.html index 97d9d60b5..3b78e572f 100644 --- a/test/index.html +++ b/test/index.html @@ -16,6 +16,9 @@ <script type="text/javascript" src="data/testrunner.js"></script> <script type="text/javascript" src="unit/core.js"></script> <script type="text/javascript" src="unit/data.js"></script> + <script type="text/javascript" src="unit/attributes.js"></script> + <script type="text/javascript" src="unit/traversing.js"></script> + <script type="text/javascript" src="unit/manipulation.js"></script> <script type="text/javascript" src="unit/dimensions.js"></script> <script type="text/javascript" src="unit/selector.js"></script> <script type="text/javascript" src="unit/event.js"></script> diff --git a/test/unit/attributes.js b/test/unit/attributes.js new file mode 100644 index 000000000..e6a30a1b8 --- /dev/null +++ b/test/unit/attributes.js @@ -0,0 +1,458 @@ +test("attr(String)", function() { + expect(27); + equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' ); + equals( jQuery('#text1').attr('value', "Test2").attr('defaultValue'), "Test", 'Check for defaultValue attribute' ); + equals( jQuery('#text1').attr('type'), "text", 'Check for type attribute' ); + equals( jQuery('#radio1').attr('type'), "radio", 'Check for type attribute' ); + equals( jQuery('#check1').attr('type'), "checkbox", 'Check for type attribute' ); + equals( jQuery('#simon1').attr('rel'), "bookmark", 'Check for rel attribute' ); + equals( jQuery('#google').attr('title'), "Google!", 'Check for title attribute' ); + equals( jQuery('#mark').attr('hreflang'), "en", 'Check for hreflang attribute' ); + equals( jQuery('#en').attr('lang'), "en", 'Check for lang attribute' ); + equals( jQuery('#simon').attr('class'), "blog link", 'Check for class attribute' ); + equals( jQuery('#name').attr('name'), "name", 'Check for name attribute' ); + equals( jQuery('#text1').attr('name'), "action", 'Check for name attribute' ); + ok( jQuery('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' ); + equals( jQuery('#text1').attr('maxlength'), '30', 'Check for maxlength attribute' ); + equals( jQuery('#text1').attr('maxLength'), '30', 'Check for maxLength attribute' ); + equals( jQuery('#area1').attr('maxLength'), '30', 'Check for maxLength attribute' ); + equals( jQuery('#select2').attr('selectedIndex'), 3, 'Check for selectedIndex attribute' ); + equals( jQuery('#foo').attr('nodeName').toUpperCase(), 'DIV', 'Check for nodeName attribute' ); + equals( jQuery('#foo').attr('tagName').toUpperCase(), 'DIV', 'Check for tagName attribute' ); + + jQuery('<a id="tAnchor5"></a>').attr('href', '#5').appendTo('#main'); // using innerHTML in IE causes href attribute to be serialized to the full path + equals( jQuery('#tAnchor5').attr('href'), "#5", 'Check for non-absolute href (an anchor)' ); + + equals( jQuery("<option/>").attr("selected"), false, "Check selected attribute on disconnected element." ); + + + // Related to [5574] and [5683] + var body = document.body, $body = jQuery(body); + + ok( $body.attr('foo') === undefined, 'Make sure that a non existent attribute returns undefined' ); + ok( $body.attr('nextSibling') === null, 'Make sure a null expando returns null' ); + + body.setAttribute('foo', 'baz'); + equals( $body.attr('foo'), 'baz', 'Make sure the dom attribute is retrieved when no expando is found' ); + + body.foo = 'bar'; + equals( $body.attr('foo'), 'bar', 'Make sure the expando is preferred over the dom attribute' ); + + $body.attr('foo','cool'); + equals( $body.attr('foo'), 'cool', 'Make sure that setting works well when both expando and dom attribute are available' ); + + body.foo = undefined; + ok( $body.attr('foo') === undefined, 'Make sure the expando is preferred over the dom attribute, even if undefined' ); + + body.removeAttribute('foo'); // Cleanup +}); + +if ( !isLocal ) { + test("attr(String) in XML Files", function() { + expect(2); + stop(); + jQuery.get("data/dashboard.xml", function(xml) { + equals( jQuery("locations", xml).attr("class"), "foo", "Check class attribute in XML document" ); + equals( jQuery("location", xml).attr("for"), "bar", "Check for attribute in XML document" ); + start(); + }); + }); +} + +test("attr(String, Function)", function() { + expect(2); + equals( jQuery('#text1').attr('value', function() { return this.id })[0].value, "text1", "Set value from id" ); + equals( jQuery('#text1').attr('title', function(i) { return i }).attr('title'), "0", "Set value with an index"); +}); + +test("attr(Hash)", function() { + expect(1); + var pass = true; + jQuery("div").attr({foo: 'baz', zoo: 'ping'}).each(function(){ + if ( this.getAttribute('foo') != "baz" && this.getAttribute('zoo') != "ping" ) pass = false; + }); + ok( pass, "Set Multiple Attributes" ); +}); + +test("attr(String, Object)", function() { + expect(21); + var div = jQuery("div").attr("foo", "bar"), + fail = false; + for ( var i = 0; i < div.size(); i++ ) { + if ( div.get(i).getAttribute('foo') != "bar" ){ + fail = i; + break; + } + } + equals( fail, false, "Set Attribute, the #"+fail+" element didn't get the attribute 'foo'" ); + + ok( jQuery("#foo").attr({"width": null}), "Try to set an attribute to nothing" ); + + jQuery("#name").attr('name', 'something'); + equals( jQuery("#name").attr('name'), 'something', 'Set name attribute' ); + jQuery("#check2").attr('checked', true); + equals( document.getElementById('check2').checked, true, 'Set checked attribute' ); + jQuery("#check2").attr('checked', false); + equals( document.getElementById('check2').checked, false, 'Set checked attribute' ); + jQuery("#text1").attr('readonly', true); + equals( document.getElementById('text1').readOnly, true, 'Set readonly attribute' ); + jQuery("#text1").attr('readonly', false); + equals( document.getElementById('text1').readOnly, false, 'Set readonly attribute' ); + jQuery("#name").attr('maxlength', '5'); + equals( document.getElementById('name').maxLength, '5', 'Set maxlength attribute' ); + jQuery("#name").attr('maxLength', '10'); + equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' ); + + // for #1070 + jQuery("#name").attr('someAttr', '0'); + equals( jQuery("#name").attr('someAttr'), '0', 'Set attribute to a string of "0"' ); + jQuery("#name").attr('someAttr', 0); + equals( jQuery("#name").attr('someAttr'), 0, 'Set attribute to the number 0' ); + jQuery("#name").attr('someAttr', 1); + equals( jQuery("#name").attr('someAttr'), 1, 'Set attribute to the number 1' ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + + j.attr("name", "attrvalue"); + equals( j.attr("name"), "attrvalue", "Check node,textnode,comment for attr" ); + j.removeAttr("name"); + + reset(); + + var type = jQuery("#check2").attr('type'); + var thrown = false; + try { + jQuery("#check2").attr('type','hidden'); + } catch(e) { + thrown = true; + } + ok( thrown, "Exception thrown when trying to change type property" ); + equals( type, jQuery("#check2").attr('type'), "Verify that you can't change the type of an input element" ); + + var check = document.createElement("input"); + var thrown = true; + try { + jQuery(check).attr('type','checkbox'); + } catch(e) { + thrown = false; + } + ok( thrown, "Exception thrown when trying to change type property" ); + equals( "checkbox", jQuery(check).attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" ); + + var check = jQuery("<input />"); + var thrown = true; + try { + check.attr('type','checkbox'); + } catch(e) { + thrown = false; + } + ok( thrown, "Exception thrown when trying to change type property" ); + equals( "checkbox", check.attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" ); + + var button = jQuery("#button"); + var thrown = false; + try { + button.attr('type','submit'); + } catch(e) { + thrown = true; + } + ok( thrown, "Exception thrown when trying to change type property" ); + equals( "button", button.attr('type'), "Verify that you can't change the type of a button element" ); +}); + +if ( !isLocal ) { + test("attr(String, Object) - Loaded via XML document", function() { + expect(2); + stop(); + jQuery.get('data/dashboard.xml', function(xml) { + var titles = []; + jQuery('tab', xml).each(function() { + titles.push(jQuery(this).attr('title')); + }); + equals( titles[0], 'Location', 'attr() in XML context: Check first title' ); + equals( titles[1], 'Users', 'attr() in XML context: Check second title' ); + start(); + }); + }); +} + +test("attr('tabindex')", function() { + expect(8); + + // elements not natively tabbable + equals(jQuery('#listWithTabIndex').attr('tabindex'), 5, 'not natively tabbable, with tabindex set to 0'); + equals(jQuery('#divWithNoTabIndex').attr('tabindex'), undefined, 'not natively tabbable, no tabindex set'); + + // anchor with href + equals(jQuery('#linkWithNoTabIndex').attr('tabindex'), 0, 'anchor with href, no tabindex set'); + equals(jQuery('#linkWithTabIndex').attr('tabindex'), 2, 'anchor with href, tabindex set to 2'); + equals(jQuery('#linkWithNegativeTabIndex').attr('tabindex'), -1, 'anchor with href, tabindex set to -1'); + + // anchor without href + equals(jQuery('#linkWithNoHrefWithNoTabIndex').attr('tabindex'), undefined, 'anchor without href, no tabindex set'); + equals(jQuery('#linkWithNoHrefWithTabIndex').attr('tabindex'), 1, 'anchor without href, tabindex set to 2'); + equals(jQuery('#linkWithNoHrefWithNegativeTabIndex').attr('tabindex'), -1, 'anchor without href, no tabindex set'); +}); + +test("attr('tabindex', value)", function() { + expect(9); + + var element = jQuery('#divWithNoTabIndex'); + equals(element.attr('tabindex'), undefined, 'start with no tabindex'); + + // set a positive string + element.attr('tabindex', '1'); + equals(element.attr('tabindex'), 1, 'set tabindex to 1 (string)'); + + // set a zero string + element.attr('tabindex', '0'); + equals(element.attr('tabindex'), 0, 'set tabindex to 0 (string)'); + + // set a negative string + element.attr('tabindex', '-1'); + equals(element.attr('tabindex'), -1, 'set tabindex to -1 (string)'); + + // set a positive number + element.attr('tabindex', 1); + equals(element.attr('tabindex'), 1, 'set tabindex to 1 (number)'); + + // set a zero number + element.attr('tabindex', 0); + equals(element.attr('tabindex'), 0, 'set tabindex to 0 (number)'); + + // set a negative number + element.attr('tabindex', -1); + equals(element.attr('tabindex'), -1, 'set tabindex to -1 (number)'); + + element = jQuery('#linkWithTabIndex'); + equals(element.attr('tabindex'), 2, 'start with tabindex 2'); + + element.attr('tabindex', -1); + equals(element.attr('tabindex'), -1, 'set negative tabindex'); +}); + +test("css(String|Hash)", function() { + expect(19); + + equals( jQuery('#main').css("display"), 'none', 'Check for css property "display"'); + + ok( jQuery('#nothiddendiv').is(':visible'), 'Modifying CSS display: Assert element is visible'); + jQuery('#nothiddendiv').css({display: 'none'}); + ok( !jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is hidden'); + jQuery('#nothiddendiv').css({display: 'block'}); + ok( jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is visible'); + + jQuery('#floatTest').css({styleFloat: 'right'}); + equals( jQuery('#floatTest').css('styleFloat'), 'right', 'Modified CSS float using "styleFloat": Assert float is right'); + jQuery('#floatTest').css({cssFloat: 'left'}); + equals( jQuery('#floatTest').css('cssFloat'), 'left', 'Modified CSS float using "cssFloat": Assert float is left'); + jQuery('#floatTest').css({'float': 'right'}); + equals( jQuery('#floatTest').css('float'), 'right', 'Modified CSS float using "float": Assert float is right'); + jQuery('#floatTest').css({'font-size': '30px'}); + equals( jQuery('#floatTest').css('font-size'), '30px', 'Modified CSS font-size: Assert font-size is 30px'); + + jQuery.each("0,0.25,0.5,0.75,1".split(','), function(i, n) { + jQuery('#foo').css({opacity: n}); + equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a String" ); + jQuery('#foo').css({opacity: parseFloat(n)}); + equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a Number" ); + }); + jQuery('#foo').css({opacity: ''}); + equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when set to an empty String" ); +}); + +test("css(String, Object)", function() { + expect(21); + ok( jQuery('#nothiddendiv').is(':visible'), 'Modifying CSS display: Assert element is visible'); + jQuery('#nothiddendiv').css("display", 'none'); + ok( !jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is hidden'); + jQuery('#nothiddendiv').css("display", 'block'); + ok( jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is visible'); + + jQuery('#floatTest').css('styleFloat', 'left'); + equals( jQuery('#floatTest').css('styleFloat'), 'left', 'Modified CSS float using "styleFloat": Assert float is left'); + jQuery('#floatTest').css('cssFloat', 'right'); + equals( jQuery('#floatTest').css('cssFloat'), 'right', 'Modified CSS float using "cssFloat": Assert float is right'); + jQuery('#floatTest').css('float', 'left'); + equals( jQuery('#floatTest').css('float'), 'left', 'Modified CSS float using "float": Assert float is left'); + jQuery('#floatTest').css('font-size', '20px'); + equals( jQuery('#floatTest').css('font-size'), '20px', 'Modified CSS font-size: Assert font-size is 20px'); + + jQuery.each("0,0.25,0.5,0.75,1".split(','), function(i, n) { + jQuery('#foo').css('opacity', n); + equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a String" ); + jQuery('#foo').css('opacity', parseFloat(n)); + equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a Number" ); + }); + jQuery('#foo').css('opacity', ''); + equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when set to an empty String" ); + // for #1438, IE throws JS error when filter exists but doesn't have opacity in it + if (jQuery.browser.msie) { + jQuery('#foo').css("filter", "progid:DXImageTransform.Microsoft.Chroma(color='red');"); + } + equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when a different filter is set in IE, #1438" ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.css("padding-left", "1px"); + equals( j.css("padding-left"), "1px", "Check node,textnode,comment css works" ); + + // opera sometimes doesn't update 'display' correctly, see #2037 + jQuery("#t2037")[0].innerHTML = jQuery("#t2037")[0].innerHTML + equals( jQuery("#t2037 .hidden").css("display"), "none", "Make sure browser thinks it is hidden" ); +}); + +test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", function () { + expect(4); + + var $checkedtest = jQuery("#checkedtest"); + // IE6 was clearing "checked" in jQuery.css(elem, "height"); + jQuery.css($checkedtest[0], "height"); + ok( !! jQuery(":radio:first", $checkedtest).attr("checked"), "Check first radio still checked." ); + ok( ! jQuery(":radio:last", $checkedtest).attr("checked"), "Check last radio still NOT checked." ); + ok( !! jQuery(":checkbox:first", $checkedtest).attr("checked"), "Check first checkbox still checked." ); + ok( ! jQuery(":checkbox:last", $checkedtest).attr("checked"), "Check last checkbox still NOT checked." ); +}); + +test("width()", function() { + expect(6); + + var $div = jQuery("#nothiddendiv"); + $div.width(30); + equals($div.width(), 30, "Test set to 30 correctly"); + $div.hide(); + equals($div.width(), 30, "Test hidden div"); + $div.show(); + $div.width(-1); // handle negative numbers by ignoring #1599 + equals($div.width(), 30, "Test negative width ignored"); + $div.css("padding", "20px"); + equals($div.width(), 30, "Test padding specified with pixels"); + $div.css("border", "2px solid #fff"); + equals($div.width(), 30, "Test border specified with pixels"); + //$div.css("padding", "2em"); + //equals($div.width(), 30, "Test padding specified with ems"); + //$div.css("border", "1em solid #fff"); + //DISABLED - Opera 9.6 fails this test, returns 8 + //equals($div.width(), 30, "Test border specified with ems"); + //$div.css("padding", "2%"); + //equals($div.width(), 30, "Test padding specified with percent"); + + $div.css({ display: "", border: "", padding: "" }); + + jQuery("#nothiddendivchild").css({ padding: "3px", border: "2px solid #fff" }); + equals(jQuery("#nothiddendivchild").width(), 20, "Test child width with border and padding"); + jQuery("#nothiddendiv, #nothiddendivchild").css({ border: "", padding: "", width: "" }); +}); + +test("height()", function() { + expect(5); + + var $div = jQuery("#nothiddendiv"); + $div.height(30); + equals($div.height(), 30, "Test set to 30 correctly"); + $div.hide(); + equals($div.height(), 30, "Test hidden div"); + $div.show(); + $div.height(-1); // handle negative numbers by ignoring #1599 + equals($div.height(), 30, "Test negative height ignored"); + $div.css("padding", "20px"); + equals($div.height(), 30, "Test padding specified with pixels"); + $div.css("border", "2px solid #fff"); + equals($div.height(), 30, "Test border specified with pixels"); + //$div.css("padding", "2em"); + //equals($div.height(), 30, "Test padding specified with ems"); + //$div.css("border", "1em solid #fff"); + //DISABLED - Opera 9.6 fails this test, returns 8 + //equals($div.height(), 30, "Test border specified with ems"); + //$div.css("padding", "2%"); + //equals($div.height(), 30, "Test padding specified with percent"); + + $div.css({ display: "", border: "", padding: "", height: "1px" }); +}); + +test("addClass(String)", function() { + expect(2); + var div = jQuery("div"); + div.addClass("test"); + var pass = true; + for ( var i = 0; i < div.size(); i++ ) { + if ( div.get(i).className.indexOf("test") == -1 ) pass = false; + } + ok( pass, "Add Class" ); + + // using contents will get regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.addClass("asdf"); + ok( j.hasClass("asdf"), "Check node,textnode,comment for addClass" ); +}); + +test("removeClass(String) - simple", function() { + expect(5); + + var $divs = jQuery('div'); + + $divs.addClass("test").removeClass("test"); + + ok( !$divs.is('.test'), "Remove Class" ); + + reset(); + + $divs.addClass("test").addClass("foo").addClass("bar"); + $divs.removeClass("test").removeClass("bar").removeClass("foo"); + + ok( !$divs.is('.test,.bar,.foo'), "Remove multiple classes" ); + + reset(); + + // Make sure that a null value doesn't cause problems + $divs.eq(0).addClass("test").removeClass(null); + ok( $divs.eq(0).is('.test'), "Null value passed to removeClass" ); + + $divs.eq(0).addClass("test").removeClass(""); + ok( $divs.eq(0).is('.test'), "Empty string passed to removeClass" ); + + // using contents will get regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.removeClass("asdf"); + ok( !j.hasClass("asdf"), "Check node,textnode,comment for removeClass" ); +}); + +test("toggleClass(String)", function() { + expect(6); + var e = jQuery("#firstp"); + ok( !e.is(".test"), "Assert class not present" ); + e.toggleClass("test"); + ok( e.is(".test"), "Assert class present" ); + e.toggleClass("test"); + ok( !e.is(".test"), "Assert class not present" ); + + e.toggleClass("test", false); + ok( !e.is(".test"), "Assert class not present" ); + e.toggleClass("test", true); + ok( e.is(".test"), "Assert class present" ); + e.toggleClass("test", false); + ok( !e.is(".test"), "Assert class not present" ); +}); + +test("removeAttr(String", function() { + expect(1); + equals( jQuery('#mark').removeAttr("class")[0].className, "", "remove class" ); +}); + +test("jQuery.className", function() { + expect(6); + var x = jQuery("<p>Hi</p>")[0]; + var c = jQuery.className; + c.add(x, "hi"); + equals( x.className, "hi", "Check single added class" ); + c.add(x, "foo bar"); + equals( x.className, "hi foo bar", "Check more added classes" ); + c.remove(x); + equals( x.className, "", "Remove all classes" ); + c.add(x, "hi foo bar"); + c.remove(x, "foo"); + equals( x.className, "hi bar", "Check removal of one class" ); + ok( c.has(x, "hi"), "Check has1" ); + ok( c.has(x, "bar"), "Check has2" ); +});
\ No newline at end of file diff --git a/test/unit/core.js b/test/unit/core.js index 289a8bace..ba45ea608 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -386,893 +386,6 @@ test("index(Object)", function() { equals( elements.index( elements.eq(1) ), 1, "Pass in a jQuery object" ); }); -test("attr(String)", function() { - expect(27); - equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' ); - equals( jQuery('#text1').attr('value', "Test2").attr('defaultValue'), "Test", 'Check for defaultValue attribute' ); - equals( jQuery('#text1').attr('type'), "text", 'Check for type attribute' ); - equals( jQuery('#radio1').attr('type'), "radio", 'Check for type attribute' ); - equals( jQuery('#check1').attr('type'), "checkbox", 'Check for type attribute' ); - equals( jQuery('#simon1').attr('rel'), "bookmark", 'Check for rel attribute' ); - equals( jQuery('#google').attr('title'), "Google!", 'Check for title attribute' ); - equals( jQuery('#mark').attr('hreflang'), "en", 'Check for hreflang attribute' ); - equals( jQuery('#en').attr('lang'), "en", 'Check for lang attribute' ); - equals( jQuery('#simon').attr('class'), "blog link", 'Check for class attribute' ); - equals( jQuery('#name').attr('name'), "name", 'Check for name attribute' ); - equals( jQuery('#text1').attr('name'), "action", 'Check for name attribute' ); - ok( jQuery('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' ); - equals( jQuery('#text1').attr('maxlength'), '30', 'Check for maxlength attribute' ); - equals( jQuery('#text1').attr('maxLength'), '30', 'Check for maxLength attribute' ); - equals( jQuery('#area1').attr('maxLength'), '30', 'Check for maxLength attribute' ); - equals( jQuery('#select2').attr('selectedIndex'), 3, 'Check for selectedIndex attribute' ); - equals( jQuery('#foo').attr('nodeName').toUpperCase(), 'DIV', 'Check for nodeName attribute' ); - equals( jQuery('#foo').attr('tagName').toUpperCase(), 'DIV', 'Check for tagName attribute' ); - - jQuery('<a id="tAnchor5"></a>').attr('href', '#5').appendTo('#main'); // using innerHTML in IE causes href attribute to be serialized to the full path - equals( jQuery('#tAnchor5').attr('href'), "#5", 'Check for non-absolute href (an anchor)' ); - - equals( jQuery("<option/>").attr("selected"), false, "Check selected attribute on disconnected element." ); - - - // Related to [5574] and [5683] - var body = document.body, $body = jQuery(body); - - ok( $body.attr('foo') === undefined, 'Make sure that a non existent attribute returns undefined' ); - ok( $body.attr('nextSibling') === null, 'Make sure a null expando returns null' ); - - body.setAttribute('foo', 'baz'); - equals( $body.attr('foo'), 'baz', 'Make sure the dom attribute is retrieved when no expando is found' ); - - body.foo = 'bar'; - equals( $body.attr('foo'), 'bar', 'Make sure the expando is preferred over the dom attribute' ); - - $body.attr('foo','cool'); - equals( $body.attr('foo'), 'cool', 'Make sure that setting works well when both expando and dom attribute are available' ); - - body.foo = undefined; - ok( $body.attr('foo') === undefined, 'Make sure the expando is preferred over the dom attribute, even if undefined' ); - - body.removeAttribute('foo'); // Cleanup -}); - -if ( !isLocal ) { - test("attr(String) in XML Files", function() { - expect(2); - stop(); - jQuery.get("data/dashboard.xml", function(xml) { - equals( jQuery("locations", xml).attr("class"), "foo", "Check class attribute in XML document" ); - equals( jQuery("location", xml).attr("for"), "bar", "Check for attribute in XML document" ); - start(); - }); - }); -} - -test("attr(String, Function)", function() { - expect(2); - equals( jQuery('#text1').attr('value', function() { return this.id })[0].value, "text1", "Set value from id" ); - equals( jQuery('#text1').attr('title', function(i) { return i }).attr('title'), "0", "Set value with an index"); -}); - -test("attr(Hash)", function() { - expect(1); - var pass = true; - jQuery("div").attr({foo: 'baz', zoo: 'ping'}).each(function(){ - if ( this.getAttribute('foo') != "baz" && this.getAttribute('zoo') != "ping" ) pass = false; - }); - ok( pass, "Set Multiple Attributes" ); -}); - -test("attr(String, Object)", function() { - expect(21); - var div = jQuery("div").attr("foo", "bar"), - fail = false; - for ( var i = 0; i < div.size(); i++ ) { - if ( div.get(i).getAttribute('foo') != "bar" ){ - fail = i; - break; - } - } - equals( fail, false, "Set Attribute, the #"+fail+" element didn't get the attribute 'foo'" ); - - ok( jQuery("#foo").attr({"width": null}), "Try to set an attribute to nothing" ); - - jQuery("#name").attr('name', 'something'); - equals( jQuery("#name").attr('name'), 'something', 'Set name attribute' ); - jQuery("#check2").attr('checked', true); - equals( document.getElementById('check2').checked, true, 'Set checked attribute' ); - jQuery("#check2").attr('checked', false); - equals( document.getElementById('check2').checked, false, 'Set checked attribute' ); - jQuery("#text1").attr('readonly', true); - equals( document.getElementById('text1').readOnly, true, 'Set readonly attribute' ); - jQuery("#text1").attr('readonly', false); - equals( document.getElementById('text1').readOnly, false, 'Set readonly attribute' ); - jQuery("#name").attr('maxlength', '5'); - equals( document.getElementById('name').maxLength, '5', 'Set maxlength attribute' ); - jQuery("#name").attr('maxLength', '10'); - equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' ); - - // for #1070 - jQuery("#name").attr('someAttr', '0'); - equals( jQuery("#name").attr('someAttr'), '0', 'Set attribute to a string of "0"' ); - jQuery("#name").attr('someAttr', 0); - equals( jQuery("#name").attr('someAttr'), 0, 'Set attribute to the number 0' ); - jQuery("#name").attr('someAttr', 1); - equals( jQuery("#name").attr('someAttr'), 1, 'Set attribute to the number 1' ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - - j.attr("name", "attrvalue"); - equals( j.attr("name"), "attrvalue", "Check node,textnode,comment for attr" ); - j.removeAttr("name"); - - reset(); - - var type = jQuery("#check2").attr('type'); - var thrown = false; - try { - jQuery("#check2").attr('type','hidden'); - } catch(e) { - thrown = true; - } - ok( thrown, "Exception thrown when trying to change type property" ); - equals( type, jQuery("#check2").attr('type'), "Verify that you can't change the type of an input element" ); - - var check = document.createElement("input"); - var thrown = true; - try { - jQuery(check).attr('type','checkbox'); - } catch(e) { - thrown = false; - } - ok( thrown, "Exception thrown when trying to change type property" ); - equals( "checkbox", jQuery(check).attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" ); - - var check = jQuery("<input />"); - var thrown = true; - try { - check.attr('type','checkbox'); - } catch(e) { - thrown = false; - } - ok( thrown, "Exception thrown when trying to change type property" ); - equals( "checkbox", check.attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" ); - - var button = jQuery("#button"); - var thrown = false; - try { - button.attr('type','submit'); - } catch(e) { - thrown = true; - } - ok( thrown, "Exception thrown when trying to change type property" ); - equals( "button", button.attr('type'), "Verify that you can't change the type of a button element" ); -}); - -if ( !isLocal ) { - test("attr(String, Object) - Loaded via XML document", function() { - expect(2); - stop(); - jQuery.get('data/dashboard.xml', function(xml) { - var titles = []; - jQuery('tab', xml).each(function() { - titles.push(jQuery(this).attr('title')); - }); - equals( titles[0], 'Location', 'attr() in XML context: Check first title' ); - equals( titles[1], 'Users', 'attr() in XML context: Check second title' ); - start(); - }); - }); -} - -test("attr('tabindex')", function() { - expect(8); - - // elements not natively tabbable - equals(jQuery('#listWithTabIndex').attr('tabindex'), 5, 'not natively tabbable, with tabindex set to 0'); - equals(jQuery('#divWithNoTabIndex').attr('tabindex'), undefined, 'not natively tabbable, no tabindex set'); - - // anchor with href - equals(jQuery('#linkWithNoTabIndex').attr('tabindex'), 0, 'anchor with href, no tabindex set'); - equals(jQuery('#linkWithTabIndex').attr('tabindex'), 2, 'anchor with href, tabindex set to 2'); - equals(jQuery('#linkWithNegativeTabIndex').attr('tabindex'), -1, 'anchor with href, tabindex set to -1'); - - // anchor without href - equals(jQuery('#linkWithNoHrefWithNoTabIndex').attr('tabindex'), undefined, 'anchor without href, no tabindex set'); - equals(jQuery('#linkWithNoHrefWithTabIndex').attr('tabindex'), 1, 'anchor without href, tabindex set to 2'); - equals(jQuery('#linkWithNoHrefWithNegativeTabIndex').attr('tabindex'), -1, 'anchor without href, no tabindex set'); -}); - -test("attr('tabindex', value)", function() { - expect(9); - - var element = jQuery('#divWithNoTabIndex'); - equals(element.attr('tabindex'), undefined, 'start with no tabindex'); - - // set a positive string - element.attr('tabindex', '1'); - equals(element.attr('tabindex'), 1, 'set tabindex to 1 (string)'); - - // set a zero string - element.attr('tabindex', '0'); - equals(element.attr('tabindex'), 0, 'set tabindex to 0 (string)'); - - // set a negative string - element.attr('tabindex', '-1'); - equals(element.attr('tabindex'), -1, 'set tabindex to -1 (string)'); - - // set a positive number - element.attr('tabindex', 1); - equals(element.attr('tabindex'), 1, 'set tabindex to 1 (number)'); - - // set a zero number - element.attr('tabindex', 0); - equals(element.attr('tabindex'), 0, 'set tabindex to 0 (number)'); - - // set a negative number - element.attr('tabindex', -1); - equals(element.attr('tabindex'), -1, 'set tabindex to -1 (number)'); - - element = jQuery('#linkWithTabIndex'); - equals(element.attr('tabindex'), 2, 'start with tabindex 2'); - - element.attr('tabindex', -1); - equals(element.attr('tabindex'), -1, 'set negative tabindex'); -}); - -test("css(String|Hash)", function() { - expect(19); - - equals( jQuery('#main').css("display"), 'none', 'Check for css property "display"'); - - ok( jQuery('#nothiddendiv').is(':visible'), 'Modifying CSS display: Assert element is visible'); - jQuery('#nothiddendiv').css({display: 'none'}); - ok( !jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is hidden'); - jQuery('#nothiddendiv').css({display: 'block'}); - ok( jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is visible'); - - jQuery('#floatTest').css({styleFloat: 'right'}); - equals( jQuery('#floatTest').css('styleFloat'), 'right', 'Modified CSS float using "styleFloat": Assert float is right'); - jQuery('#floatTest').css({cssFloat: 'left'}); - equals( jQuery('#floatTest').css('cssFloat'), 'left', 'Modified CSS float using "cssFloat": Assert float is left'); - jQuery('#floatTest').css({'float': 'right'}); - equals( jQuery('#floatTest').css('float'), 'right', 'Modified CSS float using "float": Assert float is right'); - jQuery('#floatTest').css({'font-size': '30px'}); - equals( jQuery('#floatTest').css('font-size'), '30px', 'Modified CSS font-size: Assert font-size is 30px'); - - jQuery.each("0,0.25,0.5,0.75,1".split(','), function(i, n) { - jQuery('#foo').css({opacity: n}); - equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a String" ); - jQuery('#foo').css({opacity: parseFloat(n)}); - equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a Number" ); - }); - jQuery('#foo').css({opacity: ''}); - equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when set to an empty String" ); -}); - -test("css(String, Object)", function() { - expect(21); - ok( jQuery('#nothiddendiv').is(':visible'), 'Modifying CSS display: Assert element is visible'); - jQuery('#nothiddendiv').css("display", 'none'); - ok( !jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is hidden'); - jQuery('#nothiddendiv').css("display", 'block'); - ok( jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is visible'); - - jQuery('#floatTest').css('styleFloat', 'left'); - equals( jQuery('#floatTest').css('styleFloat'), 'left', 'Modified CSS float using "styleFloat": Assert float is left'); - jQuery('#floatTest').css('cssFloat', 'right'); - equals( jQuery('#floatTest').css('cssFloat'), 'right', 'Modified CSS float using "cssFloat": Assert float is right'); - jQuery('#floatTest').css('float', 'left'); - equals( jQuery('#floatTest').css('float'), 'left', 'Modified CSS float using "float": Assert float is left'); - jQuery('#floatTest').css('font-size', '20px'); - equals( jQuery('#floatTest').css('font-size'), '20px', 'Modified CSS font-size: Assert font-size is 20px'); - - jQuery.each("0,0.25,0.5,0.75,1".split(','), function(i, n) { - jQuery('#foo').css('opacity', n); - equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a String" ); - jQuery('#foo').css('opacity', parseFloat(n)); - equals( jQuery('#foo').css('opacity'), parseFloat(n), "Assert opacity is " + parseFloat(n) + " as a Number" ); - }); - jQuery('#foo').css('opacity', ''); - equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when set to an empty String" ); - // for #1438, IE throws JS error when filter exists but doesn't have opacity in it - if (jQuery.browser.msie) { - jQuery('#foo').css("filter", "progid:DXImageTransform.Microsoft.Chroma(color='red');"); - } - equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when a different filter is set in IE, #1438" ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.css("padding-left", "1px"); - equals( j.css("padding-left"), "1px", "Check node,textnode,comment css works" ); - - // opera sometimes doesn't update 'display' correctly, see #2037 - jQuery("#t2037")[0].innerHTML = jQuery("#t2037")[0].innerHTML - equals( jQuery("#t2037 .hidden").css("display"), "none", "Make sure browser thinks it is hidden" ); -}); - -test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", function () { - expect(4); - - var $checkedtest = jQuery("#checkedtest"); - // IE6 was clearing "checked" in jQuery.css(elem, "height"); - jQuery.css($checkedtest[0], "height"); - ok( !! jQuery(":radio:first", $checkedtest).attr("checked"), "Check first radio still checked." ); - ok( ! jQuery(":radio:last", $checkedtest).attr("checked"), "Check last radio still NOT checked." ); - ok( !! jQuery(":checkbox:first", $checkedtest).attr("checked"), "Check first checkbox still checked." ); - ok( ! jQuery(":checkbox:last", $checkedtest).attr("checked"), "Check last checkbox still NOT checked." ); -}); - -test("width()", function() { - expect(6); - - var $div = jQuery("#nothiddendiv"); - $div.width(30); - equals($div.width(), 30, "Test set to 30 correctly"); - $div.hide(); - equals($div.width(), 30, "Test hidden div"); - $div.show(); - $div.width(-1); // handle negative numbers by ignoring #1599 - equals($div.width(), 30, "Test negative width ignored"); - $div.css("padding", "20px"); - equals($div.width(), 30, "Test padding specified with pixels"); - $div.css("border", "2px solid #fff"); - equals($div.width(), 30, "Test border specified with pixels"); - //$div.css("padding", "2em"); - //equals($div.width(), 30, "Test padding specified with ems"); - //$div.css("border", "1em solid #fff"); - //DISABLED - Opera 9.6 fails this test, returns 8 - //equals($div.width(), 30, "Test border specified with ems"); - //$div.css("padding", "2%"); - //equals($div.width(), 30, "Test padding specified with percent"); - - $div.css({ display: "", border: "", padding: "" }); - - jQuery("#nothiddendivchild").css({ padding: "3px", border: "2px solid #fff" }); - equals(jQuery("#nothiddendivchild").width(), 20, "Test child width with border and padding"); - jQuery("#nothiddendiv, #nothiddendivchild").css({ border: "", padding: "", width: "" }); -}); - -test("height()", function() { - expect(5); - - var $div = jQuery("#nothiddendiv"); - $div.height(30); - equals($div.height(), 30, "Test set to 30 correctly"); - $div.hide(); - equals($div.height(), 30, "Test hidden div"); - $div.show(); - $div.height(-1); // handle negative numbers by ignoring #1599 - equals($div.height(), 30, "Test negative height ignored"); - $div.css("padding", "20px"); - equals($div.height(), 30, "Test padding specified with pixels"); - $div.css("border", "2px solid #fff"); - equals($div.height(), 30, "Test border specified with pixels"); - //$div.css("padding", "2em"); - //equals($div.height(), 30, "Test padding specified with ems"); - //$div.css("border", "1em solid #fff"); - //DISABLED - Opera 9.6 fails this test, returns 8 - //equals($div.height(), 30, "Test border specified with ems"); - //$div.css("padding", "2%"); - //equals($div.height(), 30, "Test padding specified with percent"); - - $div.css({ display: "", border: "", padding: "", height: "1px" }); -}); - -test("text()", function() { - expect(1); - var expected = "This link has class=\"blog\": Simon Willison's Weblog"; - equals( jQuery('#sap').text(), expected, 'Check for merged text of more then one element.' ); -}); - -test("wrap(String|Element)", function() { - expect(10); - var defaultText = 'Try them out:' - var result = jQuery('#first').wrap('<div class="red"><span></span></div>').text(); - equals( defaultText, result, 'Check for wrapping of on-the-fly html' ); - ok( jQuery('#first').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); - - reset(); - var defaultText = 'Try them out:' - var result = jQuery('#first').wrap(document.getElementById('empty')).parent(); - ok( result.is('ol'), 'Check for element wrapping' ); - equals( result.text(), defaultText, 'Check for element wrapping' ); - - reset(); - jQuery('#check1').click(function() { - var checkbox = this; - ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); - jQuery(checkbox).wrap( '<div id="c1" style="display:none;"></div>' ); - ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); - }).click(); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.wrap("<i></i>"); - equals( jQuery("#nonnodes > i").length, 3, "Check node,textnode,comment wraps ok" ); - equals( jQuery("#nonnodes > i").text(), j.text() + j[1].nodeValue, "Check node,textnode,comment wraps doesn't hurt text" ); - - // Try wrapping a disconnected node - j = jQuery("<label/>").wrap("<li/>"); - equals( j[0].nodeName.toUpperCase(), "LABEL", "Element is a label" ); - equals( j[0].parentNode.nodeName.toUpperCase(), "LI", "Element has been wrapped" ); -}); - -test("wrapAll(String|Element)", function() { - expect(8); - var prev = jQuery("#firstp")[0].previousSibling; - var p = jQuery("#firstp,#first")[0].parentNode; - var result = jQuery('#firstp,#first').wrapAll('<div class="red"><div id="tmp"></div></div>'); - equals( result.parent().length, 1, 'Check for wrapping of on-the-fly html' ); - ok( jQuery('#first').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); - ok( jQuery('#firstp').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); - equals( jQuery("#first").parent().parent()[0].previousSibling, prev, "Correct Previous Sibling" ); - equals( jQuery("#first").parent().parent()[0].parentNode, p, "Correct Parent" ); - - reset(); - var prev = jQuery("#firstp")[0].previousSibling; - var p = jQuery("#first")[0].parentNode; - var result = jQuery('#firstp,#first').wrapAll(document.getElementById('empty')); - equals( jQuery("#first").parent()[0], jQuery("#firstp").parent()[0], "Same Parent" ); - equals( jQuery("#first").parent()[0].previousSibling, prev, "Correct Previous Sibling" ); - equals( jQuery("#first").parent()[0].parentNode, p, "Correct Parent" ); -}); - -test("wrapInner(String|Element)", function() { - expect(6); - var num = jQuery("#first").children().length; - var result = jQuery('#first').wrapInner('<div class="red"><div id="tmp"></div></div>'); - equals( jQuery("#first").children().length, 1, "Only one child" ); - ok( jQuery("#first").children().is(".red"), "Verify Right Element" ); - equals( jQuery("#first").children().children().children().length, num, "Verify Elements Intact" ); - - reset(); - var num = jQuery("#first").children().length; - var result = jQuery('#first').wrapInner(document.getElementById('empty')); - equals( jQuery("#first").children().length, 1, "Only one child" ); - ok( jQuery("#first").children().is("#empty"), "Verify Right Element" ); - equals( jQuery("#first").children().children().length, num, "Verify Elements Intact" ); -}); - -test("append(String|Element|Array<Element>|jQuery)", function() { - expect(21); - var defaultText = 'Try them out:' - var result = jQuery('#first').append('<b>buga</b>'); - equals( result.text(), defaultText + 'buga', 'Check if text appending works' ); - equals( jQuery('#select3').append('<option value="appendTest">Append Test</option>').find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); - - reset(); - var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:"; - jQuery('#sap').append(document.getElementById('first')); - equals( expected, jQuery('#sap').text(), "Check for appending of element" ); - - reset(); - expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo"; - jQuery('#sap').append([document.getElementById('first'), document.getElementById('yahoo')]); - equals( expected, jQuery('#sap').text(), "Check for appending of array of elements" ); - - reset(); - expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:"; - jQuery('#sap').append(jQuery("#first, #yahoo")); - equals( expected, jQuery('#sap').text(), "Check for appending of jQuery object" ); - - reset(); - jQuery("#sap").append( 5 ); - ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" ); - - reset(); - jQuery("#sap").append( " text with spaces " ); - ok( jQuery("#sap")[0].innerHTML.match(/ text with spaces $/), "Check for appending text with spaces" ); - - reset(); - ok( jQuery("#sap").append([]), "Check for appending an empty array." ); - ok( jQuery("#sap").append(""), "Check for appending an empty string." ); - ok( jQuery("#sap").append(document.getElementsByTagName("foo")), "Check for appending an empty nodelist." ); - - reset(); - jQuery("#sap").append(document.getElementById('form')); - equals( jQuery("#sap>form").size(), 1, "Check for appending a form" ); // Bug #910 - - reset(); - var pass = true; - try { - jQuery( jQuery("#iframe")[0].contentWindow.document.body ).append("<div>test</div>"); - } catch(e) { - pass = false; - } - - ok( pass, "Test for appending a DOM node to the contents of an IFrame" ); - - reset(); - jQuery('<fieldset/>').appendTo('#form').append('<legend id="legend">test</legend>'); - t( 'Append legend', '#legend', ['legend'] ); - - reset(); - jQuery('#select1').append('<OPTION>Test</OPTION>'); - equals( jQuery('#select1 option:last').text(), "Test", "Appending <OPTION> (all caps)" ); - - jQuery('#table').append('<colgroup></colgroup>'); - ok( jQuery('#table colgroup').length, "Append colgroup" ); - - jQuery('#table colgroup').append('<col/>'); - ok( jQuery('#table colgroup col').length, "Append col" ); - - reset(); - jQuery('#table').append('<caption></caption>'); - ok( jQuery('#table caption').length, "Append caption" ); - - reset(); - jQuery('form:last') - .append('<select id="appendSelect1"></select>') - .append('<select id="appendSelect2"><option>Test</option></select>'); - - t( "Append Select", "#appendSelect1, #appendSelect2", ["appendSelect1", "appendSelect2"] ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - var d = jQuery("<div/>").appendTo("#nonnodes").append(j); - equals( jQuery("#nonnodes").length, 1, "Check node,textnode,comment append moved leaving just the div" ); - ok( d.contents().length >= 2, "Check node,textnode,comment append works" ); - d.contents().appendTo("#nonnodes"); - d.remove(); - ok( jQuery("#nonnodes").contents().length >= 2, "Check node,textnode,comment append cleanup worked" ); -}); - -test("appendTo(String|Element|Array<Element>|jQuery)", function() { - expect(12); - var defaultText = 'Try them out:' - jQuery('<b>buga</b>').appendTo('#first'); - equals( jQuery("#first").text(), defaultText + 'buga', 'Check if text appending works' ); - equals( jQuery('<option value="appendTest">Append Test</option>').appendTo('#select3').parent().find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); - - reset(); - var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:"; - jQuery(document.getElementById('first')).appendTo('#sap'); - equals( expected, jQuery('#sap').text(), "Check for appending of element" ); - - reset(); - expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo"; - jQuery([document.getElementById('first'), document.getElementById('yahoo')]).appendTo('#sap'); - equals( expected, jQuery('#sap').text(), "Check for appending of array of elements" ); - - reset(); - ok( jQuery(document.createElement("script")).appendTo("body").length, "Make sure a disconnected script can be appended." ); - - reset(); - expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:"; - jQuery("#first, #yahoo").appendTo('#sap'); - equals( expected, jQuery('#sap').text(), "Check for appending of jQuery object" ); - - reset(); - jQuery('#select1').appendTo('#foo'); - t( 'Append select', '#foo select', ['select1'] ); - - reset(); - var div = jQuery("<div/>").click(function(){ - ok(true, "Running a cloned click."); - }); - div.appendTo("#main, #moretests"); - - jQuery("#main div:last").click(); - jQuery("#moretests div:last").click(); - - reset(); - var div = jQuery("<div/>").appendTo("#main, #moretests"); - - equals( div.length, 2, "appendTo returns the inserted elements" ); - - div.addClass("test"); - - ok( jQuery("#main div:last").hasClass("test"), "appendTo element was modified after the insertion" ); - ok( jQuery("#moretests div:last").hasClass("test"), "appendTo element was modified after the insertion" ); - - reset(); -}); - -test("prepend(String|Element|Array<Element>|jQuery)", function() { - expect(5); - var defaultText = 'Try them out:' - var result = jQuery('#first').prepend('<b>buga</b>'); - equals( result.text(), 'buga' + defaultText, 'Check if text prepending works' ); - equals( jQuery('#select3').prepend('<option value="prependTest">Prepend Test</option>').find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); - - reset(); - var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog"; - jQuery('#sap').prepend(document.getElementById('first')); - equals( expected, jQuery('#sap').text(), "Check for prepending of element" ); - - reset(); - expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog"; - jQuery('#sap').prepend([document.getElementById('first'), document.getElementById('yahoo')]); - equals( expected, jQuery('#sap').text(), "Check for prepending of array of elements" ); - - reset(); - expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; - jQuery('#sap').prepend(jQuery("#first, #yahoo")); - equals( expected, jQuery('#sap').text(), "Check for prepending of jQuery object" ); -}); - -test("prependTo(String|Element|Array<Element>|jQuery)", function() { - expect(6); - var defaultText = 'Try them out:' - jQuery('<b>buga</b>').prependTo('#first'); - equals( jQuery('#first').text(), 'buga' + defaultText, 'Check if text prepending works' ); - equals( jQuery('<option value="prependTest">Prepend Test</option>').prependTo('#select3').parent().find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); - - reset(); - var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog"; - jQuery(document.getElementById('first')).prependTo('#sap'); - equals( expected, jQuery('#sap').text(), "Check for prepending of element" ); - - reset(); - expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog"; - jQuery([document.getElementById('first'), document.getElementById('yahoo')]).prependTo('#sap'); - equals( expected, jQuery('#sap').text(), "Check for prepending of array of elements" ); - - reset(); - expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; - jQuery("#first, #yahoo").prependTo('#sap'); - equals( expected, jQuery('#sap').text(), "Check for prepending of jQuery object" ); - - reset(); - jQuery('<select id="prependSelect1"></select>').prependTo('form:last'); - jQuery('<select id="prependSelect2"><option>Test</option></select>').prependTo('form:last'); - - t( "Prepend Select", "#prependSelect2, #prependSelect1", ["prependSelect2", "prependSelect1"] ); -}); - -test("before(String|Element|Array<Element>|jQuery)", function() { - expect(4); - var expected = 'This is a normal link: bugaYahoo'; - jQuery('#yahoo').before('<b>buga</b>'); - equals( expected, jQuery('#en').text(), 'Insert String before' ); - - reset(); - expected = "This is a normal link: Try them out:Yahoo"; - jQuery('#yahoo').before(document.getElementById('first')); - equals( expected, jQuery('#en').text(), "Insert element before" ); - - reset(); - expected = "This is a normal link: Try them out:diveintomarkYahoo"; - jQuery('#yahoo').before([document.getElementById('first'), document.getElementById('mark')]); - equals( expected, jQuery('#en').text(), "Insert array of elements before" ); - - reset(); - expected = "This is a normal link: diveintomarkTry them out:Yahoo"; - jQuery('#yahoo').before(jQuery("#first, #mark")); - equals( expected, jQuery('#en').text(), "Insert jQuery before" ); -}); - -test("insertBefore(String|Element|Array<Element>|jQuery)", function() { - expect(4); - var expected = 'This is a normal link: bugaYahoo'; - jQuery('<b>buga</b>').insertBefore('#yahoo'); - equals( expected, jQuery('#en').text(), 'Insert String before' ); - - reset(); - expected = "This is a normal link: Try them out:Yahoo"; - jQuery(document.getElementById('first')).insertBefore('#yahoo'); - equals( expected, jQuery('#en').text(), "Insert element before" ); - - reset(); - expected = "This is a normal link: Try them out:diveintomarkYahoo"; - jQuery([document.getElementById('first'), document.getElementById('mark')]).insertBefore('#yahoo'); - equals( expected, jQuery('#en').text(), "Insert array of elements before" ); - - reset(); - expected = "This is a normal link: diveintomarkTry them out:Yahoo"; - jQuery("#first, #mark").insertBefore('#yahoo'); - equals( expected, jQuery('#en').text(), "Insert jQuery before" ); -}); - -test("after(String|Element|Array<Element>|jQuery)", function() { - expect(4); - var expected = 'This is a normal link: Yahoobuga'; - jQuery('#yahoo').after('<b>buga</b>'); - equals( expected, jQuery('#en').text(), 'Insert String after' ); - - reset(); - expected = "This is a normal link: YahooTry them out:"; - jQuery('#yahoo').after(document.getElementById('first')); - equals( expected, jQuery('#en').text(), "Insert element after" ); - - reset(); - expected = "This is a normal link: YahooTry them out:diveintomark"; - jQuery('#yahoo').after([document.getElementById('first'), document.getElementById('mark')]); - equals( expected, jQuery('#en').text(), "Insert array of elements after" ); - - reset(); - expected = "This is a normal link: YahoodiveintomarkTry them out:"; - jQuery('#yahoo').after(jQuery("#first, #mark")); - equals( expected, jQuery('#en').text(), "Insert jQuery after" ); -}); - -test("insertAfter(String|Element|Array<Element>|jQuery)", function() { - expect(4); - var expected = 'This is a normal link: Yahoobuga'; - jQuery('<b>buga</b>').insertAfter('#yahoo'); - equals( expected, jQuery('#en').text(), 'Insert String after' ); - - reset(); - expected = "This is a normal link: YahooTry them out:"; - jQuery(document.getElementById('first')).insertAfter('#yahoo'); - equals( expected, jQuery('#en').text(), "Insert element after" ); - - reset(); - expected = "This is a normal link: YahooTry them out:diveintomark"; - jQuery([document.getElementById('first'), document.getElementById('mark')]).insertAfter('#yahoo'); - equals( expected, jQuery('#en').text(), "Insert array of elements after" ); - - reset(); - expected = "This is a normal link: YahoodiveintomarkTry them out:"; - jQuery("#first, #mark").insertAfter('#yahoo'); - equals( expected, jQuery('#en').text(), "Insert jQuery after" ); -}); - -test("replaceWith(String|Element|Array<Element>|jQuery)", function() { - expect(10); - jQuery('#yahoo').replaceWith('<b id="replace">buga</b>'); - ok( jQuery("#replace")[0], 'Replace element with string' ); - ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after string' ); - - reset(); - jQuery('#yahoo').replaceWith(document.getElementById('first')); - ok( jQuery("#first")[0], 'Replace element with element' ); - ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after element' ); - - reset(); - jQuery('#yahoo').replaceWith([document.getElementById('first'), document.getElementById('mark')]); - ok( jQuery("#first")[0], 'Replace element with array of elements' ); - ok( jQuery("#mark")[0], 'Replace element with array of elements' ); - ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after array of elements' ); - - reset(); - jQuery('#yahoo').replaceWith(jQuery("#first, #mark")); - ok( jQuery("#first")[0], 'Replace element with set of elements' ); - ok( jQuery("#mark")[0], 'Replace element with set of elements' ); - ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after set of elements' ); -}); - -test("replaceAll(String|Element|Array<Element>|jQuery)", function() { - expect(10); - jQuery('<b id="replace">buga</b>').replaceAll("#yahoo"); - ok( jQuery("#replace")[0], 'Replace element with string' ); - ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after string' ); - - reset(); - jQuery(document.getElementById('first')).replaceAll("#yahoo"); - ok( jQuery("#first")[0], 'Replace element with element' ); - ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after element' ); - - reset(); - jQuery([document.getElementById('first'), document.getElementById('mark')]).replaceAll("#yahoo"); - ok( jQuery("#first")[0], 'Replace element with array of elements' ); - ok( jQuery("#mark")[0], 'Replace element with array of elements' ); - ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after array of elements' ); - - reset(); - jQuery("#first, #mark").replaceAll("#yahoo"); - ok( jQuery("#first")[0], 'Replace element with set of elements' ); - ok( jQuery("#mark")[0], 'Replace element with set of elements' ); - ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after set of elements' ); -}); - -test("end()", function() { - expect(3); - equals( 'Yahoo', jQuery('#yahoo').parent().end().text(), 'Check for end' ); - ok( jQuery('#yahoo').end(), 'Check for end with nothing to end' ); - - var x = jQuery('#yahoo'); - x.parent(); - equals( 'Yahoo', jQuery('#yahoo').text(), 'Check for non-destructive behaviour' ); -}); - -test("find(String)", function() { - expect(2); - equals( 'Yahoo', jQuery('#foo').find('.blogTest').text(), 'Check for find' ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - equals( j.find("div").length, 0, "Check node,textnode,comment to find zero divs" ); -}); - -test("clone()", function() { - expect(28); - equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Assert text for #en' ); - var clone = jQuery('#yahoo').clone(); - equals( 'Try them out:Yahoo', jQuery('#first').append(clone).text(), 'Check for clone' ); - equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Reassert text for #en' ); - - var cloneTags = [ - "<table/>", "<tr/>", "<td/>", "<div/>", - "<button/>", "<ul/>", "<ol/>", "<li/>", - "<input type='checkbox' />", "<select/>", "<option/>", "<textarea/>", - "<tbody/>", "<thead/>", "<tfoot/>", "<iframe/>" - ]; - for (var i = 0; i < cloneTags.length; i++) { - var j = jQuery(cloneTags[i]); - equals( j[0].tagName, j.clone()[0].tagName, 'Clone a <' + cloneTags[i].substring(1)); - } - - // using contents will get comments regular, text, and comment nodes - var cl = jQuery("#nonnodes").contents().clone(); - ok( cl.length >= 2, "Check node,textnode,comment clone works (some browsers delete comments on clone)" ); - - var div = jQuery("<div><ul><li>test</li></ul></div>").click(function(){ - ok( true, "Bound event still exists." ); - }); - - div = div.clone(true).clone(true); - equals( div.length, 1, "One element cloned" ); - equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" ); - div.trigger("click"); - - div = jQuery("<div/>").append([ document.createElement("table"), document.createElement("table") ]); - div.find("table").click(function(){ - ok( true, "Bound event still exists." ); - }); - - div = div.clone(true); - equals( div.length, 1, "One element cloned" ); - equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" ); - div.find("table:last").trigger("click"); - - div = jQuery("<div/>").html('<object height="355" width="425"> <param name="movie" value="http://www.youtube.com/v/JikaHBDoV3k&hl=en"> <param name="wmode" value="transparent"> </object>'); - - div = div.clone(true); - equals( div.length, 1, "One element cloned" ); - equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" ); -}); - -if (!isLocal) { -test("clone() on XML nodes", function() { - expect(2); - stop(); - jQuery.get("data/dashboard.xml", function (xml) { - var root = jQuery(xml.documentElement).clone(); - var origTab = jQuery("tab", xml).eq(0); - var cloneTab = jQuery("tab", root).eq(0); - origTab.text("origval"); - cloneTab.text("cloneval"); - equals(origTab.text(), "origval", "Check original XML node was correctly set"); - equals(cloneTab.text(), "cloneval", "Check cloned XML node was correctly set"); - start(); - }); -}); -} - -test("is(String)", function() { - expect(26); - ok( jQuery('#form').is('form'), 'Check for element: A form must be a form' ); - ok( !jQuery('#form').is('div'), 'Check for element: A form is not a div' ); - ok( jQuery('#mark').is('.blog'), 'Check for class: Expected class "blog"' ); - ok( !jQuery('#mark').is('.link'), 'Check for class: Did not expect class "link"' ); - ok( jQuery('#simon').is('.blog.link'), 'Check for multiple classes: Expected classes "blog" and "link"' ); - ok( !jQuery('#simon').is('.blogTest'), 'Check for multiple classes: Expected classes "blog" and "link", but not "blogTest"' ); - ok( jQuery('#en').is('[lang="en"]'), 'Check for attribute: Expected attribute lang to be "en"' ); - ok( !jQuery('#en').is('[lang="de"]'), 'Check for attribute: Expected attribute lang to be "en", not "de"' ); - ok( jQuery('#text1').is('[type="text"]'), 'Check for attribute: Expected attribute type to be "text"' ); - ok( !jQuery('#text1').is('[type="radio"]'), 'Check for attribute: Expected attribute type to be "text", not "radio"' ); - ok( jQuery('#text2').is(':disabled'), 'Check for pseudoclass: Expected to be disabled' ); - ok( !jQuery('#text1').is(':disabled'), 'Check for pseudoclass: Expected not disabled' ); - ok( jQuery('#radio2').is(':checked'), 'Check for pseudoclass: Expected to be checked' ); - ok( !jQuery('#radio1').is(':checked'), 'Check for pseudoclass: Expected not checked' ); - ok( jQuery('#foo').is(':has(p)'), 'Check for child: Expected a child "p" element' ); - ok( !jQuery('#foo').is(':has(ul)'), 'Check for child: Did not expect "ul" element' ); - ok( jQuery('#foo').is(':has(p):has(a):has(code)'), 'Check for childs: Expected "p", "a" and "code" child elements' ); - ok( !jQuery('#foo').is(':has(p):has(a):has(code):has(ol)'), 'Check for childs: Expected "p", "a" and "code" child elements, but no "ol"' ); - ok( !jQuery('#foo').is(0), 'Expected false for an invalid expression - 0' ); - ok( !jQuery('#foo').is(null), 'Expected false for an invalid expression - null' ); - ok( !jQuery('#foo').is(''), 'Expected false for an invalid expression - ""' ); - ok( !jQuery('#foo').is(undefined), 'Expected false for an invalid expression - undefined' ); - - // test is() with comma-seperated expressions - ok( jQuery('#en').is('[lang="en"],[lang="de"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); - ok( jQuery('#en').is('[lang="de"],[lang="en"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); - ok( jQuery('#en').is('[lang="en"] , [lang="de"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); - ok( jQuery('#en').is('[lang="de"] , [lang="en"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); -}); - test("jQuery.merge()", function() { expect(6); @@ -1363,313 +476,6 @@ test("jQuery.extend(Object, Object)", function() { isObj( options2, options2Copy, "Check if not modified: options2 must not be modified" ); }); -test("val()", function() { - expect(8); - - equals( jQuery("#text1").val(), "Test", "Check for value of input element" ); - // ticket #1714 this caused a JS error in IE - equals( jQuery("#first").val(), "", "Check a paragraph element to see if it has a value" ); - ok( jQuery([]).val() === undefined, "Check an empty jQuery object will return undefined from val" ); - - equals( jQuery('#select2').val(), '3', 'Call val() on a single="single" select' ); - - isSet( jQuery('#select3').val(), ['1', '2'], 'Call val() on a multiple="multiple" select' ); - - equals( jQuery('#option3c').val(), '2', 'Call val() on a option element with value' ); - - equals( jQuery('#option3a').val(), '', 'Call val() on a option element with empty value' ); - - equals( jQuery('#option3e').val(), 'no value', 'Call val() on a option element with no value attribute' ); - -}); - -test("val(String/Number)", function() { - expect(6); - document.getElementById('text1').value = "bla"; - equals( jQuery("#text1").val(), "bla", "Check for modified value of input element" ); - - jQuery("#text1").val('test'); - equals( document.getElementById('text1').value, "test", "Check for modified (via val(String)) value of input element" ); - - jQuery("#text1").val(67); - equals( document.getElementById('text1').value, "67", "Check for modified (via val(Number)) value of input element" ); - - jQuery("#select1").val("3"); - equals( jQuery("#select1").val(), "3", "Check for modified (via val(String)) value of select element" ); - - jQuery("#select1").val(2); - equals( jQuery("#select1").val(), "2", "Check for modified (via val(Number)) value of select element" ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.val("asdf"); - equals( j.val(), "asdf", "Check node,textnode,comment with val()" ); - j.removeAttr("value"); -}); - -test("html(String)", function() { - expect(17); - - jQuery.scriptorder = 0; - - var div = jQuery("#main > div"); - div.html("<b>test</b>"); - var pass = true; - for ( var i = 0; i < div.size(); i++ ) { - if ( div.get(i).childNodes.length != 1 ) pass = false; - } - ok( pass, "Set HTML" ); - - reset(); - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.html("<b>bold</b>"); - - // this is needed, or the expando added by jQuery unique will yield a different html - j.find('b').removeData(); - equals( j.html().replace(/ xmlns="[^"]+"/g, "").toLowerCase(), "<b>bold</b>", "Check node,textnode,comment with html()" ); - - jQuery("#main").html("<select/>"); - jQuery("#main select").html("<option>O1</option><option selected='selected'>O2</option><option>O3</option>"); - equals( jQuery("#main select").val(), "O2", "Selected option correct" ); - - var $div = jQuery('<div />'); - equals( $div.html( 5 ).html(), '5', 'Setting a number as html' ); - equals( $div.html( 0 ).html(), '0', 'Setting a zero as html' ); - - reset(); - - jQuery("#main").html('<script type="something/else">ok( false, "Non-script evaluated." );</script><script type="text/javascript">ok( true, "text/javascript is evaluated." );</script><script>ok( true, "No type is evaluated." );</script><div><script type="text/javascript">ok( true, "Inner text/javascript is evaluated." );</script><script>ok( true, "Inner No type is evaluated." );</script><script type="something/else">ok( false, "Non-script evaluated." );</script></div>'); - - stop(); - - jQuery("#main").html('<script type="text/javascript">ok( true, "jQuery().html().evalScripts() Evals Scripts Twice in Firefox, see #975" );</script>'); - - jQuery("#main").html('foo <form><script type="text/javascript">ok( true, "jQuery().html().evalScripts() Evals Scripts Twice in Firefox, see #975" );</script></form>'); - - // it was decided that waiting to execute ALL scripts makes sense since nested ones have to wait anyway so this test case is changed, see #1959 - jQuery("#main").html("<script>equals(jQuery.scriptorder++, 0, 'Script is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html (even though appears before)')<\/script><span id='scriptorder'><script>equals(jQuery.scriptorder++, 1, 'Script (nested) is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html')<\/script></span><script>equals(jQuery.scriptorder++, 2, 'Script (unnested) is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html')<\/script>"); - - setTimeout( start, 100 ); -}); - -test("filter()", function() { - expect(6); - isSet( jQuery("#form input").filter(":checked").get(), q("radio2", "check1"), "filter(String)" ); - isSet( jQuery("p").filter("#ap, #sndp").get(), q("ap", "sndp"), "filter('String, String')" ); - isSet( jQuery("p").filter("#ap,#sndp").get(), q("ap", "sndp"), "filter('String,String')" ); - isSet( jQuery("p").filter(function() { return !jQuery("a", this).length }).get(), q("sndp", "first"), "filter(Function)" ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - equals( j.filter("span").length, 1, "Check node,textnode,comment to filter the one span" ); - equals( j.filter("[name]").length, 0, "Check node,textnode,comment to filter the one span" ); -}); - -test("closest()", function() { - expect(6); - isSet( jQuery("body").closest("body").get(), q("body"), "closest(body)" ); - isSet( jQuery("body").closest("html").get(), q("html"), "closest(html)" ); - isSet( jQuery("body").closest("div").get(), [], "closest(div)" ); - isSet( jQuery("#main").closest("span,#html").get(), q("html"), "closest(span,#html)" ); - - isSet( jQuery("div:eq(1)").closest("div:first").get(), [], "closest(div:first)" ); - isSet( jQuery("div").closest("body:first div:last").get(), q("fx-tests"), "closest(body:first div:last)" ); -}); - -test("not()", function() { - expect(11); - equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" ); - equals( jQuery("#main > p#ap > a").not(document.getElementById("google")).length, 2, "not(DOMElement)" ); - isSet( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" ); - isSet( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" ); - isSet( jQuery("p").not(jQuery("#ap, #sndp, .result")).get(), q("firstp", "en", "sap", "first"), "not(jQuery)" ); - equals( jQuery("p").not(document.getElementsByTagName("p")).length, 0, "not(Array-like DOM collection)" ); - isSet( jQuery("#form option").not("option.emptyopt:contains('Nothing'),[selected],[value='1']").get(), q("option1c", "option1d", "option2c", "option3d", "option3e" ), "not('complex selector')"); - - var selects = jQuery("#form select"); - isSet( selects.not( selects[1] ), q("select1", "select3"), "filter out DOM element"); - - isSet( jQuery('#ap *').not('code'), q("google", "groups", "anchor1", "mark"), "not('tag selector')" ); - isSet( jQuery('#ap *').not('code, #mark'), q("google", "groups", "anchor1"), "not('tag, ID selector')" ); - isSet( jQuery('#ap *').not('#mark, code'), q("google", "groups", "anchor1"), "not('ID, tag selector')"); -}); - -test("andSelf()", function() { - expect(4); - isSet( jQuery("#en").siblings().andSelf().get(), q("sndp", "sap","en"), "Check for siblings and self" ); - isSet( jQuery("#foo").children().andSelf().get(), q("sndp", "en", "sap", "foo"), "Check for children and self" ); - isSet( jQuery("#sndp, #en").parent().andSelf().get(), q("foo","sndp","en"), "Check for parent and self" ); - isSet( jQuery("#groups").parents("p, div").andSelf().get(), q("main", "ap", "groups"), "Check for parents and self" ); -}); - -test("siblings([String])", function() { - expect(5); - isSet( jQuery("#en").siblings().get(), q("sndp", "sap"), "Check for siblings" ); - isSet( jQuery("#sndp").siblings(":has(code)").get(), q("sap"), "Check for filtered siblings (has code child element)" ); - isSet( jQuery("#sndp").siblings(":has(a)").get(), q("en", "sap"), "Check for filtered siblings (has anchor child element)" ); - isSet( jQuery("#foo").siblings("form, b").get(), q("form", "floatTest", "lengthtest", "name-tests", "testForm"), "Check for multiple filters" ); - var set = q("en", "sap", "sndp"); - isSet( jQuery("#en, #sndp").siblings().get(), set, "Check for unique results from siblings" ); -}); - -test("children([String])", function() { - expect(3); - isSet( jQuery("#foo").children().get(), q("sndp", "en", "sap"), "Check for children" ); - isSet( jQuery("#foo").children(":has(code)").get(), q("sndp", "sap"), "Check for filtered children" ); - isSet( jQuery("#foo").children("#en, #sap").get(), q("en", "sap"), "Check for multiple filters" ); -}); - -test("parent([String])", function() { - expect(5); - equals( jQuery("#groups").parent()[0].id, "ap", "Simple parent check" ); - equals( jQuery("#groups").parent("p")[0].id, "ap", "Filtered parent check" ); - equals( jQuery("#groups").parent("div").length, 0, "Filtered parent check, no match" ); - equals( jQuery("#groups").parent("div, p")[0].id, "ap", "Check for multiple filters" ); - isSet( jQuery("#en, #sndp").parent().get(), q("foo"), "Check for unique results from parent" ); -}); - -test("parents([String])", function() { - expect(5); - equals( jQuery("#groups").parents()[0].id, "ap", "Simple parents check" ); - equals( jQuery("#groups").parents("p")[0].id, "ap", "Filtered parents check" ); - equals( jQuery("#groups").parents("div")[0].id, "main", "Filtered parents check2" ); - isSet( jQuery("#groups").parents("p, div").get(), q("main", "ap"), "Check for multiple filters" ); - isSet( jQuery("#en, #sndp").parents().get(), q("foo", "main", "dl", "body", "html"), "Check for unique results from parents" ); -}); - -test("next([String])", function() { - expect(4); - equals( jQuery("#ap").next()[0].id, "foo", "Simple next check" ); - equals( jQuery("#ap").next("div")[0].id, "foo", "Filtered next check" ); - equals( jQuery("#ap").next("p").length, 0, "Filtered next check, no match" ); - equals( jQuery("#ap").next("div, p")[0].id, "foo", "Multiple filters" ); -}); - -test("prev([String])", function() { - expect(4); - equals( jQuery("#foo").prev()[0].id, "ap", "Simple prev check" ); - equals( jQuery("#foo").prev("p")[0].id, "ap", "Filtered prev check" ); - equals( jQuery("#foo").prev("div").length, 0, "Filtered prev check, no match" ); - equals( jQuery("#foo").prev("p, div")[0].id, "ap", "Multiple filters" ); -}); - -test("show()", function() { - expect(15); - var pass = true, div = jQuery("#main div"); - div.show().each(function(){ - if ( this.style.display == "none" ) pass = false; - }); - ok( pass, "Show" ); - - jQuery("#main").append('<div id="show-tests"><div><p><a href="#"></a></p><code></code><pre></pre><span></span></div><table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table><ul><li></li></ul></div>'); - - var old = jQuery("#show-tests table").show().css("display") !== "table"; - - var test = { - "div" : "block", - "p" : "block", - "a" : "inline", - "code" : "inline", - "pre" : "block", - "span" : "inline", - "table" : old ? "block" : "table", - "thead" : old ? "block" : "table-header-group", - "tbody" : old ? "block" : "table-row-group", - "tr" : old ? "block" : "table-row", - "th" : old ? "block" : "table-cell", - "td" : old ? "block" : "table-cell", - "ul" : "block", - "li" : old ? "block" : "list-item" - }; - - jQuery.each(test, function(selector, expected) { - var elem = jQuery(selector, "#show-tests").show(); - equals( elem.css("display"), expected, "Show using correct display type for " + selector ); - }); -}); - -test("addClass(String)", function() { - expect(2); - var div = jQuery("div"); - div.addClass("test"); - var pass = true; - for ( var i = 0; i < div.size(); i++ ) { - if ( div.get(i).className.indexOf("test") == -1 ) pass = false; - } - ok( pass, "Add Class" ); - - // using contents will get regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.addClass("asdf"); - ok( j.hasClass("asdf"), "Check node,textnode,comment for addClass" ); -}); - -test("removeClass(String) - simple", function() { - expect(5); - - var $divs = jQuery('div'); - - $divs.addClass("test").removeClass("test"); - - ok( !$divs.is('.test'), "Remove Class" ); - - reset(); - - $divs.addClass("test").addClass("foo").addClass("bar"); - $divs.removeClass("test").removeClass("bar").removeClass("foo"); - - ok( !$divs.is('.test,.bar,.foo'), "Remove multiple classes" ); - - reset(); - - // Make sure that a null value doesn't cause problems - $divs.eq(0).addClass("test").removeClass(null); - ok( $divs.eq(0).is('.test'), "Null value passed to removeClass" ); - - $divs.eq(0).addClass("test").removeClass(""); - ok( $divs.eq(0).is('.test'), "Empty string passed to removeClass" ); - - // using contents will get regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.removeClass("asdf"); - ok( !j.hasClass("asdf"), "Check node,textnode,comment for removeClass" ); -}); - -test("toggleClass(String)", function() { - expect(6); - var e = jQuery("#firstp"); - ok( !e.is(".test"), "Assert class not present" ); - e.toggleClass("test"); - ok( e.is(".test"), "Assert class present" ); - e.toggleClass("test"); - ok( !e.is(".test"), "Assert class not present" ); - - e.toggleClass("test", false); - ok( !e.is(".test"), "Assert class not present" ); - e.toggleClass("test", true); - ok( e.is(".test"), "Assert class present" ); - e.toggleClass("test", false); - ok( !e.is(".test"), "Assert class not present" ); -}); - -test("removeAttr(String", function() { - expect(1); - equals( jQuery('#mark').removeAttr("class")[0].className, "", "remove class" ); -}); - -test("text(String)", function() { - expect(4); - equals( jQuery("#foo").text("<div><b>Hello</b> cruel world!</div>")[0].innerHTML.replace(/>/g, ">"), "<div><b>Hello</b> cruel world!</div>", "Check escaped text" ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.text("hi!"); - equals( jQuery(j[0]).text(), "hi!", "Check node,textnode,comment with text()" ); - equals( j[1].nodeValue, " there ", "Check node,textnode,comment with text()" ); - equals( j[2].nodeType, 8, "Check node,textnode,comment with text()" ); -}); - test("jQuery.each(Object,Function)", function() { expect(12); jQuery.each( [0,1,2], function(i, n){ @@ -1684,161 +490,18 @@ test("jQuery.each(Object,Function)", function() { equals( i, n, "Check object iteration" ); }); - var total = 0; - jQuery.each([1,2,3], function(i,v){ total += v; }); - equals( total, 6, "Looping over an array" ); - total = 0; - jQuery.each([1,2,3], function(i,v){ total += v; if ( i == 1 ) return false; }); - equals( total, 3, "Looping over an array, with break" ); - total = 0; - jQuery.each({"a":1,"b":2,"c":3}, function(i,v){ total += v; }); - equals( total, 6, "Looping over an object" ); - total = 0; - jQuery.each({"a":3,"b":3,"c":3}, function(i,v){ total += v; return false; }); - equals( total, 3, "Looping over an object, with break" ); -}); - -test("jQuery.className", function() { - expect(6); - var x = jQuery("<p>Hi</p>")[0]; - var c = jQuery.className; - c.add(x, "hi"); - equals( x.className, "hi", "Check single added class" ); - c.add(x, "foo bar"); - equals( x.className, "hi foo bar", "Check more added classes" ); - c.remove(x); - equals( x.className, "", "Remove all classes" ); - c.add(x, "hi foo bar"); - c.remove(x, "foo"); - equals( x.className, "hi bar", "Check removal of one class" ); - ok( c.has(x, "hi"), "Check has1" ); - ok( c.has(x, "bar"), "Check has2" ); -}); - -test("remove()", function() { - expect(7); - jQuery("#ap").children().remove(); - ok( jQuery("#ap").text().length > 10, "Check text is not removed" ); - equals( jQuery("#ap").children().length, 0, "Check remove" ); - - reset(); - jQuery("#ap").children().remove("a"); - ok( jQuery("#ap").text().length > 10, "Check text is not removed" ); - equals( jQuery("#ap").children().length, 1, "Check filtered remove" ); - - jQuery("#ap").children().remove("a, code"); - equals( jQuery("#ap").children().length, 0, "Check multi-filtered remove" ); - - // using contents will get comments regular, text, and comment nodes - equals( jQuery("#nonnodes").contents().length, 3, "Check node,textnode,comment remove works" ); - jQuery("#nonnodes").contents().remove(); - equals( jQuery("#nonnodes").contents().length, 0, "Check node,textnode,comment remove works" ); -}); - -test("empty()", function() { - expect(3); - equals( jQuery("#ap").children().empty().text().length, 0, "Check text is removed" ); - equals( jQuery("#ap").children().length, 4, "Check elements are not removed" ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.empty(); - equals( j.html(), "", "Check node,textnode,comment empty works" ); -}); - -test("slice()", function() { - expect(6); - - var $links = jQuery("#ap a"); - - isSet( $links.slice(1,2), q("groups"), "slice(1,2)" ); - isSet( $links.slice(1), q("groups", "anchor1", "mark"), "slice(1)" ); - isSet( $links.slice(0,3), q("google", "groups", "anchor1"), "slice(0,3)" ); - isSet( $links.slice(-1), q("mark"), "slice(-1)" ); - - isSet( $links.eq(1), q("groups"), "eq(1)" ); - - isSet( $links.eq('2'), q("anchor1"), "eq('2')" ); -}); - -test("map()", function() { - expect(2);//expect(6); - - isSet( - jQuery("#ap").map(function(){ - return jQuery(this).find("a").get(); - }), - q("google", "groups", "anchor1", "mark"), - "Array Map" - ); - - isSet( - jQuery("#ap > a").map(function(){ - return this.parentNode; - }), - q("ap","ap","ap"), - "Single Map" - ); - - return;//these haven't been accepted yet - - //for #2616 - var keys = jQuery.map( {a:1,b:2}, function( v, k ){ - return k; - }, [ ] ); - - equals( keys.join(""), "ab", "Map the keys from a hash to an array" ); - - var values = jQuery.map( {a:1,b:2}, function( v, k ){ - return v; - }, [ ] ); - - equals( values.join(""), "12", "Map the values from a hash to an array" ); - - var scripts = document.getElementsByTagName("script"); - var mapped = jQuery.map( scripts, function( v, k ){ - return v; - }, {length:0} ); - - equals( mapped.length, scripts.length, "Map an array(-like) to a hash" ); - - var flat = jQuery.map( Array(4), function( v, k ){ - return k % 2 ? k : [k,k,k];//try mixing array and regular returns - }); - - equals( flat.join(""), "00012223", "try the new flatten technique(#2616)" ); -}); - -test("contents()", function() { - expect(12); - equals( jQuery("#ap").contents().length, 9, "Check element contents" ); - ok( jQuery("#iframe").contents()[0], "Check existance of IFrame document" ); - var ibody = jQuery("#loadediframe").contents()[0].body; - ok( ibody, "Check existance of IFrame body" ); - - equals( jQuery("span", ibody).text(), "span text", "Find span in IFrame and check its text" ); - - jQuery(ibody).append("<div>init text</div>"); - equals( jQuery("div", ibody).length, 2, "Check the original div and the new div are in IFrame" ); - - equals( jQuery("div:last", ibody).text(), "init text", "Add text to div in IFrame" ); - - jQuery("div:last", ibody).text("div text"); - equals( jQuery("div:last", ibody).text(), "div text", "Add text to div in IFrame" ); - - jQuery("div:last", ibody).remove(); - equals( jQuery("div", ibody).length, 1, "Delete the div and check only one div left in IFrame" ); - - equals( jQuery("div", ibody).text(), "span text", "Make sure the correct div is still left after deletion in IFrame" ); - - jQuery("<table/>", ibody).append("<tr><td>cell</td></tr>").appendTo(ibody); - jQuery("table", ibody).remove(); - equals( jQuery("div", ibody).length, 1, "Check for JS error on add and delete of a table in IFrame" ); - - // using contents will get comments regular, text, and comment nodes - var c = jQuery("#nonnodes").contents().contents(); - equals( c.length, 1, "Check node,textnode,comment contents is just one" ); - equals( c[0].nodeValue, "hi", "Check node,textnode,comment contents is just the one from span" ); + var total = 0; + jQuery.each([1,2,3], function(i,v){ total += v; }); + equals( total, 6, "Looping over an array" ); + total = 0; + jQuery.each([1,2,3], function(i,v){ total += v; if ( i == 1 ) return false; }); + equals( total, 3, "Looping over an array, with break" ); + total = 0; + jQuery.each({"a":1,"b":2,"c":3}, function(i,v){ total += v; }); + equals( total, 6, "Looping over an object" ); + total = 0; + jQuery.each({"a":3,"b":3,"c":3}, function(i,v){ total += v; return false; }); + equals( total, 3, "Looping over an object, with break" ); }); test("jQuery.makeArray", function(){ diff --git a/test/unit/fx.js b/test/unit/fx.js index de10acedc..63a3de7a6 100644 --- a/test/unit/fx.js +++ b/test/unit/fx.js @@ -1,5 +1,40 @@ module("fx"); +test("show()", function() { + expect(15); + var pass = true, div = jQuery("#main div"); + div.show().each(function(){ + if ( this.style.display == "none" ) pass = false; + }); + ok( pass, "Show" ); + + jQuery("#main").append('<div id="show-tests"><div><p><a href="#"></a></p><code></code><pre></pre><span></span></div><table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table><ul><li></li></ul></div>'); + + var old = jQuery("#show-tests table").show().css("display") !== "table"; + + var test = { + "div" : "block", + "p" : "block", + "a" : "inline", + "code" : "inline", + "pre" : "block", + "span" : "inline", + "table" : old ? "block" : "table", + "thead" : old ? "block" : "table-header-group", + "tbody" : old ? "block" : "table-row-group", + "tr" : old ? "block" : "table-row", + "th" : old ? "block" : "table-cell", + "td" : old ? "block" : "table-cell", + "ul" : "block", + "li" : old ? "block" : "list-item" + }; + + jQuery.each(test, function(selector, expected) { + var elem = jQuery(selector, "#show-tests").show(); + equals( elem.css("display"), expected, "Show using correct display type for " + selector ); + }); +}); + test("animate(Hash, Object, Function)", function() { expect(1); stop(); diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js new file mode 100644 index 000000000..0327f93b2 --- /dev/null +++ b/test/unit/manipulation.js @@ -0,0 +1,596 @@ +test("text()", function() { + expect(1); + var expected = "This link has class=\"blog\": Simon Willison's Weblog"; + equals( jQuery('#sap').text(), expected, 'Check for merged text of more then one element.' ); +}); + +test("wrap(String|Element)", function() { + expect(10); + var defaultText = 'Try them out:' + var result = jQuery('#first').wrap('<div class="red"><span></span></div>').text(); + equals( defaultText, result, 'Check for wrapping of on-the-fly html' ); + ok( jQuery('#first').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); + + reset(); + var defaultText = 'Try them out:' + var result = jQuery('#first').wrap(document.getElementById('empty')).parent(); + ok( result.is('ol'), 'Check for element wrapping' ); + equals( result.text(), defaultText, 'Check for element wrapping' ); + + reset(); + jQuery('#check1').click(function() { + var checkbox = this; + ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); + jQuery(checkbox).wrap( '<div id="c1" style="display:none;"></div>' ); + ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); + }).click(); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.wrap("<i></i>"); + equals( jQuery("#nonnodes > i").length, 3, "Check node,textnode,comment wraps ok" ); + equals( jQuery("#nonnodes > i").text(), j.text() + j[1].nodeValue, "Check node,textnode,comment wraps doesn't hurt text" ); + + // Try wrapping a disconnected node + j = jQuery("<label/>").wrap("<li/>"); + equals( j[0].nodeName.toUpperCase(), "LABEL", "Element is a label" ); + equals( j[0].parentNode.nodeName.toUpperCase(), "LI", "Element has been wrapped" ); +}); + +test("wrapAll(String|Element)", function() { + expect(8); + var prev = jQuery("#firstp")[0].previousSibling; + var p = jQuery("#firstp,#first")[0].parentNode; + var result = jQuery('#firstp,#first').wrapAll('<div class="red"><div id="tmp"></div></div>'); + equals( result.parent().length, 1, 'Check for wrapping of on-the-fly html' ); + ok( jQuery('#first').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); + ok( jQuery('#firstp').parent().parent().is('.red'), 'Check if wrapper has class "red"' ); + equals( jQuery("#first").parent().parent()[0].previousSibling, prev, "Correct Previous Sibling" ); + equals( jQuery("#first").parent().parent()[0].parentNode, p, "Correct Parent" ); + + reset(); + var prev = jQuery("#firstp")[0].previousSibling; + var p = jQuery("#first")[0].parentNode; + var result = jQuery('#firstp,#first').wrapAll(document.getElementById('empty')); + equals( jQuery("#first").parent()[0], jQuery("#firstp").parent()[0], "Same Parent" ); + equals( jQuery("#first").parent()[0].previousSibling, prev, "Correct Previous Sibling" ); + equals( jQuery("#first").parent()[0].parentNode, p, "Correct Parent" ); +}); + +test("wrapInner(String|Element)", function() { + expect(6); + var num = jQuery("#first").children().length; + var result = jQuery('#first').wrapInner('<div class="red"><div id="tmp"></div></div>'); + equals( jQuery("#first").children().length, 1, "Only one child" ); + ok( jQuery("#first").children().is(".red"), "Verify Right Element" ); + equals( jQuery("#first").children().children().children().length, num, "Verify Elements Intact" ); + + reset(); + var num = jQuery("#first").children().length; + var result = jQuery('#first').wrapInner(document.getElementById('empty')); + equals( jQuery("#first").children().length, 1, "Only one child" ); + ok( jQuery("#first").children().is("#empty"), "Verify Right Element" ); + equals( jQuery("#first").children().children().length, num, "Verify Elements Intact" ); +}); + +test("append(String|Element|Array<Element>|jQuery)", function() { + expect(21); + var defaultText = 'Try them out:' + var result = jQuery('#first').append('<b>buga</b>'); + equals( result.text(), defaultText + 'buga', 'Check if text appending works' ); + equals( jQuery('#select3').append('<option value="appendTest">Append Test</option>').find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); + + reset(); + var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:"; + jQuery('#sap').append(document.getElementById('first')); + equals( expected, jQuery('#sap').text(), "Check for appending of element" ); + + reset(); + expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo"; + jQuery('#sap').append([document.getElementById('first'), document.getElementById('yahoo')]); + equals( expected, jQuery('#sap').text(), "Check for appending of array of elements" ); + + reset(); + expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:"; + jQuery('#sap').append(jQuery("#first, #yahoo")); + equals( expected, jQuery('#sap').text(), "Check for appending of jQuery object" ); + + reset(); + jQuery("#sap").append( 5 ); + ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" ); + + reset(); + jQuery("#sap").append( " text with spaces " ); + ok( jQuery("#sap")[0].innerHTML.match(/ text with spaces $/), "Check for appending text with spaces" ); + + reset(); + ok( jQuery("#sap").append([]), "Check for appending an empty array." ); + ok( jQuery("#sap").append(""), "Check for appending an empty string." ); + ok( jQuery("#sap").append(document.getElementsByTagName("foo")), "Check for appending an empty nodelist." ); + + reset(); + jQuery("#sap").append(document.getElementById('form')); + equals( jQuery("#sap>form").size(), 1, "Check for appending a form" ); // Bug #910 + + reset(); + var pass = true; + try { + jQuery( jQuery("#iframe")[0].contentWindow.document.body ).append("<div>test</div>"); + } catch(e) { + pass = false; + } + + ok( pass, "Test for appending a DOM node to the contents of an IFrame" ); + + reset(); + jQuery('<fieldset/>').appendTo('#form').append('<legend id="legend">test</legend>'); + t( 'Append legend', '#legend', ['legend'] ); + + reset(); + jQuery('#select1').append('<OPTION>Test</OPTION>'); + equals( jQuery('#select1 option:last').text(), "Test", "Appending <OPTION> (all caps)" ); + + jQuery('#table').append('<colgroup></colgroup>'); + ok( jQuery('#table colgroup').length, "Append colgroup" ); + + jQuery('#table colgroup').append('<col/>'); + ok( jQuery('#table colgroup col').length, "Append col" ); + + reset(); + jQuery('#table').append('<caption></caption>'); + ok( jQuery('#table caption').length, "Append caption" ); + + reset(); + jQuery('form:last') + .append('<select id="appendSelect1"></select>') + .append('<select id="appendSelect2"><option>Test</option></select>'); + + t( "Append Select", "#appendSelect1, #appendSelect2", ["appendSelect1", "appendSelect2"] ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + var d = jQuery("<div/>").appendTo("#nonnodes").append(j); + equals( jQuery("#nonnodes").length, 1, "Check node,textnode,comment append moved leaving just the div" ); + ok( d.contents().length >= 2, "Check node,textnode,comment append works" ); + d.contents().appendTo("#nonnodes"); + d.remove(); + ok( jQuery("#nonnodes").contents().length >= 2, "Check node,textnode,comment append cleanup worked" ); +}); + +test("appendTo(String|Element|Array<Element>|jQuery)", function() { + expect(12); + var defaultText = 'Try them out:' + jQuery('<b>buga</b>').appendTo('#first'); + equals( jQuery("#first").text(), defaultText + 'buga', 'Check if text appending works' ); + equals( jQuery('<option value="appendTest">Append Test</option>').appendTo('#select3').parent().find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); + + reset(); + var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:"; + jQuery(document.getElementById('first')).appendTo('#sap'); + equals( expected, jQuery('#sap').text(), "Check for appending of element" ); + + reset(); + expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo"; + jQuery([document.getElementById('first'), document.getElementById('yahoo')]).appendTo('#sap'); + equals( expected, jQuery('#sap').text(), "Check for appending of array of elements" ); + + reset(); + ok( jQuery(document.createElement("script")).appendTo("body").length, "Make sure a disconnected script can be appended." ); + + reset(); + expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:"; + jQuery("#first, #yahoo").appendTo('#sap'); + equals( expected, jQuery('#sap').text(), "Check for appending of jQuery object" ); + + reset(); + jQuery('#select1').appendTo('#foo'); + t( 'Append select', '#foo select', ['select1'] ); + + reset(); + var div = jQuery("<div/>").click(function(){ + ok(true, "Running a cloned click."); + }); + div.appendTo("#main, #moretests"); + + jQuery("#main div:last").click(); + jQuery("#moretests div:last").click(); + + reset(); + var div = jQuery("<div/>").appendTo("#main, #moretests"); + + equals( div.length, 2, "appendTo returns the inserted elements" ); + + div.addClass("test"); + + ok( jQuery("#main div:last").hasClass("test"), "appendTo element was modified after the insertion" ); + ok( jQuery("#moretests div:last").hasClass("test"), "appendTo element was modified after the insertion" ); + + reset(); +}); + +test("prepend(String|Element|Array<Element>|jQuery)", function() { + expect(5); + var defaultText = 'Try them out:' + var result = jQuery('#first').prepend('<b>buga</b>'); + equals( result.text(), 'buga' + defaultText, 'Check if text prepending works' ); + equals( jQuery('#select3').prepend('<option value="prependTest">Prepend Test</option>').find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); + + reset(); + var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog"; + jQuery('#sap').prepend(document.getElementById('first')); + equals( expected, jQuery('#sap').text(), "Check for prepending of element" ); + + reset(); + expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog"; + jQuery('#sap').prepend([document.getElementById('first'), document.getElementById('yahoo')]); + equals( expected, jQuery('#sap').text(), "Check for prepending of array of elements" ); + + reset(); + expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; + jQuery('#sap').prepend(jQuery("#first, #yahoo")); + equals( expected, jQuery('#sap').text(), "Check for prepending of jQuery object" ); +}); + +test("prependTo(String|Element|Array<Element>|jQuery)", function() { + expect(6); + var defaultText = 'Try them out:' + jQuery('<b>buga</b>').prependTo('#first'); + equals( jQuery('#first').text(), 'buga' + defaultText, 'Check if text prepending works' ); + equals( jQuery('<option value="prependTest">Prepend Test</option>').prependTo('#select3').parent().find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); + + reset(); + var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog"; + jQuery(document.getElementById('first')).prependTo('#sap'); + equals( expected, jQuery('#sap').text(), "Check for prepending of element" ); + + reset(); + expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog"; + jQuery([document.getElementById('first'), document.getElementById('yahoo')]).prependTo('#sap'); + equals( expected, jQuery('#sap').text(), "Check for prepending of array of elements" ); + + reset(); + expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; + jQuery("#first, #yahoo").prependTo('#sap'); + equals( expected, jQuery('#sap').text(), "Check for prepending of jQuery object" ); + + reset(); + jQuery('<select id="prependSelect1"></select>').prependTo('form:last'); + jQuery('<select id="prependSelect2"><option>Test</option></select>').prependTo('form:last'); + + t( "Prepend Select", "#prependSelect2, #prependSelect1", ["prependSelect2", "prependSelect1"] ); +}); + +test("before(String|Element|Array<Element>|jQuery)", function() { + expect(4); + var expected = 'This is a normal link: bugaYahoo'; + jQuery('#yahoo').before('<b>buga</b>'); + equals( expected, jQuery('#en').text(), 'Insert String before' ); + + reset(); + expected = "This is a normal link: Try them out:Yahoo"; + jQuery('#yahoo').before(document.getElementById('first')); + equals( expected, jQuery('#en').text(), "Insert element before" ); + + reset(); + expected = "This is a normal link: Try them out:diveintomarkYahoo"; + jQuery('#yahoo').before([document.getElementById('first'), document.getElementById('mark')]); + equals( expected, jQuery('#en').text(), "Insert array of elements before" ); + + reset(); + expected = "This is a normal link: diveintomarkTry them out:Yahoo"; + jQuery('#yahoo').before(jQuery("#first, #mark")); + equals( expected, jQuery('#en').text(), "Insert jQuery before" ); +}); + +test("insertBefore(String|Element|Array<Element>|jQuery)", function() { + expect(4); + var expected = 'This is a normal link: bugaYahoo'; + jQuery('<b>buga</b>').insertBefore('#yahoo'); + equals( expected, jQuery('#en').text(), 'Insert String before' ); + + reset(); + expected = "This is a normal link: Try them out:Yahoo"; + jQuery(document.getElementById('first')).insertBefore('#yahoo'); + equals( expected, jQuery('#en').text(), "Insert element before" ); + + reset(); + expected = "This is a normal link: Try them out:diveintomarkYahoo"; + jQuery([document.getElementById('first'), document.getElementById('mark')]).insertBefore('#yahoo'); + equals( expected, jQuery('#en').text(), "Insert array of elements before" ); + + reset(); + expected = "This is a normal link: diveintomarkTry them out:Yahoo"; + jQuery("#first, #mark").insertBefore('#yahoo'); + equals( expected, jQuery('#en').text(), "Insert jQuery before" ); +}); + +test("after(String|Element|Array<Element>|jQuery)", function() { + expect(4); + var expected = 'This is a normal link: Yahoobuga'; + jQuery('#yahoo').after('<b>buga</b>'); + equals( expected, jQuery('#en').text(), 'Insert String after' ); + + reset(); + expected = "This is a normal link: YahooTry them out:"; + jQuery('#yahoo').after(document.getElementById('first')); + equals( expected, jQuery('#en').text(), "Insert element after" ); + + reset(); + expected = "This is a normal link: YahooTry them out:diveintomark"; + jQuery('#yahoo').after([document.getElementById('first'), document.getElementById('mark')]); + equals( expected, jQuery('#en').text(), "Insert array of elements after" ); + + reset(); + expected = "This is a normal link: YahoodiveintomarkTry them out:"; + jQuery('#yahoo').after(jQuery("#first, #mark")); + equals( expected, jQuery('#en').text(), "Insert jQuery after" ); +}); + +test("insertAfter(String|Element|Array<Element>|jQuery)", function() { + expect(4); + var expected = 'This is a normal link: Yahoobuga'; + jQuery('<b>buga</b>').insertAfter('#yahoo'); + equals( expected, jQuery('#en').text(), 'Insert String after' ); + + reset(); + expected = "This is a normal link: YahooTry them out:"; + jQuery(document.getElementById('first')).insertAfter('#yahoo'); + equals( expected, jQuery('#en').text(), "Insert element after" ); + + reset(); + expected = "This is a normal link: YahooTry them out:diveintomark"; + jQuery([document.getElementById('first'), document.getElementById('mark')]).insertAfter('#yahoo'); + equals( expected, jQuery('#en').text(), "Insert array of elements after" ); + + reset(); + expected = "This is a normal link: YahoodiveintomarkTry them out:"; + jQuery("#first, #mark").insertAfter('#yahoo'); + equals( expected, jQuery('#en').text(), "Insert jQuery after" ); +}); + +test("replaceWith(String|Element|Array<Element>|jQuery)", function() { + expect(10); + jQuery('#yahoo').replaceWith('<b id="replace">buga</b>'); + ok( jQuery("#replace")[0], 'Replace element with string' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after string' ); + + reset(); + jQuery('#yahoo').replaceWith(document.getElementById('first')); + ok( jQuery("#first")[0], 'Replace element with element' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after element' ); + + reset(); + jQuery('#yahoo').replaceWith([document.getElementById('first'), document.getElementById('mark')]); + ok( jQuery("#first")[0], 'Replace element with array of elements' ); + ok( jQuery("#mark")[0], 'Replace element with array of elements' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after array of elements' ); + + reset(); + jQuery('#yahoo').replaceWith(jQuery("#first, #mark")); + ok( jQuery("#first")[0], 'Replace element with set of elements' ); + ok( jQuery("#mark")[0], 'Replace element with set of elements' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after set of elements' ); +}); + +test("replaceAll(String|Element|Array<Element>|jQuery)", function() { + expect(10); + jQuery('<b id="replace">buga</b>').replaceAll("#yahoo"); + ok( jQuery("#replace")[0], 'Replace element with string' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after string' ); + + reset(); + jQuery(document.getElementById('first')).replaceAll("#yahoo"); + ok( jQuery("#first")[0], 'Replace element with element' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after element' ); + + reset(); + jQuery([document.getElementById('first'), document.getElementById('mark')]).replaceAll("#yahoo"); + ok( jQuery("#first")[0], 'Replace element with array of elements' ); + ok( jQuery("#mark")[0], 'Replace element with array of elements' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after array of elements' ); + + reset(); + jQuery("#first, #mark").replaceAll("#yahoo"); + ok( jQuery("#first")[0], 'Replace element with set of elements' ); + ok( jQuery("#mark")[0], 'Replace element with set of elements' ); + ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after set of elements' ); +}); + +test("clone()", function() { + expect(28); + equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Assert text for #en' ); + var clone = jQuery('#yahoo').clone(); + equals( 'Try them out:Yahoo', jQuery('#first').append(clone).text(), 'Check for clone' ); + equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Reassert text for #en' ); + + var cloneTags = [ + "<table/>", "<tr/>", "<td/>", "<div/>", + "<button/>", "<ul/>", "<ol/>", "<li/>", + "<input type='checkbox' />", "<select/>", "<option/>", "<textarea/>", + "<tbody/>", "<thead/>", "<tfoot/>", "<iframe/>" + ]; + for (var i = 0; i < cloneTags.length; i++) { + var j = jQuery(cloneTags[i]); + equals( j[0].tagName, j.clone()[0].tagName, 'Clone a <' + cloneTags[i].substring(1)); + } + + // using contents will get comments regular, text, and comment nodes + var cl = jQuery("#nonnodes").contents().clone(); + ok( cl.length >= 2, "Check node,textnode,comment clone works (some browsers delete comments on clone)" ); + + var div = jQuery("<div><ul><li>test</li></ul></div>").click(function(){ + ok( true, "Bound event still exists." ); + }); + + div = div.clone(true).clone(true); + equals( div.length, 1, "One element cloned" ); + equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" ); + div.trigger("click"); + + div = jQuery("<div/>").append([ document.createElement("table"), document.createElement("table") ]); + div.find("table").click(function(){ + ok( true, "Bound event still exists." ); + }); + + div = div.clone(true); + equals( div.length, 1, "One element cloned" ); + equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" ); + div.find("table:last").trigger("click"); + + div = jQuery("<div/>").html('<object height="355" width="425"> <param name="movie" value="http://www.youtube.com/v/JikaHBDoV3k&hl=en"> <param name="wmode" value="transparent"> </object>'); + + div = div.clone(true); + equals( div.length, 1, "One element cloned" ); + equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" ); +}); + +if (!isLocal) { +test("clone() on XML nodes", function() { + expect(2); + stop(); + jQuery.get("data/dashboard.xml", function (xml) { + var root = jQuery(xml.documentElement).clone(); + var origTab = jQuery("tab", xml).eq(0); + var cloneTab = jQuery("tab", root).eq(0); + origTab.text("origval"); + cloneTab.text("cloneval"); + equals(origTab.text(), "origval", "Check original XML node was correctly set"); + equals(cloneTab.text(), "cloneval", "Check cloned XML node was correctly set"); + start(); + }); +}); +} + +test("val()", function() { + expect(8); + + equals( jQuery("#text1").val(), "Test", "Check for value of input element" ); + // ticket #1714 this caused a JS error in IE + equals( jQuery("#first").val(), "", "Check a paragraph element to see if it has a value" ); + ok( jQuery([]).val() === undefined, "Check an empty jQuery object will return undefined from val" ); + + equals( jQuery('#select2').val(), '3', 'Call val() on a single="single" select' ); + + isSet( jQuery('#select3').val(), ['1', '2'], 'Call val() on a multiple="multiple" select' ); + + equals( jQuery('#option3c').val(), '2', 'Call val() on a option element with value' ); + + equals( jQuery('#option3a').val(), '', 'Call val() on a option element with empty value' ); + + equals( jQuery('#option3e').val(), 'no value', 'Call val() on a option element with no value attribute' ); + +}); + +test("val(String/Number)", function() { + expect(6); + document.getElementById('text1').value = "bla"; + equals( jQuery("#text1").val(), "bla", "Check for modified value of input element" ); + + jQuery("#text1").val('test'); + equals( document.getElementById('text1').value, "test", "Check for modified (via val(String)) value of input element" ); + + jQuery("#text1").val(67); + equals( document.getElementById('text1').value, "67", "Check for modified (via val(Number)) value of input element" ); + + jQuery("#select1").val("3"); + equals( jQuery("#select1").val(), "3", "Check for modified (via val(String)) value of select element" ); + + jQuery("#select1").val(2); + equals( jQuery("#select1").val(), "2", "Check for modified (via val(Number)) value of select element" ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.val("asdf"); + equals( j.val(), "asdf", "Check node,textnode,comment with val()" ); + j.removeAttr("value"); +}); + +test("html(String)", function() { + expect(17); + + jQuery.scriptorder = 0; + + var div = jQuery("#main > div"); + div.html("<b>test</b>"); + var pass = true; + for ( var i = 0; i < div.size(); i++ ) { + if ( div.get(i).childNodes.length != 1 ) pass = false; + } + ok( pass, "Set HTML" ); + + reset(); + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.html("<b>bold</b>"); + + // this is needed, or the expando added by jQuery unique will yield a different html + j.find('b').removeData(); + equals( j.html().replace(/ xmlns="[^"]+"/g, "").toLowerCase(), "<b>bold</b>", "Check node,textnode,comment with html()" ); + + jQuery("#main").html("<select/>"); + jQuery("#main select").html("<option>O1</option><option selected='selected'>O2</option><option>O3</option>"); + equals( jQuery("#main select").val(), "O2", "Selected option correct" ); + + var $div = jQuery('<div />'); + equals( $div.html( 5 ).html(), '5', 'Setting a number as html' ); + equals( $div.html( 0 ).html(), '0', 'Setting a zero as html' ); + + reset(); + + jQuery("#main").html('<script type="something/else">ok( false, "Non-script evaluated." );</script><script type="text/javascript">ok( true, "text/javascript is evaluated." );</script><script>ok( true, "No type is evaluated." );</script><div><script type="text/javascript">ok( true, "Inner text/javascript is evaluated." );</script><script>ok( true, "Inner No type is evaluated." );</script><script type="something/else">ok( false, "Non-script evaluated." );</script></div>'); + + stop(); + + jQuery("#main").html('<script type="text/javascript">ok( true, "jQuery().html().evalScripts() Evals Scripts Twice in Firefox, see #975" );</script>'); + + jQuery("#main").html('foo <form><script type="text/javascript">ok( true, "jQuery().html().evalScripts() Evals Scripts Twice in Firefox, see #975" );</script></form>'); + + // it was decided that waiting to execute ALL scripts makes sense since nested ones have to wait anyway so this test case is changed, see #1959 + jQuery("#main").html("<script>equals(jQuery.scriptorder++, 0, 'Script is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html (even though appears before)')<\/script><span id='scriptorder'><script>equals(jQuery.scriptorder++, 1, 'Script (nested) is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html')<\/script></span><script>equals(jQuery.scriptorder++, 2, 'Script (unnested) is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html')<\/script>"); + + setTimeout( start, 100 ); +}); + +test("text(String)", function() { + expect(4); + equals( jQuery("#foo").text("<div><b>Hello</b> cruel world!</div>")[0].innerHTML.replace(/>/g, ">"), "<div><b>Hello</b> cruel world!</div>", "Check escaped text" ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.text("hi!"); + equals( jQuery(j[0]).text(), "hi!", "Check node,textnode,comment with text()" ); + equals( j[1].nodeValue, " there ", "Check node,textnode,comment with text()" ); + equals( j[2].nodeType, 8, "Check node,textnode,comment with text()" ); +}); + +test("remove()", function() { + expect(7); + jQuery("#ap").children().remove(); + ok( jQuery("#ap").text().length > 10, "Check text is not removed" ); + equals( jQuery("#ap").children().length, 0, "Check remove" ); + + reset(); + jQuery("#ap").children().remove("a"); + ok( jQuery("#ap").text().length > 10, "Check text is not removed" ); + equals( jQuery("#ap").children().length, 1, "Check filtered remove" ); + + jQuery("#ap").children().remove("a, code"); + equals( jQuery("#ap").children().length, 0, "Check multi-filtered remove" ); + + // using contents will get comments regular, text, and comment nodes + equals( jQuery("#nonnodes").contents().length, 3, "Check node,textnode,comment remove works" ); + jQuery("#nonnodes").contents().remove(); + equals( jQuery("#nonnodes").contents().length, 0, "Check node,textnode,comment remove works" ); +}); + +test("empty()", function() { + expect(3); + equals( jQuery("#ap").children().empty().text().length, 0, "Check text is removed" ); + equals( jQuery("#ap").children().length, 4, "Check elements are not removed" ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.empty(); + equals( j.html(), "", "Check node,textnode,comment empty works" ); +}); + diff --git a/test/unit/traversing.js b/test/unit/traversing.js new file mode 100644 index 000000000..8abb73751 --- /dev/null +++ b/test/unit/traversing.js @@ -0,0 +1,246 @@ +test("end()", function() { + expect(3); + equals( 'Yahoo', jQuery('#yahoo').parent().end().text(), 'Check for end' ); + ok( jQuery('#yahoo').end(), 'Check for end with nothing to end' ); + + var x = jQuery('#yahoo'); + x.parent(); + equals( 'Yahoo', jQuery('#yahoo').text(), 'Check for non-destructive behaviour' ); +}); + +test("find(String)", function() { + expect(2); + equals( 'Yahoo', jQuery('#foo').find('.blogTest').text(), 'Check for find' ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + equals( j.find("div").length, 0, "Check node,textnode,comment to find zero divs" ); +}); + +test("is(String)", function() { + expect(26); + ok( jQuery('#form').is('form'), 'Check for element: A form must be a form' ); + ok( !jQuery('#form').is('div'), 'Check for element: A form is not a div' ); + ok( jQuery('#mark').is('.blog'), 'Check for class: Expected class "blog"' ); + ok( !jQuery('#mark').is('.link'), 'Check for class: Did not expect class "link"' ); + ok( jQuery('#simon').is('.blog.link'), 'Check for multiple classes: Expected classes "blog" and "link"' ); + ok( !jQuery('#simon').is('.blogTest'), 'Check for multiple classes: Expected classes "blog" and "link", but not "blogTest"' ); + ok( jQuery('#en').is('[lang="en"]'), 'Check for attribute: Expected attribute lang to be "en"' ); + ok( !jQuery('#en').is('[lang="de"]'), 'Check for attribute: Expected attribute lang to be "en", not "de"' ); + ok( jQuery('#text1').is('[type="text"]'), 'Check for attribute: Expected attribute type to be "text"' ); + ok( !jQuery('#text1').is('[type="radio"]'), 'Check for attribute: Expected attribute type to be "text", not "radio"' ); + ok( jQuery('#text2').is(':disabled'), 'Check for pseudoclass: Expected to be disabled' ); + ok( !jQuery('#text1').is(':disabled'), 'Check for pseudoclass: Expected not disabled' ); + ok( jQuery('#radio2').is(':checked'), 'Check for pseudoclass: Expected to be checked' ); + ok( !jQuery('#radio1').is(':checked'), 'Check for pseudoclass: Expected not checked' ); + ok( jQuery('#foo').is(':has(p)'), 'Check for child: Expected a child "p" element' ); + ok( !jQuery('#foo').is(':has(ul)'), 'Check for child: Did not expect "ul" element' ); + ok( jQuery('#foo').is(':has(p):has(a):has(code)'), 'Check for childs: Expected "p", "a" and "code" child elements' ); + ok( !jQuery('#foo').is(':has(p):has(a):has(code):has(ol)'), 'Check for childs: Expected "p", "a" and "code" child elements, but no "ol"' ); + ok( !jQuery('#foo').is(0), 'Expected false for an invalid expression - 0' ); + ok( !jQuery('#foo').is(null), 'Expected false for an invalid expression - null' ); + ok( !jQuery('#foo').is(''), 'Expected false for an invalid expression - ""' ); + ok( !jQuery('#foo').is(undefined), 'Expected false for an invalid expression - undefined' ); + + // test is() with comma-seperated expressions + ok( jQuery('#en').is('[lang="en"],[lang="de"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); + ok( jQuery('#en').is('[lang="de"],[lang="en"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); + ok( jQuery('#en').is('[lang="en"] , [lang="de"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); + ok( jQuery('#en').is('[lang="de"] , [lang="en"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); +}); + +test("filter()", function() { + expect(6); + isSet( jQuery("#form input").filter(":checked").get(), q("radio2", "check1"), "filter(String)" ); + isSet( jQuery("p").filter("#ap, #sndp").get(), q("ap", "sndp"), "filter('String, String')" ); + isSet( jQuery("p").filter("#ap,#sndp").get(), q("ap", "sndp"), "filter('String,String')" ); + isSet( jQuery("p").filter(function() { return !jQuery("a", this).length }).get(), q("sndp", "first"), "filter(Function)" ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + equals( j.filter("span").length, 1, "Check node,textnode,comment to filter the one span" ); + equals( j.filter("[name]").length, 0, "Check node,textnode,comment to filter the one span" ); +}); + +test("closest()", function() { + expect(6); + isSet( jQuery("body").closest("body").get(), q("body"), "closest(body)" ); + isSet( jQuery("body").closest("html").get(), q("html"), "closest(html)" ); + isSet( jQuery("body").closest("div").get(), [], "closest(div)" ); + isSet( jQuery("#main").closest("span,#html").get(), q("html"), "closest(span,#html)" ); + + isSet( jQuery("div:eq(1)").closest("div:first").get(), [], "closest(div:first)" ); + isSet( jQuery("div").closest("body:first div:last").get(), q("fx-tests"), "closest(body:first div:last)" ); +}); + +test("not()", function() { + expect(11); + equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" ); + equals( jQuery("#main > p#ap > a").not(document.getElementById("google")).length, 2, "not(DOMElement)" ); + isSet( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" ); + isSet( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" ); + isSet( jQuery("p").not(jQuery("#ap, #sndp, .result")).get(), q("firstp", "en", "sap", "first"), "not(jQuery)" ); + equals( jQuery("p").not(document.getElementsByTagName("p")).length, 0, "not(Array-like DOM collection)" ); + isSet( jQuery("#form option").not("option.emptyopt:contains('Nothing'),[selected],[value='1']").get(), q("option1c", "option1d", "option2c", "option3d", "option3e" ), "not('complex selector')"); + + var selects = jQuery("#form select"); + isSet( selects.not( selects[1] ), q("select1", "select3"), "filter out DOM element"); + + isSet( jQuery('#ap *').not('code'), q("google", "groups", "anchor1", "mark"), "not('tag selector')" ); + isSet( jQuery('#ap *').not('code, #mark'), q("google", "groups", "anchor1"), "not('tag, ID selector')" ); + isSet( jQuery('#ap *').not('#mark, code'), q("google", "groups", "anchor1"), "not('ID, tag selector')"); +}); + +test("andSelf()", function() { + expect(4); + isSet( jQuery("#en").siblings().andSelf().get(), q("sndp", "sap","en"), "Check for siblings and self" ); + isSet( jQuery("#foo").children().andSelf().get(), q("sndp", "en", "sap", "foo"), "Check for children and self" ); + isSet( jQuery("#sndp, #en").parent().andSelf().get(), q("foo","sndp","en"), "Check for parent and self" ); + isSet( jQuery("#groups").parents("p, div").andSelf().get(), q("main", "ap", "groups"), "Check for parents and self" ); +}); + +test("siblings([String])", function() { + expect(5); + isSet( jQuery("#en").siblings().get(), q("sndp", "sap"), "Check for siblings" ); + isSet( jQuery("#sndp").siblings(":has(code)").get(), q("sap"), "Check for filtered siblings (has code child element)" ); + isSet( jQuery("#sndp").siblings(":has(a)").get(), q("en", "sap"), "Check for filtered siblings (has anchor child element)" ); + isSet( jQuery("#foo").siblings("form, b").get(), q("form", "floatTest", "lengthtest", "name-tests", "testForm"), "Check for multiple filters" ); + var set = q("en", "sap", "sndp"); + isSet( jQuery("#en, #sndp").siblings().get(), set, "Check for unique results from siblings" ); +}); + +test("children([String])", function() { + expect(3); + isSet( jQuery("#foo").children().get(), q("sndp", "en", "sap"), "Check for children" ); + isSet( jQuery("#foo").children(":has(code)").get(), q("sndp", "sap"), "Check for filtered children" ); + isSet( jQuery("#foo").children("#en, #sap").get(), q("en", "sap"), "Check for multiple filters" ); +}); + +test("parent([String])", function() { + expect(5); + equals( jQuery("#groups").parent()[0].id, "ap", "Simple parent check" ); + equals( jQuery("#groups").parent("p")[0].id, "ap", "Filtered parent check" ); + equals( jQuery("#groups").parent("div").length, 0, "Filtered parent check, no match" ); + equals( jQuery("#groups").parent("div, p")[0].id, "ap", "Check for multiple filters" ); + isSet( jQuery("#en, #sndp").parent().get(), q("foo"), "Check for unique results from parent" ); +}); + +test("parents([String])", function() { + expect(5); + equals( jQuery("#groups").parents()[0].id, "ap", "Simple parents check" ); + equals( jQuery("#groups").parents("p")[0].id, "ap", "Filtered parents check" ); + equals( jQuery("#groups").parents("div")[0].id, "main", "Filtered parents check2" ); + isSet( jQuery("#groups").parents("p, div").get(), q("main", "ap"), "Check for multiple filters" ); + isSet( jQuery("#en, #sndp").parents().get(), q("foo", "main", "dl", "body", "html"), "Check for unique results from parents" ); +}); + +test("next([String])", function() { + expect(4); + equals( jQuery("#ap").next()[0].id, "foo", "Simple next check" ); + equals( jQuery("#ap").next("div")[0].id, "foo", "Filtered next check" ); + equals( jQuery("#ap").next("p").length, 0, "Filtered next check, no match" ); + equals( jQuery("#ap").next("div, p")[0].id, "foo", "Multiple filters" ); +}); + +test("prev([String])", function() { + expect(4); + equals( jQuery("#foo").prev()[0].id, "ap", "Simple prev check" ); + equals( jQuery("#foo").prev("p")[0].id, "ap", "Filtered prev check" ); + equals( jQuery("#foo").prev("div").length, 0, "Filtered prev check, no match" ); + equals( jQuery("#foo").prev("p, div")[0].id, "ap", "Multiple filters" ); +}); + +test("slice()", function() { + expect(6); + + var $links = jQuery("#ap a"); + + isSet( $links.slice(1,2), q("groups"), "slice(1,2)" ); + isSet( $links.slice(1), q("groups", "anchor1", "mark"), "slice(1)" ); + isSet( $links.slice(0,3), q("google", "groups", "anchor1"), "slice(0,3)" ); + isSet( $links.slice(-1), q("mark"), "slice(-1)" ); + + isSet( $links.eq(1), q("groups"), "eq(1)" ); + + isSet( $links.eq('2'), q("anchor1"), "eq('2')" ); +}); + +test("map()", function() { + expect(2);//expect(6); + + isSet( + jQuery("#ap").map(function(){ + return jQuery(this).find("a").get(); + }), + q("google", "groups", "anchor1", "mark"), + "Array Map" + ); + + isSet( + jQuery("#ap > a").map(function(){ + return this.parentNode; + }), + q("ap","ap","ap"), + "Single Map" + ); + + return;//these haven't been accepted yet + + //for #2616 + var keys = jQuery.map( {a:1,b:2}, function( v, k ){ + return k; + }, [ ] ); + + equals( keys.join(""), "ab", "Map the keys from a hash to an array" ); + + var values = jQuery.map( {a:1,b:2}, function( v, k ){ + return v; + }, [ ] ); + + equals( values.join(""), "12", "Map the values from a hash to an array" ); + + var scripts = document.getElementsByTagName("script"); + var mapped = jQuery.map( scripts, function( v, k ){ + return v; + }, {length:0} ); + + equals( mapped.length, scripts.length, "Map an array(-like) to a hash" ); + + var flat = jQuery.map( Array(4), function( v, k ){ + return k % 2 ? k : [k,k,k];//try mixing array and regular returns + }); + + equals( flat.join(""), "00012223", "try the new flatten technique(#2616)" ); +}); + +test("contents()", function() { + expect(12); + equals( jQuery("#ap").contents().length, 9, "Check element contents" ); + ok( jQuery("#iframe").contents()[0], "Check existance of IFrame document" ); + var ibody = jQuery("#loadediframe").contents()[0].body; + ok( ibody, "Check existance of IFrame body" ); + + equals( jQuery("span", ibody).text(), "span text", "Find span in IFrame and check its text" ); + + jQuery(ibody).append("<div>init text</div>"); + equals( jQuery("div", ibody).length, 2, "Check the original div and the new div are in IFrame" ); + + equals( jQuery("div:last", ibody).text(), "init text", "Add text to div in IFrame" ); + + jQuery("div:last", ibody).text("div text"); + equals( jQuery("div:last", ibody).text(), "div text", "Add text to div in IFrame" ); + + jQuery("div:last", ibody).remove(); + equals( jQuery("div", ibody).length, 1, "Delete the div and check only one div left in IFrame" ); + + equals( jQuery("div", ibody).text(), "span text", "Make sure the correct div is still left after deletion in IFrame" ); + + jQuery("<table/>", ibody).append("<tr><td>cell</td></tr>").appendTo(ibody); + jQuery("table", ibody).remove(); + equals( jQuery("div", ibody).length, 1, "Check for JS error on add and delete of a table in IFrame" ); + + // using contents will get comments regular, text, and comment nodes + var c = jQuery("#nonnodes").contents().contents(); + equals( c.length, 1, "Check node,textnode,comment contents is just one" ); + equals( c[0].nodeValue, "hi", "Check node,textnode,comment contents is just the one from span" ); +});
\ No newline at end of file |