diff options
author | Timmy Willison <timmywillisn@gmail.com> | 2015-05-05 11:44:55 -0700 |
---|---|---|
committer | Timmy Willison <timmywillisn@gmail.com> | 2015-05-05 11:44:55 -0700 |
commit | a74320fca8bb0a2190f6e1fdb71a73733b6986e4 (patch) | |
tree | 36e4af65a7acfb354f7d713a1859ba81e7d53116 /src/manipulation | |
parent | 6d7ef56ed3004a18f5139928455cdbdc169e1232 (diff) | |
download | jquery-a74320fca8bb0a2190f6e1fdb71a73733b6986e4.tar.gz jquery-a74320fca8bb0a2190f6e1fdb71a73733b6986e4.zip |
Manipulation: privatize buildFragment() function
Fixes gh-2224
Diffstat (limited to 'src/manipulation')
-rw-r--r-- | src/manipulation/buildFragment.js | 101 | ||||
-rw-r--r-- | src/manipulation/getAll.js | 20 | ||||
-rw-r--r-- | src/manipulation/setGlobalEval.js | 20 | ||||
-rw-r--r-- | src/manipulation/var/rscriptType.js | 3 | ||||
-rw-r--r-- | src/manipulation/var/rtagName.js | 3 | ||||
-rw-r--r-- | src/manipulation/wrapMap.js | 35 |
6 files changed, 182 insertions, 0 deletions
diff --git a/src/manipulation/buildFragment.js b/src/manipulation/buildFragment.js new file mode 100644 index 000000000..d5cb4062a --- /dev/null +++ b/src/manipulation/buildFragment.js @@ -0,0 +1,101 @@ +define([ + "../core", + "./var/rtagName", + "./var/rscriptType", + "./wrapMap", + "./getAll", + "./setGlobalEval" +], function( jQuery, rtagName, rscriptType, wrapMap, getAll, setGlobalEval ) { + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + +return buildFragment; +}); diff --git a/src/manipulation/getAll.js b/src/manipulation/getAll.js new file mode 100644 index 000000000..d08470b48 --- /dev/null +++ b/src/manipulation/getAll.js @@ -0,0 +1,20 @@ +define([ + "../core" +], function( jQuery ) { + +function getAll( context, tag ) { + // Support: IE9-11+ + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + +return getAll; +}); diff --git a/src/manipulation/setGlobalEval.js b/src/manipulation/setGlobalEval.js new file mode 100644 index 000000000..2eab9cf53 --- /dev/null +++ b/src/manipulation/setGlobalEval.js @@ -0,0 +1,20 @@ +define([ + "../data/var/dataPriv" +], function( dataPriv ) { + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + +return setGlobalEval; +}); diff --git a/src/manipulation/var/rscriptType.js b/src/manipulation/var/rscriptType.js new file mode 100644 index 000000000..60ef70ac8 --- /dev/null +++ b/src/manipulation/var/rscriptType.js @@ -0,0 +1,3 @@ +define(function() { + return ( /^$|\/(?:java|ecma)script/i ); +}); diff --git a/src/manipulation/var/rtagName.js b/src/manipulation/var/rtagName.js new file mode 100644 index 000000000..cd0b768e0 --- /dev/null +++ b/src/manipulation/var/rtagName.js @@ -0,0 +1,3 @@ +define(function() { + return ( /<([\w:-]+)/ ); +}); diff --git a/src/manipulation/wrapMap.js b/src/manipulation/wrapMap.js new file mode 100644 index 000000000..7080bf996 --- /dev/null +++ b/src/manipulation/wrapMap.js @@ -0,0 +1,35 @@ +define(function() { + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE9 + option: [ 1, "<select multiple='multiple'>", "</select>" ], + + thead: [ 1, "<table>", "</table>" ], + + // Some of the following wrappers are not fully defined, because + // their parent elements (except for "table" element) could be omitted + // since browser parsers are smart enough to auto-insert them + + // Support: Android 2.3 + // Android browser doesn't auto-insert colgroup + col: [ 2, "<table><colgroup>", "</colgroup></table>" ], + + // Auto-insert "tbody" element + tr: [ 2, "<table>", "</table>" ], + + // Auto-insert "tbody" and "tr" elements + td: [ 3, "<table>", "</table>" ], + + _default: [ 0, "", "" ] +}; + +// Support: IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +return wrapMap; +}); |