Commit d343e6b9 authored by Richard Gibson's avatar Richard Gibson

Fix #12904: Firefox defaultDisplay with body/iframe display:none. Report and...

Fix #12904: Firefox defaultDisplay with body/iframe display:none. Report and solution by @maranomynet; test by @rwldrn.
parent 23d7cf04
var curCSS, iframe, iframeDoc, var curCSS, iframe,
ralpha = /alpha\([^)]*\)/i, ralpha = /alpha\([^)]*\)/i,
ropacity = /opacity\s*=\s*([^)]*)/, ropacity = /opacity\s*=\s*([^)]*)/,
rposition = /^(top|right|bottom|left)$/, rposition = /^(top|right|bottom|left)$/,
...@@ -446,44 +446,38 @@ function getWidthOrHeight( elem, name, extra ) { ...@@ -446,44 +446,38 @@ function getWidthOrHeight( elem, name, extra ) {
// Try to determine the default display value of an element // Try to determine the default display value of an element
function css_defaultDisplay( nodeName ) { function css_defaultDisplay( nodeName ) {
if ( elemdisplay[ nodeName ] ) { var elem,
return elemdisplay[ nodeName ]; doc = document,
} display = elemdisplay[ nodeName ];
var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), if ( !display ) {
display = elem.css("display"); elem = jQuery( doc.createElement( nodeName ) );
elem.remove(); display = curCSS( elem.appendTo( doc.body )[0], "display" );
elem.remove();
// If the simple way fails,
// get element's real default display by attaching it to a temp iframe // If the simple way fails, read from inside an iframe
if ( display === "none" || display === "" ) { if ( display === "none" || !display ) {
// Use the already-created iframe if possible // Use the already-created iframe if possible
iframe = document.body.appendChild( iframe = ( iframe ||
iframe || jQuery.extend( document.createElement("iframe"), { jQuery("<iframe frameborder='0' width='0' height='0'/>")
frameBorder: 0, .css( "cssText", "display:block !important" )
width: 0, ).appendTo( doc.documentElement );
height: 0
}) // 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>");
// Create a cacheable copy of the iframe document on first call. doc.close();
// 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. elem = jQuery( doc.createElement( nodeName ) );
if ( !iframeDoc || !iframe.createElement ) { display = curCSS( elem.appendTo( doc.body )[0], "display" );
iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; elem.remove();
iframeDoc.write("<!doctype html><html><body>"); iframe.detach();
iframeDoc.close();
} }
elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); // Store the correct default display
elemdisplay[ nodeName ] = display;
display = curCSS( elem, "display" );
document.body.removeChild( iframe );
} }
// Store the correct default display
elemdisplay[ nodeName ] = display;
return display; return display;
} }
......
...@@ -574,19 +574,33 @@ test( "show() resolves correct default display for detached nodes", function(){ ...@@ -574,19 +574,33 @@ test( "show() resolves correct default display for detached nodes", function(){
test("show() resolves correct default display #10227", function() { test("show() resolves correct default display #10227", function() {
expect(2); expect(2);
jQuery("html").append( var body = jQuery("body");
body.append(
"<p id='ddisplay'>a<style>body{display:none}</style></p>" "<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(); body.show();
equal( body.css("display"), "block", "Correct display: block" );
equal( jQuery("body").css("display"), "block", "Correct display: block" );
jQuery("#ddisplay").remove(); 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() { test("toggle()", function() {
...@@ -871,17 +885,17 @@ test( "cssHooks - expand", function() { ...@@ -871,17 +885,17 @@ test( "cssHooks - expand", function() {
test( "css opacity consistency across browsers (#12685)", function() { test( "css opacity consistency across browsers (#12685)", function() {
expect( 4 ); expect( 4 );
var fixture = jQuery("#qunit-fixture"), 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), 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); 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)" ); equal( Math.round( el.css("opacity") * 100 ), 10, "opacity from style sheet (filter:alpha with spaces)" );
el.removeClass("opacityWithSpaces_t12685").addClass("opacityNoSpaces_t12685"); el.removeClass("opacityWithSpaces_t12685").addClass("opacityNoSpaces_t12685");
equal( Math.round( el.css("opacity") * 100 ), 20, "opacity from style sheet (filter:alpha without spaces)" ); equal( Math.round( el.css("opacity") * 100 ), 20, "opacity from style sheet (filter:alpha without spaces)" );
el.css( "opacity", 0.3 ); el.css( "opacity", 0.3 );
equal( Math.round( el.css("opacity") * 100 ), 30, "override opacity" ); equal( Math.round( el.css("opacity") * 100 ), 30, "override opacity" );
el.css( "opacity", "" ); el.css( "opacity", "" );
equal( Math.round( el.css("opacity") * 100 ), 20, "remove opacity override" ); equal( Math.round( el.css("opacity") * 100 ), 20, "remove opacity override" );
}); });
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment