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.