1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "ia2AccessibleTextSelectionContainer.h"
10 #include "AccessibleTextSelectionContainer_i.c"
11 #include "ia2AccessibleHypertext.h"
12 #include "mozilla/a11y/HyperTextAccessibleBase.h"
13 #include "TextRange.h"
14 #include "TextLeafRange.h"
16 using namespace mozilla::a11y
;
18 // IAccessibleTextSelectionContainer
21 ia2AccessibleTextSelectionContainer::get_selections(
22 IA2TextSelection
** selections
, long* nSelections
) {
23 if (!selections
|| !nSelections
) {
27 HyperTextAccessibleBase
* text
= TextAcc();
29 return CO_E_OBJNOTCONNECTED
;
31 AutoTArray
<TextRange
, 1> ranges
;
32 text
->CroppedSelectionRanges(ranges
);
33 *nSelections
= ranges
.Length();
34 *selections
= static_cast<IA2TextSelection
*>(
35 ::CoTaskMemAlloc(sizeof(IA2TextSelection
) * *nSelections
));
39 for (uint32_t idx
= 0; idx
< static_cast<uint32_t>(*nSelections
); idx
++) {
40 RefPtr
<IAccessibleText
> startObj
=
41 GetIATextFrom(ranges
[idx
].StartContainer());
42 startObj
.forget(&(*selections
)[idx
].startObj
);
43 (*selections
)[idx
].startOffset
= ranges
[idx
].StartOffset();
44 RefPtr
<IAccessibleText
> endObj
= GetIATextFrom(ranges
[idx
].EndContainer());
45 endObj
.forget(&(*selections
)[idx
].endObj
);
46 (*selections
)[idx
].endOffset
= ranges
[idx
].EndOffset();
47 // XXX Expose this properly somehow.
48 (*selections
)[idx
].startIsActive
= true;
54 ia2AccessibleTextSelectionContainer::setSelections(
55 long nSelections
, IA2TextSelection
* selections
) {
56 if (nSelections
< 0 || (nSelections
> 0 && !selections
)) {
59 HyperTextAccessibleBase
* text
= TextAcc();
61 return CO_E_OBJNOTCONNECTED
;
63 // Build and validate new selection ranges.
64 AutoTArray
<TextLeafRange
, 1> newRanges
;
65 newRanges
.SetCapacity(nSelections
);
66 for (long r
= 0; r
< nSelections
; ++r
) {
67 TextLeafRange
range(GetTextLeafPointFrom(selections
[r
].startObj
,
68 selections
[r
].startOffset
, false),
69 GetTextLeafPointFrom(selections
[r
].endObj
,
70 selections
[r
].endOffset
, true));
74 newRanges
.AppendElement(range
);
76 // Get the number of existing selections. We use SelectionRanges rather than
77 // SelectionCount because SelectionCount is restricted to this Accessible,
78 // whereas we want all selections within the control/document.
79 AutoTArray
<TextRange
, 1> oldRanges
;
80 text
->SelectionRanges(&oldRanges
);
81 // Set the new selections.
82 for (long r
= 0; r
< nSelections
; ++r
) {
83 newRanges
[r
].SetSelection(r
);
85 // Remove any remaining old selections if there were more than nSelections.
86 for (long r
= nSelections
; r
< static_cast<long>(oldRanges
.Length()); ++r
) {
87 text
->RemoveFromSelection(r
);
92 // ia2AccessibleTextSelectionContainer
94 HyperTextAccessibleBase
* ia2AccessibleTextSelectionContainer::TextAcc() {
95 auto hyp
= static_cast<ia2AccessibleHypertext
*>(this);
96 Accessible
* acc
= hyp
->Acc();
97 return acc
? acc
->AsHyperTextBase() : nullptr;
101 RefPtr
<IAccessibleText
> ia2AccessibleTextSelectionContainer::GetIATextFrom(
103 MsaaAccessible
* msaa
= MsaaAccessible::GetFrom(aAcc
);
105 RefPtr
<IAccessibleText
> text
;
106 msaa
->QueryInterface(IID_IAccessibleText
, getter_AddRefs(text
));
112 TextLeafPoint
ia2AccessibleTextSelectionContainer::GetTextLeafPointFrom(
113 IAccessibleText
* aText
, long aOffset
, bool aDescendToEnd
) {
115 return TextLeafPoint();
117 Accessible
* acc
= MsaaAccessible::GetAccessibleFrom(aText
);
119 return TextLeafPoint();
121 HyperTextAccessibleBase
* hyp
= acc
->AsHyperTextBase();
123 return TextLeafPoint();
125 return hyp
->ToTextLeafPoint(aOffset
, aDescendToEnd
);