From 02b4894dcab0abb7b97d283e080a4ce8811e879e Mon Sep 17 00:00:00 2001 From: Morgan Reschenberg Date: Wed, 20 Oct 2021 14:49:14 +0000 Subject: [PATCH] Bug 1733440: Adjust RemoteAccessibleBase::Bounds for root relative coordinates r=Jamie Differential Revision: https://phabricator.services.mozilla.com/D127848 --- accessible/generic/LocalAccessible.cpp | 34 +++++++++++-- accessible/tests/browser/bounds/browser.ini | 1 + .../bounds/browser_test_display_contents.js | 48 +++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 accessible/tests/browser/bounds/browser_test_display_contents.js diff --git a/accessible/generic/LocalAccessible.cpp b/accessible/generic/LocalAccessible.cpp index 6fa745d344de..38be6d1929eb 100644 --- a/accessible/generic/LocalAccessible.cpp +++ b/accessible/generic/LocalAccessible.cpp @@ -646,12 +646,40 @@ nsRect LocalAccessible::ParentRelativeBounds() { } } - if (mParent) { - boundingFrame = mParent->GetFrame(); + // We need to find a frame to make our bounds relative to. We'll store this + // in `boundingFrame`. Ultimately, we'll create screen-relative coordinates + // by summing the x, y offsets of our ancestors' bounds in + // RemoteAccessibleBase::Bounds(), so it is important that our bounding + // frame have a corresponding accessible. + if (IsDoc() && + nsCoreUtils::IsTopLevelContentDocInProcess(AsDoc()->DocumentNode())) { + // Tab documents and OOP iframe docs won't have ancestor accessibles with + // frames. We'll use their presshell root frame instead. + // XXX bug 1736635: Should DocAccessibles return their presShell frame on + // GetFrame()? + boundingFrame = nsLayoutUtils::GetContainingBlockForClientRect(frame); + } + + // Iterate through ancestors to find one with a frame. + LocalAccessible* parent = mParent; + while (parent && !boundingFrame) { + if (parent->IsDoc()) { + // If we find a doc accessible, use its presshell's root frame + // (since doc accessibles themselves don't have frames). + boundingFrame = nsLayoutUtils::GetContainingBlockForClientRect(frame); + break; + } + + if ((boundingFrame = parent->GetFrame())) { + // Otherwise, if the parent has a frame, use that + break; + } + + parent = parent->LocalParent(); } if (!boundingFrame) { - // if we can't get the bounding frame, use the pres shell root + MOZ_ASSERT_UNREACHABLE("No ancestor with frame?"); boundingFrame = nsLayoutUtils::GetContainingBlockForClientRect(frame); } diff --git a/accessible/tests/browser/bounds/browser.ini b/accessible/tests/browser/bounds/browser.ini index 4bd25fbefc8c..5b0fcc6d31ff 100644 --- a/accessible/tests/browser/bounds/browser.ini +++ b/accessible/tests/browser/bounds/browser.ini @@ -14,3 +14,4 @@ skip-if = webrender # Bug 1734271 https_first_disabled = true skip-if = e10s && os == 'win' # bug 1372296 [browser_zero_area.js] +[browser_test_display_contents.js] diff --git a/accessible/tests/browser/bounds/browser_test_display_contents.js b/accessible/tests/browser/bounds/browser_test_display_contents.js new file mode 100644 index 000000000000..881eaa5c7ecc --- /dev/null +++ b/accessible/tests/browser/bounds/browser_test_display_contents.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +/* import-globals-from ../../mochitest/layout.js */ + +async function testContentBounds(browser, acc) { + let [ + expectedX, + expectedY, + expectedWidth, + expectedHeight, + ] = await getContentBoundsForDOMElm(browser, getAccessibleDOMNodeID(acc)); + + let contentDPR = await getContentDPR(browser); + let [x, y, width, height] = getBounds(acc, contentDPR); + let prettyAccName = prettyName(acc); + is(x, expectedX, "Wrong x coordinate of " + prettyAccName); + is(y, expectedY, "Wrong y coordinate of " + prettyAccName); + is(width, expectedWidth, "Wrong width of " + prettyAccName); + ok(height >= expectedHeight, "Wrong height of " + prettyAccName); +} + +async function runTests(browser, accDoc) { + let p = findAccessibleChildByID(accDoc, "div"); + let p2 = findAccessibleChildByID(accDoc, "p"); + + await testContentBounds(browser, p); + await testContentBounds(browser, p2); +} + +/** + * Test accessible bounds for accs with display:contents + */ +addAccessibleTask( + ` +
before + +
`, + runTests, + { iframe: true, remoteIframe: true } +);