Bug 1477919 [wpt PR 12154] - url: DecodeURLEscapeSequences() should not apply UTF...
[gecko.git] / widget / TextRange.h
blob9ce888c855c9a1178038e66b8b858a94eb0f83c0
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_TextRage_h_
7 #define mozilla_TextRage_h_
9 #include <stdint.h>
11 #include "mozilla/EventForwards.h"
13 #include "nsColor.h"
14 #include "nsISelectionController.h"
15 #include "nsITextInputProcessor.h"
16 #include "nsStyleConsts.h"
17 #include "nsTArray.h"
19 namespace mozilla {
21 /******************************************************************************
22 * mozilla::TextRangeStyle
23 ******************************************************************************/
25 struct TextRangeStyle
27 enum
29 LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE,
30 LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID,
31 LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED,
32 LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED,
33 LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE,
34 LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY
37 enum
39 DEFINED_NONE = 0x00,
40 DEFINED_LINESTYLE = 0x01,
41 DEFINED_FOREGROUND_COLOR = 0x02,
42 DEFINED_BACKGROUND_COLOR = 0x04,
43 DEFINED_UNDERLINE_COLOR = 0x08
46 // Initialize all members, because TextRange instances may be compared by
47 // memcomp.
48 TextRangeStyle()
50 Clear();
53 void Clear()
55 mDefinedStyles = DEFINED_NONE;
56 mLineStyle = LINESTYLE_NONE;
57 mIsBoldLine = false;
58 mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0);
61 bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; }
63 bool IsLineStyleDefined() const
65 return (mDefinedStyles & DEFINED_LINESTYLE) != 0;
68 bool IsForegroundColorDefined() const
70 return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0;
73 bool IsBackgroundColorDefined() const
75 return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0;
78 bool IsUnderlineColorDefined() const
80 return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0;
83 bool IsNoChangeStyle() const
85 return !IsForegroundColorDefined() && !IsBackgroundColorDefined() &&
86 IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE;
89 bool Equals(const TextRangeStyle& aOther) const
91 if (mDefinedStyles != aOther.mDefinedStyles)
92 return false;
93 if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle ||
94 !mIsBoldLine != !aOther.mIsBoldLine))
95 return false;
96 if (IsForegroundColorDefined() &&
97 (mForegroundColor != aOther.mForegroundColor))
98 return false;
99 if (IsBackgroundColorDefined() &&
100 (mBackgroundColor != aOther.mBackgroundColor))
101 return false;
102 if (IsUnderlineColorDefined() &&
103 (mUnderlineColor != aOther.mUnderlineColor))
104 return false;
105 return true;
108 bool operator !=(const TextRangeStyle &aOther) const
110 return !Equals(aOther);
113 bool operator ==(const TextRangeStyle &aOther) const
115 return Equals(aOther);
118 uint8_t mDefinedStyles;
119 uint8_t mLineStyle; // DEFINED_LINESTYLE
121 bool mIsBoldLine; // DEFINED_LINESTYLE
123 nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR
124 nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR
125 nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR
128 /******************************************************************************
129 * mozilla::TextRange
130 ******************************************************************************/
132 enum class TextRangeType : RawTextRangeType
134 eUninitialized = 0x00,
135 eCaret = 0x01,
136 eRawClause = nsITextInputProcessor::ATTR_RAW_CLAUSE,
137 eSelectedRawClause = nsITextInputProcessor::ATTR_SELECTED_RAW_CLAUSE,
138 eConvertedClause = nsITextInputProcessor::ATTR_CONVERTED_CLAUSE,
139 eSelectedClause = nsITextInputProcessor::ATTR_SELECTED_CLAUSE
142 bool IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeValue);
143 RawTextRangeType ToRawTextRangeType(TextRangeType aTextRangeType);
144 TextRangeType ToTextRangeType(RawTextRangeType aRawTextRangeType);
145 const char* ToChar(TextRangeType aTextRangeType);
146 SelectionType ToSelectionType(TextRangeType aTextRangeType);
148 struct TextRange
150 TextRange()
151 : mStartOffset(0)
152 , mEndOffset(0)
153 , mRangeType(TextRangeType::eUninitialized)
157 uint32_t mStartOffset;
158 // XXX Storing end offset makes the initializing code very complicated.
159 // We should replace it with mLength.
160 uint32_t mEndOffset;
162 TextRangeStyle mRangeStyle;
164 TextRangeType mRangeType;
166 uint32_t Length() const { return mEndOffset - mStartOffset; }
168 bool IsClause() const
170 return mRangeType != TextRangeType::eCaret;
173 bool Equals(const TextRange& aOther) const
175 return mStartOffset == aOther.mStartOffset &&
176 mEndOffset == aOther.mEndOffset &&
177 mRangeType == aOther.mRangeType &&
178 mRangeStyle == aOther.mRangeStyle;
181 void RemoveCharacter(uint32_t aOffset)
183 if (mStartOffset > aOffset) {
184 --mStartOffset;
185 --mEndOffset;
186 } else if (mEndOffset > aOffset) {
187 --mEndOffset;
192 /******************************************************************************
193 * mozilla::TextRangeArray
194 ******************************************************************************/
195 class TextRangeArray final : public AutoTArray<TextRange, 10>
197 friend class WidgetCompositionEvent;
199 ~TextRangeArray() {}
201 NS_INLINE_DECL_REFCOUNTING(TextRangeArray)
203 const TextRange* GetTargetClause() const
205 for (uint32_t i = 0; i < Length(); ++i) {
206 const TextRange& range = ElementAt(i);
207 if (range.mRangeType == TextRangeType::eSelectedRawClause ||
208 range.mRangeType == TextRangeType::eSelectedClause) {
209 return &range;
212 return nullptr;
215 // Returns target clause offset. If there are selected clauses, this returns
216 // the first selected clause offset. Otherwise, 0.
217 uint32_t TargetClauseOffset() const
219 const TextRange* range = GetTargetClause();
220 return range ? range->mStartOffset : 0;
223 // Returns target clause length. If there are selected clauses, this returns
224 // the first selected clause length. Otherwise, UINT32_MAX.
225 uint32_t TargetClauseLength() const
227 const TextRange* range = GetTargetClause();
228 return range ? range->Length() : UINT32_MAX;
231 public:
232 bool IsComposing() const
234 for (uint32_t i = 0; i < Length(); ++i) {
235 if (ElementAt(i).IsClause()) {
236 return true;
239 return false;
242 bool Equals(const TextRangeArray& aOther) const
244 size_t len = Length();
245 if (len != aOther.Length()) {
246 return false;
248 for (size_t i = 0; i < len; i++) {
249 if (!ElementAt(i).Equals(aOther.ElementAt(i))) {
250 return false;
253 return true;
256 void RemoveCharacter(uint32_t aOffset)
258 for (size_t i = 0, len = Length(); i < len; i++) {
259 ElementAt(i).RemoveCharacter(aOffset);
263 bool HasCaret() const
265 for (const TextRange& range : *this) {
266 if (range.mRangeType == TextRangeType::eCaret) {
267 return true;
270 return false;
273 bool HasClauses() const
275 for (const TextRange& range : *this) {
276 if (range.IsClause()) {
277 return true;
280 return false;
283 uint32_t GetCaretPosition() const
285 for (const TextRange& range : *this) {
286 if (range.mRangeType == TextRangeType::eCaret) {
287 return range.mStartOffset;
290 return UINT32_MAX;
293 const TextRange* GetFirstClause() const
295 for (const TextRange& range : *this) {
296 // Look for the range of a clause whose start offset is 0 because the
297 // first clause's start offset is always 0.
298 if (range.IsClause() && !range.mStartOffset) {
299 return &range;
302 MOZ_ASSERT(!HasClauses());
303 return nullptr;
307 } // namespace mozilla
309 #endif // mozilla_TextRage_h_