Line data Source code
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/. */
5 :
6 : #ifndef mozilla_a11y_HyperTextAccessible_inl_h__
7 : #define mozilla_a11y_HyperTextAccessible_inl_h__
8 :
9 : #include "HyperTextAccessible.h"
10 :
11 : #include "nsAccUtils.h"
12 :
13 : #include "nsIClipboard.h"
14 : #include "nsIEditor.h"
15 : #include "nsIPersistentProperties2.h"
16 : #include "nsIPlaintextEditor.h"
17 : #include "nsFrameSelection.h"
18 :
19 : namespace mozilla {
20 : namespace a11y {
21 :
22 : inline bool
23 0 : HyperTextAccessible::IsValidOffset(int32_t aOffset)
24 : {
25 0 : index_t offset = ConvertMagicOffset(aOffset);
26 0 : return offset.IsValid() && offset <= CharacterCount();
27 : }
28 :
29 : inline bool
30 0 : HyperTextAccessible::IsValidRange(int32_t aStartOffset, int32_t aEndOffset)
31 : {
32 0 : index_t startOffset = ConvertMagicOffset(aStartOffset);
33 0 : index_t endOffset = ConvertMagicOffset(aEndOffset);
34 0 : return startOffset.IsValid() && endOffset.IsValid() &&
35 0 : startOffset <= endOffset && endOffset <= CharacterCount();
36 : }
37 :
38 : inline void
39 0 : HyperTextAccessible::SetCaretOffset(int32_t aOffset)
40 : {
41 0 : SetSelectionRange(aOffset, aOffset);
42 : // XXX: Force cache refresh until a good solution for AT emulation of user
43 : // input is implemented (AccessFu caret movement).
44 0 : SelectionMgr()->UpdateCaretOffset(this, aOffset);
45 0 : }
46 :
47 : inline bool
48 0 : HyperTextAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset)
49 : {
50 0 : dom::Selection* domSel = DOMSelection();
51 0 : return domSel &&
52 0 : SetSelectionBoundsAt(domSel->RangeCount(), aStartOffset, aEndOffset);
53 : }
54 :
55 : inline void
56 0 : HyperTextAccessible::ReplaceText(const nsAString& aText)
57 : {
58 : // We need to call DeleteText() even if there is no contents because we need
59 : // to ensure to move focus to the editor via SetSelectionRange() called in
60 : // DeleteText().
61 0 : DeleteText(0, CharacterCount());
62 :
63 0 : nsCOMPtr<nsIEditor> editor = GetEditor();
64 0 : nsCOMPtr<nsIPlaintextEditor> plaintextEditor(do_QueryInterface(editor));
65 0 : if (!plaintextEditor) {
66 0 : return;
67 : }
68 :
69 : // DeleteText() may cause inserting <br> element in some cases. Let's
70 : // select all again and replace whole contents.
71 0 : editor->SelectAll();
72 :
73 0 : plaintextEditor->InsertText(aText);
74 : }
75 :
76 : inline void
77 0 : HyperTextAccessible::InsertText(const nsAString& aText, int32_t aPosition)
78 : {
79 0 : nsCOMPtr<nsIEditor> editor = GetEditor();
80 0 : nsCOMPtr<nsIPlaintextEditor> peditor(do_QueryInterface(editor));
81 0 : if (peditor) {
82 0 : SetSelectionRange(aPosition, aPosition);
83 0 : peditor->InsertText(aText);
84 : }
85 0 : }
86 :
87 : inline void
88 0 : HyperTextAccessible::CopyText(int32_t aStartPos, int32_t aEndPos)
89 : {
90 0 : nsCOMPtr<nsIEditor> editor = GetEditor();
91 0 : if (editor) {
92 0 : SetSelectionRange(aStartPos, aEndPos);
93 0 : editor->Copy();
94 : }
95 0 : }
96 :
97 : inline void
98 0 : HyperTextAccessible::CutText(int32_t aStartPos, int32_t aEndPos)
99 : {
100 0 : nsCOMPtr<nsIEditor> editor = GetEditor();
101 0 : if (editor) {
102 0 : SetSelectionRange(aStartPos, aEndPos);
103 0 : editor->Cut();
104 : }
105 0 : }
106 :
107 : inline void
108 0 : HyperTextAccessible::DeleteText(int32_t aStartPos, int32_t aEndPos)
109 : {
110 0 : nsCOMPtr<nsIEditor> editor = GetEditor();
111 0 : if (editor) {
112 0 : SetSelectionRange(aStartPos, aEndPos);
113 0 : editor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
114 : }
115 0 : }
116 :
117 : inline void
118 0 : HyperTextAccessible::PasteText(int32_t aPosition)
119 : {
120 0 : nsCOMPtr<nsIEditor> editor = GetEditor();
121 0 : if (editor) {
122 0 : SetSelectionRange(aPosition, aPosition);
123 0 : editor->Paste(nsIClipboard::kGlobalClipboard);
124 : }
125 0 : }
126 :
127 : inline index_t
128 0 : HyperTextAccessible::ConvertMagicOffset(int32_t aOffset) const
129 : {
130 0 : if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
131 0 : return CharacterCount();
132 :
133 0 : if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
134 0 : return CaretOffset();
135 :
136 0 : return aOffset;
137 : }
138 :
139 : inline uint32_t
140 0 : HyperTextAccessible::AdjustCaretOffset(uint32_t aOffset) const
141 : {
142 : // It is the same character offset when the caret is visually at the very
143 : // end of a line or the start of a new line (soft line break). Getting text
144 : // at the line should provide the line with the visual caret, otherwise
145 : // screen readers will announce the wrong line as the user presses up or
146 : // down arrow and land at the end of a line.
147 0 : if (aOffset > 0 && IsCaretAtEndOfLine())
148 0 : return aOffset - 1;
149 :
150 0 : return aOffset;
151 : }
152 :
153 : inline bool
154 0 : HyperTextAccessible::IsCaretAtEndOfLine() const
155 : {
156 0 : RefPtr<nsFrameSelection> frameSelection = FrameSelection();
157 0 : return frameSelection &&
158 0 : frameSelection->GetHint() == CARET_ASSOCIATE_BEFORE;
159 : }
160 :
161 : inline already_AddRefed<nsFrameSelection>
162 0 : HyperTextAccessible::FrameSelection() const
163 : {
164 0 : nsIFrame* frame = GetFrame();
165 0 : return frame ? frame->GetFrameSelection() : nullptr;
166 : }
167 :
168 : inline dom::Selection*
169 0 : HyperTextAccessible::DOMSelection() const
170 : {
171 0 : RefPtr<nsFrameSelection> frameSelection = FrameSelection();
172 0 : return frameSelection ? frameSelection->GetSelection(SelectionType::eNormal) :
173 0 : nullptr;
174 : }
175 :
176 : } // namespace a11y
177 : } // namespace mozilla
178 :
179 : #endif
180 :
|