mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1826264 - P2: Add range TextLeafRange::ScrollIntoView. r=Jamie
Use it when caching is enabled. Differential Revision: https://phabricator.services.mozilla.com/D174977
This commit is contained in:
parent
60909e6894
commit
d70f1224fa
@ -532,25 +532,19 @@ static gboolean setCaretOffsetCB(AtkText* aText, gint aOffset) {
|
||||
|
||||
static gboolean scrollSubstringToCB(AtkText* aText, gint aStartOffset,
|
||||
gint aEndOffset, AtkScrollType aType) {
|
||||
AtkObject* atkObject = ATK_OBJECT(aText);
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(atkObject);
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole() ||
|
||||
!text->IsValidRange(aStartOffset, aEndOffset)) {
|
||||
return FALSE;
|
||||
}
|
||||
text->ScrollSubstringTo(aStartOffset, aEndOffset, aType);
|
||||
return TRUE;
|
||||
Accessible* acc = GetInternalObj(ATK_OBJECT(aText));
|
||||
if (!acc) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RemoteAccessible* proxy = GetProxy(atkObject);
|
||||
if (proxy) {
|
||||
proxy->ScrollSubstringTo(aStartOffset, aEndOffset, aType);
|
||||
return TRUE;
|
||||
HyperTextAccessibleBase* text = acc->AsHyperTextBase();
|
||||
if (!text) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
text->ScrollSubstringTo(aStartOffset, aEndOffset, aType);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean scrollSubstringToPointCB(AtkText* aText, gint aStartOffset,
|
||||
|
@ -1858,6 +1858,42 @@ bool TextLeafRange::SetSelection(int32_t aSelectionNum) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void TextLeafRange::ScrollIntoView(uint32_t aScrollType) const {
|
||||
if (!mStart || !mEnd || mStart.mAcc->IsLocal() != mEnd.mAcc->IsLocal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mStart.mAcc->IsRemote()) {
|
||||
DocAccessibleParent* doc = mStart.mAcc->AsRemote()->Document();
|
||||
if (doc != mEnd.mAcc->AsRemote()->Document()) {
|
||||
// Can't scroll range that spans docs.
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << doc->SendScrollTextLeafRangeIntoView(
|
||||
mStart.mAcc->ID(), mStart.mOffset, mEnd.mAcc->ID(), mEnd.mOffset,
|
||||
aScrollType);
|
||||
return;
|
||||
}
|
||||
|
||||
auto [startContent, startContentOffset] = mStart.ToDOMPoint();
|
||||
auto [endContent, endContentOffset] = mEnd.ToDOMPoint();
|
||||
|
||||
if (!startContent || !endContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorResult er;
|
||||
RefPtr<nsRange> domRange = nsRange::Create(startContent, startContentOffset,
|
||||
endContent, endContentOffset, er);
|
||||
if (er.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCoreUtils::ScrollSubstringTo(mStart.mAcc->AsLocal()->GetFrame(), domRange,
|
||||
aScrollType);
|
||||
}
|
||||
|
||||
TextLeafRange::Iterator TextLeafRange::Iterator::BeginIterator(
|
||||
const TextLeafRange& aRange) {
|
||||
Iterator result(aRange);
|
||||
|
@ -297,6 +297,8 @@ class TextLeafRange final {
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT bool SetSelection(int32_t aSelectionNum) const;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT void ScrollIntoView(uint32_t aScrollType) const;
|
||||
|
||||
private:
|
||||
TextLeafPoint mStart;
|
||||
TextLeafPoint mEnd;
|
||||
|
@ -263,19 +263,6 @@ bool TextRange::Crop(Accessible* aContainer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextRange::ScrollIntoView(uint32_t aScrollType) const {
|
||||
LocalAccessible* root = mRoot->AsLocal();
|
||||
if (!root) {
|
||||
MOZ_ASSERT_UNREACHABLE("Not supported for RemoteAccessible");
|
||||
return;
|
||||
}
|
||||
RefPtr<nsRange> range = nsRange::Create(root->GetContent());
|
||||
if (AssignDOMRange(range)) {
|
||||
nsCoreUtils::ScrollSubstringTo(mStartContainer->AsLocal()->GetFrame(),
|
||||
range, aScrollType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given DOM point to a DOM point in non-generated contents.
|
||||
*
|
||||
|
@ -111,11 +111,6 @@ class TextRange final {
|
||||
*/
|
||||
bool Crop(Accessible* aContainer);
|
||||
|
||||
/**
|
||||
* Scroll the text range into view.
|
||||
*/
|
||||
void ScrollIntoView(uint32_t aScrollType) const;
|
||||
|
||||
/**
|
||||
* Convert stored hypertext offsets into DOM offsets and assign it to DOM
|
||||
* range.
|
||||
|
@ -789,4 +789,12 @@ bool HyperTextAccessibleBase::SetSelectionBoundsAt(int32_t aSelectionNum,
|
||||
return range.SetSelection(aSelectionNum);
|
||||
}
|
||||
|
||||
void HyperTextAccessibleBase::ScrollSubstringTo(int32_t aStartOffset,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aScrollType) {
|
||||
TextLeafRange range(ToTextLeafPoint(aStartOffset),
|
||||
ToTextLeafPoint(aEndOffset, true));
|
||||
range.ScrollIntoView(aScrollType);
|
||||
}
|
||||
|
||||
} // namespace mozilla::a11y
|
||||
|
@ -233,6 +233,12 @@ class HyperTextAccessibleBase {
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual bool RemoveFromSelection(
|
||||
int32_t aSelectionNum) = 0;
|
||||
|
||||
/**
|
||||
* Scroll the given text range into view.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual void ScrollSubstringTo(
|
||||
int32_t aStartOffset, int32_t aEndOffset, uint32_t aScrollType);
|
||||
|
||||
protected:
|
||||
virtual const Accessible* Acc() const = 0;
|
||||
Accessible* Acc() {
|
||||
|
@ -1943,13 +1943,6 @@ bool HyperTextAccessible::RemoveFromSelection(int32_t aSelectionNum) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void HyperTextAccessible::ScrollSubstringTo(int32_t aStartOffset,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aScrollType) {
|
||||
TextRange range(this, this, aStartOffset, this, aEndOffset);
|
||||
range.ScrollIntoView(aScrollType);
|
||||
}
|
||||
|
||||
void HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aCoordinateType,
|
||||
|
@ -211,12 +211,6 @@ class HyperTextAccessible : public AccessibleWrap,
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual bool RemoveFromSelection(
|
||||
int32_t aSelectionNum) override;
|
||||
|
||||
/**
|
||||
* Scroll the given text range into view.
|
||||
*/
|
||||
void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
|
||||
uint32_t aScrollType);
|
||||
|
||||
/**
|
||||
* Scroll the given text range to the given point.
|
||||
*/
|
||||
|
@ -244,6 +244,19 @@ mozilla::ipc::IPCResult DocAccessibleChildBase::RecvSetTextSelection(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult DocAccessibleChildBase::RecvScrollTextLeafRangeIntoView(
|
||||
const uint64_t& aStartID, const int32_t& aStartOffset,
|
||||
const uint64_t& aEndID, const int32_t& aEndOffset,
|
||||
const uint32_t& aScrollType) {
|
||||
TextLeafRange range(TextLeafPoint(IdToAccessible(aStartID), aStartOffset),
|
||||
TextLeafPoint(IdToAccessible(aEndID), aEndOffset));
|
||||
if (range) {
|
||||
range.ScrollIntoView(aScrollType);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult DocAccessibleChildBase::RecvRemoveTextSelection(
|
||||
const uint64_t& aID, const int32_t& aSelectionNum) {
|
||||
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
|
||||
|
@ -84,6 +84,12 @@ class DocAccessibleChildBase : public PDocAccessibleChild {
|
||||
const uint64_t& aEndID, const int32_t& aEndOffset,
|
||||
const int32_t& aSelectionNum) override;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
virtual mozilla::ipc::IPCResult RecvScrollTextLeafRangeIntoView(
|
||||
const uint64_t& aStartID, const int32_t& aStartOffset,
|
||||
const uint64_t& aEndID, const int32_t& aEndOffset,
|
||||
const uint32_t& aScrollType) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvRemoveTextSelection(
|
||||
const uint64_t& aID, const int32_t& aSelectionNum) override;
|
||||
|
||||
|
@ -85,8 +85,8 @@ virtual bool SetSelectionBoundsAt(int32_t aSelectionNum, int32_t aStartOffset,
|
||||
|
||||
virtual bool RemoveFromSelection(int32_t aSelectionNum) override;
|
||||
|
||||
void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
|
||||
uint32_t aScrollType);
|
||||
virtual void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
|
||||
uint32_t aScrollType) override;
|
||||
|
||||
void ScrollSubstringToPoint(int32_t aStartOffset, int32_t aEndOffset,
|
||||
uint32_t aCoordinateType, int32_t aX, int32_t aY);
|
||||
|
@ -211,6 +211,9 @@ child:
|
||||
int32_t aSelectionNum);
|
||||
async RemoveTextSelection(uint64_t aID, int32_t aSelectionNum);
|
||||
|
||||
async ScrollTextLeafRangeIntoView(uint64_t aStartID, int32_t aStartOffset,
|
||||
uint64_t aEndID, int32_t aEndOffset,
|
||||
uint32_t aScrollType);
|
||||
async ScrollSubstringTo(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
|
||||
uint32_t aScrollType);
|
||||
async ScrollSubstringToPoint(uint64_t aID,
|
||||
|
@ -351,6 +351,13 @@ bool RemoteAccessible::RemoveFromSelection(int32_t aSelectionNum) {
|
||||
void RemoteAccessible::ScrollSubstringTo(int32_t aStartOffset,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aScrollType) {
|
||||
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
|
||||
MOZ_ASSERT(IsHyperText(), "is not hypertext?");
|
||||
RemoteAccessibleBase<RemoteAccessible>::ScrollSubstringTo(
|
||||
aStartOffset, aEndOffset, aScrollType);
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << mDoc->SendScrollSubstringTo(mID, aStartOffset, aEndOffset,
|
||||
aScrollType);
|
||||
}
|
||||
|
@ -142,6 +142,10 @@ child:
|
||||
int32_t aSelectionNum);
|
||||
async RemoveTextSelection(uint64_t aID, int32_t aSelectionNum);
|
||||
|
||||
async ScrollTextLeafRangeIntoView(uint64_t aStartID, int32_t aStartOffset,
|
||||
uint64_t aEndID, int32_t aEndOffset,
|
||||
uint32_t aScrollType);
|
||||
|
||||
/*
|
||||
* Verify the cache. Used for testing purposes.
|
||||
*/
|
||||
|
@ -733,9 +733,12 @@ void RemoteAccessible::ScrollSubstringTo(int32_t aStartOffset,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aScrollType) {
|
||||
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
|
||||
// Not yet supported by the cache.
|
||||
MOZ_ASSERT(IsHyperText(), "is not hypertext?");
|
||||
RemoteAccessibleBase<RemoteAccessible>::ScrollSubstringTo(
|
||||
aStartOffset, aEndOffset, aScrollType);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
|
||||
if (!acc) {
|
||||
return;
|
||||
|
@ -236,16 +236,9 @@ inline NSString* ToNSString(id aValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGeckoAccessible->IsLocal()) {
|
||||
if (HyperTextAccessible* textAcc =
|
||||
mGeckoAccessible->AsLocal()->AsHyperText()) {
|
||||
textAcc->ScrollSubstringTo(range.location, range.location + range.length,
|
||||
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
|
||||
}
|
||||
} else {
|
||||
mGeckoAccessible->AsRemote()->ScrollSubstringTo(
|
||||
range.location, range.location + range.length,
|
||||
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
|
||||
if (HyperTextAccessibleBase* textAcc = mGeckoAccessible->AsHyperTextBase()) {
|
||||
textAcc->ScrollSubstringTo(range.location, range.location + range.length,
|
||||
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,3 +12,4 @@ prefs =
|
||||
skip-if = os == 'win' # bug 1372296
|
||||
[browser_test_scroll_bounds.js]
|
||||
[browser_test_scrollTo.js]
|
||||
[browser_test_scroll_substring.js]
|
||||
|
@ -0,0 +1,67 @@
|
||||
/* 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 */
|
||||
loadScripts({ name: "layout.js", dir: MOCHITESTS_DIR });
|
||||
|
||||
/**
|
||||
* Test nsIAccessibleText::scrollSubstringTo.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: Ahem;
|
||||
src: url(${CURRENT_CONTENT_DIR}e10s/fonts/Ahem.sjs);
|
||||
}
|
||||
pre {
|
||||
font: 20px/20px Ahem;
|
||||
height: 40px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
</style>
|
||||
<pre id="text">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
It's a jetpack, Michael. What could possibly go wrong?
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The only thing I found in the fridge was a dead dove in a bag.
|
||||
</pre>`,
|
||||
async function(browser, docAcc) {
|
||||
let text = findAccessibleChildByID(docAcc, "text", [nsIAccessibleText]);
|
||||
let [, containerY, , containerHeight] = getBounds(text);
|
||||
let getCharY = () => {
|
||||
let objY = {};
|
||||
text.getCharacterExtents(7, {}, objY, {}, {}, COORDTYPE_SCREEN_RELATIVE);
|
||||
return objY.value;
|
||||
};
|
||||
ok(
|
||||
containerHeight < getCharY(),
|
||||
"Character is outside of container bounds"
|
||||
);
|
||||
text.scrollSubstringTo(7, 8, SCROLL_TYPE_TOP_EDGE);
|
||||
|
||||
await waitForContentPaint(browser);
|
||||
await untilCacheIs(
|
||||
getCharY,
|
||||
containerY,
|
||||
"Character is scrolled to top of container"
|
||||
);
|
||||
},
|
||||
{
|
||||
topLevel: !isWinNoCache,
|
||||
iframe: !isWinNoCache,
|
||||
remoteIframe: !isWinNoCache,
|
||||
chrome: true,
|
||||
}
|
||||
);
|
@ -82,6 +82,7 @@ const SEAMONKEY = navigator.userAgent.match(/ SeaMonkey\//);
|
||||
|
||||
const STATE_BUSY = nsIAccessibleStates.STATE_BUSY;
|
||||
|
||||
const SCROLL_TYPE_TOP_EDGE = nsIAccessibleScrollType.SCROLL_TYPE_TOP_EDGE;
|
||||
const SCROLL_TYPE_ANYWHERE = nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE;
|
||||
|
||||
const COORDTYPE_SCREEN_RELATIVE =
|
||||
|
@ -380,9 +380,9 @@ ia2AccessibleText::get_nCharacters(long* aNCharacters) {
|
||||
STDMETHODIMP
|
||||
ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
|
||||
enum IA2ScrollType aScrollType) {
|
||||
auto [textAcc, hr] = LocalTextAcc();
|
||||
HyperTextAccessibleBase* textAcc = TextAcc();
|
||||
if (!textAcc) {
|
||||
return hr;
|
||||
return CO_E_OBJNOTCONNECTED;
|
||||
}
|
||||
|
||||
if (!textAcc->IsValidRange(aStartIndex, aEndIndex)) return E_INVALIDARG;
|
||||
|
@ -388,11 +388,7 @@ xpcAccessibleHyperText::ScrollSubstringTo(int32_t aStartOffset,
|
||||
uint32_t aScrollType) {
|
||||
if (!mIntl) return NS_ERROR_FAILURE;
|
||||
|
||||
if (mIntl->IsLocal()) {
|
||||
IntlLocal()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
|
||||
} else {
|
||||
mIntl->AsRemote()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
|
||||
}
|
||||
Intl()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user