aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeresig <jeresig@gmail.com>2011-04-10 15:41:51 -0400
committerjeresig <jeresig@gmail.com>2011-04-10 15:41:51 -0400
commitb92d2f0bc96d65c83252fa3033c37b92eb32d442 (patch)
treeac8545d23de62865406703eb3eb7ff3bd7401d75
parentd4e4414451e15d23d7174e8eeddaa952ed0e4d73 (diff)
parent3a1b4661f5b8249ce7a741084824ec5445c75719 (diff)
downloadjquery-b92d2f0bc96d65c83252fa3033c37b92eb32d442.tar.gz
jquery-b92d2f0bc96d65c83252fa3033c37b92eb32d442.zip
Merge branch 'attrhooks.1.6v2' of https://github.com/timmywil/jquery into timmywil-attrhooks.1.6v2
Conflicts: src/attributes.js
-rw-r--r--.gitignore2
-rw-r--r--.gitmodules6
-rw-r--r--Makefile66
-rw-r--r--src/ajax.js9
-rw-r--r--src/attributes.js216
-rw-r--r--src/core.js2
-rw-r--r--src/css.js25
-rw-r--r--src/deferred.js5
-rw-r--r--src/event.js34
-rw-r--r--src/manipulation.js9
-rw-r--r--src/offset.js9
m---------src/sizzle0
-rw-r--r--src/support.js36
-rw-r--r--test/data/offset/fixed.html1
-rw-r--r--test/index.html4
m---------test/qunit0
-rw-r--r--test/unit/ajax.js12
-rw-r--r--test/unit/attributes.js227
-rw-r--r--test/unit/css.js12
-rw-r--r--test/unit/event.js44
-rw-r--r--test/unit/manipulation.js13
-rw-r--r--test/unit/offset.js17
-rw-r--r--version.txt2
23 files changed, 508 insertions, 243 deletions
diff --git a/.gitignore b/.gitignore
index a77d67a96..6cd547974 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,5 @@ dist
*~
*.diff
*.patch
-test/qunit
-src/sizzle
/*.html
.DS_Store
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..19c60418e
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "src/sizzle"]
+ path = src/sizzle
+ url = git://github.com/jquery/sizzle.git
+[submodule "test/qunit"]
+ path = test/qunit
+ url = git://github.com/jquery/qunit.git
diff --git a/Makefile b/Makefile
index a6aae4253..cfd2a9752 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,3 @@
-V ?= 0
-
SRC_DIR = src
TEST_DIR = test
BUILD_DIR = build
@@ -38,48 +36,21 @@ JQ = ${DIST_DIR}/jquery.js
JQ_MIN = ${DIST_DIR}/jquery.min.js
SIZZLE_DIR = ${SRC_DIR}/sizzle
-QUNIT_DIR = ${TEST_DIR}/qunit
JQ_VER = $(shell cat version.txt)
VER = sed "s/@VERSION/${JQ_VER}/"
DATE=$(shell git log -1 --pretty=format:%ad)
-all: jquery min lint
+all: update_submodules core
+
+core: jquery min lint
@@echo "jQuery build complete."
${DIST_DIR}:
@@mkdir -p ${DIST_DIR}
-ifeq ($(strip $(V)),0)
-verbose = --quiet
-else ifeq ($(strip $(V)),1)
-verbose =
-else
-verbose = --verbose
-endif
-
-define clone_or_pull
--@@if test ! -d $(strip ${1})/.git; then \
- echo "Cloning $(strip ${1})..."; \
- git clone $(strip ${verbose}) --depth=1 $(strip ${2}) $(strip ${1}); \
- else \
- echo "Pulling $(strip ${1})..."; \
- git --git-dir=$(strip ${1})/.git pull $(strip ${verbose}) origin master; \
- fi
-
-endef
-
-${QUNIT_DIR}:
- $(call clone_or_pull, ${QUNIT_DIR}, git://github.com/jquery/qunit.git)
-
-${SIZZLE_DIR}:
- $(call clone_or_pull, ${SIZZLE_DIR}, git://github.com/jeresig/sizzle.git)
-
-init: ${QUNIT_DIR} ${SIZZLE_DIR}
-
-jquery: init ${JQ}
-jq: init ${JQ}
+jquery: ${JQ}
${JQ}: ${MODULES} | ${DIST_DIR}
@@echo "Building" ${JQ}
@@ -102,9 +73,9 @@ lint: jquery
echo "You must have NodeJS installed in order to test jQuery against JSLint."; \
fi
-min: ${JQ_MIN}
+min: jquery ${JQ_MIN}
-${JQ_MIN}: jquery
+${JQ_MIN}: ${JQ}
@@if test ! -z ${JS_ENGINE}; then \
echo "Minifying jQuery" ${JQ_MIN}; \
${COMPILER} ${JQ} > ${JQ_MIN}.tmp; \
@@ -122,7 +93,28 @@ clean:
@@echo "Removing built copy of Sizzle"
@@rm -f src/selector.js
- @@echo "Removing cloned directories"
+distclean: clean
+ @@echo "Removing submodules"
@@rm -rf test/qunit src/sizzle
-.PHONY: all jquery lint min init jq clean
+# change pointers for submodules and update them to what is specified in jQuery
+# --merge doesn't work when doing an initial clone, thus test if we have non-existing
+# submodules, then do an real update
+update_submodules:
+ @@if [ -d .git ]; then \
+ if git submodule status | grep -q -E '^-'; then \
+ git submodule update --init --recursive; \
+ else \
+ git submodule update --init --recursive --merge; \
+ fi; \
+ fi;
+
+# update the submodules to the latest at the most logical branch
+pull_submodules:
+ @@git submodule foreach "git pull origin \$$(git branch --no-color --contains \$$(git rev-parse HEAD) | grep -v \( | head -1)"
+ @@git submodule summary
+
+pull: pull_submodules
+ @@git pull ${REMOTE} ${BRANCH}
+
+.PHONY: all jquery lint min clean distclean update_submodules pull_submodules pull core
diff --git a/src/ajax.js b/src/ajax.js
index 4714afdae..d94abd6fc 100644
--- a/src/ajax.js
+++ b/src/ajax.js
@@ -7,7 +7,7 @@ var r20 = /%20/g,
rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
// #7653, #8125, #8152: local protocol detection
- rlocalProtocol = /(?:^file|^widget|\-extension):$/,
+ rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
rnoContent = /^(?:GET|HEAD)$/,
rprotocol = /^\/\//,
rquery = /\?/,
@@ -19,7 +19,7 @@ var r20 = /%20/g,
rucHeadersFunc = function( _, $1, $2 ) {
return $1 + $2.toUpperCase();
},
- rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?|\/[^\/])/,
+ rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
// Keep a copy of the old load method
_load = jQuery.fn.load,
@@ -61,7 +61,7 @@ try {
}
// Segment location into parts
-ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() );
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
function addToPrefiltersOrTransports( structure ) {
@@ -319,7 +319,6 @@ jQuery.extend({
cache: null,
traditional: false,
headers: {},
- crossDomain: null,
*/
accepts: {
@@ -604,7 +603,7 @@ jQuery.extend({
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
// Determine if a cross-domain request is in order
- if ( !s.crossDomain ) {
+ if ( s.crossDomain == null ) {
parts = rurl.exec( s.url.toLowerCase() );
s.crossDomain = !!( parts &&
( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
diff --git a/src/attributes.js b/src/attributes.js
index e5425a051..f7c2e9818 100644
--- a/src/attributes.js
+++ b/src/attributes.js
@@ -6,7 +6,8 @@ var rclass = /[\n\t\r]/g,
rtype = /^(?:button|input)$/i,
rfocusable = /^(?:button|input|object|select|textarea)$/i,
rclickable = /^a(?:rea)?$/i,
- rradiocheck = /^(?:radio|checkbox)$/i;
+ rradiocheck = /^(?:radio|checkbox)$/i,
+ formHook;
jQuery.fn.extend({
attr: function( name, value ) {
@@ -15,9 +16,21 @@ jQuery.fn.extend({
removeAttr: function( name ) {
return this.each(function() {
- if ( this.nodeType === 1 ) {
- this.removeAttribute( name );
- }
+ jQuery.removeAttr( this, name );
+ });
+ },
+
+ prop: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.prop );
+ },
+
+ removeProp: function( name ) {
+ return this.each(function() {
+ // try/catch handles cases where IE balks (such as removing a property on window)
+ try {
+ this[ name ] = undefined;
+ delete this[ name ];
+ } catch( e ) {}
});
},
@@ -36,10 +49,10 @@ jQuery.fn.extend({
},
addClass: function( value ) {
- if ( jQuery.isFunction(value) ) {
+ if ( jQuery.isFunction( value ) ) {
return this.each(function(i) {
var self = jQuery(this);
- self.addClass( value.call(this, i, self.attr("class")) );
+ self.addClass( value.call(this, i, self.attr("class") || "") );
});
}
@@ -275,80 +288,79 @@ jQuery.extend({
offset: true
},
- // TODO: Check to see if any of these are needed anymore?
- // If not, it may be good to standardize on all-lowercase names instead
attrFix: {
- "for": "htmlFor",
- "class": "className",
- readonly: "readOnly",
- maxlength: "maxLength",
- cellspacing: "cellSpacing",
- rowspan: "rowSpan",
- colspan: "colSpan",
+ // Always normalize to ensure hook usage
tabindex: "tabIndex",
- usemap: "useMap",
- frameborder: "frameBorder"
+ readonly: "readOnly"
},
-
+
attr: function( elem, name, value, pass ) {
+ var nType = elem.nodeType;
+
// don't get/set attributes on text, comment and attribute nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined;
}
if ( pass && name in jQuery.attrFn ) {
- return jQuery(elem)[name](value);
+ return jQuery( elem )[ name ]( value );
}
-
- var ret,
- notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
- hooks;
-
- // Try to normalize/fix the name
- name = notxml && jQuery.attrFix[ name ] || name;
- hooks = jQuery.attrHooks[ name ];
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+ // Normalize the name if needed
+ name = notxml && jQuery.attrFix[ name ] || name;
+
+ // Get the appropriate hook, or the formHook
+ // if getSetAttribute is not supported and we have form objects in IE6/7
+ hooks = jQuery.attrHooks[ name ] || ( elem.nodeName === "FORM" && formHook );
+
if ( value !== undefined ) {
-
- if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value )) !== undefined ) {
+
+ if ( value === null ) {
+ jQuery.removeAttr( elem, name );
+ return undefined;
+
+ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
-
+
} else {
- // convert the value to a string (all browsers do this but IE) see #1070
- value = "" + value;
-
- elem.setAttribute( name, value );
-
+ elem.setAttribute( name, "" + value );
return value;
}
-
+
} else {
-
- if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem )) !== undefined ) {
- return ret;
-
+
+ if ( hooks && "get" in hooks && notxml ) {
+ return hooks.get( elem, name );
+
} else {
-
- if ( !jQuery.hasAttr( elem, name ) ) {
- return undefined;
- }
- var attr = elem.getAttribute( name );
+ ret = elem.getAttribute( name );
// Non-existent attributes return null, we normalize to undefined
- return attr === null ?
+ return ret === null ?
undefined :
- attr;
+ ret;
}
}
},
- hasAttr: function( elem, name ) {
- // Blackberry 4.7 returns "" from getAttribute #6938
- return elem.attributes[ name ] || (elem.hasAttribute && elem.hasAttribute( name ));
+ removeAttr: function( elem, name ) {
+ if ( elem.nodeType === 1 ) {
+ name = jQuery.attrFix[ name ] || name;
+
+ if ( jQuery.support.getSetAttribute ) {
+ // Use removeAttribute in browsers that support it
+ elem.removeAttribute( name );
+ } else {
+ jQuery.attr( elem, name, "" );
+ elem.removeAttributeNode( elem.getAttributeNode( name ) );
+ }
+ }
},
-
+
attrHooks: {
type: {
set: function( elem, value ) {
@@ -358,15 +370,14 @@ jQuery.extend({
}
}
},
-
- // 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/
tabIndex: {
get: function( elem ) {
- var attributeNode = elem.getAttributeNode( "tabIndex" );
+ // 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/
+ var attributeNode = elem.getAttributeNode("tabIndex");
return attributeNode && attributeNode.specified ?
- attributeNode.value :
+ parseInt( attributeNode.value, 10 ) :
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
0 :
undefined;
@@ -374,11 +385,18 @@ jQuery.extend({
}
},
- // TODO: Check to see if we really need any here.
propFix: {},
prop: function( elem, name, value ) {
- var ret, hooks;
+ var nType = elem.nodeType;
+
+ // don't get/set properties on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return undefined;
+ }
+
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
// Try to normalize/fix the name
name = notxml && jQuery.propFix[ name ] || name;
@@ -386,7 +404,7 @@ jQuery.extend({
hooks = jQuery.propHooks[ name ];
if ( value !== undefined ) {
- if ( hooks && "set" in hooks && (ret = hooks.set( elem, value )) !== undefined ) {
+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
@@ -394,7 +412,7 @@ jQuery.extend({
}
} else {
- if ( hooks && "get" in hooks && (ret = hooks.get( elem )) !== undefined ) {
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
return ret;
} else {
@@ -406,12 +424,73 @@ jQuery.extend({
propHooks: {}
});
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !jQuery.support.getSetAttribute ) {
+ jQuery.attrFix = jQuery.extend( jQuery.attrFix, {
+ "for": "htmlFor",
+ "class": "className",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+ });
+
+ // Use this for any attribute on a form in IE6/7
+ // And the name attribute
+ formHook = jQuery.attrHooks.name = {
+ get: function( elem, name ) {
+ var ret = elem.getAttributeNode( name );
+ // Return undefined if not specified instead of empty string
+ return ret && ret.specified ?
+ ret.nodeValue :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ // Check form objects in IE (multiple bugs related)
+ // Only use nodeValue if the attribute node exists on the form
+ var ret = elem.getAttributeNode( name );
+ if ( ret ) {
+ ret.nodeValue = value;
+ return value;
+ }
+ }
+ };
+
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+ // This is for removals
+ jQuery.each([ "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ set: function( elem, value ) {
+ if ( value === "" ) {
+ elem.setAttribute( name, "auto" );
+ return value;
+ }
+ }
+ });
+ });
+}
+
+// Remove certain attrs if set to false
+jQuery.each([ "selected", "checked", "readOnly", "disabled" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ set: function( elem, value ) {
+ if ( value === false ) {
+ jQuery.removeAttr( elem, name );
+ return value;
+ }
+ }
+ });
+});
+
// Some attributes require a special call on IE
if ( !jQuery.support.hrefNormalized ) {
- jQuery.each([ "href", "src", "style" ], function( i, name ) {
+ jQuery.each([ "href", "src", "width", "height", "list" ], function( i, name ) {
jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
get: function( elem ) {
- return elem.getAttribute( name, 2 );
+ var ret = elem.getAttribute( name, 2 );
+ return ret === null ? undefined : ret;
}
});
});
@@ -420,9 +499,10 @@ if ( !jQuery.support.hrefNormalized ) {
if ( !jQuery.support.style ) {
jQuery.attrHooks.style = {
get: function( elem ) {
- return elem.style.cssText;
+ // Return undefined in the case of empty string
+ // Normalize to lowercase since IE uppercases css property names
+ return elem.style.cssText.toLowerCase() || undefined;
},
-
set: function( elem, value ) {
return (elem.style.cssText = "" + value);
}
@@ -432,10 +512,10 @@ if ( !jQuery.support.style ) {
// Safari mis-reports the default selected property of an option
// Accessing the parent's selectedIndex property fixes it
if ( !jQuery.support.optSelected ) {
- jQuery.attrHooks.selected = {
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
get: function( elem ) {
var parent = elem.parentNode;
-
+
if ( parent ) {
parent.selectedIndex;
@@ -445,7 +525,7 @@ if ( !jQuery.support.optSelected ) {
}
}
}
- };
+ });
}
})( jQuery );
diff --git a/src/core.js b/src/core.js
index 9312ee288..6b00a0151 100644
--- a/src/core.js
+++ b/src/core.js
@@ -894,4 +894,4 @@ function doScrollCheck() {
// Expose jQuery to the global object
return jQuery;
-})();
+})(); \ No newline at end of file
diff --git a/src/css.js b/src/css.js
index 8a982312f..17ac136bb 100644
--- a/src/css.js
+++ b/src/css.js
@@ -3,7 +3,8 @@
var ralpha = /alpha\([^)]*\)/i,
ropacity = /opacity=([^)]*)/,
rdashAlpha = /-([a-z])/ig,
- rupper = /([A-Z])/g,
+ // fixed for IE9, see #8346
+ rupper = /([A-Z]|^ms)/g,
rnumpx = /^-?\d+(?:px)?$/i,
rnum = /^-?\d/,
@@ -240,6 +241,28 @@ if ( !jQuery.support.opacity ) {
};
}
+jQuery(function() {
+ // This hook cannot be added until DOM ready because the support test
+ // for it is not run until after DOM ready
+ if ( !jQuery.support.reliableMarginRight ) {
+ jQuery.cssHooks.marginRight = {
+ get: function( elem, computed ) {
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ // Work around by temporarily setting element display to inline-block
+ var ret;
+ jQuery.swap( elem, { "display": "inline-block" }, function() {
+ if ( computed ) {
+ ret = curCSS( elem, "margin-right", "marginRight" );
+ } else {
+ ret = elem.style.marginRight;
+ }
+ });
+ return ret;
+ }
+ };
+ }
+});
+
if ( document.defaultView && document.defaultView.getComputedStyle ) {
getComputedStyle = function( elem, newName, name ) {
var ret, defaultView, computedStyle;
diff --git a/src/deferred.js b/src/deferred.js
index f0d7c08c5..90f9c8089 100644
--- a/src/deferred.js
+++ b/src/deferred.js
@@ -144,7 +144,10 @@ jQuery.extend({
return function( value ) {
args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
if ( !( --count ) ) {
- deferred.resolveWith( deferred, args );
+ // Strange bug in FF4:
+ // Values changed onto the arguments object sometimes end up as undefined values
+ // outside the $.when method. Cloning the object into a fresh array solves the issue
+ deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
}
};
}
diff --git a/src/event.js b/src/event.js
index f7e0a08c0..bc2cf76eb 100644
--- a/src/event.js
+++ b/src/event.js
@@ -70,10 +70,10 @@ jQuery.event = {
}
if ( !eventHandle ) {
- elemData.handle = eventHandle = function() {
+ elemData.handle = eventHandle = function( e ) {
// Handle the second event of a trigger and when
// an event is called after a page has unloaded
- return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
jQuery.event.handle.apply( eventHandle.elem, arguments ) :
undefined;
};
@@ -380,7 +380,7 @@ jQuery.event = {
target[ "on" + targetType ] = null;
}
- jQuery.event.triggered = true;
+ jQuery.event.triggered = event.type;
target[ targetType ]();
}
@@ -391,7 +391,7 @@ jQuery.event = {
target[ "on" + targetType ] = old;
}
- jQuery.event.triggered = false;
+ jQuery.event.triggered = undefined;
}
}
},
@@ -661,7 +661,7 @@ var withinElement = function( event ) {
// Chrome does something similar, the parentNode property
// can be accessed but is null.
- if ( parent !== document && !parent.parentNode ) {
+ if ( parent && parent !== document && !parent.parentNode ) {
return;
}
// Traverse up the tree
@@ -868,19 +868,33 @@ function trigger( type, elem, args ) {
// Create "bubbling" focus and blur events
if ( document.addEventListener ) {
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+ // Attach a single capturing handler while someone wants focusin/focusout
+ var attaches = 0;
+
jQuery.event.special[ fix ] = {
setup: function() {
- this.addEventListener( orig, handler, true );
+ if ( attaches++ === 0 ) {
+ document.addEventListener( orig, handler, true );
+ }
},
teardown: function() {
- this.removeEventListener( orig, handler, true );
+ if ( --attaches === 0 ) {
+ document.removeEventListener( orig, handler, true );
+ }
}
};
- function handler( e ) {
- e = jQuery.event.fix( e );
+ function handler( donor ) {
+ // Donor event is always a native one; fix it and switch its type.
+ // Let focusin/out handler cancel the donor focus/blur event.
+ var e = jQuery.event.fix( donor );
e.type = fix;
- return jQuery.event.handle.call( this, e );
+ e.originalEvent = {};
+ jQuery.event.trigger( e, null, e.target );
+ if ( e.isDefaultPrevented() ) {
+ donor.preventDefault();
+ }
}
});
}
diff --git a/src/manipulation.js b/src/manipulation.js
index ba3169715..758cdbae0 100644
--- a/src/manipulation.js
+++ b/src/manipulation.js
@@ -261,7 +261,9 @@ jQuery.fn.extend({
}
});
} else {
- return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+ return this.length ?
+ this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
+ this;
}
},
@@ -375,7 +377,7 @@ function cloneCopyEvent( src, dest ) {
}
}
-function cloneFixAttributes(src, dest) {
+function cloneFixAttributes( src, dest ) {
// We do not need to do anything for non-Elements
if ( dest.nodeType !== 1 ) {
return;
@@ -547,7 +549,8 @@ jQuery.extend({
// Return the cloned set
return clone;
-},
+ },
+
clean: function( elems, context, fragment, scripts ) {
context = context || document;
diff --git a/src/offset.js b/src/offset.js
index 1003c400c..a0cd7a156 100644
--- a/src/offset.js
+++ b/src/offset.js
@@ -37,8 +37,8 @@ if ( "getBoundingClientRect" in document.documentElement ) {
win = getWindow(doc),
clientTop = docElem.clientTop || body.clientTop || 0,
clientLeft = docElem.clientLeft || body.clientLeft || 0,
- scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ),
- scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
+ scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
+ scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
top = box.top + scrollTop - clientTop,
left = box.left + scrollLeft - clientLeft;
@@ -151,7 +151,6 @@ jQuery.offset = {
this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
body.removeChild( container );
- body = container = innerDiv = checkDiv = table = td = null;
jQuery.offset.initialize = jQuery.noop;
},
@@ -181,10 +180,10 @@ jQuery.offset = {
curOffset = curElem.offset(),
curCSSTop = jQuery.css( elem, "top" ),
curCSSLeft = jQuery.css( elem, "left" ),
- calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
+ calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1,
props = {}, curPosition = {}, curTop, curLeft;
- // need to be able to calculate position if either top or left is auto and position is absolute
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
if ( calculatePosition ) {
curPosition = curElem.position();
}
diff --git a/src/sizzle b/src/sizzle
new file mode 160000
+Subproject f12b9309269ba7e705a99efe099f86ed1fe98d5
diff --git a/src/support.js b/src/support.js
index 7470b33e8..89d2bfea2 100644
--- a/src/support.js
+++ b/src/support.js
@@ -7,8 +7,9 @@
var div = document.createElement("div");
div.style.display = "none";
- div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
-
+ div.setAttribute("className", "t");
+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
var all = div.getElementsByTagName("*"),
a = div.getElementsByTagName("a")[0],
select = document.createElement("select"),
@@ -33,8 +34,8 @@
htmlSerialize: !!div.getElementsByTagName("link").length,
// Get the style information from getAttribute
- // (IE uses .cssText insted)
- style: /red/.test( a.getAttribute("style") ),
+ // (IE uses .cssText instead, and capitalizes all property names)
+ style: /top/.test( a.getAttribute("style") ),
// Make sure that URLs aren't manipulated
// (IE normalizes it by default)
@@ -57,6 +58,9 @@
// Make sure that a selected-by-default option has a working selected property.
// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
optSelected: opt.selected,
+
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+ getSetAttribute: div.className !== "t",
// Will be defined later
deleteExpando: true,
@@ -67,7 +71,8 @@
boxModel: null,
inlineBlockNeedsLayout: false,
shrinkWrapBlocks: false,
- reliableHiddenOffsets: true
+ reliableHiddenOffsets: true,
+ reliableMarginRight: true
};
input.checked = true;
@@ -85,15 +90,15 @@
script = document.createElement("script"),
id = "script" + jQuery.now();
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
try {
script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
} catch(e) {}
root.insertBefore( script, root.firstChild );
- // Make sure that the execution of code works by injecting a script
- // tag with appendChild/createTextNode
- // (IE doesn't support this, fails, and uses .text instead)
if ( window[ id ] ) {
_scriptEval = true;
delete window[ id ];
@@ -102,8 +107,6 @@
}
root.removeChild( script );
- // release memory in IE
- root = script = id = null;
}
return _scriptEval;
@@ -188,6 +191,17 @@
jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
div.innerHTML = "";
+ // Check if div with explicit width and no margin-right incorrectly
+ // gets computed margin-right based on width of container. For more
+ // info see bug #3333
+ // Fails in WebKit before Feb 2011 nightlies
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ div.style.width = "1px";
+ div.style.marginRight = "0";
+ jQuery.support.reliableMarginRight = ( parseInt(document.defaultView.getComputedStyle(div, null).marginRight, 10) || 0 ) === 0;
+ }
+
body.removeChild( div ).style.display = "none";
div = tds = null;
});
@@ -211,8 +225,6 @@
el.setAttribute(eventName, "return;");
isSupported = typeof el[eventName] === "function";
}
- el = null;
-
return isSupported;
};
diff --git a/test/data/offset/fixed.html b/test/data/offset/fixed.html
index 3181718da..81ba4ca7d 100644
--- a/test/data/offset/fixed.html
+++ b/test/data/offset/fixed.html
@@ -35,6 +35,7 @@
<body>
<div id="fixed-1" class="fixed"></div>
<div id="fixed-2" class="fixed"></div>
+ <div id="fixed-no-top-left" class="fixed"></div>
<div id="forceScroll"></div>
<div id="marker"></div>
<p class="instructions">Click the white box to move the marker to it.</p>
diff --git a/test/index.html b/test/index.html
index c7c2ae55d..a10655089 100644
--- a/test/index.html
+++ b/test/index.html
@@ -203,6 +203,10 @@ Z</textarea>
<select name="D4" disabled="disabled">
<option selected="selected" value="NO">NO</option>
</select>
+ <input id="list-test" type="text" />
+ <datalist id="datalist">
+ <option value="option"></option>
+ </datalist>
</form>
<div id="moretests">
<form>
diff --git a/test/qunit b/test/qunit
new file mode 160000
+Subproject d404faf8f587fcbe6b8907943022e6318dd51e0
diff --git a/test/unit/ajax.js b/test/unit/ajax.js
index 2a2ac46a1..7c572a32c 100644
--- a/test/unit/ajax.js
+++ b/test/unit/ajax.js
@@ -492,7 +492,7 @@ test(".ajax() - hash", function() {
test("jQuery ajax - cross-domain detection", function() {
- expect( 5 );
+ expect( 6 );
var loc = document.location,
otherPort = loc.port === 666 ? 667 : 666,
@@ -508,6 +508,7 @@ test("jQuery ajax - cross-domain detection", function() {
});
jQuery.ajax({
+ dataType: "jsonp",
url: 'app:/path',
beforeSend: function( _ , s ) {
ok( s.crossDomain , "Adobe AIR app:/ URL detected as cross-domain" );
@@ -535,6 +536,15 @@ test("jQuery ajax - cross-domain detection", function() {
jQuery.ajax({
dataType: "jsonp",
+ url: "about:blank",
+ beforeSend: function( _ , s ) {
+ ok( s.crossDomain , "Test about:blank is detected as cross-domain" );
+ return false;
+ }
+ });
+
+ jQuery.ajax({
+ dataType: "jsonp",
url: loc.protocol + "//" + loc.host,
crossDomain: true,
beforeSend: function( _ , s ) {
diff --git a/test/unit/attributes.js b/test/unit/attributes.js
index 8cf47bed6..fa30ff042 100644
--- a/test/unit/attributes.js
+++ b/test/unit/attributes.js
@@ -3,38 +3,81 @@ module("attributes", { teardown: moduleTeardown });
var bareObj = function(value) { return value; };
var functionReturningObj = function(value) { return (function() { return value; }); };
-test("jQuery.props: itegrity test", function() {
-
- expect(1);
-
- // This must be maintained and equal jQuery.props
- // Ensure that accidental or erroneous property
- // overwrites don't occur
- // This is simply for better code coverage and future proofing.
- var propsShouldBe = {
- "for": "htmlFor",
- "class": "className",
- readonly: "readOnly",
- maxlength: "maxLength",
- cellspacing: "cellSpacing",
- rowspan: "rowSpan",
- colspan: "colSpan",
- tabindex: "tabIndex",
- usemap: "useMap",
- frameborder: "frameBorder"
- };
-
- same(propsShouldBe, jQuery.props, "jQuery.props passes integrity check");
+test("jQuery.attrFix integrity test", function() {
+ expect(1);
+
+ // This must be maintained and equal jQuery.attrFix when appropriate
+ // Ensure that accidental or erroneous property
+ // overwrites don't occur
+ // This is simply for better code coverage and future proofing.
+ var propsShouldBe;
+ if ( !jQuery.support.getSetAttribute ) {
+ propsShouldBe = {
+ tabindex: "tabIndex",
+ readonly: "readOnly",
+ "for": "htmlFor",
+ "class": "className",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+ };
+ } else {
+ propsShouldBe = {
+ tabindex: "tabIndex",
+ readonly: "readOnly"
+ };
+ }
+
+ same(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check");
});
-test("attr(String)", function() {
- expect(37);
+test("prop(String, Object)", function() {
+ expect(19);
+ equals( jQuery('#text1').prop('value'), "Test", 'Check for value attribute' );
+ equals( jQuery('#text1').prop('value', "Test2").prop('defaultValue'), "Test", 'Check for defaultValue attribute' );
+ equals( jQuery('#select2').prop('selectedIndex'), 3, 'Check for selectedIndex attribute' );
+ equals( jQuery('#foo').prop('nodeName').toUpperCase(), 'DIV', 'Check for nodeName attribute' );
+ equals( jQuery('#foo').prop('tagName').toUpperCase(), 'DIV', 'Check for tagName attribute' );
+ equals( jQuery("<option/>").prop("selected"), false, "Check selected attribute on disconnected element." );
+
+ var body = document.body, $body = jQuery( body );
+ ok( $body.prop('nextSibling') === null, 'Make sure a null expando returns null' );
+ body.foo = 'bar';
+ equals( $body.prop('foo'), 'bar', 'Make sure the expando is preferred over the dom attribute' );
+ body.foo = undefined;
+ ok( $body.prop('foo') === undefined, 'Make sure the expando is preferred over the dom attribute, even if undefined' );
+
+ var select = document.createElement("select"), optgroup = document.createElement("optgroup"), option = document.createElement("option");
+ optgroup.appendChild( option );
+ select.appendChild( optgroup );
+
+ equals( jQuery(option).prop("selected"), true, "Make sure that a single option is selected, even when in an optgroup." );
+ equals( jQuery(document).prop("nodeName"), "#document", "prop works correctly on document nodes (bug #7451)." );
+
+ var attributeNode = document.createAttribute("irrelevant"),
+ commentNode = document.createComment("some comment"),
+ textNode = document.createTextNode("some text"),
+ obj = {};
+ jQuery.each( [document, attributeNode, commentNode, textNode, obj, "#firstp"], function( i, ele ) {
+ strictEqual( jQuery(ele).prop("nonexisting"), undefined, "prop works correctly for non existing attributes (bug #7500)." );
+ });
+
+ var obj = {};
+ jQuery.each( [document, obj], function( i, ele ) {
+ var $ele = jQuery( ele );
+ $ele.prop( "nonexisting", "foo" );
+ equal( $ele.prop("nonexisting"), "foo", "prop(name, value) works correctly for non existing attributes (bug #7500)." );
+ });
+ jQuery( document ).removeProp("nonexisting");
+});
- // This one sometimes fails randomly ?!
- equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' );
+test("attr(String)", function() {
+ expect(32);
- 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' );
@@ -46,60 +89,58 @@ test("attr(String)", function() {
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' );
- // Temporarily disabled. See: #4299
- // ok( jQuery('#form').attr('action','newformaction').attr('action').indexOf("newformaction") >= 0, 'Check that action attribute was changed' );
+ equals( jQuery('#form').attr('blah', 'blah').attr('blah'), 'blah', 'Set non-existant attribute on a form' );
+ equals( jQuery('#foo').attr('height'), undefined, 'Non existent height attribute should return undefined' );
+
+ // [7472] & [3113] (form contains an input with name="action" or name="id")
+ var extras = jQuery('<input name="id" name="name" /><input id="target" name="target" />').appendTo('#testForm');
+ equals( jQuery('#form').attr('action','newformaction').attr('action'), 'newformaction', 'Check that action attribute was changed' );
+ equals( jQuery('#testForm').attr('target'), undefined, 'Retrieving target does not equal the input with name=target' );
+ equals( jQuery('#testForm').attr('target', 'newTarget').attr('target'), 'newTarget', 'Set target successfully on a form' );
+ equals( jQuery('#testForm').removeAttr('id').attr('id'), undefined, 'Retrieving id does not equal the input with name=id after id is removed [#7472]' );
+ // Bug #3685 (form contains input with name="name")
+ equals( jQuery('#testForm').attr('name'), undefined, 'Retrieving name does not retrieve input with name=name' );
+ extras.remove();
+
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' );
// using innerHTML in IE causes href attribute to be serialized to the full path
jQuery('<a/>').attr({ 'id': 'tAnchor5', 'href': '#5' }).appendTo('#main');
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." );
-
+ // list attribute is readonly by default in browsers that support it
+ jQuery('#list-test').attr('list', 'datalist');
+ equals( jQuery('#list-test').attr('list'), 'datalist', 'Check setting list attribute' );
// 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' );
+ strictEqual( $body.attr('foo'), undefined, 'Make sure that a non existent attribute returns undefined' );
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
var select = document.createElement("select"), optgroup = document.createElement("optgroup"), option = document.createElement("option");
optgroup.appendChild( option );
select.appendChild( optgroup );
- equals( jQuery(option).attr("selected"), true, "Make sure that a single option is selected, even when in an optgroup." );
+ var $img = jQuery('<img style="display:none" width="215" height="53" src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif"/>').appendTo('body');
+ equals( $img.attr('width'), "215", "Retrieve width attribute an an element with display:none." );
+ equals( $img.attr('height'), "53", "Retrieve height attribute an an element with display:none." );
+
+ // Check for style support
+ ok( !!~jQuery('#dl').attr('style').indexOf('position'), 'Check style attribute getter, also normalize css props to lowercase' );
+ ok( !!~jQuery('#foo').attr('style', 'position:absolute;').attr('style').indexOf('position'), 'Check style setter' );
ok( jQuery("<div/>").attr("doesntexist") === undefined, "Make sure undefined is returned when no attribute is found." );
ok( jQuery().attr("doesntexist") === undefined, "Make sure undefined is returned when no element is there." );
-
- equals( jQuery(document).attr("nodeName"), "#document", "attr works correctly on document nodes (bug #7451)." );
-
- var attributeNode = document.createAttribute("irrelevant"),
- commentNode = document.createComment("some comment"),
- textNode = document.createTextNode("some text"),
- obj = {};
- jQuery.each( [document, attributeNode, commentNode, textNode, obj, "#firstp"], function( i, ele ) {
- strictEqual( jQuery(ele).attr("nonexisting"), undefined, "attr works correctly for non existing attributes (bug #7500)." );
- });
});
if ( !isLocal ) {
@@ -116,8 +157,8 @@ if ( !isLocal ) {
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");
+ 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() {
@@ -133,7 +174,7 @@ test("attr(Hash)", function() {
});
test("attr(String, Object)", function() {
- expect(30);
+ expect(29);
var div = jQuery("div").attr("foo", "bar"),
fail = false;
@@ -153,7 +194,7 @@ test("attr(String, Object)", function() {
jQuery("#name").attr('name', 'something');
equals( jQuery("#name").attr('name'), 'something', 'Set name attribute' );
jQuery("#name").attr('name', null);
- equals( jQuery("#name").attr('title'), '', 'Remove name attribute' );
+ equals( jQuery("#name").attr('name'), undefined, 'Remove name attribute' );
jQuery("#check2").attr('checked', true);
equals( document.getElementById('check2').checked, true, 'Set checked attribute' );
jQuery("#check2").attr('checked', false);
@@ -163,28 +204,22 @@ test("attr(String, Object)", function() {
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' );
+ equals( document.getElementById('name').maxLength, 5, 'Set maxlength attribute' );
jQuery("#name").attr('maxLength', '10');
- equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' );
-
+ equals( document.getElementById('name').maxLength, 10, 'Set maxlength attribute' );
+ var $p = jQuery('#firstp').attr('nonexisting', 'foo');
+ equals( $p.attr('nonexisting'), 'foo', "attr(name, value) works correctly for non existing attributes (bug #7500).");
+ $p.removeAttr('nonexisting');
+
var attributeNode = document.createAttribute("irrelevant"),
commentNode = document.createComment("some comment"),
- textNode = document.createTextNode("some text"),
- obj = {};
- jQuery.each( [document, obj, "#firstp"], function( i, ele ) {
- var $ele = jQuery( ele );
- $ele.attr( "nonexisting", "foo" );
- equal( $ele.attr("nonexisting"), "foo", "attr(name, value) works correctly for non existing attributes (bug #7500)." );
- });
+ textNode = document.createTextNode("some text");
+
jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
var $ele = jQuery( ele );
$ele.attr( "nonexisting", "foo" );
strictEqual( $ele.attr("nonexisting"), undefined, "attr(name, value) works correctly on comment and text nodes (bug #7500)." );
});
- //cleanup
- jQuery.each( [document, "#firstp"], function( i, ele ) {
- jQuery( ele ).removeAttr("nonexisting");
- });
var table = jQuery('#table').append("<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>"),
td = table.find('td:first');
@@ -193,15 +228,15 @@ test("attr(String, Object)", function() {
td.attr("colspan", "2");
equals( td[0].colSpan, 2, "Check colspan is correctly set" );
table.attr("cellspacing", "2");
- equals( table[0].cellSpacing, 2, "Check cellspacing is correctly set" );
+ equals( table[0].cellSpacing, "2", "Check cellspacing is correctly set" );
// 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' );
+ 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' );
+ 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();
@@ -211,7 +246,8 @@ test("attr(String, Object)", function() {
j.removeAttr("name");
QUnit.reset();
-
+
+ // Type
var type = jQuery("#check2").attr('type');
var thrown = false;
try {
@@ -251,6 +287,13 @@ test("attr(String, Object)", function() {
}
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" );
+
+ // Setting attributes on svg elements (bug #3116)
+ var $svg = jQuery('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="3000" height="3000">'
+ + '<circle cx="200" cy="200" r="150" />'
+ + '</svg>').appendTo('body');
+ equals( $svg.attr('cx', 100).attr('cx'), "100", "Set attribute on svg element" );
+ $svg.remove();
});
test("attr(jquery_method)", function(){
@@ -356,25 +399,32 @@ test("attr('tabindex', value)", function() {
});
test("removeAttr(String)", function() {
- expect(7);
+ expect(5);
equals( jQuery('#mark').removeAttr( "class" )[0].className, "", "remove class" );
+ equals( jQuery('#form').removeAttr('id').attr('id'), undefined, 'Remove id' );
+ equals( jQuery('#foo').attr('style', 'position:absolute;').removeAttr('style').attr('style'), undefined, 'Check removing style attribute' );
+ equals( jQuery('#form').attr('style', 'position:absolute;').removeAttr('style').attr('style'), undefined, 'Check removing style attribute on a form' );
+ equals( jQuery('#fx-test-group').attr('height', '3px').removeAttr('height').css('height'), "1px", 'Removing height attribute has no effect on height set with style attribute' );
+});
+test("removeProp(String)", function() {
+ expect(6);
var attributeNode = document.createAttribute("irrelevant"),
commentNode = document.createComment("some comment"),
textNode = document.createTextNode("some text"),
obj = {};
- //removeAttr only really removes on DOM element nodes handle all other seperatyl
- strictEqual( jQuery( "#firstp" ).attr( "nonexisting", "foo" ).removeAttr( "nonexisting" )[0].nonexisting, undefined, "removeAttr works correctly on DOM element nodes" );
+
+ strictEqual( jQuery( "#firstp" ).prop( "nonexisting", "foo" ).removeProp( "nonexisting" )[0].nonexisting, undefined, "removeprop works correctly on DOM element nodes" );
jQuery.each( [document, obj], function( i, ele ) {
var $ele = jQuery( ele );
- $ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
- strictEqual( ele.nonexisting, "", "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+ $ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
+ strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." );
});
jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
$ele = jQuery( ele );
- $ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
- strictEqual( ele.nonexisting, undefined, "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+ $ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
+ strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." );
});
});
@@ -604,21 +654,20 @@ test("addClass(Function)", function() {
test("addClass(Function) with incoming value", function() {
expect(45);
-
var div = jQuery("div"), old = div.map(function(){
- return jQuery(this).attr("class");
+ return jQuery(this).attr("class") || "";
});
-
+
div.addClass(function(i, val) {
- if ( this.id !== "_firebugConsole" ) {
+ if ( this.id !== "_firebugConsole") {
equals( val, old[i], "Make sure the incoming value is correct." );
return "test";
}
});
var pass = true;
- for ( var i = 0; i < div.size(); i++ ) {
- if ( div.get(i).className.indexOf("test") == -1 ) pass = false;
+ for ( var i = 0; i < div.length; i++ ) {
+ if ( div.get(i).className.indexOf("test") == -1 ) pass = false;
}
ok( pass, "Add Class" );
});
@@ -843,4 +892,4 @@ test("addClass, removeClass, hasClass", function() {
ok( jq.hasClass("cla.ss3")==false, "Check the dotted class has been removed" );
jq.removeClass("class4");
ok( jq.hasClass("class4")==false, "Check the class has been properly removed" );
-});
+}); \ No newline at end of file
diff --git a/test/unit/css.js b/test/unit/css.js
index 555f13575..8ae8fcb34 100644
--- a/test/unit/css.js
+++ b/test/unit/css.js
@@ -333,3 +333,15 @@ test("internal ref to elem.runtimeStyle (bug #7608)", function () {
ok( result, "elem.runtimeStyle does not throw exception" );
});
+
+test("marginRight computed style (bug #3333)", function() {
+ expect(1);
+
+ var $div = jQuery("#foo");
+ $div.css({
+ width: "1px",
+ marginRight: 0
+ });
+
+ equals($div.css("marginRight"), "0px");
+});
diff --git a/test/unit/event.js b/test/unit/event.js
index b7b260462..2a6d8a669 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -683,6 +683,20 @@ test("hover()", function() {
equals( times, 4, "hover handlers fired" );
});
+test("mouseover triggers mouseenter", function() {
+ expect(1);
+
+ var count = 0,
+ elem = jQuery("<a />");
+ elem.mouseenter(function () {
+ count++;
+ });
+ elem.trigger('mouseover');
+ equals(count, 1, "make sure mouseover triggers a mouseenter" );
+
+ elem.remove();
+});
+
test("trigger() shortcuts", function() {
expect(6);
@@ -1966,6 +1980,36 @@ test("window resize", function() {
ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." );
});
+test("focusin bubbles", function() {
+ expect(5);
+
+ var input = jQuery( '<input type="text" />' ).prependTo( "body" ),
+ order = 0;
+
+ jQuery( "body" ).bind( "focusin.focusinBubblesTest", function(){
+ equals( 1, order++, "focusin on the body second" );
+ });
+
+ input.bind( "focusin.focusinBubblesTest", function(){
+ equals( 0, order++, "focusin on the element first" );
+ });
+
+ // DOM focus method
+ input[0].focus();
+
+ // To make the next focus test work, we need to take focus off the input.
+ // This will fire another focusin event, so set order to reflect that.
+ order = 1;
+ jQuery("#text1")[0].focus();
+
+ // jQuery trigger, which calls DOM focus
+ order = 0;
+ input.trigger( "focus" );
+
+ input.remove();
+ jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
+});
+
/*
test("jQuery(function($) {})", function() {
stop();
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index 34425ed3a..e972a4792 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -739,7 +739,7 @@ test("insertAfter(String|Element|Array&lt;Element&gt;|jQuery)", function() {
});
var testReplaceWith = function(val) {
- expect(20);
+ expect(21);
jQuery('#yahoo').replaceWith(val( '<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' );
@@ -800,6 +800,9 @@ var testReplaceWith = function(val) {
equals( set[0].nodeName.toLowerCase(), "span", "Replace the disconnected node." );
equals( set.length, 1, "Replace the disconnected node." );
+ var non_existant = jQuery('#does-not-exist').replaceWith( val("<b>should not throw an error</b>") );
+ equals( non_existant.length, 0, "Length of non existant element." );
+
var $div = jQuery("<div class='replacewith'></div>").appendTo("body");
// TODO: Work on jQuery(...) inline script execution
//$div.replaceWith("<div class='replacewith'></div><script>" +
@@ -827,7 +830,7 @@ test("replaceWith(String|Element|Array&lt;Element&gt;|jQuery)", function() {
test("replaceWith(Function)", function() {
testReplaceWith(functionReturningObj);
- expect(21);
+ expect(22);
var y = jQuery("#yahoo")[0];
@@ -1006,7 +1009,7 @@ test("clone()", function() {
});
test("clone(form element) (Bug #3879, #6655)", function() {
- expect(6);
+ expect(5);
var element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
@@ -1016,7 +1019,9 @@ test("clone(form element) (Bug #3879, #6655)", function() {
equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" );
- equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" );
+
+ // defaultChecked also gets set now due to setAttribute in attr, is this check still valid?
+ // equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" );
element = jQuery("<input type='text' value='foo'>");
clone = element.clone();
diff --git a/test/unit/offset.js b/test/unit/offset.js
index 329d69f95..ae0518849 100644
--- a/test/unit/offset.js
+++ b/test/unit/offset.js
@@ -265,7 +265,7 @@ testoffset("static", function( jQuery ) {
});
testoffset("fixed", function( jQuery ) {
- expect(28);
+ expect(30);
jQuery.offset.initialize();
@@ -320,6 +320,17 @@ testoffset("fixed", function( jQuery ) {
ok( true, 'Fixed position is not supported' );
}
});
+
+ // Bug 8316
+ var $noTopLeft = jQuery('#fixed-no-top-left');
+ if ( jQuery.offset.supportsFixedPosition ) {
+ equals( $noTopLeft.offset().top, 1007, "Check offset top for fixed element with no top set" );
+ equals( $noTopLeft.offset().left, 1007, "Check offset left for fixed element with no left set" );
+ } else {
+ // need to have same number of assertions
+ ok( true, 'Fixed position is not supported' );
+ ok( true, 'Fixed position is not supported' );
+ }
});
testoffset("table", function( jQuery ) {
@@ -422,7 +433,7 @@ test("offsetParent", function(){
equals( div[1], jQuery("#nothiddendiv")[0], "The div is the offsetParent." );
});
-function testoffset(name, fn) {
+function testoffset( name, fn ) {
test(name, function() {
// pause execution for now
@@ -447,7 +458,7 @@ function testoffset(name, fn) {
function loadFixture() {
var src = './data/offset/' + name + '.html?' + parseInt( Math.random()*1000, 10 ),
iframe = jQuery('<iframe />').css({
- width: 500, height: 500, position: 'absolute', top: -600, left: -600, visiblity: 'hidden'
+ width: 500, height: 500, position: 'absolute', top: -600, left: -600, visibility: 'hidden'
}).appendTo('body')[0];
iframe.contentWindow.location = src;
return iframe;
diff --git a/version.txt b/version.txt
index 0b7675087..0a0196e21 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-1.5.2pre \ No newline at end of file
+1.6pre \ No newline at end of file