Line data Source code
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/. */
6 :
7 : #ifndef mozilla_a11y_TextRange_h__
8 : #define mozilla_a11y_TextRange_h__
9 :
10 : #include "mozilla/Move.h"
11 : #include "nsCaseTreatment.h"
12 : #include "nsRect.h"
13 : #include "nsTArray.h"
14 :
15 : class nsIVariant;
16 :
17 : namespace mozilla {
18 : namespace a11y {
19 :
20 : class Accessible;
21 : class HyperTextAccessible;
22 :
23 : /**
24 : * A text point (hyper text + offset), represents a boundary of text range.
25 : */
26 : struct TextPoint final
27 : {
28 0 : TextPoint(HyperTextAccessible* aContainer, int32_t aOffset) :
29 0 : mContainer(aContainer), mOffset(aOffset) { }
30 : TextPoint(const TextPoint& aPoint) :
31 : mContainer(aPoint.mContainer), mOffset(aPoint.mOffset) { }
32 :
33 : HyperTextAccessible* mContainer;
34 : int32_t mOffset;
35 :
36 0 : bool operator ==(const TextPoint& aPoint) const
37 0 : { return mContainer == aPoint.mContainer && mOffset == aPoint.mOffset; }
38 : bool operator <(const TextPoint& aPoint) const;
39 : };
40 :
41 : /**
42 : * Represents a text range within the text control or document.
43 : */
44 0 : class TextRange final
45 : {
46 : public:
47 : TextRange(HyperTextAccessible* aRoot,
48 : HyperTextAccessible* aStartContainer, int32_t aStartOffset,
49 : HyperTextAccessible* aEndContainer, int32_t aEndOffset);
50 0 : TextRange() {}
51 0 : TextRange(TextRange&& aRange) :
52 0 : mRoot(mozilla::Move(aRange.mRoot)),
53 0 : mStartContainer(mozilla::Move(aRange.mStartContainer)),
54 0 : mEndContainer(mozilla::Move(aRange.mEndContainer)),
55 0 : mStartOffset(aRange.mStartOffset), mEndOffset(aRange.mEndOffset) {}
56 :
57 0 : TextRange& operator= (TextRange&& aRange)
58 : {
59 0 : mRoot = mozilla::Move(aRange.mRoot);
60 0 : mStartContainer = mozilla::Move(aRange.mStartContainer);
61 0 : mEndContainer = mozilla::Move(aRange.mEndContainer);
62 0 : mStartOffset = aRange.mStartOffset;
63 0 : mEndOffset = aRange.mEndOffset;
64 0 : return *this;
65 : }
66 :
67 0 : HyperTextAccessible* StartContainer() const { return mStartContainer; }
68 0 : int32_t StartOffset() const { return mStartOffset; }
69 0 : HyperTextAccessible* EndContainer() const { return mEndContainer; }
70 0 : int32_t EndOffset() const { return mEndOffset; }
71 :
72 0 : bool operator ==(const TextRange& aRange) const
73 : {
74 0 : return mStartContainer == aRange.mStartContainer &&
75 0 : mStartOffset == aRange.mStartOffset &&
76 0 : mEndContainer == aRange.mEndContainer && mEndOffset == aRange.mEndOffset;
77 : }
78 :
79 0 : TextPoint StartPoint() const { return TextPoint(mStartContainer, mStartOffset); }
80 0 : TextPoint EndPoint() const { return TextPoint(mEndContainer, mEndOffset); }
81 :
82 : /**
83 : * Return a container containing both start and end points.
84 : */
85 : Accessible* Container() const;
86 :
87 : /**
88 : * Return a list of embedded objects enclosed by the text range (includes
89 : * partially overlapped objects).
90 : */
91 : void EmbeddedChildren(nsTArray<Accessible*>* aChildren) const;
92 :
93 : /**
94 : * Return text enclosed by the range.
95 : */
96 : void Text(nsAString& aText) const;
97 :
98 : /**
99 : * Return list of bounding rects of the text range by lines.
100 : */
101 : void Bounds(nsTArray<nsIntRect> aRects) const;
102 :
103 : enum ETextUnit {
104 : eFormat,
105 : eWord,
106 : eLine,
107 : eParagraph,
108 : ePage,
109 : eDocument
110 : };
111 :
112 : /**
113 : * Move the range or its points on specified amount of given units.
114 : */
115 : void Move(ETextUnit aUnit, int32_t aCount)
116 : {
117 : MoveEnd(aUnit, aCount);
118 : MoveStart(aUnit, aCount);
119 : }
120 : void MoveStart(ETextUnit aUnit, int32_t aCount)
121 : {
122 : MoveInternal(aUnit, aCount, *mStartContainer, mStartOffset,
123 : mEndContainer, mEndOffset);
124 : }
125 : void MoveEnd(ETextUnit aUnit, int32_t aCount)
126 : { MoveInternal(aUnit, aCount, *mEndContainer, mEndOffset); }
127 :
128 : /**
129 : * Move the range points to the closest unit boundaries.
130 : */
131 : void Normalize(ETextUnit aUnit);
132 :
133 : /**
134 : * Crops the range if it overlaps the given accessible element boundaries,
135 : * returns true if the range was cropped successfully.
136 : */
137 : bool Crop(Accessible* aContainer);
138 :
139 : enum EDirection {
140 : eBackward,
141 : eForward
142 : };
143 :
144 : /**
145 : * Return range enclosing the found text.
146 : */
147 : void FindText(const nsAString& aText, EDirection aDirection,
148 : nsCaseTreatment aCaseSensitive, TextRange* aFoundRange) const;
149 :
150 : enum EAttr {
151 : eAnimationStyleAttr,
152 : eAnnotationObjectsAttr,
153 : eAnnotationTypesAttr,
154 : eBackgroundColorAttr,
155 : eBulletStyleAttr,
156 : eCapStyleAttr,
157 : eCaretBidiModeAttr,
158 : eCaretPositionAttr,
159 : eCultureAttr,
160 : eFontNameAttr,
161 : eFontSizeAttr,
162 : eFontWeightAttr,
163 : eForegroundColorAttr,
164 : eHorizontalTextAlignmentAttr,
165 : eIndentationFirstLineAttr,
166 : eIndentationLeadingAttr,
167 : eIndentationTrailingAttr,
168 : eIsActiveAttr,
169 : eIsHiddenAttr,
170 : eIsItalicAttr,
171 : eIsReadOnlyAttr,
172 : eIsSubscriptAttr,
173 : eIsSuperscriptAttr,
174 : eLinkAttr,
175 : eMarginBottomAttr,
176 : eMarginLeadingAttr,
177 : eMarginTopAttr,
178 : eMarginTrailingAttr,
179 : eOutlineStylesAttr,
180 : eOverlineColorAttr,
181 : eOverlineStyleAttr,
182 : eSelectionActiveEndAttr,
183 : eStrikethroughColorAttr,
184 : eStrikethroughStyleAttr,
185 : eStyleIdAttr,
186 : eStyleNameAttr,
187 : eTabsAttr,
188 : eTextFlowDirectionsAttr,
189 : eUnderlineColorAttr,
190 : eUnderlineStyleAttr
191 : };
192 :
193 : /**
194 : * Return range enclosing text having requested attribute.
195 : */
196 : void FindAttr(EAttr aAttr, nsIVariant* aValue, EDirection aDirection,
197 : TextRange* aFoundRange) const;
198 :
199 : /**
200 : * Add/remove the text range from selection.
201 : */
202 : void AddToSelection() const;
203 : void RemoveFromSelection() const;
204 : void Select() const;
205 :
206 : /**
207 : * Scroll the text range into view.
208 : */
209 : enum EHowToAlign {
210 : eAlignToTop,
211 : eAlignToBottom
212 : };
213 : void ScrollIntoView(EHowToAlign aHow) const;
214 :
215 : /**
216 : * Return true if this TextRange object represents an actual range of text.
217 : */
218 0 : bool IsValid() const { return mRoot; }
219 :
220 : void SetStartPoint(HyperTextAccessible* aContainer, int32_t aOffset)
221 : { mStartContainer = aContainer; mStartOffset = aOffset; }
222 : void SetEndPoint(HyperTextAccessible* aContainer, int32_t aOffset)
223 : { mStartContainer = aContainer; mStartOffset = aOffset; }
224 :
225 : private:
226 : TextRange(const TextRange& aRange) = delete;
227 : TextRange& operator=(const TextRange& aRange) = delete;
228 :
229 : friend class HyperTextAccessible;
230 : friend class xpcAccessibleTextRange;
231 :
232 : void Set(HyperTextAccessible* aRoot,
233 : HyperTextAccessible* aStartContainer, int32_t aStartOffset,
234 : HyperTextAccessible* aEndContainer, int32_t aEndOffset);
235 :
236 : /**
237 : * Text() method helper.
238 : * @param aText [in,out] calculated text
239 : * @param aCurrent [in] currently traversed node
240 : * @param aStartIntlOffset [in] start offset if current node is a text node
241 : * @return true if calculation is not finished yet
242 : */
243 : bool TextInternal(nsAString& aText, Accessible* aCurrent,
244 : uint32_t aStartIntlOffset) const;
245 :
246 : void MoveInternal(ETextUnit aUnit, int32_t aCount,
247 : HyperTextAccessible& aContainer, int32_t aOffset,
248 : HyperTextAccessible* aStopContainer = nullptr,
249 : int32_t aStopOffset = 0);
250 :
251 : /**
252 : * A helper method returning a common parent for two given accessible
253 : * elements.
254 : */
255 : Accessible* CommonParent(Accessible* aAcc1, Accessible* aAcc2,
256 : nsTArray<Accessible*>* aParents1, uint32_t* aPos1,
257 : nsTArray<Accessible*>* aParents2, uint32_t* aPos2) const;
258 :
259 : RefPtr<HyperTextAccessible> mRoot;
260 : RefPtr<HyperTextAccessible> mStartContainer;
261 : RefPtr<HyperTextAccessible> mEndContainer;
262 : int32_t mStartOffset;
263 : int32_t mEndOffset;
264 : };
265 :
266 :
267 : } // namespace a11y
268 : } // namespace mozilla
269 :
270 : #endif
|