Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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

…orrect support completions for upcoming support changes.
  • Loading branch information...
commit 3d6237ef8aff8a31ace3e956e2700aa11e3da752 1 parent 0de484d
@timmywil timmywil authored
View
166 src/support.js
@@ -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,
@mikesherov Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
- 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,11 +41,11 @@ 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)
@@ -58,7 +53,7 @@ jQuery.support = (function() {
// 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,81 +135,13 @@ 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
@@ -222,13 +149,14 @@ jQuery.support = (function() {
// 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;
@mikesherov Collaborator

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

@timmywil Collaborator

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

@rwaldron Collaborator

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

@mikesherov Collaborator

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

@jdalton
jdalton added a note

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

@timmywil Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
// 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;
@mikesherov Collaborator

body is not defined before this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
// 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,7 +279,7 @@ jQuery.support = (function() {
offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
body.removeChild( container );
- testElement = container = null;
+ div = container = null;
jQuery.extend( support, offsetSupport );
});
@@ -320,7 +287,4 @@ jQuery.support = (function() {
return support;
})();
-// Keep track of boxModel
-jQuery.boxModel = jQuery.support.boxModel;
-
})( jQuery );
View
2  test/data/support/boxModelIE.html
@@ -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
2  test/index.html
@@ -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>
View
264 test/unit/support.js
@@ -60,3 +60,267 @@ supportIFrameTest( "A background on the testElement does not cause IE8 to crash
expect(1);
ok( true, "IE8 does not crash" );
});
+
+var userAgent = window.navigator.userAgent;
+
+// These tests do not have to stay
+// They are here to help with upcoming support changes for 1.8
+if ( /chrome\/16\.0/i.test(userAgent) ) {
+ test("Verify that the support tests resolve as expected per browser", function() {
+ var i,
+ expected = {
+ "leadingWhitespace":true,
+ "tbody":true,
+ "htmlSerialize":true,
+ "style":true,
+ "hrefNormalized":true,
+ "opacity":true,
+ "cssFloat":true,
+ "checkOn":true,
+ "optSelected":true,
+ "getSetAttribute":true,
+ "enctype":true,
+ "html5Clone":true,
+ "submitBubbles":true,
+ "changeBubbles":true,
+ "focusinBubbles":false,
+ "deleteExpando":true,
+ "noCloneEvent":true,
+ "inlineBlockNeedsLayout":false,
+ "shrinkWrapBlocks":false,
+ "reliableMarginRight":true,
+ "noCloneChecked":true,
+ "optDisabled":true,
+ "radioValue":true,
+ "checkClone":true,
+ "appendChecked":true,
+ "boxModel":true,
+ "reliableHiddenOffsets":true,
+ "ajax":true,
+ "cors":true,
+ "doesNotAddBorder":true,
+ "doesAddBorderForTableAndCells":false,
+ "fixedPosition":true,
+ "subtractsBorderForOverflowNotVisible":false,
+ "doesNotIncludeMarginInBodyOffset":true
+ };
+ for ( i in expected ) {
+ equal( jQuery.support[i], expected[i], "jQuery.support['" + i + "']: " + jQuery.support[i] + ", expected['" + i + "']: " + expected[i]);
+ }
+ });
+} else if ( /msie 8\.0/i.test(userAgent) ) {
+ test("Verify that the support tests resolve as expected per browser", function() {
+ var i,
+ expected = {
+ "leadingWhitespace":false,
+ "tbody":true,
+ "htmlSerialize":false,
+ "style":false,
+ "hrefNormalized":true,
+ "opacity":false,
+ "cssFloat":false,
+ "checkOn":true,
+ "optSelected":false,
+ "getSetAttribute":true,
+ "enctype":true,
+ "html5Clone":false,
+ "submitBubbles":false,
+ "changeBubbles":false,
+ "focusinBubbles":true,
+ "deleteExpando":false,
+ "noCloneEvent":false,
+ "inlineBlockNeedsLayout":false,
+ "shrinkWrapBlocks":false,
+ "reliableMarginRight":true,
+ "noCloneChecked":false,
+ "optDisabled":true,
+ "radioValue":false,
+ "checkClone":true,
+ "appendChecked":true,
+ "boxModel":true,
+ "reliableHiddenOffsets":false,
+ "ajax":true,
+ "cors":false,
+ "doesNotAddBorder":false,
+ "doesAddBorderForTableAndCells":true,
+ "fixedPosition":true,
+ "subtractsBorderForOverflowNotVisible":false,
+ "doesNotIncludeMarginInBodyOffset":true
+ };
+ for ( i in expected ) {
+ equal( jQuery.support[i], expected[i], "jQuery.support['" + i + "']: " + jQuery.support[i] + ", expected['" + i + "']: " + expected[i]);
+ }
+ });
+} else if ( /msie 7\.0/i.test(userAgent) ) {
+ test("Verify that the support tests resolve as expected per browser", function() {
+ var i,
+ expected = {
+ "ajax": true,
+ "appendChecked": false,
+ "boxModel": true,
+ "changeBubbles": false,
+ "checkClone": false,
+ "checkOn": true,
+ "cors": false,
+ "cssFloat": false,
+ "deleteExpando": false,
+ "doesAddBorderForTableAndCells": true,
+ "doesNotAddBorder": true,
+ "doesNotIncludeMarginInBodyOffset": true,
+ "enctype": true,
+ "fixedPosition": true,
+ "focusinBubbles": true,
+ "getSetAttribute": false,
+ "hrefNormalized": false,
+ "html5Clone": false,
+ "htmlSerialize": false,
+ "inlineBlockNeedsLayout": true,
+ "leadingWhitespace": false,
+ "noCloneChecked": false,
+ "noCloneEvent": false,
+ "opacity": false,
+ "optDisabled": true,
+ "optSelected": false,
+ "radioValue": false,
+ "reliableHiddenOffsets": false,
+ "reliableMarginRight": true,
+ "shrinkWrapBlocks": false,
+ "submitBubbles": false,
+ "subtractsBorderForOverflowNotVisible": false,
+ "tbody": false,
+ "style": false
+ };
+ for ( i in expected ) {
+ equal( jQuery.support[i], expected[i], "jQuery.support['" + i + "']: " + jQuery.support[i] + ", expected['" + i + "']: " + expected[i]);
+ }
+ });
+} else if ( /msie 6\.0/i.test(userAgent) ) {
+ test("Verify that the support tests resolve as expected per browser", function() {
+ var i,
+ expected = {
+ "leadingWhitespace":false,
+ "tbody":false,
+ "htmlSerialize":false,
+ "style":false,
+ "hrefNormalized":false,
+ "opacity":false,
+ "cssFloat":false,
+ "checkOn":true,
+ "optSelected":false,
+ "getSetAttribute":false,
+ "enctype":true,
+ "html5Clone":false,
+ "submitBubbles":false,
+ "changeBubbles":false,
+ "focusinBubbles":true,
+ "deleteExpando":false,
+ "noCloneEvent":false,
+ "inlineBlockNeedsLayout":true,
+ "shrinkWrapBlocks":true,
+ "reliableMarginRight":true,
+ "noCloneChecked":false,
+ "optDisabled":true,
+ "radioValue":false,
+ "checkClone":false,
+ "appendChecked":false,
+ "boxModel":true,
+ "reliableHiddenOffsets":false,
+ "ajax":true,
+ "cors":false,
+ "doesNotAddBorder":true,
+ "doesAddBorderForTableAndCells":true,
+ "fixedPosition":false,
+ "subtractsBorderForOverflowNotVisible":false,
+ "doesNotIncludeMarginInBodyOffset":true
+ };
+ for ( i in expected ) {
+ equal( jQuery.support[i], expected[i], "jQuery.support['" + i + "']: " + jQuery.support[i] + ", expected['" + i + "']: " + expected[i]);
+ }
+ });
+} else if ( /5\.1\.1 safari/i.test(userAgent) ) {
+ test("Verify that the support tests resolve as expected per browser", function() {
+ var i,
+ expected = {
+ "leadingWhitespace":true,
+ "tbody":true,
+ "htmlSerialize":true,
+ "style":true,
+ "hrefNormalized":true,
+ "opacity":true,
+ "cssFloat":true,
+ "checkOn":false,
+ "optSelected":true,
+ "getSetAttribute":true,
+ "enctype":true,
+ "html5Clone":true,
+ "submitBubbles":true,
+ "changeBubbles":true,
+ "focusinBubbles":false,
+ "deleteExpando":true,
+ "noCloneEvent":true,
+ "inlineBlockNeedsLayout":false,
+ "shrinkWrapBlocks":false,
+ "reliableMarginRight":true,
+ "noCloneChecked":true,
+ "optDisabled":true,
+ "radioValue":true,
+ "checkClone":true,
+ "appendChecked":true,
+ "boxModel":true,
+ "reliableHiddenOffsets":true,
+ "ajax":true,
+ "cors":true,
+ "doesNotAddBorder":true,
+ "doesAddBorderForTableAndCells":false,
+ "fixedPosition":true,
+ "subtractsBorderForOverflowNotVisible":false,
+ "doesNotIncludeMarginInBodyOffset":true
+ };
+ for ( i in expected ) {
+ equal( jQuery.support[i], expected[i], "jQuery.support['" + i + "']: " + jQuery.support[i] + ", expected['" + i + "']: " + expected[i]);
+ }
+ });
+} else if ( /firefox\/3\.6/i.test(userAgent) ) {
+ test("Verify that the support tests resolve as expected per browser", function() {
+ var i,
+ expected = {
+ "leadingWhitespace":true,
+ "tbody":true,
+ "htmlSerialize":true,
+ "style":true,
+ "hrefNormalized":true,
+ "opacity":true,
+ "cssFloat":true,
+ "checkOn":true,
+ "optSelected":true,
+ "getSetAttribute":true,
+ "enctype":false,
+ "html5Clone":true,
+ "submitBubbles":true,
+ "changeBubbles":true,
+ "focusinBubbles":false,
+ "deleteExpando":true,
+ "noCloneEvent":true,
+ "inlineBlockNeedsLayout":false,
+ "shrinkWrapBlocks":false,
+ "reliableMarginRight":true,
+ "noCloneChecked":true,
+ "optDisabled":true,
+ "radioValue":true,
+ "checkClone":true,
+ "appendChecked":true,
+ "boxModel":true,
+ "reliableHiddenOffsets":true,
+ "ajax":true,
+ "cors":true,
+ "doesNotAddBorder":true,
+ "doesAddBorderForTableAndCells":true,
+ "fixedPosition":true,
+ "subtractsBorderForOverflowNotVisible":false,
+ "doesNotIncludeMarginInBodyOffset":true
+ };
+ for ( i in expected ) {
+ equal( jQuery.support[i], expected[i], "jQuery.support['" + i + "']: " + jQuery.support[i] + ", expected['" + i + "']: " + expected[i]);
+ }
+ });
+}

18 comments on commit 3d6237e

@mikesherov
Collaborator

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

@timmywil
Collaborator

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

@rwaldron
Collaborator

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

@mikesherov
Collaborator

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

@rwaldron
Collaborator

These tests are great.

@rwaldron
Collaborator

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

@jdalton

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

@mikesherov
Collaborator

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

@mikesherov
Collaborator

body is not defined before this.

@timmywil
Collaborator

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?

@timmywil
Collaborator

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

@rwaldron
Collaborator

@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

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

@rwaldron
Collaborator

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

@rdworth

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
Collaborator

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

@rwaldron
Collaborator

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

@timmywil
Collaborator

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

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

@rwaldron
Collaborator

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

@eddiemonge

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
Collaborator

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

@mikesherov
Collaborator
@rdworth

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

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

@rwaldron
Collaborator

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

Please sign in to comment.
Something went wrong with that request. Please try again.