Permalink
Browse files

Fix #12904: Firefox defaultDisplay with body/iframe display:none. Rep…

…ort and solution by @maranomynet; test by @rwldrn.
  • Loading branch information...
1 parent 23d7cf0 commit d343e6b9ed501052f1676694d5e53649c92e65a0 @gibson042 gibson042 committed Dec 8, 2012
Showing with 60 additions and 52 deletions.
  1. +29 −35 src/css.js
  2. +31 −17 test/unit/css.js
View
@@ -1,4 +1,4 @@
-var curCSS, iframe, iframeDoc,
+var curCSS, iframe,
ralpha = /alpha\([^)]*\)/i,
ropacity = /opacity\s*=\s*([^)]*)/,
rposition = /^(top|right|bottom|left)$/,
@@ -446,44 +446,38 @@ function getWidthOrHeight( elem, name, extra ) {
// Try to determine the default display value of an element
function css_defaultDisplay( nodeName ) {
- if ( elemdisplay[ nodeName ] ) {
- return elemdisplay[ nodeName ];
- }
-
- var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
- display = elem.css("display");
- elem.remove();
-
- // If the simple way fails,
- // get element's real default display by attaching it to a temp iframe
- if ( display === "none" || display === "" ) {
- // Use the already-created iframe if possible
- iframe = document.body.appendChild(
- iframe || jQuery.extend( document.createElement("iframe"), {
- frameBorder: 0,
- width: 0,
- height: 0
- })
- );
-
- // Create a cacheable copy of the iframe document on first call.
- // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
- // document to it; WebKit & Firefox won't allow reusing the iframe document.
- if ( !iframeDoc || !iframe.createElement ) {
- iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
- iframeDoc.write("<!doctype html><html><body>");
- iframeDoc.close();
+ var elem,
+ doc = document,
+ display = elemdisplay[ nodeName ];
+
+ if ( !display ) {
+ elem = jQuery( doc.createElement( nodeName ) );
+ display = curCSS( elem.appendTo( doc.body )[0], "display" );
+ elem.remove();
+
+ // If the simple way fails, read from inside an iframe
+ if ( display === "none" || !display ) {
+ // Use the already-created iframe if possible
+ iframe = ( iframe ||
+ jQuery("<iframe frameborder='0' width='0' height='0'/>")
+ .css( "cssText", "display:block !important" )
+ ).appendTo( doc.documentElement );
+
+ // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+ doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
+ doc.write("<!doctype html><html><body>");
+ doc.close();
+
+ elem = jQuery( doc.createElement( nodeName ) );
+ display = curCSS( elem.appendTo( doc.body )[0], "display" );
+ elem.remove();
+ iframe.detach();
}
- elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
-
- display = curCSS( elem, "display" );
- document.body.removeChild( iframe );
+ // Store the correct default display
+ elemdisplay[ nodeName ] = display;
}
- // Store the correct default display
- elemdisplay[ nodeName ] = display;
-
return display;
}
View
@@ -574,19 +574,33 @@ test( "show() resolves correct default display for detached nodes", function(){
test("show() resolves correct default display #10227", function() {
expect(2);
- jQuery("html").append(
+ var body = jQuery("body");
+ body.append(
"<p id='ddisplay'>a<style>body{display:none}</style></p>"
);
- equal( jQuery("body").css("display"), "none", "Initial display: none" );
+ equal( body.css("display"), "none", "Initial display: none" );
- jQuery("body").show();
-
- equal( jQuery("body").css("display"), "block", "Correct display: block" );
+ body.show();
+ equal( body.css("display"), "block", "Correct display: block" );
jQuery("#ddisplay").remove();
+ QUnit.expectJqData( body[0], "olddisplay" );
+});
+
+test("show() resolves correct default display when iframe display:none #12904", function() {
+ expect(2);
+
+ var ddisplay = jQuery(
+ "<p id='ddisplay'>a<style>p{display:none}iframe{display:none !important}</style></p>"
+ ).appendTo("body");
+
+ equal( ddisplay.css("display"), "none", "Initial display: none" );
+
+ ddisplay.show();
+ equal( ddisplay.css("display"), "block", "Correct display: block" );
- jQuery.cache = {};
+ ddisplay.remove();
});
test("toggle()", function() {
@@ -871,17 +885,17 @@ test( "cssHooks - expand", function() {
test( "css opacity consistency across browsers (#12685)", function() {
expect( 4 );
- var fixture = jQuery("#qunit-fixture"),
- style = jQuery("<style>.opacityWithSpaces_t12685 { opacity: 0.1; filter: alpha(opacity = 10); } .opacityNoSpaces_t12685 { opacity: 0.2; filter: alpha(opacity=20); }</style>").appendTo(fixture),
- el = jQuery("<div class='opacityWithSpaces_t12685'></div>").appendTo(fixture);
-
- equal( Math.round( el.css("opacity") * 100 ), 10, "opacity from style sheet (filter:alpha with spaces)" );
- el.removeClass("opacityWithSpaces_t12685").addClass("opacityNoSpaces_t12685");
- equal( Math.round( el.css("opacity") * 100 ), 20, "opacity from style sheet (filter:alpha without spaces)" );
- el.css( "opacity", 0.3 );
- equal( Math.round( el.css("opacity") * 100 ), 30, "override opacity" );
- el.css( "opacity", "" );
- equal( Math.round( el.css("opacity") * 100 ), 20, "remove opacity override" );
+ var fixture = jQuery("#qunit-fixture"),
+ style = jQuery("<style>.opacityWithSpaces_t12685 { opacity: 0.1; filter: alpha(opacity = 10); } .opacityNoSpaces_t12685 { opacity: 0.2; filter: alpha(opacity=20); }</style>").appendTo(fixture),
+ el = jQuery("<div class='opacityWithSpaces_t12685'></div>").appendTo(fixture);
+
+ equal( Math.round( el.css("opacity") * 100 ), 10, "opacity from style sheet (filter:alpha with spaces)" );
+ el.removeClass("opacityWithSpaces_t12685").addClass("opacityNoSpaces_t12685");
+ equal( Math.round( el.css("opacity") * 100 ), 20, "opacity from style sheet (filter:alpha without spaces)" );
+ el.css( "opacity", 0.3 );
+ equal( Math.round( el.css("opacity") * 100 ), 30, "override opacity" );
+ el.css( "opacity", "" );
+ equal( Math.round( el.css("opacity") * 100 ), 20, "remove opacity override" );
});
}

0 comments on commit d343e6b

Please sign in to comment.