Permalink
Browse files

Remove the invisible body in support; Add temporary tests to verify c…

…orrect support completions for upcoming support changes.
  • Loading branch information...
timmywil committed Nov 17, 2011
1 parent 0de484d commit 3d6237ef8aff8a31ace3e956e2700aa11e3da752
Showing with 331 additions and 103 deletions.
  1. +65 −101 src/support.js
  2. +1 −1 test/data/support/boxModelIE.html
  3. +1 −1 test/index.html
  4. +264 −0 test/unit/support.js
View
@@ -2,31 +2,26 @@
jQuery.support = (function() {
- var div = document.createElement( "div" ),
- documentElement = document.documentElement,
+ var support,
all,
a,
select,
opt,
input,
marginDiv,
- support,
fragment,
- body,

This comment has been minimized.

Show comment
Hide comment
@mikesherov

mikesherov Nov 18, 2011

Member

body leaks to global now, right? I found this with JSHint, btw. ;-)

@mikesherov

mikesherov Nov 18, 2011

Member

body leaks to global now, right? I found this with JSHint, btw. ;-)

- testElementParent,
- testElement,
- testElementStyle,
tds,
events,
eventName,
i,
- isSupported;
+ isSupported,
+ div = document.createElement( "div" ),
+ documentElement = document.documentElement;
// Preliminary tests
div.setAttribute("className", "t");
div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
-
all = div.getElementsByTagName( "*" );
a = div.getElementsByTagName( "a" )[ 0 ];
@@ -46,19 +41,19 @@ jQuery.support = (function() {
// Make sure that tbody elements aren't automatically inserted
// IE will insert them into empty tables
- tbody: !div.getElementsByTagName( "tbody" ).length,
+ tbody: !div.getElementsByTagName("tbody").length,
// Make sure that link elements get serialized correctly by innerHTML
// This requires a wrapper element in IE
- htmlSerialize: !!div.getElementsByTagName( "link" ).length,
+ htmlSerialize: !!div.getElementsByTagName("link").length,
// Get the style information from getAttribute
// (IE uses .cssText instead)
style: /top/.test( a.getAttribute("style") ),
// Make sure that URLs aren't manipulated
// (IE normalizes it by default)
- hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
+ hrefNormalized: ( a.getAttribute("href") === "/a" ),
// Make sure that element opacity exists
// (IE uses filter instead)
@@ -140,95 +135,28 @@ jQuery.support = (function() {
// WebKit doesn't clone checked state correctly in fragments
support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
- div.innerHTML = "";
-
- // Figure out if the W3C box model works as expected
- div.style.width = div.style.paddingLeft = "1px";
-
- // We don't want to do body-related feature tests on frameset
- // documents, which lack a body. So we use
- // document.getElementsByTagName("body")[0], which is undefined in
- // frameset documents, while document.body isn’t. (7398)
- body = document.getElementsByTagName("body")[ 0 ];
- // We use our own, invisible, body unless the body is already present
- // in which case we use a div (#9239)
- testElement = document.createElement( body ? "div" : "body" );
- testElementStyle = {
- visibility: "hidden",
- width: 0,
- height: 0,
- border: 0,
- margin: 0,
- background: "none"
- };
- if ( body ) {
- jQuery.extend( testElementStyle, {
- position: "absolute",
- left: "-999px",
- top: "-999px"
- });
- }
- for ( i in testElementStyle ) {
- testElement.style[ i ] = testElementStyle[ i ];
- }
- testElement.appendChild( div );
- testElementParent = body || documentElement;
- testElementParent.insertBefore( testElement, testElementParent.firstChild );
-
// Check if a disconnected checkbox will retain its checked
// value of true after appended to the DOM (IE6/7)
support.appendChecked = input.checked;
- support.boxModel = div.offsetWidth === 2;
-
- if ( "zoom" in div.style ) {
- // Check if natively block-level elements act like inline-block
- // elements when setting their display to 'inline' and giving
- // them layout
- // (IE < 8 does this)
- div.style.display = "inline";
- div.style.zoom = 1;
- support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
-
- // Check if elements with layout shrink-wrap their children
- // (IE 6 does this)
- div.style.display = "";
- div.innerHTML = "<div style='width:4px;'></div>";
- support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
- }
-
- div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
- tds = div.getElementsByTagName( "td" );
-
- // Check if table cells still have offsetWidth/Height when they are set
- // to display:none and there are still other visible table cells in a
- // table row; if so, offsetWidth/Height are not reliable for use when
- // determining if an element has been hidden directly using
- // display:none (it is still safe to use offsets if a parent element is
- // hidden; don safety goggles and see bug #4512 for more information).
- // (only IE 8 fails this test)
- isSupported = ( tds[ 0 ].offsetHeight === 0 );
-
- tds[ 0 ].style.display = "";
- tds[ 1 ].style.display = "none";
+ fragment.removeChild( input );
+ fragment.appendChild( div );
- // Check if empty table cells still have offsetWidth/Height
- // (IE < 8 fail this test)
- support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
div.innerHTML = "";
// Check if div with explicit width and no margin-right incorrectly
// gets computed margin-right based on width of container. For more
// info see bug #3333
// Fails in WebKit before Feb 2011 nightlies
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ if ( window.getComputedStyle ) {
marginDiv = document.createElement( "div" );
marginDiv.style.width = "0";
marginDiv.style.marginRight = "0";
+ div.style.width = "2px";
div.appendChild( marginDiv );
support.reliableMarginRight =
- ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
+ ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;

This comment has been minimized.

Show comment
Hide comment
@mikesherov

mikesherov Nov 17, 2011

Member

excuse my ignorance, but doesn't FF3.6 need document.defaultView so IFRAME's will be happy? #524 (comment)

@mikesherov

mikesherov Nov 17, 2011

Member

excuse my ignorance, but doesn't FF3.6 need document.defaultView so IFRAME's will be happy? #524 (comment)

This comment has been minimized.

Show comment
Hide comment
@timmywil

timmywil Nov 18, 2011

Member

It is needed in css.js, not in the support test.

@timmywil

timmywil Nov 18, 2011

Member

It is needed in css.js, not in the support test.

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

What if jQuery is loaded in an iframe that has display:none in Firefox 3.6? (I'm curious, I haven't tested this)

@rwaldron

rwaldron Nov 18, 2011

Member

What if jQuery is loaded in an iframe that has display:none in Firefox 3.6? (I'm curious, I haven't tested this)

This comment has been minimized.

Show comment
Hide comment
@mikesherov

mikesherov Nov 18, 2011

Member

funny you should ask, @rwldrn, I have a PR for this sitting in the queue: #555

@mikesherov

mikesherov Nov 18, 2011

Member

funny you should ask, @rwldrn, I have a PR for this sitting in the queue: #555

This comment has been minimized.

Show comment
Hide comment
@jdalton

jdalton Nov 18, 2011

Member

Ok, so this is kinda an interesting issue. Would ❤️ a blog post on it.

@jdalton

jdalton Nov 18, 2011

Member

Ok, so this is kinda an interesting issue. Would ❤️ a blog post on it.

This comment has been minimized.

Show comment
Hide comment
@timmywil

timmywil Nov 18, 2011

Member

@rwldrn: Just tested and looks like it has the correct result.

@timmywil

timmywil Nov 18, 2011

Member

@rwldrn: Just tested and looks like it has the correct result.

}
// Technique from Juriy Zaytsev
@@ -242,7 +170,7 @@ jQuery.support = (function() {
submit: 1,
change: 1,
focusin: 1
- } ) {
+ }) {
eventName = "on" + i;
isSupported = ( eventName in div );
if ( !isSupported ) {
@@ -253,11 +181,10 @@ jQuery.support = (function() {
}
}
- testElement.innerHTML = "";
- testElementParent.removeChild( testElement );
+ fragment.removeChild( div );
- // Null connected elements to avoid leaks in IE
- testElement = fragment = select = opt = body = marginDiv = div = input = null;
+ // Null elements to avoid leaks in IE
+ fragment = select = opt = body = marginDiv = div = input = null;

This comment has been minimized.

Show comment
Hide comment
@mikesherov

mikesherov Nov 18, 2011

Member

body is not defined before this.

@mikesherov

mikesherov Nov 18, 2011

Member

body is not defined before this.

// Run fixed position tests at doc ready to avoid a crash
// related to the invisible body in IE8
@@ -268,8 +195,8 @@ jQuery.support = (function() {
vb = "visibility:hidden;border:0;",
style = "style='" + ptlm + "border:5px solid #000;padding:0;'",
html = "<div " + style + "><div></div></div>" +
- "<table " + style + " cellpadding='0' cellspacing='0'>" +
- "<tr><td></td></tr></table>";
+ "<table " + style + " cellpadding='0' cellspacing='0'>" +
+ "<tr><td></td></tr></table>";
// Reconstruct a container
body = document.getElementsByTagName("body")[0];
@@ -283,13 +210,53 @@ jQuery.support = (function() {
container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
body.insertBefore( container, body.firstChild );
- // Construct a test element
- testElement = document.createElement("div");
- testElement.style.cssText = ptlm + vb;
+ // Construct the test element
+ div = document.createElement("div");
+ container.appendChild( div );
+
+ // Check if table cells still have offsetWidth/Height when they are set
+ // to display:none and there are still other visible table cells in a
+ // table row; if so, offsetWidth/Height are not reliable for use when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element is
+ // hidden; don safety goggles and see bug #4512 for more information).
+ // (only IE 8 fails this test)
+ div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
+ tds = div.getElementsByTagName( "td" );
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+ tds[ 0 ].style.display = "";
+ tds[ 1 ].style.display = "none";
+
+ // Check if empty table cells still have offsetWidth/Height
+ // (IE <= 8 fail this test)
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+ // Figure out if the W3C box model works as expected
+ div.innerHTML = "";
+ div.style.width = div.style.paddingLeft = "1px";
+ jQuery.boxModel = support.boxModel = div.offsetWidth === 2;
+
+ if ( typeof div.style.zoom !== "undefined" ) {
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ // (IE < 8 does this)
+ div.style.display = "inline";
+ div.style.zoom = 1;
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
+
+ // Check if elements with layout shrink-wrap their children
+ // (IE 6 does this)
+ div.style.display = "";
+ div.innerHTML = "<div style='width:4px;'></div>";
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
+ }
+
+ div.style.cssText = ptlm + vb;
+ div.innerHTML = html;
- testElement.innerHTML = html;
- container.appendChild( testElement );
- outer = testElement.firstChild;
+ outer = div.firstChild;
inner = outer.firstChild;
td = outer.nextSibling.firstChild.firstChild;
@@ -312,15 +279,12 @@ jQuery.support = (function() {
offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
body.removeChild( container );
- testElement = container = null;
+ div = container = null;
jQuery.extend( support, offsetSupport );
});
return support;
})();
-// Keep track of boxModel
-jQuery.boxModel = jQuery.support.boxModel;
-
})( jQuery );
@@ -22,7 +22,7 @@
<script src="../../../src/offset.js"></script>
<script src="../../../src/dimensions.js"></script>
<script>
- window.parent.supportCallback( document.compatMode, jQuery.support.boxModel );
+ jQuery(function() { window.parent.supportCallback( document.compatMode, jQuery.support.boxModel ) });
</script>
</body>
</html>
View
@@ -36,9 +36,9 @@
<script src="data/testrunner.js"></script>
<script src="unit/core.js"></script>
- <script src="unit/support.js"></script>
<script src="unit/callbacks.js"></script>
<script src="unit/deferred.js"></script>
+ <script src="unit/support.js"></script>
<script src="unit/data.js"></script>
<script src="unit/queue.js"></script>
<script src="unit/attributes.js"></script>
Oops, something went wrong.

18 comments on commit 3d6237e

@rwaldron

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

These tests are great.

Member

rwaldron replied Nov 18, 2011

These tests are great.

@rwaldron

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

One thing... really inconsistent with space around foo("here") vs foo( "here" )...

Member

rwaldron replied Nov 18, 2011

One thing... really inconsistent with space around foo("here") vs foo( "here" )...

@timmywil

This comment has been minimized.

Show comment
Hide comment
@timmywil

timmywil Nov 18, 2011

Member

True, that is inconsistent. I should fix that.

But...since we're discussing it, I prefer foo("here") to foo( "here" ). Double quotes provide a visible space by themselves don't you think?

Member

timmywil replied Nov 18, 2011

True, that is inconsistent. I should fix that.

But...since we're discussing it, I prefer foo("here") to foo( "here" ). Double quotes provide a visible space by themselves don't you think?

@rwaldron

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

@timmywil As it turns out, I do agree. My nit wasn't that it should be padded, but just that you're all over the damn place ;)

I think I'm going to open a ticket to officially change the style guide to reflect this, what do you think? I'll deal with the grunt work myself.

Member

rwaldron replied Nov 18, 2011

@timmywil As it turns out, I do agree. My nit wasn't that it should be padded, but just that you're all over the damn place ;)

I think I'm going to open a ticket to officially change the style guide to reflect this, what do you think? I'll deal with the grunt work myself.

@rdworth

This comment has been minimized.

Show comment
Hide comment
@rdworth

rdworth Nov 18, 2011

Contributor

@rwldrn your proposed change seems like a real source for even worse inconsistency. Imagine
foo("here", 4 )
or
foo( 4, "here")
Yuck.

Contributor

rdworth replied Nov 18, 2011

@rwldrn your proposed change seems like a real source for even worse inconsistency. Imagine
foo("here", 4 )
or
foo( 4, "here")
Yuck.

@rwaldron

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

@rdworth tough one, part of me thinks that's not too bad and pretty damn readable.

Member

rwaldron replied Nov 18, 2011

@rdworth tough one, part of me thinks that's not too bad and pretty damn readable.

@rdworth

This comment has been minimized.

Show comment
Hide comment
@rdworth

rdworth Nov 18, 2011

Contributor

My cry is not "it's not readable because of lack of horizontal space" it's "that's an ugly inconsistency that adds complexity to something that should be as simple as possible (and already isn't)". My 2c

Contributor

rdworth replied Nov 18, 2011

My cry is not "it's not readable because of lack of horizontal space" it's "that's an ugly inconsistency that adds complexity to something that should be as simple as possible (and already isn't)". My 2c

@rwaldron

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

@rdworth hahaha, ok! stop yelling at me.. geez... ;)

Member

rwaldron replied Nov 18, 2011

@rdworth hahaha, ok! stop yelling at me.. geez... ;)

@rwaldron

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

@timmywil Can you update the whitespace in accordance with style guide - thanks dude :)

Member

rwaldron replied Nov 18, 2011

@timmywil Can you update the whitespace in accordance with style guide - thanks dude :)

@timmywil

This comment has been minimized.

Show comment
Hide comment
@timmywil

timmywil Nov 18, 2011

Member

haha, and it's over that quick? @rdworth: we already have an answer to that. If either one or both of the parenthesis do not have quotes next to them, insert an extra space next to the quote. So what I propose would still be:

foo( "here", 4 );
foo( 4, "here" );
foo("here");
Member

timmywil replied Nov 18, 2011

haha, and it's over that quick? @rdworth: we already have an answer to that. If either one or both of the parenthesis do not have quotes next to them, insert an extra space next to the quote. So what I propose would still be:

foo( "here", 4 );
foo( 4, "here" );
foo("here");
@rdworth

This comment has been minimized.

Show comment
Hide comment
@rdworth

rdworth Nov 18, 2011

Contributor

Oh, if it's single arg only, I won't lose sleep. Sorry for the noise.

Contributor

rdworth replied Nov 18, 2011

Oh, if it's single arg only, I won't lose sleep. Sorry for the noise.

@rwaldron

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

Yes, that is nice. Thanks for the follow through haha.

Member

rwaldron replied Nov 18, 2011

Yes, that is nice. Thanks for the follow through haha.

@eddiemonge

This comment has been minimized.

Show comment
Hide comment
@eddiemonge

eddiemonge Nov 18, 2011

Contributor

How is foo(4) handled? is it like that or foo( 4 )? If its the second, then seems like it should always be spaced wrapped in parens

Contributor

eddiemonge replied Nov 18, 2011

How is foo(4) handled? is it like that or foo( 4 )? If its the second, then seems like it should always be spaced wrapped in parens

@timmywil

This comment has been minimized.

Show comment
Hide comment
@timmywil

timmywil Nov 18, 2011

Member

Everything else is the same, so foo( 4 ). Quotes on both sides of the parens is the only exception.

Member

timmywil replied Nov 18, 2011

Everything else is the same, so foo( 4 ). Quotes on both sides of the parens is the only exception.

@mikesherov

This comment has been minimized.

Show comment
Hide comment
@mikesherov

mikesherov Nov 18, 2011

Member
Member

mikesherov replied Nov 18, 2011

@rdworth

This comment has been minimized.

Show comment
Hide comment
@rdworth

rdworth Nov 18, 2011

Contributor

Quotes on both sides of the parens is the only exception.

Other than curly braces and square brackets which are the current exceptions it is proposed quotes be added to ;)

Contributor

rdworth replied Nov 18, 2011

Quotes on both sides of the parens is the only exception.

Other than curly braces and square brackets which are the current exceptions it is proposed quotes be added to ;)

@eddiemonge

This comment has been minimized.

Show comment
Hide comment
@eddiemonge

eddiemonge Nov 18, 2011

Contributor

So many inconsistencies. I say its spaces next to the parens always, and maybe braces and brackets should be added to that.

Contributor

eddiemonge replied Nov 18, 2011

So many inconsistencies. I say its spaces next to the parens always, and maybe braces and brackets should be added to that.

@rwaldron

This comment has been minimized.

Show comment
Hide comment
@rwaldron

rwaldron Nov 18, 2011

Member

Other style guide changes are not up for discussion. Thanks to everyone, please consider the thread closed

Member

rwaldron replied Nov 18, 2011

Other style guide changes are not up for discussion. Thanks to everyone, please consider the thread closed

Please sign in to comment.