]> source.dussan.org Git - jquery.git/commitdiff
Manipulation: Bring tagname regexes up to spec
authorLeonardo Braga <leonardo.braga@gmail.com>
Wed, 7 Oct 2015 04:51:23 +0000 (00:51 -0400)
committerRichard Gibson <richard.gibson@gmail.com>
Thu, 7 Jan 2016 21:48:49 +0000 (16:48 -0500)
Fixes gh-2005
Closes gh-2634

src/core/var/rsingleTag.js
src/manipulation.js
src/manipulation/var/rtagName.js
test/unit/manipulation.js

index 1a55ee39d2c74a04bccd2d0c54838492e8df9103..1ddf95ed4dcea3122294ea7aba287edada6690c2 100644 (file)
@@ -1,5 +1,5 @@
 define( function() {
 
        // Match a standalone tag
-       return ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
+       return ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
 } );
index cc4fd16cd7a2081de5b5c2ab9b5c7eaf504e5da7..6c4b3ede873934b0f39a59aed5fecbd972c06a12 100644 (file)
@@ -27,7 +27,7 @@ define( [
        dataPriv, dataUser, acceptData, DOMEval ) {
 
 var
-       rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
+       rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
 
        // Support: IE 10-11, Edge 10240+
        // In IE/Edge using regex groups here causes severe slowdowns.
index 9e542694a7da514a61169bbd6ab4547aa8155a5c..1f8751ed8a48569cc081a830b37100bdac5f16e4 100644 (file)
@@ -1,3 +1,3 @@
 define( function() {
-       return ( /<([\w:-]+)/ );
+       return ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
 } );
index 4d8eed7d9ab70dc68c1466542ec1ae969fd0c3bc..f72000fc4d3c20faeab0089e541b858645eb4423 100644 (file)
@@ -500,6 +500,73 @@ QUnit.test( "html(String) tag-hyphenated elements (Bug #1987)", function( assert
        assert.equal( j.children().text(), "text", "Tags with multiple hypens behave normally" );
 } );
 
+QUnit.test( "Tag name processing respects the HTML Standard (gh-2005)", function( assert ) {
+
+       assert.expect( 240 );
+
+       var wrapper = jQuery( "<div></div>" ),
+               nameTerminatingChars = "\x20\t\r\n\f".split( "" ),
+               specialChars = "[ ] { } _ - = + \\ ( ) * & ^ % $ # @ ! ~ ` ' ; ? ¥ « µ λ ⊕ ≈ ξ ℜ ♣ €"
+                       .split( " " );
+
+       specialChars.push( specialChars.join( "" ) );
+
+       jQuery.each( specialChars, function( i, characters ) {
+               assertSpecialCharsSupport( "html", characters );
+               assertSpecialCharsSupport( "append", characters );
+       } );
+
+       jQuery.each( nameTerminatingChars, function( i, character ) {
+               assertNameTerminatingCharsHandling( "html", character );
+               assertNameTerminatingCharsHandling( "append", character );
+       } );
+
+       function buildChild( method, html ) {
+               wrapper[ method ]( html );
+               return wrapper.children()[ 0 ];
+       }
+
+       function assertSpecialCharsSupport( method, characters ) {
+               var child,
+                       codepoint = characters.charCodeAt( 0 ).toString( 16 ).toUpperCase(),
+                       description = characters.length === 1 ?
+                               "U+" + ( "000" + codepoint ).slice( -4 ) + " " + characters :
+                               "all special characters",
+                       nodeName = "valid" + characters + "tagname";
+
+               child = buildChild( method, "<" + nodeName + "></" + nodeName + ">" );
+               assert.equal( child.nodeName.toUpperCase(), nodeName.toUpperCase(),
+                       method + "(): Paired tag name includes " + description );
+
+               child = buildChild( method, "<" + nodeName + ">" );
+               assert.equal( child.nodeName.toUpperCase(), nodeName.toUpperCase(),
+                       method + "(): Unpaired tag name includes " + description );
+
+               child = buildChild( method, "<" + nodeName + "/>" );
+               assert.equal( child.nodeName.toUpperCase(), nodeName.toUpperCase(),
+                       method + "(): Self-closing tag name includes " + description );
+       }
+
+       function assertNameTerminatingCharsHandling( method, character ) {
+               var child,
+                       codepoint = character.charCodeAt( 0 ).toString( 16 ).toUpperCase(),
+                       description = "U+" + ( "000" + codepoint ).slice( -4 ) + " " + character,
+                       nodeName = "div" + character + "this-will-be-discarded";
+
+               child = buildChild( method, "<" + nodeName + "></" + nodeName + ">" );
+               assert.equal( child.nodeName.toUpperCase(), "DIV",
+                       method + "(): Paired tag name terminated by " + description );
+
+               child = buildChild( method, "<" + nodeName + ">" );
+               assert.equal( child.nodeName.toUpperCase(), "DIV",
+                       method + "(): Unpaired open tag name terminated by " + description );
+
+               child = buildChild( method, "<" + nodeName + "/>" );
+               assert.equal( child.nodeName.toUpperCase(), "DIV",
+                       method + "(): Self-closing tag name terminated by " + description );
+       }
+} );
+
 QUnit.test( "IE8 serialization bug", function( assert ) {
 
        assert.expect( 2 );