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 * Scroll the text range into view.
117 void ScrollIntoView(uint32_t aScrollType
) const;
120 * Convert stored hypertext offsets into DOM offsets and assign it to DOM
123 * Note that if start and/or end accessible offsets are in generated content
124 * such as ::before or
125 * ::after, the result range excludes the generated content. See also
126 * ClosestNotGeneratedDOMPoint() for more information.
128 * @param aRange [in, out] the range whose bounds to set
129 * @param aReversed [out] whether the start/end offsets were reversed.
130 * @return true if conversion was successful
132 bool AssignDOMRange(nsRange
* aRange
, bool* aReversed
= nullptr) const;
135 * Return true if this TextRange object represents an actual range of text.
137 bool IsValid() const { return mRoot
; }
139 void SetStartPoint(Accessible
* aContainer
, int32_t aOffset
) {
140 mStartContainer
= aContainer
;
141 mStartOffset
= aOffset
;
143 void SetEndPoint(Accessible
* aContainer
, int32_t aOffset
) {
144 mStartContainer
= aContainer
;
145 mStartOffset
= aOffset
;
148 static void TextRangesFromSelection(dom::Selection
* aSelection
,
149 nsTArray
<TextRange
>* aRanges
);
152 TextRange(const TextRange
& aRange
) = delete;
153 TextRange
& operator=(const TextRange
& aRange
) = delete;
155 friend class HyperTextAccessible
;
156 friend class xpcAccessibleTextRange
;
158 void Set(Accessible
* aRoot
, Accessible
* aStartContainer
, int32_t aStartOffset
,
159 Accessible
* aEndContainer
, int32_t aEndOffset
);
162 * Text() method helper.
163 * @param aText [in,out] calculated text
164 * @param aCurrent [in] currently traversed node
165 * @param aStartIntlOffset [in] start offset if current node is a text node
166 * @return true if calculation is not finished yet
168 bool TextInternal(nsAString
& aText
, Accessible
* aCurrent
,
169 uint32_t aStartIntlOffset
) const;
172 * A helper method returning a common parent for two given accessible
175 Accessible
* CommonParent(Accessible
* aAcc1
, Accessible
* aAcc2
,
176 nsTArray
<Accessible
*>* aParents1
, uint32_t* aPos1
,
177 nsTArray
<Accessible
*>* aParents2
,
178 uint32_t* aPos2
) const;
181 Accessible
* mStartContainer
;
182 Accessible
* mEndContainer
;
183 int32_t mStartOffset
;
188 } // namespace mozilla