Fix :visible does not work properly when display:none is set directly on an element...
authorColin Snover <github.com@zetafleet.com>
Tue, 5 Oct 2010 18:23:10 +0000 (13:23 -0500)
committerColin Snover <github.com@zetafleet.com>
Tue, 5 Oct 2010 18:23:10 +0000 (13:23 -0500)
src/css.js
src/support.js
test/unit/css.js

index 4bf818e..8751860 100644 (file)
@@ -280,14 +280,9 @@ function getWH( elem, name, extra ) {
 
 if ( jQuery.expr && jQuery.expr.filters ) {
        jQuery.expr.filters.hidden = function( elem ) {
-               var width = elem.offsetWidth, height = elem.offsetHeight,
-                       skip = elem.nodeName.toLowerCase() === "tr";
-
-               return width === 0 && height === 0 && !skip ?
-                       true :
-                       width > 0 && height > 0 && !skip ?
-                               false :
-                               (elem.style.display || jQuery.css( elem, "display" )) === "none";
+               var width = elem.offsetWidth, height = elem.offsetHeight;
+
+               return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
        };
 
        jQuery.expr.filters.visible = function( elem ) {
index d35dbed..299fbd2 100644 (file)
@@ -65,7 +65,8 @@
                checkClone: false,
                scriptEval: false,
                noCloneEvent: true,
-               boxModel: null
+               boxModel: null,
+               reliableHiddenOffsets: true
        };
 
        // Make sure that the options inside disabled selects aren't marked as disabled
 
                document.body.appendChild( div );
                jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+
+               // 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="display:none"></td><td>t</td></tr></table>';
+               jQuery.support.reliableHiddenOffsets = div.getElementsByTagName('td')[0].offsetHeight === 0;
+               div.innerHTML = '';
+
                document.body.removeChild( div ).style.display = 'none';
                div = null;
        });
index 468f763..cfffb78 100644 (file)
@@ -256,3 +256,16 @@ test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", funct
        ok( !! jQuery(":checkbox:first", $checkedtest).attr("checked"), "Check first checkbox still checked." );
        ok( ! jQuery(":checkbox:last", $checkedtest).attr("checked"), "Check last checkbox still NOT checked." );
 });
+
+test(":visible selector works properly on table elements (bug #4512)", function () {
+       expect(1);
+
+       jQuery('#table').html('<tr><td style="display:none">cell</td><td>cell</td></tr>');
+       equals(jQuery('#table td:visible').length, 1, "hidden cell is not perceived as visible");
+});
+
+test(":visible selector works properly on children with a hidden parent (bug #4512)", function () {
+       expect(1);
+       jQuery('#table').css('display', 'none').html('<tr><td>cell</td><td>cell</td></tr>');
+       equals(jQuery('#table td:visible').length, 0, "hidden cell children not perceived as visible");
+});
\ No newline at end of file