Permalink
Browse files

CSS: Ignore the CSS cascade in show()/hide()/etc.

Fixes gh-1767
Fixes gh-2071
Closes gh-2180
  • Loading branch information...
gibson042 committed Apr 2, 2015
1 parent 5c3101f commit 86419b10bfa5e3b71a7d416288ab806d47a31d1f
Showing with 379 additions and 429 deletions.
  1. +2 −62 src/css.js
  2. +0 −71 src/css/defaultDisplay.js
  3. +47 −0 src/css/showHide.js
  4. +102 −76 src/effects.js
  5. +2 −10 test/data/testsuite.css
  6. +58 −117 test/unit/css.js
  7. +168 −93 test/unit/effects.js
View
@@ -11,16 +11,15 @@ define([
"./css/var/swap",
"./css/curCSS",
"./css/adjustCSS",
"./css/defaultDisplay",
"./css/addGetHookIf",
"./css/support",
"./data/var/dataPriv",
"./css/showHide",
"./core/init",
"./core/ready",
"./selector" // contains
], function( jQuery, pnum, access, rmargin, rcssNum, rnumnonpx, cssExpand, isHidden,
getStyles, swap, curCSS, adjustCSS, defaultDisplay, addGetHookIf, support, dataPriv ) {
getStyles, swap, curCSS, adjustCSS, addGetHookIf, support, showHide ) {
var
// Swappable if display is none or starts with table
@@ -151,65 +150,6 @@ function getWidthOrHeight( elem, name, extra ) {
) + "px";
}
function showHide( elements, show ) {
var display, elem, hidden,
values = [],
index = 0,
length = elements.length;
for ( ; index < length; index++ ) {
elem = elements[ index ];
if ( !elem.style ) {
continue;
}
values[ index ] = dataPriv.get( elem, "olddisplay" );
display = elem.style.display;
if ( show ) {
// Reset the inline display of this element to learn if it is
// being hidden by cascaded rules or not
if ( !values[ index ] && display === "none" ) {
elem.style.display = "";
}
// Set elements which have been overridden with display: none
// in a stylesheet to whatever the default browser style is
// for such an element
if ( elem.style.display === "" && isHidden( elem ) ) {
values[ index ] = dataPriv.access(
elem,
"olddisplay",
defaultDisplay(elem.nodeName)
);
}
} else {
hidden = isHidden( elem );
if ( display !== "none" || !hidden ) {
dataPriv.set(
elem,
"olddisplay",
hidden ? display : jQuery.css( elem, "display" )
);
}
}
}
// Set the display of most of the elements in a second loop
// to avoid the constant reflow
for ( index = 0; index < length; index++ ) {
elem = elements[ index ];
if ( !elem.style ) {
continue;
}
if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
elem.style.display = show ? values[ index ] || "" : "none";
}
}
return elements;
}
jQuery.extend({
// Add in style property hooks for overriding the default
View
@@ -1,71 +0,0 @@
define([
"../core",
"../var/document",
"../manipulation" // appendTo
], function( jQuery, document ) {
var iframe,
elemdisplay = {
// Support: Firefox
// We have to pre-define these values for FF (#10227)
HTML: "block",
BODY: "block"
};
/**
* Retrieve the actual display of a element
* @param {String} name nodeName of the element
* @param {Object} doc Document object
*/
// Called only from within defaultDisplay
function actualDisplay( name, doc ) {
var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
display = jQuery.css( elem[ 0 ], "display" );
// We don't have any data stored on the element,
// so use "detach" method as fast way to get rid of the element
elem.detach();
return display;
}
/**
* Try to determine the default display value of an element
* @param {String} nodeName
*/
function defaultDisplay( nodeName ) {
var doc = document,
display = elemdisplay[ nodeName ];
if ( !display ) {
display = actualDisplay( nodeName, doc );
// 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'/>" ))
.appendTo( doc.documentElement );
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
doc = iframe[ 0 ].contentDocument;
// Support: IE
doc.write();
doc.close();
display = actualDisplay( nodeName, doc );
iframe.detach();
}
// Store the correct default display
elemdisplay[ nodeName ] = display;
}
return display;
}
return defaultDisplay;
});
View
@@ -0,0 +1,47 @@
define([
"../data/var/dataPriv"
], function( dataPriv ) {
function showHide( elements, show ) {
var display, elem,
values = [],
index = 0,
length = elements.length;
// Determine new display value for elements that need to change
for ( ; index < length; index++ ) {
elem = elements[ index ];
if ( !elem.style ) {
continue;
}
display = elem.style.display;
if ( show ) {
if ( display === "none" ) {
// Restore a pre-hide() value if we have one
values[ index ] = dataPriv.get( elem, "display" ) || "";
}
} else {
if ( display !== "none" ) {
values[ index ] = "none";
// Remember the value we're replacing
dataPriv.set( elem, "display", display );
}
}
}
// Set the display of the elements in a second loop
// to avoid the constant reflow
for ( index = 0; index < length; index++ ) {
if ( values[ index ] != null ) {
elements[ index ].style.display = values[ index ];
}
}
return elements;
}
return showHide;
});
Oops, something went wrong.

2 comments on commit 86419b1

@phistuck

This comment has been minimized.

Show comment
Hide comment
@phistuck

phistuck May 13, 2015

Please, revert this. This breaks $(element).slideDown() where element is display: none using a class (or any other CSS rule) and does not have any inline style that suggests it is display: none. The element will not slide down.
I will be creating an issue shortly.

phistuck replied May 13, 2015

Please, revert this. This breaks $(element).slideDown() where element is display: none using a class (or any other CSS rule) and does not have any inline style that suggests it is display: none. The element will not slide down.
I will be creating an issue shortly.

@phistuck

This comment has been minimized.

Show comment
Hide comment
@phistuck

phistuck May 13, 2015

Scratch that - it happens whenever the element is display: none, whether as an inline style or not.

phistuck replied May 13, 2015

Scratch that - it happens whenever the element is display: none, whether as an inline style or not.

Please sign in to comment.