Portals: Ignore AX objects in portal subtree

Bug: 1066200, 1045608
Change-Id: I953209f3da2799fdf8b4383794023c33b010dab7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2134615
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Adithya Srinivasan <adithyas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756795}
diff --git a/content/test/data/accessibility/html/portal-expected-blink.txt b/content/test/data/accessibility/html/portal-expected-blink.txt
index efabb3c1..e65e79ad 100644
--- a/content/test/data/accessibility/html/portal-expected-blink.txt
+++ b/content/test/data/accessibility/html/portal-expected-blink.txt
@@ -5,6 +5,7 @@
 ++++++++inlineTextBox name='Before portal'
 ++++portal focusable name='portal'
 ++++++rootWebArea name='Text in iframe'
+++++++++genericContainer ignored
 ++++paragraph
 ++++++staticText name='After portal'
 ++++++++inlineTextBox name='After portal'
diff --git a/content/test/data/accessibility/html/portal-name-from-text-expected-blink.txt b/content/test/data/accessibility/html/portal-name-from-text-expected-blink.txt
index 405b4c4..e4147eaa 100644
--- a/content/test/data/accessibility/html/portal-name-from-text-expected-blink.txt
+++ b/content/test/data/accessibility/html/portal-name-from-text-expected-blink.txt
@@ -2,3 +2,4 @@
 ++genericContainer
 ++++portal
 ++++++rootWebArea name='Text in iframe'
+++++++++genericContainer ignored
diff --git a/content/test/data/accessibility/html/portal-name-from-visible-text-expected-blink.txt b/content/test/data/accessibility/html/portal-name-from-visible-text-expected-blink.txt
index 5ff2a3d1..0dae2e0 100644
--- a/content/test/data/accessibility/html/portal-name-from-visible-text-expected-blink.txt
+++ b/content/test/data/accessibility/html/portal-name-from-visible-text-expected-blink.txt
@@ -2,3 +2,7 @@
 ++genericContainer
 ++++portal
 ++++++rootWebArea name='visible text'
+++++++++genericContainer ignored
+++++++++++genericContainer ignored
+++++++++++genericContainer ignored
+++++++++++genericContainer ignored
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 1806def4..110c4e7c 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -189,6 +189,15 @@
     return kIgnoreObject;
   }
 
+  // Objects inside a portal should be ignored. Portals don't directly expose
+  // their contents as the contents are not focusable (portals do not currently
+  // support input events). Portals do use their contents to compute a default
+  // accessible name.
+  if (GetDocument() && GetDocument()->GetPage() &&
+      GetDocument()->GetPage()->InsidePortal()) {
+    return kIgnoreObject;
+  }
+
   if (IsTableLikeRole() || IsTableRowLikeRole() || IsTableCellLikeRole())
     return kIncludeObject;
 
@@ -2972,12 +2981,6 @@
   if (GetNode() && IsA<HTMLMapElement>(GetNode()))
     return false;  // Does not have a role, so check here
 
-  // The AXTree of a portal should only have one node: the root document node.
-  if (GetNode() && GetNode()->IsDocumentNode() &&
-      GetNode()->GetDocument().GetPage() &&
-      GetNode()->GetDocument().GetPage()->InsidePortal())
-    return false;
-
   switch (native_role_) {
     case ax::mojom::Role::kCheckBox:
     case ax::mojom::Role::kImage:
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index 8673b9e1..8982c381 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1346,15 +1346,12 @@
   if (IsDetached())
     return false;
 
-  // NOT focusable: anything inside a <portal> (the portal element itself is).
-  if (GetDocument() && GetDocument()->GetPage() &&
-      GetDocument()->GetPage()->InsidePortal()) {
-    return false;
-  }
-
-  // Focusable: web area -- this is the only focusable non-element.
+  bool inside_portal = GetDocument() && GetDocument()->GetPage() &&
+                       GetDocument()->GetPage()->InsidePortal();
+  // Focusable: web area -- this is the only focusable non-element. Web areas
+  // inside portals are not focusable though (portal contents cannot get focus).
   if (IsWebArea())
-    return true;
+    return !inside_portal;
 
   // NOT focusable: objects with no DOM node, e.g. extra layout blocks inserted
   // as filler, or objects where the node is not an element, such as a text