Bug 1687263: part 4) Defer and in some cases avoid removing spellchecking-ranges...
[gecko.git] / accessible / base / TextRange.h
blobad3f476a38a8b8f2fc3af6d4b5f9e514670c2109
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__
10 #include <utility>
12 #include "nsCaseTreatment.h"
13 #include "nsRect.h"
14 #include "nsTArray.h"
16 class nsIVariant;
17 class nsRange;
19 namespace mozilla {
20 namespace dom {
21 class Selection;
22 } // namespace dom
23 namespace a11y {
25 class LocalAccessible;
26 class HyperTextAccessible;
28 /**
29 * A text point (hyper text + offset), represents a boundary of text range.
31 struct TextPoint final {
32 TextPoint(HyperTextAccessible* aContainer, int32_t aOffset)
33 : mContainer(aContainer), mOffset(aOffset) {}
34 TextPoint(const TextPoint& aPoint)
35 : mContainer(aPoint.mContainer), mOffset(aPoint.mOffset) {}
37 HyperTextAccessible* mContainer;
38 int32_t mOffset;
40 bool operator==(const TextPoint& aPoint) const {
41 return mContainer == aPoint.mContainer && mOffset == aPoint.mOffset;
43 bool operator<(const TextPoint& aPoint) const;
46 /**
47 * Represents a text range within the text control or document.
49 class TextRange final {
50 public:
51 TextRange(HyperTextAccessible* aRoot, HyperTextAccessible* aStartContainer,
52 int32_t aStartOffset, HyperTextAccessible* aEndContainer,
53 int32_t aEndOffset);
54 TextRange() : mStartOffset{0}, mEndOffset{0} {}
55 TextRange(TextRange&& aRange)
56 : mRoot(std::move(aRange.mRoot)),
57 mStartContainer(std::move(aRange.mStartContainer)),
58 mEndContainer(std::move(aRange.mEndContainer)),
59 mStartOffset(aRange.mStartOffset),
60 mEndOffset(aRange.mEndOffset) {}
62 TextRange& operator=(TextRange&& aRange) {
63 mRoot = std::move(aRange.mRoot);
64 mStartContainer = std::move(aRange.mStartContainer);
65 mEndContainer = std::move(aRange.mEndContainer);
66 mStartOffset = aRange.mStartOffset;
67 mEndOffset = aRange.mEndOffset;
68 return *this;
71 HyperTextAccessible* StartContainer() const { return mStartContainer; }
72 int32_t StartOffset() const { return mStartOffset; }
73 HyperTextAccessible* EndContainer() const { return mEndContainer; }
74 int32_t EndOffset() const { return mEndOffset; }
76 bool operator==(const TextRange& aRange) const {
77 return mStartContainer == aRange.mStartContainer &&
78 mStartOffset == aRange.mStartOffset &&
79 mEndContainer == aRange.mEndContainer &&
80 mEndOffset == aRange.mEndOffset;
83 TextPoint StartPoint() const {
84 return TextPoint(mStartContainer, mStartOffset);
86 TextPoint EndPoint() const { return TextPoint(mEndContainer, mEndOffset); }
88 /**
89 * Return a container containing both start and end points.
91 LocalAccessible* Container() const;
93 /**
94 * Return a list of embedded objects enclosed by the text range (includes
95 * partially overlapped objects).
97 void EmbeddedChildren(nsTArray<LocalAccessible*>* aChildren) const;
99 /**
100 * Return text enclosed by the range.
102 void Text(nsAString& aText) const;
105 * Return list of bounding rects of the text range by lines.
107 void Bounds(nsTArray<nsIntRect> aRects) const;
109 enum ETextUnit { eFormat, eWord, eLine, eParagraph, ePage, eDocument };
112 * Move the range or its points on specified amount of given units.
114 void Move(ETextUnit aUnit, int32_t aCount) {
115 MoveEnd(aUnit, aCount);
116 MoveStart(aUnit, aCount);
118 void MoveStart(ETextUnit aUnit, int32_t aCount) {
119 MoveInternal(aUnit, aCount, *mStartContainer, mStartOffset, mEndContainer,
120 mEndOffset);
122 void MoveEnd(ETextUnit aUnit, int32_t aCount) {
123 MoveInternal(aUnit, aCount, *mEndContainer, mEndOffset);
127 * Move the range points to the closest unit boundaries.
129 void Normalize(ETextUnit aUnit);
132 * Crops the range if it overlaps the given accessible element boundaries,
133 * returns true if the range was cropped successfully.
135 bool Crop(LocalAccessible* aContainer);
137 enum EDirection { eBackward, eForward };
140 * Return range enclosing the found text.
142 void FindText(const nsAString& aText, EDirection aDirection,
143 nsCaseTreatment aCaseSensitive, TextRange* aFoundRange) const;
145 enum EAttr {
146 eAnimationStyleAttr,
147 eAnnotationObjectsAttr,
148 eAnnotationTypesAttr,
149 eBackgroundColorAttr,
150 eBulletStyleAttr,
151 eCapStyleAttr,
152 eCaretBidiModeAttr,
153 eCaretPositionAttr,
154 eCultureAttr,
155 eFontNameAttr,
156 eFontSizeAttr,
157 eFontWeightAttr,
158 eForegroundColorAttr,
159 eHorizontalTextAlignmentAttr,
160 eIndentationFirstLineAttr,
161 eIndentationLeadingAttr,
162 eIndentationTrailingAttr,
163 eIsActiveAttr,
164 eIsHiddenAttr,
165 eIsItalicAttr,
166 eIsReadOnlyAttr,
167 eIsSubscriptAttr,
168 eIsSuperscriptAttr,
169 eLinkAttr,
170 eMarginBottomAttr,
171 eMarginLeadingAttr,
172 eMarginTopAttr,
173 eMarginTrailingAttr,
174 eOutlineStylesAttr,
175 eOverlineColorAttr,
176 eOverlineStyleAttr,
177 eSelectionActiveEndAttr,
178 eStrikethroughColorAttr,
179 eStrikethroughStyleAttr,
180 eStyleIdAttr,
181 eStyleNameAttr,
182 eTabsAttr,
183 eTextFlowDirectionsAttr,
184 eUnderlineColorAttr,
185 eUnderlineStyleAttr
189 * Return range enclosing text having requested attribute.
191 void FindAttr(EAttr aAttr, nsIVariant* aValue, EDirection aDirection,
192 TextRange* aFoundRange) const;
195 * Add/remove the text range from selection.
197 void AddToSelection() const;
198 void RemoveFromSelection() const;
199 MOZ_CAN_RUN_SCRIPT bool SetSelectionAt(int32_t aSelectionNum) const;
202 * Scroll the text range into view.
204 void ScrollIntoView(uint32_t aScrollType) const;
207 * Convert stored hypertext offsets into DOM offsets and assign it to DOM
208 * range.
210 * Note that if start and/or end accessible offsets are in generated content
211 * such as ::before or
212 * ::after, the result range excludes the generated content. See also
213 * ClosestNotGeneratedDOMPoint() for more information.
215 * @param aRange [in, out] the range whose bounds to set
216 * @param aReversed [out] whether the start/end offsets were reversed.
217 * @return true if conversion was successful
219 bool AssignDOMRange(nsRange* aRange, bool* aReversed = nullptr) const;
222 * Return true if this TextRange object represents an actual range of text.
224 bool IsValid() const { return mRoot; }
226 void SetStartPoint(HyperTextAccessible* aContainer, int32_t aOffset) {
227 mStartContainer = aContainer;
228 mStartOffset = aOffset;
230 void SetEndPoint(HyperTextAccessible* aContainer, int32_t aOffset) {
231 mStartContainer = aContainer;
232 mStartOffset = aOffset;
235 static void TextRangesFromSelection(dom::Selection* aSelection,
236 nsTArray<TextRange>* aRanges);
238 private:
239 TextRange(const TextRange& aRange) = delete;
240 TextRange& operator=(const TextRange& aRange) = delete;
242 friend class HyperTextAccessible;
243 friend class xpcAccessibleTextRange;
245 void Set(HyperTextAccessible* aRoot, HyperTextAccessible* aStartContainer,
246 int32_t aStartOffset, HyperTextAccessible* aEndContainer,
247 int32_t aEndOffset);
250 * Text() method helper.
251 * @param aText [in,out] calculated text
252 * @param aCurrent [in] currently traversed node
253 * @param aStartIntlOffset [in] start offset if current node is a text node
254 * @return true if calculation is not finished yet
256 bool TextInternal(nsAString& aText, LocalAccessible* aCurrent,
257 uint32_t aStartIntlOffset) const;
259 void MoveInternal(ETextUnit aUnit, int32_t aCount,
260 HyperTextAccessible& aContainer, int32_t aOffset,
261 HyperTextAccessible* aStopContainer = nullptr,
262 int32_t aStopOffset = 0);
265 * A helper method returning a common parent for two given accessible
266 * elements.
268 LocalAccessible* CommonParent(LocalAccessible* aAcc1, LocalAccessible* aAcc2,
269 nsTArray<LocalAccessible*>* aParents1,
270 uint32_t* aPos1,
271 nsTArray<LocalAccessible*>* aParents2,
272 uint32_t* aPos2) const;
274 RefPtr<HyperTextAccessible> mRoot;
275 RefPtr<HyperTextAccessible> mStartContainer;
276 RefPtr<HyperTextAccessible> mEndContainer;
277 int32_t mStartOffset;
278 int32_t mEndOffset;
281 } // namespace a11y
282 } // namespace mozilla
284 #endif