Fix busted rnoshimcache. Correctly clone detached unknown elems. Fixes #10667, #10670.

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

- Adds tests for clone attributes, children and events
This commit is contained in:
Rick Waldron 2011-11-07 21:22:04 -05:00 committed by timmywil
parent 68ca9d47a0
commit 66e65c8168
2 changed files with 108 additions and 11 deletions

View File

@ -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 );

View File

@ -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" );
});