Skip to content
Permalink
Browse files

Fix busted rnoshimcache. Correctly clone detached unknown elems. Fixe…

…s #10667, #10670.

- \s => |, Removes 4 bytes from gzipped build

- Adds tests for clone attributes, children and events
  • Loading branch information...
rwaldron authored and timmywil committed Nov 8, 2011
1 parent 68ca9d4 commit 66e65c81684e314448620822c0ba93d9d8c523cd
Showing with 108 additions and 11 deletions.
  1. +24 −11 src/manipulation.js
  2. +84 −0 test/unit/manipulation.js
@@ -1,7 +1,7 @@
(function( jQuery ) {

function createSafeFragment( document ) {
var list = nodeNames.split( " " ),
var list = nodeNames.split( "|" ),
safeFrag = document.createDocumentFragment();

if ( safeFrag.createElement ) {
@@ -14,8 +14,8 @@ function createSafeFragment( document ) {
return safeFrag;
}

var nodeNames = "abbr article aside audio canvas datalist details figcaption figure footer " +
"header hgroup mark meter nav output progress section summary time video",
var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" +
"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
rleadingWhitespace = /^\s+/,
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
@@ -24,7 +24,7 @@ var nodeNames = "abbr article aside audio canvas datalist details figcaption fig
rhtml = /<|&#?\w+;/,
rnoInnerhtml = /<(?:script|style)/i,
rnocache = /<(?:script|object|embed|option|style)/i,
rnoshimcache = new RegExp("<(?:" + nodeNames.replace(" ", "|") + ")", "i"),
rnoshimcache = new RegExp("<(?:" + nodeNames + ")", "i"),
// checked="checked" or checked
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
rscriptType = /\/(java|ecma)script/i,
@@ -468,7 +468,7 @@ jQuery.buildFragment = function( args, nodes, scripts ) {
doc = nodes[0].ownerDocument || nodes[0];
}

// Ensure that an attr object doesn't incorrectly stand in as a document object
// Ensure that an attr object doesn't incorrectly stand in as a document object
// Chrome and Firefox seem to allow this to occur and will throw exception
// Fixes #8950
if ( !doc.createDocumentFragment ) {
@@ -564,12 +564,21 @@ function findInputs( elem ) {
}
}

// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js
function shimCloneNode( elem ) {
var div = document.createElement( "div" );
safeFragment.appendChild( div );

div.innerHTML = elem.outerHTML;
return div.firstChild;
}

jQuery.extend({
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
var clone = elem.cloneNode(true),
srcElements,
destElements,
i;
var srcElements,
destElements,
i,
clone = elem.cloneNode( true );

if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
@@ -579,10 +588,14 @@ jQuery.extend({
// proprietary methods to clear the events. Thanks to MooTools
// guys for this hotness.

// IE<=8 does not properly clone detached, unknown element nodes
if ( rnoshimcache.test( "<" + elem.nodeName ) ) {
clone = shimCloneNode( elem );
}

cloneFixAttributes( elem, clone );

// Using Sizzle here is crazy slow, so we use getElementsByTagName
// instead
// Using Sizzle here is crazy slow, so we use getElementsByTagName instead
srcElements = getAll( elem );
destElements = getAll( clone );

@@ -1558,3 +1558,87 @@ test("jQuery.clone - no exceptions for object elements #9587", function() {
ok( false, e.message );
}
});

test("jQuery(<tag>) & wrap[Inner/All]() handle unknown elems (#10667)", function() {
expect(2);

var $wraptarget = jQuery( "<div id='wrap-target'>Target</div>" ).appendTo( "#qunit-fixture" ),
$section = jQuery( "<section>" ).appendTo( "#qunit-fixture" );

$wraptarget.wrapAll("<aside style='background-color:green'></aside>");

notEqual( $wraptarget.parent("aside").css("background-color"), "transparent", "HTML5 elements created with wrapAll inherit styles" );
notEqual( $section.css("background-color"), "transparent", "HTML5 elements create with jQuery( string ) inherit styles" );
});

test("Cloned, detached HTML5 elems (#10667,10670)", function() {
expect(7);

var $section = jQuery( "<section>" ).appendTo( "#qunit-fixture" ),
$clone;

// First clone
$clone = $section.clone();

// Infer that the test is being run in IE<=8
if ( $clone[0].outerHTML && !jQuery.support.opacity ) {
// This branch tests cloning nodes by reading the outerHTML, used only in IE<=8
equal( $clone[0].outerHTML, "<section></section>", "detached clone outerHTML matches '<section></section>'" );
} else {
// This branch tests a known behaviour in modern browsers that should never fail.
// Included for expected test count symmetry (expecting 1)
equal( $clone[0].nodeName, "SECTION", "detached clone nodeName matches 'SECTION' in modern browsers" );
}

// Bind an event
$section.bind( "click", function( event ) {
ok( true, "clone fired event" );
});

// Second clone (will have an event bound)
$clone = $section.clone( true );

// Trigger an event from the first clone
$clone.trigger( "click" );
$clone.unbind( "click" );

// Add a child node with text to the original
$section.append( "<p>Hello</p>" );

// Third clone (will have child node and text)
$clone = $section.clone( true );

equal( $clone.find("p").text(), "Hello", "Assert text in child of clone" );

// Trigger an event from the third clone
$clone.trigger( "click" );
$clone.unbind( "click" );

// Add attributes to copy
$section.attr({
"class": "foo bar baz",
"title": "This is a title"
});

// Fourth clone (will have newly added attributes)
$clone = $section.clone( true );

equal( $clone.attr("class"), $section.attr("class"), "clone and element have same class attribute" );
equal( $clone.attr("title"), $section.attr("title"), "clone and element have same title attribute" );

// Remove the original
$section.remove();

// Clone the clone
$section = $clone.clone( true );

// Remove the clone
$clone.remove();

// Trigger an event from the clone of the clone
$section.trigger( "click" );

// Unbind any remaining events
$section.unbind( "click" );
$clone.unbind( "click" );
});

0 comments on commit 66e65c8

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.