Bug 1572811 - Explicitly check for removed anonymous children in reframe. r=Jamie
☠☠ backed out by 7f41e2dd2f99 ☠ ☠
authorEitan Isaacson <eitan@monotonous.org>
Thu, 15 Aug 2019 16:06:33 +0000
changeset 488261 067d47e20a9439ad81d0b119b1b660c9638ff08e
parent 488260 d3b872e9aca1f511c540704d6354149b737e3d72
child 488262 31f858085f7cbfccf75359c3a583f5b27a33e50a
push id113906
push userncsoregi@mozilla.com
push dateFri, 16 Aug 2019 04:07:24 +0000
treeherdermozilla-inbound@d887276421d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJamie
bugs1572811
milestone70.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 1572811 - Explicitly check for removed anonymous children in reframe. r=Jamie The DOM mutation observer method is called during frame destruction which is not a good state to be in when constructing and dispatching events. Differential Revision: https://phabricator.services.mozilla.com/D41825
accessible/generic/DocAccessible.cpp
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -668,30 +668,20 @@ void DocAccessible::AttributeWillChange(
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_disabled ||
       aAttribute == nsGkAtoms::disabled)
     mStateBitWasOn = accessible->Unavailable();
 }
 
+// We don't use this for insertions or removals because the frame tree
+// may be in a transitional state.
 void DocAccessible::NativeAnonymousChildListChange(nsIContent* aContent,
-                                                   bool aIsRemove) {
-  if (aIsRemove) {
-#ifdef A11Y_LOG
-    if (logging::IsEnabled(logging::eTree)) {
-      logging::MsgBegin("TREE", "Anonymous content removed; doc: %p", this);
-      logging::Node("node", aContent);
-      logging::MsgEnd();
-    }
-#endif
-
-    ContentRemoved(aContent);
-  }
-}
+                                                   bool aIsRemove) {}
 
 void DocAccessible::AttributeChanged(dom::Element* aElement,
                                      int32_t aNameSpaceID, nsAtom* aAttribute,
                                      int32_t aModType,
                                      const nsAttrValue* aOldValue) {
   NS_ASSERTION(!IsDefunct(),
                "Attribute changed called on defunct document accessible!");
 
@@ -1329,16 +1319,32 @@ bool DocAccessible::PruneOrInsertSubtree
     }
 
     // It is a broken image that is being reframed because it either got
     // or lost an `alt` tag that would rerender this node as text.
     if (frame && (acc->IsImage() != (frame->AccessibleType() == eImageType))) {
       ContentRemoved(aRoot);
       return true;
     }
+
+    // Content may have, or may previously have had, anonymous items
+    // that were removed during frame reconstruction. We check here
+    // for any dangling anonymous content and remove their accessibles.
+    if (aRoot->MayHaveAnonymousChildren()) {
+      auto child = acc->FirstChild();
+      while (child) {
+        auto nextChild = child->NextSibling();
+        auto childContent = child->GetContent();
+        if (childContent && childContent->IsInAnonymousSubtree() &&
+            !childContent->GetPrimaryFrame()) {
+          ContentRemoved(child);
+        }
+        child = nextChild;
+      }
+    }
   } else {
     // If there is no current accessible, and the node has a frame, or is
     // display:contents, schedule it for insertion.
     if (aRoot->GetPrimaryFrame() || nsCoreUtils::IsDisplayContents(aRoot)) {
       // This may be a new subtree, the insertion process will recurse through
       // its descendants.
       if (!GetAccessibleOrDescendant(aRoot)) {
         return true;