]> source.dussan.org Git - jquery.git/commitdiff
Fix #12904: Firefox defaultDisplay with body/iframe display:none. Report and solution...
authorRichard Gibson <richard.gibson@gmail.com>
Sat, 8 Dec 2012 23:04:13 +0000 (18:04 -0500)
committerRichard Gibson <richard.gibson@gmail.com>
Sat, 8 Dec 2012 23:04:13 +0000 (18:04 -0500)
src/css.js
test/unit/css.js

index 334e31a9268df5f0c3f78b2869c5ccf945d3766a..c9a1ab4335752f3e2fa7d565309ebe5647ec9052 100644 (file)
@@ -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;
 }
 
index 94d972793b371d3d359920851f2853e87755d967..c90011687fbe8a6b601ff61fe396d03f64430c4a 100644 (file)
@@ -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" );
 });
 
 }