1 /* 2 * This file is part of the DOM implementation for WebCore. 3 * 4 * Copyright (C) 2006 Apple Computer, 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 THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_DOCUMENT_MARKER_H_ 24 #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_DOCUMENT_MARKER_H_ 25 26 #include "base/optional.h" 27 #include "third_party/blink/renderer/core/core_export.h" 28 #include "third_party/blink/renderer/platform/graphics/color.h" 29 #include "third_party/blink/renderer/platform/heap/handle.h" 30 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" 31 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" 32 #include "third_party/blink/renderer/platform/wtf/vector_traits.h" 33 34 namespace blink { 35 36 // A range of a node within a document that is "marked", such as the range of a 37 // misspelled word. It optionally includes a description that could be displayed 38 // in the user interface. 39 class CORE_EXPORT DocumentMarker : public GarbageCollected<DocumentMarker> { 40 public: 41 enum MarkerTypeIndex { 42 kSpellingMarkerIndex = 0, 43 kGrammarMarkerIndex, 44 kTextMatchMarkerIndex, 45 kCompositionMarkerIndex, 46 kActiveSuggestionMarkerIndex, 47 kSuggestionMarkerIndex, 48 kTextFragmentMarkerIndex, 49 kMarkerTypeIndexesCount 50 }; 51 52 enum MarkerType { 53 kSpelling = 1 << kSpellingMarkerIndex, 54 kGrammar = 1 << kGrammarMarkerIndex, 55 kTextMatch = 1 << kTextMatchMarkerIndex, 56 kComposition = 1 << kCompositionMarkerIndex, 57 kActiveSuggestion = 1 << kActiveSuggestionMarkerIndex, 58 kSuggestion = 1 << kSuggestionMarkerIndex, 59 kTextFragment = 1 << kTextFragmentMarkerIndex, 60 }; 61 62 class MarkerTypesIterator 63 : public std::iterator<std::forward_iterator_tag, MarkerType> { 64 public: MarkerTypesIterator(unsigned marker_types)65 explicit MarkerTypesIterator(unsigned marker_types) 66 : remaining_types_(marker_types) {} 67 MarkerTypesIterator(const MarkerTypesIterator& other) = default; 68 69 bool operator==(const MarkerTypesIterator& other) { 70 return remaining_types_ == other.remaining_types_; 71 } 72 bool operator!=(const MarkerTypesIterator& other) { 73 return !operator==(other); 74 } 75 76 MarkerTypesIterator& operator++() { 77 DCHECK(remaining_types_); 78 // Turn off least significant 1-bit (from Hacker's Delight 2-1) 79 // Example: 80 // 7: 7 & 6 = 6 81 // 6: 6 & 5 = 4 82 // 4: 4 & 3 = 0 83 remaining_types_ &= (remaining_types_ - 1); 84 return *this; 85 } 86 87 MarkerType operator*() const { 88 DCHECK(remaining_types_); 89 // Isolate least significant 1-bit (from Hacker's Delight 2-1) 90 // Example: 91 // 7: 7 & -7 = 1 92 // 6: 6 & -6 = 2 93 // 4: 4 & -4 = 4 94 return static_cast<MarkerType>(remaining_types_ & 95 (~remaining_types_ + 1)); 96 } 97 98 private: 99 unsigned remaining_types_; 100 }; 101 102 class MarkerTypes { 103 DISALLOW_NEW(); 104 105 public: mask_(mask)106 explicit MarkerTypes(unsigned mask = 0) : mask_(mask) {} 107 All()108 static MarkerTypes All() { 109 return MarkerTypes((1 << kMarkerTypeIndexesCount) - 1); 110 } 111 AllBut(const MarkerTypes & types)112 static MarkerTypes AllBut(const MarkerTypes& types) { 113 return MarkerTypes(All().mask_ & ~types.mask_); 114 } 115 ActiveSuggestion()116 static MarkerTypes ActiveSuggestion() { 117 return MarkerTypes(kActiveSuggestion); 118 } Composition()119 static MarkerTypes Composition() { return MarkerTypes(kComposition); } Grammar()120 static MarkerTypes Grammar() { return MarkerTypes(kGrammar); } Misspelling()121 static MarkerTypes Misspelling() { 122 return MarkerTypes(kSpelling | kGrammar); 123 } Spelling()124 static MarkerTypes Spelling() { return MarkerTypes(kSpelling); } TextMatch()125 static MarkerTypes TextMatch() { return MarkerTypes(kTextMatch); } Suggestion()126 static MarkerTypes Suggestion() { return MarkerTypes(kSuggestion); } TextFragment()127 static MarkerTypes TextFragment() { return MarkerTypes(kTextFragment); } 128 Contains(MarkerType type)129 bool Contains(MarkerType type) const { return mask_ & type; } Intersects(const MarkerTypes & types)130 bool Intersects(const MarkerTypes& types) const { 131 return (mask_ & types.mask_); 132 } 133 bool operator==(const MarkerTypes& other) const { 134 return mask_ == other.mask_; 135 } 136 Add(const MarkerTypes & types)137 MarkerTypes Add(const MarkerTypes& types) const { 138 return MarkerTypes(mask_ | types.mask_); 139 } 140 begin()141 MarkerTypesIterator begin() const { return MarkerTypesIterator(mask_); } end()142 MarkerTypesIterator end() const { return MarkerTypesIterator(0); } 143 144 private: 145 unsigned mask_; 146 }; 147 148 virtual ~DocumentMarker(); 149 150 virtual MarkerType GetType() const = 0; StartOffset()151 unsigned StartOffset() const { return start_offset_; } EndOffset()152 unsigned EndOffset() const { return end_offset_; } 153 154 struct MarkerOffsets { 155 unsigned start_offset; 156 unsigned end_offset; 157 }; 158 159 base::Optional<MarkerOffsets> ComputeOffsetsAfterShift( 160 unsigned offset, 161 unsigned old_length, 162 unsigned new_length) const; 163 164 // Offset modifications are done by DocumentMarkerController. 165 // Other classes should not call following setters. SetStartOffset(unsigned offset)166 void SetStartOffset(unsigned offset) { start_offset_ = offset; } SetEndOffset(unsigned offset)167 void SetEndOffset(unsigned offset) { end_offset_ = offset; } 168 void ShiftOffsets(int delta); 169 Trace(Visitor * visitor)170 virtual void Trace(Visitor* visitor) const {} 171 172 protected: 173 DocumentMarker(unsigned start_offset, unsigned end_offset); 174 175 private: 176 unsigned start_offset_; 177 unsigned end_offset_; 178 179 DISALLOW_COPY_AND_ASSIGN(DocumentMarker); 180 }; 181 182 using DocumentMarkerVector = HeapVector<Member<DocumentMarker>>; 183 184 } // namespace blink 185 186 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_DOCUMENT_MARKER_H_ 187