Bug 1541253 - Check PresShell::IsUnderHiddenEmbedderElement where we need to check CSS visibility state across the document boundary. r=tnikkel
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 10 May 2019 11:22:28 +0000
changeset 473383 57c522abe28f6d78f646d90c720022057205666c
parent 473382 335b9a8f496819c5777c0f67eff5f88bf983288b
child 473384 c052518818dff9b913814d785606a0d11ec65e4e
push id35996
push userdvarga@mozilla.com
push dateFri, 10 May 2019 21:46:48 +0000
treeherdermozilla-central@362df4629f8f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1541253
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1541253 - Check PresShell::IsUnderHiddenEmbedderElement where we need to check CSS visibility state across the document boundary. r=tnikkel Depends on D26252 Differential Revision: https://phabricator.services.mozilla.com/D26253
accessible/generic/Accessible.cpp
layout/generic/nsFrame.cpp
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -310,23 +310,29 @@ uint64_t Accessible::VisibilityState() c
     // Element having display:contents is considered visible semantically,
     // despite it doesn't have a visually visible box.
     if (mContent->IsElement() && mContent->AsElement()->IsDisplayContents()) {
       return states::OFFSCREEN;
     }
     return states::INVISIBLE;
   }
 
-  // Walk the parent frame chain to see if there's invisible parent or the frame
-  // is in background tab.
   if (!frame->StyleVisibility()->IsVisible()) return states::INVISIBLE;
 
+  // It's invisible if the presshell is hidden by a visibility:hidden element in
+  // an ancestor document.
+  if (frame->PresShell()->IsUnderHiddenEmbedderElement()) {
+    return states::INVISIBLE;
+  }
+
   // Offscreen state if the document's visibility state is not visible.
   if (Document()->IsHidden()) return states::OFFSCREEN;
 
+  // Walk the parent frame chain to see if the frame is in background tab or
+  // scrolled out.
   nsIFrame* curFrame = frame;
   do {
     nsView* view = curFrame->GetView();
     if (view && view->GetVisibility() == nsViewVisibility_kHide)
       return states::INVISIBLE;
 
     if (nsLayoutUtils::IsPopup(curFrame)) return 0;
 
@@ -361,18 +367,16 @@ uint64_t Accessible::VisibilityState() c
         const nscoord kMinPixels = nsPresContext::CSSPixelsToAppUnits(12);
         scrollPortRect.Deflate(kMinPixels, kMinPixels);
         if (!scrollPortRect.Intersects(frameRect)) return states::OFFSCREEN;
       }
     }
 
     if (!parentFrame) {
       parentFrame = nsLayoutUtils::GetCrossDocParentFrame(curFrame);
-      if (parentFrame && !parentFrame->StyleVisibility()->IsVisible())
-        return states::INVISIBLE;
     }
 
     curFrame = parentFrame;
   } while (curFrame);
 
   // Zero area rects can occur in the first frame of a multi-frame text flow,
   // in which case the rendered text is not empty and the frame should not be
   // marked invisible.
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -388,16 +388,20 @@ bool nsIFrame::CheckAndClearDisplayListS
   return result;
 }
 
 bool nsIFrame::IsVisibleConsideringAncestors(uint32_t aFlags) const {
   if (!StyleVisibility()->IsVisible()) {
     return false;
   }
 
+  if (PresShell()->IsUnderHiddenEmbedderElement()) {
+    return false;
+  }
+
   const nsIFrame* frame = this;
   while (frame) {
     nsView* view = frame->GetView();
     if (view && view->GetVisibility() == nsViewVisibility_kHide) return false;
 
     nsIFrame* parent = frame->GetParent();
     nsDeckFrame* deck = do_QueryFrame(parent);
     if (deck) {
@@ -411,18 +415,16 @@ bool nsIFrame::IsVisibleConsideringAnces
       if (!parent) break;
 
       if ((aFlags & nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY) == 0 &&
           parent->PresContext()->IsChrome() &&
           !frame->PresContext()->IsChrome()) {
         break;
       }
 
-      if (!parent->StyleVisibility()->IsVisible()) return false;
-
       frame = parent;
     }
   }
 
   return true;
 }
 
 void nsIFrame::FindCloserFrameForSelection(