Skip to content
Permalink
Browse files

Do not call getElements on a script tag. Avoids unnecessary execution…

…. Fixes #10176.
  • Loading branch information...
timmywil committed Oct 12, 2011
1 parent 92b06d3 commit 3ad0ba62f03ff3d7aec7d3dfb25492cdf33350a7
Showing with 14 additions and 6 deletions.
  1. +6 −4 src/manipulation.js
  2. +8 −2 test/unit/manipulation.js
@@ -530,10 +530,10 @@ jQuery.each({
});

function getAll( elem ) {
if ( "getElementsByTagName" in elem ) {
if ( typeof elem.getElementsByTagName !== "undefined" ) {
return elem.getElementsByTagName( "*" );

} else if ( "querySelectorAll" in elem ) {
} else if ( typeof elem.querySelectorAll !== "undefined" ) {
return elem.querySelectorAll( "*" );

} else {
@@ -549,9 +549,11 @@ function fixDefaultChecked( elem ) {
}
// Finds all inputs and passes them to fixDefaultChecked
function findInputs( elem ) {
if ( jQuery.nodeName( elem, "input" ) ) {
var nodeName = (elem.nodeName || "").toLowerCase();
if ( nodeName === "input" ) {
fixDefaultChecked( elem );
} else if ( "getElementsByTagName" in elem ) {
// Skip scripts, get other children
} else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {
jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
}
}
@@ -531,7 +531,7 @@ test("append(xml)", function() {
});

test("appendTo(String|Element|Array<Element>|jQuery)", function() {
expect(16);
expect(17);

var defaultText = "Try them out:"
jQuery("<b>buga</b>").appendTo("#first");
@@ -579,7 +579,7 @@ test("appendTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
jQuery("#moretests div:last").click();

QUnit.reset();
var div = jQuery("<div/>").appendTo("#qunit-fixture, #moretests");
div = jQuery("<div/>").appendTo("#qunit-fixture, #moretests");

equals( div.length, 2, "appendTo returns the inserted elements" );

@@ -603,6 +603,12 @@ test("appendTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
equals( jQuery("#qunit-fixture div").length, num, "Make sure all the removed divs were inserted." );

QUnit.reset();

stop();
jQuery.getScript('data/test.js', function() {
jQuery('script[src*="data\\/test\\.js"]').remove();
start();
});
});

var testPrepend = function(val) {

8 comments on commit 3ad0ba6

@Krinkle

This comment has been minimized.

Copy link
Member

replied Oct 23, 2011

Perhaps use !== undefined instead of typeof .. !== "undefined" ? Afaik 'undefined' can be safely used in a strict comparison within jQuery context since it's explicitly made undefined in the closure. Using a strict reference comparison gives faster performance (and it's shorter in code/bandwidth) than executing the typeof operator and doing a string comparison on the result.

@timmywil

This comment has been minimized.

Copy link
Member Author

replied Oct 23, 2011

Passing as an argument to typeof avoids the arbitrary execution of the given function in IE and has the added bonus of being noticeably faster than using the in operator. Using typeof vs. solely checking for property existence does not actually differ in performance enough to be a concern, according to what we've seen. http://jsperf.com/in-vs-typeof

@Krinkle

This comment has been minimized.

Copy link
Member

replied Oct 23, 2011

I wasn't suggesting to use the in operator... suggesting to use strict comparison to the undefined reference instead of the string "undefined" returned by the typeof operator. As done in other parts of jQuery core, like here

@mikesherov

This comment has been minimized.

Copy link
Member

replied Oct 24, 2011

@Krinkle, using strict comparison causes the function to be executed in IE... thus causing side effects. The fact that certain other parts of jQuery core may or may not conform to such standards (although the line you pointed do isn't an example of inconsistency in this case, it just looks like one) isn't really a good argument.

The three options are:

  1. use strict comparison, and get unnecessary side effects in IE.
  2. use "in", which is ridiculously slow.
  3. use typeof !== "undefined"

3 is the clear winner here.

@Krinkle

This comment has been minimized.

Copy link
Member

replied Oct 24, 2011

Interesting, I didn't think there'd that much of a difference in how IE treats the object member access between if ( foo.bar !== undefined ) and if ( typeof foo.bar !== 'undefined' ). Anyway, I agree option 3 makes perfect sense here. Thanks

@timmywil

This comment has been minimized.

Copy link
Member Author

replied Oct 24, 2011

Thanks Mike. You said it better.

@anddoutoi

This comment has been minimized.

Copy link

replied Nov 7, 2011

@mikesherov this was interesting. I am looking for sources that support this (yes I have trid google it). You know for which versions of IE this is true? You got any method checking this? Is this true only for built in native methods? Cause I couldn´t reproduce it with userland code.

@timmywil

This comment has been minimized.

Copy link
Member Author

replied Nov 7, 2011

@anddoutoi: http://jsfiddle.net/timmywil/NzUKW/ A situation where the method call throws an error.

Please sign in to comment.
You can’t perform that action at this time.