1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_a11y_TextRange_h__
8 #define mozilla_a11y_TextRange_h__
23 class LocalAccessible
;
26 * A text point (HyperText + offset), represents a boundary of text range.
27 * In new code, This should only be used when you explicitly need to deal with
28 * HyperText containers and offsets, including embedded objects; e.g. for
29 * IAccessible2 and ATK. Otherwise, use TextLeafPoint instead.
31 struct TextPoint final
{
32 TextPoint(Accessible
* aContainer
, int32_t aOffset
)
33 : mContainer(aContainer
), mOffset(aOffset
) {}
34 TextPoint(const TextPoint
& aPoint
)
35 : mContainer(aPoint
.mContainer
), mOffset(aPoint
.mOffset
) {}
37 Accessible
* mContainer
;
40 bool operator==(const TextPoint
& aPoint
) const {
41 return mContainer
== aPoint
.mContainer
&& mOffset
== aPoint
.mOffset
;
43 bool operator<(const TextPoint
& aPoint
) const;
47 * Represents a HyperText range within the text control or document.
48 * In new code, This should only be used when you explicitly need to deal with
49 * HyperText containers and offsets, including embedded objects; e.g. for
50 * IAccessible2 and ATK. Otherwise, use TextLeafRange instead.
52 class TextRange final
{
54 TextRange(Accessible
* aRoot
, Accessible
* aStartContainer
,
55 int32_t aStartOffset
, Accessible
* aEndContainer
,
57 TextRange() : mStartOffset
{0}, mEndOffset
{0} {}
58 TextRange(TextRange
&& aRange
)
59 : mRoot(std::move(aRange
.mRoot
)),
60 mStartContainer(std::move(aRange
.mStartContainer
)),
61 mEndContainer(std::move(aRange
.mEndContainer
)),
62 mStartOffset(aRange
.mStartOffset
),
63 mEndOffset(aRange
.mEndOffset
) {}
65 TextRange
& operator=(TextRange
&& aRange
) {
66 mRoot
= std::move(aRange
.mRoot
);
67 mStartContainer
= std::move(aRange
.mStartContainer
);
68 mEndContainer
= std::move(aRange
.mEndContainer
);
69 mStartOffset
= aRange
.mStartOffset
;
70 mEndOffset
= aRange
.mEndOffset
;
74 Accessible
* Root() { return mRoot
; }
75 Accessible
* StartContainer() const { return mStartContainer
; }
76 int32_t StartOffset() const { return mStartOffset
; }
77 Accessible
* EndContainer() const { return mEndContainer
; }
78 int32_t EndOffset() const { return mEndOffset
; }
80 bool operator==(const TextRange
& aRange
) const {
81 return mStartContainer
== aRange
.mStartContainer
&&
82 mStartOffset
== aRange
.mStartOffset
&&
83 mEndContainer
== aRange
.mEndContainer
&&
84 mEndOffset
== aRange
.mEndOffset
;
87 TextPoint
StartPoint() const {
88 return TextPoint(mStartContainer
, mStartOffset
);
90 TextPoint
EndPoint() const { return TextPoint(mEndContainer
, mEndOffset
); }
93 * Return a container containing both start and end points.
95 Accessible
* Container() const;
98 * Return a list of embedded objects enclosed by the text range (includes
99 * partially overlapped objects).
101 void EmbeddedChildren(nsTArray
<Accessible
*>* aChildren
) const;
104 * Return text enclosed by the range.
106 void Text(nsAString
& aText
) const;
109 * Crops the range if it overlaps the given accessible element boundaries,
110 * returns true if the range was cropped successfully.
112 bool Crop(Accessible
* aContainer
);
115 * Convert stored hypertext offsets into DOM offsets and assign it to DOM
118 * Note that if start and/or end accessible offsets are in generated content
119 * such as ::before or
120 * ::after, the result range excludes the generated content. See also
121 * ClosestNotGeneratedDOMPoint() for more information.
123 * @param aRange [in, out] the range whose bounds to set
124 * @param aReversed [out] whether the start/end offsets were reversed.
125 * @return true if conversion was successful
127 bool AssignDOMRange(nsRange
* aRange
, bool* aReversed
= nullptr) const;
130 * Return true if this TextRange object represents an actual range of text.
132 bool IsValid() const { return mRoot
; }
134 void SetStartPoint(Accessible
* aContainer
, int32_t aOffset
) {
135 mStartContainer
= aContainer
;
136 mStartOffset
= aOffset
;
138 void SetEndPoint(Accessible
* aContainer
, int32_t aOffset
) {
139 mStartContainer
= aContainer
;
140 mStartOffset
= aOffset
;
143 static void TextRangesFromSelection(dom::Selection
* aSelection
,
144 nsTArray
<TextRange
>* aRanges
);
147 TextRange(const TextRange
& aRange
) = delete;
148 TextRange
& operator=(const TextRange
& aRange
) = delete;
150 friend class HyperTextAccessible
;
151 friend class xpcAccessibleTextRange
;
153 void Set(Accessible
* aRoot
, Accessible
* aStartContainer
, int32_t aStartOffset
,
154 Accessible
* aEndContainer
, int32_t aEndOffset
);
157 * Text() method helper.
158 * @param aText [in,out] calculated text
159 * @param aCurrent [in] currently traversed node
160 * @param aStartIntlOffset [in] start offset if current node is a text node
161 * @return true if calculation is not finished yet
163 bool TextInternal(nsAString
& aText
, Accessible
* aCurrent
,
164 uint32_t aStartIntlOffset
) const;
167 * A helper method returning a common parent for two given accessible
170 Accessible
* CommonParent(Accessible
* aAcc1
, Accessible
* aAcc2
,
171 nsTArray
<Accessible
*>* aParents1
, uint32_t* aPos1
,
172 nsTArray
<Accessible
*>* aParents2
,
173 uint32_t* aPos2
) const;
176 Accessible
* mStartContainer
;
177 Accessible
* mEndContainer
;
178 int32_t mStartOffset
;
183 } // namespace mozilla