Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
23f45a9
new branch for bug_44087 using alternative solution to bug_4087 and b…
Nov 21, 2012
6d57472
Merge branch 'master' of https://github.com/jquery/jquery into bug_40…
PaulBRamos Nov 22, 2012
53ec7b7
Merge branch 'master' of https://github.com/jquery/jquery into bug_40…
PaulBRamos Nov 27, 2012
34df192
Merge branch 'master' of https://github.com/jquery/jquery into bug_40…
PaulBRamos Nov 28, 2012
e67daf2
#4087 - manipulation doesn't work if origin & destination are same el…
PaulBRamos Nov 28, 2012
4ccecf9
Merge branch 'master' of https://github.com/jquery/jquery into bug_40…
PaulBRamos Dec 3, 2012
5b9bf13
No ticket: improve global variable/ajax request tracking
gibson042 Dec 3, 2012
ad690f8
Improvements per @jaubourg
gibson042 Dec 3, 2012
4ada325
More improvements per @jaubourg
gibson042 Dec 3, 2012
3ab2634
Fix #12856: keep PSEUDO regex non-greedy
gibson042 Dec 4, 2012
228ab3d
Organizes the php scripts used for testing better, so that the whole …
jaubourg Dec 4, 2012
2a419a7
Fixes spacing
jaubourg Dec 4, 2012
ec72d9f
Fix #12756. Restyle manipulation unit tests. Close gh-1053.
PaulBRamos Dec 4, 2012
13449a9
Fix #11989. Remove fragment cache, moving to jquery-compat. Close gh-…
PaulBRamos Dec 5, 2012
551c2c9
Fixes #12449. make replaceWith() clone elements where required. Close…
rvagg Dec 5, 2012
4437002
Radical idea: Calculate `expect()` value before fn call. :purple_heart:
dmethvin Dec 5, 2012
5ded0c2
new branch for bug_44087 using alternative solution to bug_4087 and b…
Nov 21, 2012
995837e
#4087 - manipulation doesn't work if origin & destination are same el…
PaulBRamos Nov 28, 2012
2eda89d
Removed check for same origin/destination from if clause to body | Fi…
PaulBRamos Dec 5, 2012
d518251
Moved 4087 fix from if clause to body, and fixed unit test expectatio…
PaulBRamos Dec 5, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,7 @@ jQuery.extend({
if ( scripts ) {
jQuery( scripts ).remove();
}
return jQuery.merge( [],
( parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment ).childNodes );
return jQuery.merge( [], parsed.childNodes );
},

parseJSON: function( data ) {
Expand Down
93 changes: 34 additions & 59 deletions src/manipulation.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca
rtbody = /<tbody/i,
rhtml = /<|&#?\w+;/,
rnoInnerhtml = /<(?:script|style|link)/i,
rnocache = /<(?:script|style|object|embed|applet|option)/i,
manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
// checked="checked" or checked
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
Expand Down Expand Up @@ -256,35 +255,32 @@ jQuery.fn.extend({
// Make sure that the elements are removed from the DOM before they are inserted
// this can help fix replacing a parent with child elements
if ( !isFunc && typeof value !== "string" ) {
value = jQuery( value ).detach();
value = jQuery( value ).not( this ).detach();
}

this.each( function( i ) {
var next = this.nextSibling,
parent = this.parentNode,
// HTML argument replaced by "this" element
// 1. There were no supporting tests
// 2. There was no internal code relying on this
// 3. There was no documentation of an html argument
val = !isFunc ? value : value.call( this, i, this );
return this.domManip( [ value ], true, function( elem, i ) {
var next, parent;

if ( isDisconnected( this ) ) {
// for disconnected elements, we replace with the new content in the set. We use
// clone here to ensure that each replaced instance is unique
self[ i ] = jQuery( val ).clone()[ 0 ];
// for disconnected elements, we simply replace
// with the new content in the set
self[ i ] = elem;
return;
}

jQuery( this ).remove();
if ( this.nodeType === 1 || this.nodeType === 11 ) {
next = this.nextSibling;
parent = this.parentNode;

if ( next ) {
jQuery( next ).before( val );
} else {
jQuery( parent ).append( val );
jQuery( this ).remove();

if ( next ) {
next.parentNode.insertBefore( elem, next );
} else {
parent.appendChild( elem );
}
}
});

return this;
},

detach: function( selector ) {
Expand Down Expand Up @@ -314,8 +310,8 @@ jQuery.fn.extend({
}

if ( this[0] ) {
results = jQuery.buildFragment( args, this );
fragment = results.fragment;
results = jQuery.buildFragment( args, this, undefined, this );
fragment = results;
first = fragment.firstChild;

if ( fragment.childNodes.length === 1 ) {
Expand All @@ -329,9 +325,9 @@ jQuery.fn.extend({

// Use the original fragment for the last item instead of the first because it can end up
// being emptied incorrectly in certain situations (#8070).
// Fragments from the fragment cache must always be cloned and never used in place.
for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {
for ( iNoClone = l - 1; i < l; i++ ) {
node = fragment;

if ( i !== iNoClone ) {
node = jQuery.clone( node, true, true );

Expand All @@ -340,11 +336,13 @@ jQuery.fn.extend({
jQuery.merge( scripts, getAll( node, "script" ) );
}
}

callback.call(
table && jQuery.nodeName( this[i], "table" ) ?
findOrAppend( this[i], "tbody" ) :
this[i],
node
node,
i
);
}

Expand Down Expand Up @@ -514,9 +512,8 @@ function cloneFixAttributes( src, dest ) {
dest.removeAttribute( jQuery.expando );
}

jQuery.buildFragment = function( args, context, scripts ) {
var fragment, cacheable, cachehit,
first = args[ 0 ];
jQuery.buildFragment = function( args, context, scripts, selection ) {
var fragment;

// Set context from what may come in as undefined or a jQuery collection or a node
// Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &
Expand All @@ -525,38 +522,12 @@ jQuery.buildFragment = function( args, context, scripts ) {
context = !context.nodeType && context[0] || context;
context = context.ownerDocument || context;

// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
// Cloning options loses the selected state, so don't cache them
// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
// Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document &&
first.charAt(0) === "<" && !rnocache.test( first ) &&
(jQuery.support.checkClone || !rchecked.test( first )) &&
(jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {

// Mark cacheable and look for a hit
cacheable = true;
fragment = jQuery.fragments[ first ];
cachehit = fragment !== undefined;
}

if ( !fragment ) {
fragment = context.createDocumentFragment();
jQuery.clean( args, context, fragment, scripts );
fragment = context.createDocumentFragment();
jQuery.clean( args, context, fragment, scripts, selection );

// Update the cache, but only store false
// unless this is a second parsing of the same content
if ( cacheable ) {
jQuery.fragments[ first ] = cachehit && fragment;
}
}

return { fragment: fragment, cacheable: cacheable };
return fragment;
};

jQuery.fragments = {};

jQuery.each({
appendTo: "append",
prependTo: "prepend",
Expand Down Expand Up @@ -683,7 +654,7 @@ jQuery.extend({
return clone;
},

clean: function( elems, context, fragment, scripts ) {
clean: function( elems, context, fragment, scripts, selection ) {
var elem, j, tmp, tag, wrap, tbody,
ret = [],
i = 0,
Expand Down Expand Up @@ -778,7 +749,11 @@ jQuery.extend({
safe = jQuery.contains( elem.ownerDocument, elem );

// Append to fragment
fragment.appendChild( elem );
// #4087 - If origin and destination elements are the same, and this is
// that element, do not append to fragment
if ( !( selection && jQuery.inArray( elem, selection ) !== -1 ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ticket was always going to incur a performance hit, but I really like the elegance of this solution. Note that if ( !selection || jQuery.inArray( elem, selection ) < 0 ) will probably compress a little better, but what's a De Morgan transformation or two between friends?

ALSO: This changes the return value of buildFragment, and https://github.com/PaulBRamos/jquery/blob/e67daf2018c4d7661d4c45e3ba5ad38db9a36bf9/src/manipulation.js#L317-L336 will need some attention as a result. @dmethvin, we've been thinking about dropping the fragment cache anyway... it would probably simplify things here. I'm inclined to place the burden of proof on someone who wants to keep a ~100 byte eight-clause if, but I know there's a lot of history behind that preceding me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look at it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hard numbers are masked by rounding, but http://jsperf.com/jquery-fragcache shows a ~7% speed improvement from the cache on IE6-7, no significant difference on IE8-9 and Chromium 20, and ~13% on Firefox 17 (not that we really care on newer browsers).

There is a benefit, but it's so modest that I'm still in favor of dropping the cache.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, thanks for that bench @gibson042! IE6 is just pitiful, but we knew that. Okay, I think we should go ahead and do this thing. It will be a good file size savings and also in-memory usage will be lower since we won't be creating frag cache entries. There's already a ticket for it at http://bugs.jquery.com/ticket/11989 and we can just pull it forward into 1.9.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PaulBRamos, do you want to take that too? Removing the fragment cache will make your job here much easier. You'll probably want to submit a separate pull request for http://bugs.jquery.com/ticket/11989 and then rebase this one after it lands.

I'm happy to do it if you prefer, but rebasing seems so much more pleasant when it's on top of your own changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/kill fragcache \o/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on it!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woah. Fragment cache gone just like that. Amazing.

fragment.appendChild( elem );
}
tmp = getAll( elem, "script" );

// Preserve script evaluation history
Expand Down
2 changes: 1 addition & 1 deletion src/sizzle
Submodule sizzle updated 3 files
+102 −75 sizzle.js
+1 −1 test/index.html
+126 −48 test/unit/selector.js
5 changes: 4 additions & 1 deletion test/.jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@
"ajaxTest": true,
"testIframe": true,
"testIframeWithCallback": true,
"createComplexHTML": true,
"createDashboardXML": true,
"createWithFriesXML": true,
"createXMLFragment": true,
"moduleTeardown": true,
"testBar": true,
"testFoo": true,
"foobar": true,
"url": true,
"service": true,
"t": true,
"q": true,
"amdDefined": true,
Expand Down
43 changes: 43 additions & 0 deletions test/data/ajax/echo/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

$requestArray = "REQUEST";

if ( isset( $_REQUEST["requestArray"] ) ) {
$requestArray = $_REQUEST["requestArray"];
}

$requestArray =& ${"_$requestArray"};

$response = array(
"status" => "200",
"statusText" => "",
"contentType" => "text/plain",
"content" => "",
"callback" => "",
"delay" => 0
);

foreach( $response as $field => &$value ) {
if ( isset( $requestArray[ $field ] ) ) {
$value = $requestArray[ $field ];
}
}

if ( is_array( $response["content"] ) ) {
$response["content"] = http_build_query( $response["content"] );
}

if ( !$response["callback"] && preg_match( '/index.php\/([^\/\?&]+)/', $_SERVER["REQUEST_URI"], $match ) ) {
$response["callback"] = $match[ 1 ];
}

header("HTTP/1.1 $response[status] $response[statusText]");
header("Content-Type: $response[contentType]");

if ( $response["delay"] ) {
sleep( $response["delay"] );
}

echo $response["callback"]
? "$response[callback](" . json_encode("$response[content]") . ");"
: "$response[content]";
30 changes: 30 additions & 0 deletions test/data/ajax/headers/cache/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
$headers = array(

"If-Modified-Since" => array(
"request" => "HTTP_IF_MODIFIED_SINCE",
"response" => "Last-Modified",
),
"If-None-Match" => array(
"request" => "HTTP_IF_NONE_MATCH",
"response" => "Etag",
),

);

$header = $_REQUEST["header"];
$value = $_REQUEST["value"];

if ( $header === "If-None-Match" ) {
$value = md5( $value );
}

$headers = $headers[ $header ];

$requestHeader = isset( $_SERVER[ $headers["request"] ] ) ? stripslashes($_SERVER[ $headers["request"] ]) : false;
if ( $requestHeader === $value ) {
header("HTTP/1.0 304 Not Modified");
} else {
header("$headers[response]: $value");
echo $requestHeader ? "OK: $value": "FAIL";
}
12 changes: 12 additions & 0 deletions test/data/ajax/headers/request/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

$headers = array();

foreach( $_SERVER as $key => $value ) {
$key = str_replace( "_" , "-" , substr($key,0,5) == "HTTP_" ? substr($key,5) : $key );
$headers[ $key ] = $value;
}

foreach( explode( "," , $_GET["headers"] ) as $key ) {
echo "$key: " . @$headers[ strtoupper( $key ) ] . "\n";
}
5 changes: 5 additions & 0 deletions test/data/ajax/headers/response/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

foreach( $_REQUEST as $header => $value ) {
@header("$header: $value");
}
4 changes: 0 additions & 4 deletions test/data/atom+xml.php

This file was deleted.

1 change: 0 additions & 1 deletion test/data/badcall.js

This file was deleted.

1 change: 0 additions & 1 deletion test/data/badjson.js

This file was deleted.

10 changes: 0 additions & 10 deletions test/data/cleanScript.html

This file was deleted.

11 changes: 0 additions & 11 deletions test/data/dashboard.xml

This file was deleted.

1 change: 0 additions & 1 deletion test/data/echoData.php

This file was deleted.

1 change: 0 additions & 1 deletion test/data/echoQuery.php

This file was deleted.

5 changes: 0 additions & 5 deletions test/data/errorWithText.php

This file was deleted.

21 changes: 0 additions & 21 deletions test/data/etag.php

This file was deleted.

1 change: 0 additions & 1 deletion test/data/evalScript.php

This file was deleted.

18 changes: 0 additions & 18 deletions test/data/headers.php

This file was deleted.

Loading