Reduce uses of PassRefPtr in WebCore/dom - 6
[WebKit-https.git] / Source / WebCore / dom / DocumentMarker.h
1 /*
2  * This file is part of the DOM implementation for WebCore.
3  *
4  * Copyright (C) 2006 Apple Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifndef DocumentMarker_h
24 #define DocumentMarker_h
25
26 #include <wtf/Forward.h>
27 #include <wtf/RefCounted.h>
28 #include <wtf/RefPtr.h>
29 #include <wtf/text/WTFString.h>
30
31 #if PLATFORM(IOS)
32 #import <wtf/RetainPtr.h>
33 typedef struct objc_object *id;
34 #endif
35
36 namespace WebCore {
37
38 class DocumentMarkerDetails;
39
40 // A range of a node within a document that is "marked", such as the range of a misspelled word.
41 // It optionally includes a description that could be displayed in the user interface.
42 // It also optionally includes a flag specifying whether the match is active, which is ignored
43 // for all types other than type TextMatch.
44 class DocumentMarker {
45 public:
46     enum MarkerType {
47         Spelling = 1 << 0,
48         Grammar = 1 << 1,
49         TextMatch = 1 << 2,
50         // Text has been modified by spell correction, reversion of spell correction or other type of substitution. 
51         // On some platforms, this prevents the text from being autocorrected again. On post Snow Leopard Mac OS X, 
52         // if a Replacement marker contains non-empty description, a reversion UI will be shown.
53         Replacement = 1 << 3,
54         // Renderer needs to add underline indicating that the text has been modified by spell
55         // correction. Text with Replacement marker doesn't necessarily has CorrectionIndicator
56         // marker. For instance, after some text has been corrected, it will have both Replacement
57         // and CorrectionIndicator. However, if user further modifies such text, we would remove
58         // CorrectionIndicator marker, but retain Replacement marker.
59         CorrectionIndicator = 1 << 4,
60         // Correction suggestion has been offered, but got rejected by user.
61         RejectedCorrection = 1 << 5,
62         // Text has been modified by autocorrection. The description of this marker is the original text before autocorrection.
63         Autocorrected = 1 << 6,
64         // On some platforms, this prevents the text from being spellchecked again.
65         SpellCheckingExemption = 1 << 7,
66         // This marker indicates user has deleted an autocorrection starting at the end of the
67         // range that bears this marker. In some platforms, if the user later inserts the same original
68         // word again at this position, it will not be autocorrected again. The description of this
69         // marker is the original word before autocorrection was applied.
70         DeletedAutocorrection = 1 << 8,
71         // This marker indicates that the range of text spanned by the marker is entered by voice dictation,
72         // and it has alternative text.
73         DictationAlternatives = 1 << 9,
74 #if ENABLE(TELEPHONE_NUMBER_DETECTION)
75         TelephoneNumber = 1 << 10,
76 #endif
77 #if PLATFORM(IOS)
78         // FIXME: iOS should share the same Dictation marks as everyone else.
79         DictationPhraseWithAlternatives = 1 << 11,
80         DictationResult = 1 << 12,
81 #endif
82         // This marker indicates that the user has selected a text candidate.
83         AcceptedCandidate = 1 << 13,
84     };
85
86     class MarkerTypes {
87     public:
88         // The constructor is intentionally implicit to allow conversion from the bit-wise sum of above types
89         MarkerTypes(unsigned mask) : m_mask(mask) { }
90
91         bool contains(MarkerType type) const { return m_mask & type; }
92         bool intersects(const MarkerTypes& types) const { return (m_mask & types.m_mask); }
93         bool operator==(const MarkerTypes& other) const { return m_mask == other.m_mask; }
94
95         void add(const MarkerTypes& types) { m_mask |= types.m_mask; }
96         void remove(const MarkerTypes& types) { m_mask &= ~types.m_mask; }
97
98     private:
99         unsigned m_mask;
100     };
101
102     class AllMarkers : public MarkerTypes {
103     public:
104         AllMarkers()
105 #if !PLATFORM(IOS)
106 #if !ENABLE(TELEPHONE_NUMBER_DETECTION)
107             : MarkerTypes(Spelling | Grammar | TextMatch | Replacement | CorrectionIndicator | RejectedCorrection | Autocorrected | SpellCheckingExemption | DeletedAutocorrection | DictationAlternatives | AcceptedCandidate)
108 #else
109             : MarkerTypes(Spelling | Grammar | TextMatch | Replacement | CorrectionIndicator | RejectedCorrection | Autocorrected | SpellCheckingExemption | DeletedAutocorrection | DictationAlternatives | TelephoneNumber | AcceptedCandidate)
110 #endif // !ENABLE(TELEPHONE_NUMBER_DETECTION)
111 #else
112             : MarkerTypes(Spelling | Grammar | TextMatch | Replacement | CorrectionIndicator | RejectedCorrection | Autocorrected | SpellCheckingExemption | DeletedAutocorrection | DictationAlternatives | TelephoneNumber | DictationPhraseWithAlternatives | DictationResult | AcceptedCandidate)
113 #endif // !PLATFORM(IOS)
114         {
115         }
116     };
117
118     DocumentMarker();
119     DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset);
120     DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset, const String& description);
121 #if PLATFORM(IOS)
122     DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset, const String& description, const Vector<String>& alternatives, RetainPtr<id> metadata);
123 #endif
124     DocumentMarker(unsigned startOffset, unsigned endOffset, bool activeMatch);
125     DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset, RefPtr<DocumentMarkerDetails>&&);
126
127     MarkerType type() const { return m_type; }
128     unsigned startOffset() const { return m_startOffset; }
129     unsigned endOffset() const { return m_endOffset; }
130
131     WEBCORE_EXPORT const String& description() const;
132     bool activeMatch() const;
133     DocumentMarkerDetails* details() const;
134
135     void setActiveMatch(bool);
136     void clearDetails() { m_details = nullptr; }
137
138     // Offset modifications are done by DocumentMarkerController.
139     // Other classes should not call following setters.
140     void setStartOffset(unsigned offset) { m_startOffset = offset; }
141     void setEndOffset(unsigned offset) { m_endOffset = offset; }
142     void shiftOffsets(int delta);
143
144 #if PLATFORM(IOS)
145     const Vector<String>& alternatives() const;
146     void setAlternative(const String&, size_t index);
147     id metadata() const;
148     void setMetadata(id);
149 #endif
150
151     bool operator==(const DocumentMarker& o) const
152     {
153         return type() == o.type() && startOffset() == o.startOffset() && endOffset() == o.endOffset();
154     }
155
156     bool operator!=(const DocumentMarker& o) const
157     {
158         return !(*this == o);
159     }
160
161 private:
162     MarkerType m_type;
163     unsigned m_startOffset;
164     unsigned m_endOffset;
165 #if PLATFORM(IOS)
166     // FIXME: See <rdar://problem/9431249>.
167     Vector<String> m_alternatives;
168     RetainPtr<id> m_metadata;
169 #endif
170     RefPtr<DocumentMarkerDetails> m_details;
171 };
172
173 inline DocumentMarkerDetails* DocumentMarker::details() const
174 {
175     return m_details.get();
176 }
177
178 #if PLATFORM(IOS)
179 inline DocumentMarker::DocumentMarker(MarkerType type, unsigned startOffset, unsigned endOffset, const String&, const Vector<String>& alternatives, RetainPtr<id> metadata)
180     : m_type(type)
181     , m_startOffset(startOffset)
182     , m_endOffset(endOffset)
183     , m_alternatives(alternatives)
184     , m_metadata(metadata)
185 {
186     // FIXME: <rdar://problem/11306422> iOS should investigate cleaner merge with ToT Dictation support
187     ASSERT(type == DictationPhraseWithAlternatives || type == DictationResult);
188 }
189 #endif
190
191 #if PLATFORM(IOS)
192 inline const Vector<String>& DocumentMarker::alternatives() const
193 {
194     ASSERT(m_type == DocumentMarker::DictationPhraseWithAlternatives);
195     return m_alternatives;
196 }
197
198 inline void DocumentMarker::setAlternative(const String& alternative, size_t index)
199 {
200     ASSERT(m_type == DocumentMarker::DictationPhraseWithAlternatives);
201     m_alternatives[index] = alternative;
202 }
203
204 inline id DocumentMarker::metadata() const
205 {
206     return m_metadata.get();
207 }
208
209 inline void DocumentMarker::setMetadata(id metadata)
210 {
211     m_metadata = metadata;
212 }
213 #endif
214
215 class DocumentMarkerDetails : public RefCounted<DocumentMarkerDetails>
216 {
217 public:
218     DocumentMarkerDetails() { }
219     virtual ~DocumentMarkerDetails();
220     virtual bool isDescription() const { return false; }
221     virtual bool isTextMatch() const { return false; }
222 };
223
224 } // namespace WebCore
225
226 #endif // DocumentMarker_h