1
0
Fork 0
firefox/accessible/windows/ia2/ia2AccessibleTextSelectionContainer.cpp
Daniel Baumann 5e9a113729
Adding upstream version 140.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-25 09:37:52 +02:00

121 lines
3.8 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* 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/. */
#include "ia2AccessibleTextSelectionContainer.h"
#include "AccessibleTextSelectionContainer_i.c"
#include "ia2AccessibleHypertext.h"
#include "mozilla/a11y/HyperTextAccessibleBase.h"
#include "TextRange.h"
#include "TextLeafRange.h"
using namespace mozilla::a11y;
// IAccessibleTextSelectionContainer
STDMETHODIMP
ia2AccessibleTextSelectionContainer::get_selections(
IA2TextSelection** selections, long* nSelections) {
if (!selections || !nSelections) {
return E_INVALIDARG;
}
*nSelections = 0;
HyperTextAccessibleBase* text = TextAcc();
if (!text) {
return CO_E_OBJNOTCONNECTED;
}
AutoTArray<TextRange, 1> ranges;
text->CroppedSelectionRanges(ranges);
*nSelections = ranges.Length();
*selections = static_cast<IA2TextSelection*>(
::CoTaskMemAlloc(sizeof(IA2TextSelection) * *nSelections));
if (!*selections) {
return E_OUTOFMEMORY;
}
for (uint32_t idx = 0; idx < static_cast<uint32_t>(*nSelections); idx++) {
RefPtr<IAccessibleText> startObj =
GetIATextFrom(ranges[idx].StartContainer());
startObj.forget(&(*selections)[idx].startObj);
(*selections)[idx].startOffset = ranges[idx].StartOffset();
RefPtr<IAccessibleText> endObj = GetIATextFrom(ranges[idx].EndContainer());
endObj.forget(&(*selections)[idx].endObj);
(*selections)[idx].endOffset = ranges[idx].EndOffset();
// XXX Expose this properly somehow.
(*selections)[idx].startIsActive = true;
}
return S_OK;
}
STDMETHODIMP
ia2AccessibleTextSelectionContainer::setSelections(
long nSelections, IA2TextSelection* selections) {
if (nSelections < 0 || !selections) {
return E_INVALIDARG;
}
HyperTextAccessibleBase* text = TextAcc();
if (!text) {
return CO_E_OBJNOTCONNECTED;
}
if (nSelections == 0) {
text->RemoveFromSelection(TextLeafRange::kRemoveAllExistingSelectedRanges);
return S_OK;
}
// Build and validate new selection ranges.
AutoTArray<TextLeafRange, 1> newRanges;
newRanges.SetCapacity(nSelections);
for (long r = 0; r < nSelections; ++r) {
TextLeafRange range(
GetTextLeafPointFrom(selections[r].startObj, selections[r].startOffset),
GetTextLeafPointFrom(selections[r].endObj, selections[r].endOffset));
if (!range) {
return E_INVALIDARG;
}
newRanges.AppendElement(range);
}
// Set the new selections.
newRanges[0].SetSelection(TextLeafRange::kRemoveAllExistingSelectedRanges);
for (long r = 1; r < nSelections; ++r) {
newRanges[r].SetSelection(r);
}
return S_OK;
}
// ia2AccessibleTextSelectionContainer
HyperTextAccessibleBase* ia2AccessibleTextSelectionContainer::TextAcc() {
auto hyp = static_cast<ia2AccessibleHypertext*>(this);
Accessible* acc = hyp->Acc();
return acc ? acc->AsHyperTextBase() : nullptr;
}
/* static */
RefPtr<IAccessibleText> ia2AccessibleTextSelectionContainer::GetIATextFrom(
Accessible* aAcc) {
MsaaAccessible* msaa = MsaaAccessible::GetFrom(aAcc);
MOZ_ASSERT(msaa);
RefPtr<IAccessibleText> text;
msaa->QueryInterface(IID_IAccessibleText, getter_AddRefs(text));
MOZ_ASSERT(text);
return text;
}
/* static */
TextLeafPoint ia2AccessibleTextSelectionContainer::GetTextLeafPointFrom(
IAccessibleText* aText, long aOffset) {
if (!aText) {
return TextLeafPoint();
}
Accessible* acc = MsaaAccessible::GetAccessibleFrom(aText);
if (!acc) {
return TextLeafPoint();
}
HyperTextAccessibleBase* hyp = acc->AsHyperTextBase();
if (!hyp) {
return TextLeafPoint();
}
return hyp->ToTextLeafPoint(aOffset);
}