X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fmanipulation.js;h=9b7cfefb43fd85046b88d12980ddc951a1fd6fda;hb=7481a3645af63cef1406687190fd62bdfb1bf254;hp=99d51a80cacb0ca20cde0d8cdca49c534b086a41;hpb=b5b3c73db3e4e615e504cd0af08ff6842b104542;p=jquery.git diff --git a/src/manipulation.js b/src/manipulation.js index 99d51a8..9b7cfef 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -9,7 +9,6 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, rnocache = /<(?:script|object|embed|option|style)/i, // checked="checked" or checked (html5) rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - raction = /\=([^="'>\s]+\/)>/g, wrapMap = { option: [ 1, "" ], legend: [ 1, "
", "
" ], @@ -34,7 +33,8 @@ jQuery.fn.extend({ text: function( text ) { if ( jQuery.isFunction(text) ) { return this.each(function(i) { - var self = jQuery(this); + var self = jQuery( this ); + self.text( text.call(this, i, self.text()) ); }); } @@ -83,7 +83,8 @@ jQuery.fn.extend({ } return this.each(function() { - var self = jQuery( this ), contents = self.contents(); + var self = jQuery( this ), + contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); @@ -147,7 +148,7 @@ jQuery.fn.extend({ return set; } }, - + // keepData is for internal use only--do not document remove: function( selector, keepData ) { for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { @@ -162,7 +163,7 @@ jQuery.fn.extend({ } } } - + return this; }, @@ -178,36 +179,45 @@ jQuery.fn.extend({ elem.removeChild( elem.firstChild ); } } - + return this; }, 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; - } + var clone = this.cloneNode(true); + if ( !jQuery.support.noCloneEvent && (this.nodeType === 1 || this.nodeType === 11) && !jQuery.isXMLDoc(this) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + var srcElements = jQuery(this).find('*').andSelf(); + jQuery(clone).find('*').andSelf().each(function (i, clone) { + // We do not need to do anything for non-Elements + if (this.nodeType !== 1) { + return; + } - return jQuery.clean([html.replace(rinlinejQuery, "") - // Handle the case in IE 8 where action=/test/> self-closes a tag - .replace(raction, '="$1">') - .replace(rleadingWhitespace, "")], ownerDocument)[0]; - } else { - return this.cloneNode(true); + // clearAttributes removes the attributes, but also + // removes the attachEvent events + clone.clearAttributes(); + + // mergeAttributes only merges back on the original attributes, + // not the events + clone.mergeAttributes(srcElements[i]); + + // IE6-8 fail to clone children inside object elements that use + // the proprietary classid attribute value (rather than the type + // attribute) to identify the type of content to display + if (clone.nodeName.toLowerCase() === 'object') { + clone.outerHTML = srcElements[i].outerHTML; + } + }); } + + return clone; }); // Copy the events from the original to the clone @@ -249,7 +259,8 @@ jQuery.fn.extend({ } else if ( jQuery.isFunction( value ) ) { this.each(function(i){ - var self = jQuery(this); + var self = jQuery( this ); + self.html( value.call(this, i, self.html()) ); }); @@ -272,13 +283,14 @@ jQuery.fn.extend({ } if ( typeof value !== "string" ) { - value = jQuery(value).detach(); + value = jQuery( value ).detach(); } return this.each(function() { - var next = this.nextSibling, parent = this.parentNode; + var next = this.nextSibling, + parent = this.parentNode; - jQuery(this).remove(); + jQuery( this ).remove(); if ( next ) { jQuery(next).before( value ); @@ -296,7 +308,9 @@ jQuery.fn.extend({ }, domManip: function( args, table, callback ) { - var results, first, value = args[0], scripts = [], fragment, parent; + var results, first, fragment, parent, + value = args[0], + scripts = []; // We can't cloneNode fragments that contain checked, in WebKit if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { @@ -323,9 +337,9 @@ jQuery.fn.extend({ } else { results = jQuery.buildFragment( args, this, scripts ); } - + fragment = results.fragment; - + if ( fragment.childNodes.length === 1 ) { first = fragment = fragment.firstChild; } else { @@ -341,7 +355,7 @@ jQuery.fn.extend({ root(this[i], first) : this[i], i > 0 || results.cacheable || this.length > 1 ? - fragment.cloneNode(true) : + jQuery(fragment).clone(true)[0] : fragment ); } @@ -367,11 +381,13 @@ function cloneCopyEvent(orig, ret) { var i = 0; ret.each(function() { - if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) { + if ( this.nodeType !== 1 || this.nodeName !== (orig[i] && orig[i].nodeName) ) { return; } - var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events; + var oldData = jQuery.data( orig[i++] ), + curData = jQuery.data( this, oldData ), + events = oldData && oldData.events; if ( events ) { delete curData.handle; @@ -428,20 +444,21 @@ jQuery.each({ replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { - var ret = [], insert = jQuery( selector ), + var ret = [], + insert = jQuery( selector ), parent = this.length === 1 && this[0].parentNode; - + if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { insert[ original ]( this[0] ); return this; - + } else { for ( var i = 0, l = insert.length; i < l; i++ ) { var elems = (i > 0 ? this.clone(true) : this).get(); jQuery( insert[i] )[ original ]( elems ); ret = ret.concat( elems ); } - + return this.pushStack( ret, name, insert.selector ); } }; @@ -529,7 +546,7 @@ jQuery.extend({ for ( i = 0; ret[i]; i++ ) { if ( scripts && 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"))) ); @@ -541,22 +558,22 @@ jQuery.extend({ return ret; }, - + cleanData: function( elems ) { var data, id, cache = jQuery.cache, special = jQuery.event.special, deleteExpando = jQuery.support.deleteExpando; - + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { continue; } id = elem[ jQuery.expando ]; - + if ( id ) { data = cache[ id ]; - + if ( data && data.events ) { for ( var type in data.events ) { if ( special[ type ] ) { @@ -567,14 +584,14 @@ jQuery.extend({ } } } - + if ( deleteExpando ) { delete elem[ jQuery.expando ]; } else if ( elem.removeAttribute ) { elem.removeAttribute( jQuery.expando ); } - + delete cache[ id ]; } }