Bug 1951833 part 2: Make ITextRangeProvider::GetBoundingRectangles return a rectangle for a collapsed range. r=morgan

Differential Revision: https://phabricator.services.mozilla.com/D249710
This commit is contained in:
James Teh
2025-05-20 22:59:07 +00:00
committed by jteh@mozilla.com
parent f66cf4466a
commit 1b591364ab
2 changed files with 79 additions and 1 deletions

View File

@@ -1,3 +1,4 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* 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/. */
@@ -2162,6 +2163,69 @@ addUiaTask(
{ uiaEnabled: true, uiaDisabled: true, chrome: true }
);
/**
* Test the Text pattern's GetBoundingRectangles method with the caret.
*/
addUiaTask(
`
<div id="editable" contenteditable role="textbox">
<div id="ce0">a</div>
<div id="ce1"><br></div>
<div id="ce2">b</div>
</div>
`,
async function testTextRangeGetBoundingRectanglesCaret(browser, docAcc) {
info("Focusing editable");
const editable = findAccessibleChildByID(docAcc, "editable");
const ce0 = findAccessibleChildByID(docAcc, "ce0");
let moved = waitForEvent(EVENT_TEXT_CARET_MOVED, ce0);
editable.takeFocus();
await moved;
await runPython(`
global text
doc = getDocUia()
editable = findUiaByDomId(doc, "editable")
text = getUiaPattern(editable, "Text")
`);
let uiaRects = await runPython(
`text.GetSelection().GetElement(0).GetBoundingRectangles()`
);
testTextPos(ce0, 0, [uiaRects[0], uiaRects[1]], COORDTYPE_SCREEN_RELATIVE);
info("ArrowRight to end of line");
moved = waitForEvent(EVENT_TEXT_CARET_MOVED, ce0);
EventUtils.synthesizeKey("KEY_ArrowRight");
await moved;
uiaRects = await runPython(
`text.GetSelection().GetElement(0).GetBoundingRectangles()`
);
// Bug 1966812: We would ideally return a rect here.
is(uiaRects.length, 0, "GetBoundingRectangles returned nothing");
info("ArrowRight to line feed on blank line");
const ce1 = findAccessibleChildByID(docAcc, "ce1");
moved = waitForEvent(EVENT_TEXT_CARET_MOVED, ce1);
EventUtils.synthesizeKey("KEY_ArrowRight");
await moved;
uiaRects = await runPython(
`text.GetSelection().GetElement(0).GetBoundingRectangles()`
);
testTextPos(ce1, 0, [uiaRects[0], uiaRects[1]], COORDTYPE_SCREEN_RELATIVE);
info("ArrowRight to b");
const ce2 = findAccessibleChildByID(docAcc, "ce2");
moved = waitForEvent(EVENT_TEXT_CARET_MOVED, ce2);
EventUtils.synthesizeKey("KEY_ArrowRight");
await moved;
uiaRects = await runPython(
`text.GetSelection().GetElement(0).GetBoundingRectangles()`
);
testTextPos(ce2, 0, [uiaRects[0], uiaRects[1]], COORDTYPE_SCREEN_RELATIVE);
},
// The IA2 -> UIA proxy doesn't support this.
{ uiaEnabled: true, uiaDisabled: false }
);
/**
* Test the TextRange pattern's ScrollIntoView method.
*/

View File

@@ -703,7 +703,21 @@ UiaTextRange::GetBoundingRectangles(__RPC__deref_out_opt SAFEARRAY** aRetVal) {
}
// Get the rectangles for each line.
const nsTArray<LayoutDeviceIntRect> lineRects = range.LineRects();
nsTArray<LayoutDeviceIntRect> lineRects = range.LineRects();
if (lineRects.IsEmpty() && !mIsEndOfLineInsertionPoint &&
range.Start() == range.End()) {
// The documentation for GetBoundingRectangles says that we should return
// "An empty array for a degenerate range.":
// https://learn.microsoft.com/en-us/windows/win32/api/uiautomationcore/nf-uiautomationcore-itextrangeprovider-getboundingrectangles#return-value
// This is exactly what range.LineRects() just did. However, contrary to
// this, some clients (including Microsoft Text Cursor Indicator) call
// GetBoundingRectangles on a degenerate range when querying the caret and
// expect rectangles to be returned. Therefore, use the character bounds.
// Bug 1966812: Ideally, we would also return a rectangle when
// mIsEndOfLineInsertionPoint is true. However, we don't currently have code
// to calculate a rectangle in that case.
lineRects.AppendElement(range.Start().CharBounds());
}
// For UIA's purposes, the rectangles of this array are four doubles arranged
// in order {left, top, width, height}.