From 18e7a53d15dadae24703178a87192104935551b4 Mon Sep 17 00:00:00 2001 From: Oleg Date: Thu, 25 Oct 2012 20:41:47 -0400 Subject: [PATCH] Elements created from html strings have a parentnode. Fixes #12392 --- src/manipulation.js | 35 ++++++++++++++++++++++++++--------- test/unit/manipulation.js | 27 ++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index f0f65ecff..55fe52457 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -1,6 +1,6 @@ function createSafeFragment( document ) { var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); + safeFrag = document.createDocumentFragment(); if ( safeFrag.createElement ) { while ( list.length ) { @@ -49,9 +49,9 @@ wrapMap.th = wrapMap.td; // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, // unless wrapped in a div with non-breaking characters in front of it. if ( !jQuery.support.htmlSerialize ) { - wrapMap._default = [ 1, "X
", "
" ]; + wrapMap._default = [ 1, "X
", "" ]; // Fixes #11280 - wrapMap.param = [ 1, "X", "" ]; + wrapMap.param = [ 1, "X", "" ]; // Fixes #11280. HTMLParam name attribute added to avoid IE6-8 parsing issue. addMandatoryAttributes = function( elem ) { // If it's a param @@ -650,7 +650,7 @@ jQuery.extend({ }, clean: function( elems, context, fragment, scripts ) { - var i, j, elem, tag, wrap, depth, div, hasBody, tbody, handleScript, jsTags, + var i, j, elem, tag, wrap, depth, parent, div, hasBody, tbody, handleScript, jsTags, safe = context === document && safeFragment, ret = []; @@ -676,8 +676,7 @@ jQuery.extend({ } else { // Ensure a safe container in which to render the html safe = safe || createSafeFragment( context ); - div = context.createElement("div"); - safe.appendChild( div ); + div = div || safe.appendChild( context.createElement("div") ); // Fix "XHTML"-style tags in all browsers elem = elem.replace(rxhtmlTag, "<$1>"); @@ -719,9 +718,10 @@ jQuery.extend({ } elem = div.childNodes; + parent = div; - // Take out of fragment container (we need a fresh div each time) - div.parentNode.removeChild( div ); + // Remember the top-level container for proper cleanup + div = safe.lastChild; } } @@ -729,14 +729,31 @@ jQuery.extend({ ret.push( elem ); } else { jQuery.merge( ret, elem ); + + // Fix #12392 + if ( parent ) { + + // for WebKit and IE > 9 + parent.textContent = ""; + + // for oldIE + while ( parent.firstChild ) { + parent.removeChild( parent.firstChild ); + } + + parent = null; + } } } // Fix #11356: Clear elements from safeFragment if ( div ) { - elem = div = safe = null; + safe.removeChild( div ); } + elem = div = safe = null; + + // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if ( !jQuery.support.appendChecked ) { diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 7b5fee197..06e8b3050 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -473,11 +473,11 @@ test("append(param) to object, see #11280", function() { expect(11); var objectElement = document.createElement("object"), - $objectElement = jQuery( objectElement ), - paramElement = jQuery(""), - paramElement2 = jQuery(""), - paramElement3 = jQuery(""), - newObject = jQuery(""); + $objectElement = jQuery( objectElement ), + paramElement = jQuery(""), + paramElement2 = jQuery(""), + paramElement3 = jQuery(""), + newObject = jQuery(""); equal( objectElement.childNodes.length, 0, "object did not have childNodes previously" ); @@ -613,6 +613,23 @@ test("append HTML5 sectioning elements (Bug #6485)", function () { equal( aside.length, 1, "HTML5 elements do not collapse their children"); }); +test( "jQuery.clean, #12392", function() { + expect( 6 ); + + var elems = jQuery.clean([ "
test div
", "

test p

" ]); + + ok( elems[ 0 ].parentNode == null || elems[ 0 ].parentNode.nodeType === 11, "parentNode should be documentFragment or null" ); + ok( elems[ 1 ].parentNode == null || elems[ 1 ].parentNode.nodeType === 11, "parentNode should be documentFragment or null" ); + + equal( elems[ 0 ].innerHTML, "test div", "Content should be preserved" ); + equal( elems[ 1 ].innerHTML, "test p", "Content should be preserved" ); + + equal( jQuery.clean([ "" ]).length, 1, "Incorrect html-strings should not break anything" ); + + elems = jQuery.clean([ "" ]); + ok( elems[ 1 ].parentNode == null || elems[ 1 ].parentNode.nodeType === 11, "parentNode should be documentFragment or null" ); +}); + if ( jQuery.css ) { test("HTML5 Elements inherit styles from style rules (Bug #10501)", function () { expect(1); -- 2.39.5