Bug 1760738 [wpt PR 33295] - Remove subresource loading with WebBundles's WPT of...
[gecko.git] / accessible / generic / HyperTextAccessible.h
blob33468a4d9897587904474a4a6f69f1784e0ea887
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_a11y_HyperTextAccessible_h__
7 #define mozilla_a11y_HyperTextAccessible_h__
9 #include "AccessibleWrap.h"
10 #include "mozilla/a11y/HyperTextAccessibleBase.h"
11 #include "nsIAccessibleText.h"
12 #include "nsIAccessibleTypes.h"
13 #include "nsIFrame.h" // only for nsSelectionAmount
14 #include "nsISelectionController.h"
15 #include "nsDirection.h"
16 #include "WordMovementType.h"
18 class nsFrameSelection;
19 class nsIFrame;
20 class nsRange;
21 class nsIWidget;
23 namespace mozilla {
24 class EditorBase;
25 namespace dom {
26 class Selection;
29 namespace a11y {
31 class TextLeafPoint;
32 class TextRange;
34 struct DOMPoint {
35 DOMPoint() : node(nullptr), idx(0) {}
36 DOMPoint(nsINode* aNode, int32_t aIdx) : node(aNode), idx(aIdx) {}
38 nsINode* node;
39 int32_t idx;
42 /**
43 * Special Accessible that knows how contain both text and embedded objects
45 class HyperTextAccessible : public AccessibleWrap,
46 public HyperTextAccessibleBase {
47 public:
48 HyperTextAccessible(nsIContent* aContent, DocAccessible* aDoc);
50 NS_INLINE_DECL_REFCOUNTING_INHERITED(HyperTextAccessible, AccessibleWrap)
52 // LocalAccessible
53 virtual already_AddRefed<AccAttributes> NativeAttributes() override;
54 virtual mozilla::a11y::role NativeRole() const override;
55 virtual uint64_t NativeState() const override;
57 virtual void Shutdown() override;
58 virtual bool RemoveChild(LocalAccessible* aAccessible) override;
59 virtual bool InsertChildAt(uint32_t aIndex, LocalAccessible* aChild) override;
60 virtual Relation RelationByType(RelationType aType) const override;
62 // HyperTextAccessible (static helper method)
64 // Convert content offset to rendered text offset
65 nsresult ContentToRenderedOffset(nsIFrame* aFrame, int32_t aContentOffset,
66 uint32_t* aRenderedOffset) const;
68 // Convert rendered text offset to content offset
69 nsresult RenderedToContentOffset(nsIFrame* aFrame, uint32_t aRenderedOffset,
70 int32_t* aContentOffset) const;
72 //////////////////////////////////////////////////////////////////////////////
73 // HyperLinkAccessible
75 /**
76 * Return link count within this hypertext accessible.
78 uint32_t LinkCount() { return EmbeddedChildCount(); }
80 /**
81 * Return link accessible at the given index.
83 LocalAccessible* LinkAt(uint32_t aIndex) { return EmbeddedChildAt(aIndex); }
85 //////////////////////////////////////////////////////////////////////////////
86 // HyperTextAccessible: DOM point to text offset conversions.
88 /**
89 * Turn a DOM point (node and offset) into a character offset of this
90 * hypertext. Will look for closest match when the DOM node does not have
91 * an accessible object associated with it. Will return an offset for the end
92 * of the string if the node is not found.
94 * @param aNode [in] the node to look for
95 * @param aNodeOffset [in] the offset to look for
96 * if -1 just look directly for the node
97 * if >=0 and aNode is text, this represents a char
98 * offset if >=0 and aNode is not text, this represents a child node offset
99 * @param aIsEndOffset [in] if true, then this offset is not inclusive. The
100 * character indicated by the offset returned is at [offset - 1]. This means
101 * if the passed-in offset is really in a descendant, then the offset
102 * returned will come just after the relevant embedded object characer. If
103 * false, then the offset is inclusive. The character indicated by the offset
104 * returned is at [offset]. If the passed-in offset in inside a descendant,
105 * then the returned offset will be on the relevant embedded object char.
107 uint32_t DOMPointToOffset(nsINode* aNode, int32_t aNodeOffset,
108 bool aIsEndOffset = false) const;
111 * Transform the given a11y point into the offset relative this hypertext.
113 uint32_t TransformOffset(LocalAccessible* aDescendant, uint32_t aOffset,
114 bool aIsEndOffset) const;
117 * Convert the given offset into DOM point.
119 * If offset is at text leaf then DOM point is (text node, offsetInTextNode),
120 * if before embedded object then (parent node, indexInParent), if after then
121 * (parent node, indexInParent + 1).
123 DOMPoint OffsetToDOMPoint(int32_t aOffset) const;
125 //////////////////////////////////////////////////////////////////////////////
126 // TextAccessible
128 using HyperTextAccessibleBase::CharAt;
130 char16_t CharAt(int32_t aOffset) {
131 nsAutoString charAtOffset;
132 CharAt(aOffset, charAtOffset);
133 return charAtOffset.CharAt(0);
137 * Return true if char at the given offset equals to given char.
139 bool IsCharAt(int32_t aOffset, char16_t aChar) {
140 return CharAt(aOffset) == aChar;
144 * Return true if terminal char is at the given offset.
146 bool IsLineEndCharAt(int32_t aOffset) { return IsCharAt(aOffset, '\n'); }
148 virtual void TextBeforeOffset(int32_t aOffset,
149 AccessibleTextBoundary aBoundaryType,
150 int32_t* aStartOffset, int32_t* aEndOffset,
151 nsAString& aText) override;
152 virtual void TextAtOffset(int32_t aOffset,
153 AccessibleTextBoundary aBoundaryType,
154 int32_t* aStartOffset, int32_t* aEndOffset,
155 nsAString& aText) override;
156 virtual void TextAfterOffset(int32_t aOffset,
157 AccessibleTextBoundary aBoundaryType,
158 int32_t* aStartOffset, int32_t* aEndOffset,
159 nsAString& aText) override;
161 virtual already_AddRefed<AccAttributes> TextAttributes(
162 bool aIncludeDefAttrs, int32_t aOffset, int32_t* aStartOffset,
163 int32_t* aEndOffset) override;
165 virtual already_AddRefed<AccAttributes> DefaultTextAttributes() override;
167 // HyperTextAccessibleBase provides an overload which takes an Accessible.
168 using HyperTextAccessibleBase::GetChildOffset;
169 virtual int32_t GetChildOffset(uint32_t aChildIndex,
170 bool aInvalidateAfter = false) const override;
172 virtual int32_t GetChildIndexAtOffset(uint32_t aOffset) const override;
174 virtual LocalAccessible* GetChildAtOffset(uint32_t aOffset) const override {
175 return LocalChildAt(GetChildIndexAtOffset(aOffset));
179 * Return an offset at the given point.
181 int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
184 * Return a rect (in dev pixels) of the given text range relative given
185 * coordinate system.
187 LayoutDeviceIntRect TextBounds(
188 int32_t aStartOffset, int32_t aEndOffset,
189 uint32_t aCoordType =
190 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
193 * Return a rect (in dev pixels) for character at given offset relative given
194 * coordinate system.
196 LayoutDeviceIntRect CharBounds(int32_t aOffset, uint32_t aCoordType) {
197 int32_t endOffset = aOffset == static_cast<int32_t>(CharacterCount())
198 ? aOffset
199 : aOffset + 1;
200 return TextBounds(aOffset, endOffset, aCoordType);
204 * Get/set caret offset, if no caret then -1.
206 virtual int32_t CaretOffset() const override;
207 void SetCaretOffset(int32_t aOffset);
210 * Provide the line number for the caret.
211 * @return 1-based index for the line number with the caret
213 int32_t CaretLineNumber();
216 * Return the caret rect and the widget containing the caret within this
217 * text accessible.
219 * @param [out] the widget containing the caret
220 * @return the caret rect
222 mozilla::LayoutDeviceIntRect GetCaretRect(nsIWidget** aWidget);
225 * Return true if caret is at end of line.
227 bool IsCaretAtEndOfLine() const;
229 virtual int32_t SelectionCount() override;
231 virtual bool SelectionBoundsAt(int32_t aSelectionNum, int32_t* aStartOffset,
232 int32_t* aEndOffset) override;
235 * Changes the start and end offset of the specified selection.
236 * @return true if succeeded
238 // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
239 MOZ_CAN_RUN_SCRIPT_BOUNDARY bool SetSelectionBoundsAt(int32_t aSelectionNum,
240 int32_t aStartOffset,
241 int32_t aEndOffset);
244 * Adds a selection bounded by the specified offsets.
245 * @return true if succeeded
247 bool AddToSelection(int32_t aStartOffset, int32_t aEndOffset);
250 * Removes the specified selection.
251 * @return true if succeeded
253 // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
254 MOZ_CAN_RUN_SCRIPT_BOUNDARY bool RemoveFromSelection(int32_t aSelectionNum);
257 * Scroll the given text range into view.
259 void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
260 uint32_t aScrollType);
263 * Scroll the given text range to the given point.
265 void ScrollSubstringToPoint(int32_t aStartOffset, int32_t aEndOffset,
266 uint32_t aCoordinateType, int32_t aX, int32_t aY);
269 * Return a range that encloses the text control or the document this
270 * accessible belongs to.
272 void EnclosingRange(TextRange& aRange) const;
274 virtual void SelectionRanges(nsTArray<TextRange>* aRanges) const override;
277 * Return an array of disjoint ranges of visible text within the text control
278 * or the document this accessible belongs to.
280 void VisibleRanges(nsTArray<TextRange>* aRanges) const;
283 * Return a range containing the given accessible.
285 void RangeByChild(LocalAccessible* aChild, TextRange& aRange) const;
288 * Return a range containing an accessible at the given point.
290 void RangeAtPoint(int32_t aX, int32_t aY, TextRange& aRange) const;
292 //////////////////////////////////////////////////////////////////////////////
293 // EditableTextAccessible
295 MOZ_CAN_RUN_SCRIPT_BOUNDARY void ReplaceText(const nsAString& aText);
296 MOZ_CAN_RUN_SCRIPT_BOUNDARY void InsertText(const nsAString& aText,
297 int32_t aPosition);
298 void CopyText(int32_t aStartPos, int32_t aEndPos);
299 MOZ_CAN_RUN_SCRIPT_BOUNDARY void CutText(int32_t aStartPos, int32_t aEndPos);
300 MOZ_CAN_RUN_SCRIPT_BOUNDARY void DeleteText(int32_t aStartPos,
301 int32_t aEndPos);
302 MOZ_CAN_RUN_SCRIPT
303 void PasteText(int32_t aPosition);
306 * Return the editor associated with the accessible.
307 * The result may be either TextEditor or HTMLEditor.
309 virtual already_AddRefed<EditorBase> GetEditor() const;
312 * Return DOM selection object for the accessible.
314 dom::Selection* DOMSelection() const;
316 protected:
317 virtual ~HyperTextAccessible() {}
319 // LocalAccessible
320 virtual ENameValueFlag NativeName(nsString& aName) const override;
322 // HyperTextAccessible
325 * Adjust an offset the caret stays at to get a text by line boundary.
327 uint32_t AdjustCaretOffset(uint32_t aOffset) const;
330 * Return true if the given offset points to terminal empty line if any.
332 bool IsEmptyLastLineOffset(int32_t aOffset) {
333 return aOffset == static_cast<int32_t>(CharacterCount()) &&
334 IsLineEndCharAt(aOffset - 1);
338 * Return an offset of the found word boundary.
340 uint32_t FindWordBoundary(uint32_t aOffset, nsDirection aDirection,
341 EWordMovementType aWordMovementType);
344 * Used to get begin/end of previous/this/next line. Note: end of line
345 * is an offset right before '\n' character if any, the offset is right after
346 * '\n' character is begin of line. In case of wrap word breaks these offsets
347 * are equal.
349 enum EWhichLineBoundary {
350 ePrevLineBegin,
351 ePrevLineEnd,
352 eThisLineBegin,
353 eThisLineEnd,
354 eNextLineBegin,
355 eNextLineEnd
359 * Return an offset for requested line boundary. See constants above.
361 uint32_t FindLineBoundary(uint32_t aOffset,
362 EWhichLineBoundary aWhichLineBoundary);
365 * Find the start offset for a paragraph , taking into account
366 * inner block elements and line breaks.
368 int32_t FindParagraphStartOffset(uint32_t aOffset);
371 * Find the end offset for a paragraph , taking into account
372 * inner block elements and line breaks.
374 int32_t FindParagraphEndOffset(uint32_t aOffset);
377 * Return an offset corresponding to the given direction and selection amount
378 * relative the given offset. A helper used to find word or line boundaries.
380 uint32_t FindOffset(uint32_t aOffset, nsDirection aDirection,
381 nsSelectionAmount aAmount,
382 EWordMovementType aWordMovementType = eDefaultBehavior);
385 * Return the boundaries (in dev pixels) of the substring in case of textual
386 * frame or frame boundaries in case of non textual frame, offsets are
387 * ignored.
389 LayoutDeviceIntRect GetBoundsInFrame(nsIFrame* aFrame,
390 uint32_t aStartRenderedOffset,
391 uint32_t aEndRenderedOffset);
393 // Selection helpers
396 * Return frame selection object for the accessible.
398 already_AddRefed<nsFrameSelection> FrameSelection() const;
401 * Return selection ranges within the accessible subtree.
403 void GetSelectionDOMRanges(SelectionType aSelectionType,
404 nsTArray<nsRange*>* aRanges);
406 // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
407 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult SetSelectionRange(int32_t aStartPos,
408 int32_t aEndPos);
410 // Helpers
411 nsresult GetDOMPointByFrameOffset(nsIFrame* aFrame, int32_t aOffset,
412 LocalAccessible* aAccessible,
413 mozilla::a11y::DOMPoint* aPoint);
416 * Set 'misspelled' text attribute and return range offsets where the
417 * attibute is stretched. If the text is not misspelled at the given offset
418 * then we expose only range offsets where text is not misspelled. The method
419 * is used by TextAttributes() method.
421 * @param aIncludeDefAttrs [in] points whether text attributes having default
422 * values of attributes should be included
423 * @param aSourceNode [in] the node we start to traverse from
424 * @param aStartOffset [in, out] the start offset
425 * @param aEndOffset [in, out] the end offset
426 * @param aAttributes [out, optional] result attributes
428 void GetSpellTextAttr(nsINode* aNode, uint32_t aNodeOffset,
429 uint32_t* aStartOffset, uint32_t* aEndOffset,
430 AccAttributes* aAttributes);
433 * Set xml-roles attributes for MathML elements.
434 * @param aAttributes
436 void SetMathMLXMLRoles(AccAttributes* aAttributes);
438 // HyperTextAccessibleBase
439 virtual const Accessible* Acc() const override { return this; }
441 private:
443 * End text offsets array.
445 mutable nsTArray<uint32_t> mOffsets;
448 ////////////////////////////////////////////////////////////////////////////////
449 // LocalAccessible downcasting method
451 inline HyperTextAccessible* LocalAccessible::AsHyperText() {
452 return IsHyperText() ? static_cast<HyperTextAccessible*>(this) : nullptr;
455 inline HyperTextAccessibleBase* LocalAccessible::AsHyperTextBase() {
456 return AsHyperText();
459 } // namespace a11y
460 } // namespace mozilla
462 #endif