Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp

Issue 2650113004: [WIP] Add support for Android SuggestionSpans when editing text (Closed)
Patch Set: Uploading the latest version from my repo so I can reference it Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights
7 * reserved. 7 * reserved.
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9 * (http://www.torchmobile.com/) 9 * (http://www.torchmobile.com/)
10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
(...skipping 15 matching lines...) Expand all
26 * 26 *
27 */ 27 */
28 28
29 #include "core/editing/markers/DocumentMarkerController.h" 29 #include "core/editing/markers/DocumentMarkerController.h"
30 30
31 #include <algorithm> 31 #include <algorithm>
32 #include "core/dom/Node.h" 32 #include "core/dom/Node.h"
33 #include "core/dom/NodeTraversal.h" 33 #include "core/dom/NodeTraversal.h"
34 #include "core/dom/Range.h" 34 #include "core/dom/Range.h"
35 #include "core/dom/Text.h" 35 #include "core/dom/Text.h"
36 #include "core/editing/FrameSelection.h"
36 #include "core/editing/iterators/TextIterator.h" 37 #include "core/editing/iterators/TextIterator.h"
37 #include "core/editing/markers/CompositionMarker.h" 38 #include "core/editing/markers/CompositionMarker.h"
38 #include "core/editing/markers/CompositionMarkerList.h" 39 #include "core/editing/markers/CompositionMarkerList.h"
39 #include "core/editing/markers/DocumentMarkerList.h" 40 #include "core/editing/markers/DocumentMarkerList.h"
40 #include "core/editing/markers/EditingMarkerList.h" 41 #include "core/editing/markers/EditingMarkerList.h"
41 #include "core/editing/markers/SpellCheckMarker.h" 42 #include "core/editing/markers/SpellCheckMarker.h"
42 #include "core/editing/markers/SpellCheckMarkerList.h" 43 #include "core/editing/markers/SpellCheckMarkerList.h"
44 #include "core/editing/markers/SuggestionHighlightMarker.h"
45 #include "core/editing/markers/SuggestionHighlightMarkerList.h"
46 #include "core/editing/markers/SuggestionMarkerList.h"
43 #include "core/editing/markers/TextMatchMarkerList.h" 47 #include "core/editing/markers/TextMatchMarkerList.h"
44 #include "core/frame/FrameView.h" 48 #include "core/frame/FrameView.h"
49 #include "core/frame/LocalFrame.h"
45 #include "core/layout/LayoutObject.h" 50 #include "core/layout/LayoutObject.h"
46 51
47 #ifndef NDEBUG 52 #ifndef NDEBUG
48 #include <stdio.h> 53 #include <stdio.h>
49 #endif 54 #endif
50 55
51 namespace blink { 56 namespace blink {
52 57
53 DocumentMarkerController::DocumentMarkerController(Document& document) 58 DocumentMarkerController::DocumentMarkerController(Document& document)
54 : m_document(&document) { 59 : m_document(&document) {
55 setContext(&document); 60 setContext(&document);
56 } 61 }
57 62
58 void DocumentMarkerController::clear() { 63 void DocumentMarkerController::clear() {
59 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 64 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
60 MarkerMap& markerMap = markerMapForType(type); 65 MarkerMap& markerMap = markerMapForType(type);
61 markerMap.clear(); 66 markerMap.clear();
62 } 67 }
68
69 // Don't reset m_nextSuggestionMarkerID so if anything is still holding
70 // onto an old ID, it won't get confused by new markers
63 } 71 }
64 72
65 void DocumentMarkerController::addGrammarOrSpellingMarker( 73 void DocumentMarkerController::addGrammarOrSpellingMarker(
66 const EphemeralRange& range, 74 const EphemeralRange& range,
67 DocumentMarker::MarkerType type, 75 DocumentMarker::MarkerType type,
68 const String& description) { 76 const String& description) {
69 DCHECK(!m_document->needsLayoutTreeUpdate()); 77 DCHECK(!m_document->needsLayoutTreeUpdate());
70 DCHECK(type == DocumentMarker::Grammar || type == DocumentMarker::Spelling) 78 DCHECK(type == DocumentMarker::Grammar || type == DocumentMarker::Spelling)
71 << type; 79 << type;
72 // Use a TextIterator to visit the potentially multiple nodes the range 80 // Use a TextIterator to visit the potentially multiple nodes the range
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 124
117 for (TextIterator markedText(range.startPosition(), range.endPosition()); 125 for (TextIterator markedText(range.startPosition(), range.endPosition());
118 !markedText.atEnd(); markedText.advance()) { 126 !markedText.atEnd(); markedText.advance()) {
119 addMarker(markedText.currentContainer(), 127 addMarker(markedText.currentContainer(),
120 new CompositionMarker(markedText.startOffsetInCurrentContainer(), 128 new CompositionMarker(markedText.startOffsetInCurrentContainer(),
121 markedText.endOffsetInCurrentContainer(), 129 markedText.endOffsetInCurrentContainer(),
122 underlineColor, thick, backgroundColor)); 130 underlineColor, thick, backgroundColor));
123 } 131 }
124 } 132 }
125 133
134 void DocumentMarkerController::addSuggestionMarker(const EphemeralRange& range,
135 Color underlineColor,
136 bool thick,
137 Color backgroundColor,
138 const Vector<String>& suggest ions) {
139 DCHECK(!m_document->needsLayoutTreeUpdate());
140
141 for (TextIterator markedText(range.startPosition(), range.endPosition());
142 !markedText.atEnd(); markedText.advance()) {
143 addMarker(markedText.currentContainer(),
144 new SuggestionMarker(
145 markedText.startOffsetInCurrentContainer(),
146 markedText.endOffsetInCurrentContainer(), underlineColor,
147 thick, backgroundColor, suggestions, m_nextSuggestionMarkerID+ +));
148 }
149 }
150
151 void DocumentMarkerController::addSuggestionHighlightMarker(
152 const EphemeralRange& range,
153 Color underlineColor,
154 bool thick,
155 Color backgroundColor) {
156 DCHECK(!m_document->needsLayoutTreeUpdate());
157
158 for (TextIterator markedText(range.startPosition(), range.endPosition());
159 !markedText.atEnd(); markedText.advance()) {
160 addMarker(markedText.currentContainer(),
161 new SuggestionHighlightMarker(
162 markedText.startOffsetInCurrentContainer(),
163 markedText.endOffsetInCurrentContainer(),
164 underlineColor,
165 thick, backgroundColor));
166 }
167 }
168
126 void DocumentMarkerController::prepareForDestruction() { 169 void DocumentMarkerController::prepareForDestruction() {
127 clear(); 170 clear();
128 } 171 }
129 172
130 void DocumentMarkerController::removeMarkers( 173 void DocumentMarkerController::removeMarkers(
131 const EphemeralRange& range, 174 const EphemeralRange& range,
132 DocumentMarker::MarkerTypes markerTypes, 175 DocumentMarker::MarkerTypes markerTypes,
133 RemovePartiallyOverlappingMarkerOrNot 176 RemovePartiallyOverlappingMarkerOrNot
134 shouldRemovePartiallyOverlappingMarker) { 177 shouldRemovePartiallyOverlappingMarker) {
135 DCHECK(!m_document->needsLayoutTreeUpdate()); 178 DCHECK(!m_document->needsLayoutTreeUpdate());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 PaintInvalidationDocumentMarkerChange); 248 PaintInvalidationDocumentMarkerChange);
206 } 249 }
207 } 250 }
208 251
209 void DocumentMarkerController::removeMarkers( 252 void DocumentMarkerController::removeMarkers(
210 Node* node, 253 Node* node,
211 unsigned startOffset, 254 unsigned startOffset,
212 int length, 255 int length,
213 DocumentMarker::MarkerTypes markerTypes, 256 DocumentMarker::MarkerTypes markerTypes,
214 RemovePartiallyOverlappingMarkerOrNot 257 RemovePartiallyOverlappingMarkerOrNot
215 shouldRemovePartiallyOverlappingMarker) { 258 shouldRemovePartiallyOverlappingMarker) {
216 if (length <= 0) 259 if (length <= 0)
217 return; 260 return;
218 261
219 bool docDirty = false; 262 bool docDirty = false;
220 for (DocumentMarker::MarkerType type : markerTypes) { 263 for (DocumentMarker::MarkerType type : markerTypes) {
221 MarkerMap& markerMap = markerMapForType(type); 264 MarkerMap& markerMap = markerMapForType(type);
222 auto it = markerMap.find(node); 265 auto it = markerMap.find(node);
223 if (it != markerMap.end()) { 266 if (it != markerMap.end()) {
224 docDirty = 267 docDirty =
225 (it->value->removeMarkers(startOffset, length, 268 (it->value->removeMarkers(startOffset, length,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 it->value->appendMarkersToInputList(&result); 303 it->value->appendMarkersToInputList(&result);
261 } 304 }
262 305
263 std::sort(result.begin(), result.end(), compareByStart); 306 std::sort(result.begin(), result.end(), compareByStart);
264 return result; 307 return result;
265 } 308 }
266 309
267 DocumentMarkerVector DocumentMarkerController::markersInRange( 310 DocumentMarkerVector DocumentMarkerController::markersInRange(
268 const EphemeralRange& range, 311 const EphemeralRange& range,
269 DocumentMarker::MarkerTypes markerTypes) { 312 DocumentMarker::MarkerTypes markerTypes) {
313 return markersInRangeInternal(range, markerTypes, false);
314 }
270 315
316 DocumentMarkerVector DocumentMarkerController::markersInRangeInclusive(
317 const EphemeralRange& range,
318 DocumentMarker::MarkerTypes markerTypes) {
319 return markersInRangeInternal(range, markerTypes, true);
320 }
321
322 DocumentMarkerVector DocumentMarkerController::markersInRangeInternal(
323 const EphemeralRange& range,
324 DocumentMarker::MarkerTypes markerTypes,
325 bool includeSpansTouchingEndpoints) {
271 DocumentMarkerVector foundMarkers; 326 DocumentMarkerVector foundMarkers;
272 327
273 Node* startContainer = range.startPosition().computeContainerNode(); 328 Node* startContainer = range.startPosition().computeContainerNode();
274 DCHECK(startContainer); 329 if (!startContainer)
330 return DocumentMarkerVector();
331
275 unsigned startOffset = static_cast<unsigned>( 332 unsigned startOffset = static_cast<unsigned>(
276 range.startPosition().computeOffsetInContainerNode()); 333 range.startPosition().computeOffsetInContainerNode());
334
277 Node* endContainer = range.endPosition().computeContainerNode(); 335 Node* endContainer = range.endPosition().computeContainerNode();
278 DCHECK(endContainer); 336 if (!endContainer)
337 return DocumentMarkerVector();
338
279 unsigned endOffset = 339 unsigned endOffset =
280 static_cast<unsigned>(range.endPosition().computeOffsetInContainerNode()); 340 static_cast<unsigned>(range.endPosition().computeOffsetInContainerNode());
281 341
282 for (Node& node : range.nodes()) { 342 for (Node& node : range.nodes()) {
283 for (DocumentMarker* marker : markersFor(&node)) { 343 for (DocumentMarker* marker : markersFor(&node)) {
284 if (!markerTypes.contains(marker->type())) 344 if (!markerTypes.contains(marker->type()))
285 continue; 345 continue;
286 if (node == startContainer && marker->endOffset() <= startOffset) 346 if (node == startContainer) {
287 continue; 347 if (marker->endOffset() < startOffset ||
288 if (node == endContainer && marker->startOffset() >= endOffset) 348 (marker->endOffset() == startOffset &&
289 continue; 349 !includeSpansTouchingEndpoints))
350 continue;
351 }
352 if (node == endContainer) {
353 if (marker->startOffset() > endOffset ||
354 (marker->startOffset() == endOffset &&
355 !includeSpansTouchingEndpoints))
356 continue;
357 }
290 foundMarkers.push_back(marker); 358 foundMarkers.push_back(marker);
291 } 359 }
292 } 360 }
293 return foundMarkers; 361 return foundMarkers;
294 } 362 }
295 363
296 Vector<IntRect> DocumentMarkerController::renderedRectsForTextMatchMarkers() { 364 Vector<IntRect> DocumentMarkerController::renderedRectsForTextMatchMarkers() {
297 Vector<IntRect> result; 365 Vector<IntRect> result;
298 for (auto nodeIterator = m_textMatches.begin(); 366 for (auto nodeIterator = m_textMatches.begin();
299 nodeIterator != m_textMatches.end(); ++nodeIterator) { 367 nodeIterator != m_textMatches.end(); ++nodeIterator) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 for (auto& nodeMarkers : m_textMatches) 399 for (auto& nodeMarkers : m_textMatches)
332 invalidateRectsForTextMatchMarkersInNode(*nodeMarkers.key); 400 invalidateRectsForTextMatchMarkersInNode(*nodeMarkers.key);
333 } 401 }
334 402
335 DEFINE_TRACE(DocumentMarkerController) { 403 DEFINE_TRACE(DocumentMarkerController) {
336 visitor->trace(m_spelling); 404 visitor->trace(m_spelling);
337 visitor->trace(m_grammar); 405 visitor->trace(m_grammar);
338 visitor->trace(m_textMatches); 406 visitor->trace(m_textMatches);
339 visitor->trace(m_compositions); 407 visitor->trace(m_compositions);
340 visitor->trace(m_document); 408 visitor->trace(m_document);
409 visitor->trace(m_suggestions);
410 visitor->trace(m_suggestionHighlights);
341 SynchronousMutationObserver::trace(visitor); 411 SynchronousMutationObserver::trace(visitor);
342 } 412 }
343 413
344 void DocumentMarkerController::removeMarkers( 414 void DocumentMarkerController::removeMarkers(
345 Node* node, 415 Node* node,
346 DocumentMarker::MarkerTypes markerTypes) { 416 DocumentMarker::MarkerTypes markerTypes) {
347 for (DocumentMarker::MarkerType type : markerTypes) { 417 for (DocumentMarker::MarkerType type : markerTypes) {
348 MarkerMap& markerMap = markerMapForType(type); 418 MarkerMap& markerMap = markerMapForType(type);
349 markerMap.erase(node); 419 markerMap.erase(node);
350 } 420 }
(...skipping 11 matching lines...) Expand all
362 const Vector<String>& words) { 432 const Vector<String>& words) {
363 for (auto& nodeMarkers : m_spelling) { 433 for (auto& nodeMarkers : m_spelling) {
364 const Node& node = *nodeMarkers.key; 434 const Node& node = *nodeMarkers.key;
365 if (!node.isTextNode()) 435 if (!node.isTextNode())
366 continue; 436 continue;
367 toSpellCheckMarkerList(nodeMarkers.value.get()) 437 toSpellCheckMarkerList(nodeMarkers.value.get())
368 ->removeMarkersForWords(static_cast<const Text&>(node).data(), words); 438 ->removeMarkersForWords(static_cast<const Text&>(node).data(), words);
369 } 439 }
370 } 440 }
371 441
442 void DocumentMarkerController::removeMarkersForWordsAffectedByEditing(
443 DocumentMarker::MarkerTypes markerTypes,
444 bool doNotRemoveIfSelectionAtWordBoundary) {
445 LOG(INFO) << "removeMarkersForWordsAffectedByEditing: " << doNotRemoveIfSelect ionAtWordBoundary;
446 LOG(INFO) << "clearing suggestion markers: " << markerTypes.contains(DocumentM arker::Suggestion);
447 DCHECK(m_document->frame()->selection().isAvailable());
448 TRACE_EVENT0(
449 "blink",
450 "DocumentMarkerController::removeMarkersForWordsAffectedByEditing");
451
452 Document* document = m_document->frame()->document();
453 DCHECK(document);
454
455 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
456 // needs to be audited. See http://crbug.com/590369 for more details.
457 document->updateStyleAndLayoutIgnorePendingStylesheets();
458
459 // We want to remove the markers from a word if an editing command will change
460 // the word. This can happen in one of several scenarios:
461 // 1. Insert in the middle of a word.
462 // 2. Appending non whitespace at the beginning of word.
463 // 3. Appending non whitespace at the end of word.
464 // Note that, appending only whitespaces at the beginning or end of word won't
465 // change the word, so we don't need to remove the markers on that word. Of
466 // course, if current selection is a range, we potentially will edit two words
467 // that fall on the boundaries of selection, and remove words between the
468 // selection boundaries.
469 VisiblePosition startOfSelection = m_document->frame()
470 ->selection()
471 .computeVisibleSelectionInDOMTree()
472 .visibleStart();
473 VisiblePosition endOfSelection = m_document->frame()
474 ->selection()
475 .computeVisibleSelectionInDOMTree()
476 .visibleEnd();
477 if (startOfSelection.isNull())
478 return;
479 // First word is the word that ends after or on the start of selection.
480 VisiblePosition startOfFirstWord =
481 startOfWord(startOfSelection, LeftWordIfOnBoundary);
482 VisiblePosition endOfFirstWord =
483 endOfWord(startOfSelection, LeftWordIfOnBoundary);
484 // Last word is the word that begins before or on the end of selection
485 VisiblePosition startOfLastWord =
486 startOfWord(endOfSelection, RightWordIfOnBoundary);
487 VisiblePosition endOfLastWord =
488 endOfWord(endOfSelection, RightWordIfOnBoundary);
489
490 if (startOfFirstWord.isNull()) {
491 startOfFirstWord = startOfWord(startOfSelection, RightWordIfOnBoundary);
492 endOfFirstWord = endOfWord(startOfSelection, RightWordIfOnBoundary);
493 }
494
495 if (endOfLastWord.isNull()) {
496 startOfLastWord = startOfWord(endOfSelection, LeftWordIfOnBoundary);
497 endOfLastWord = endOfWord(endOfSelection, LeftWordIfOnBoundary);
498 }
499
500 // If doNotRemoveIfSelectionAtWordBoundary is true, and first word ends at the
501 // start of selection, we choose next word as the first word.
502 if (doNotRemoveIfSelectionAtWordBoundary &&
503 endOfFirstWord.deepEquivalent() == startOfSelection.deepEquivalent()) {
504 startOfFirstWord = nextWordPosition(startOfFirstWord);
505 endOfFirstWord = endOfWord(startOfFirstWord, RightWordIfOnBoundary);
506 if (startOfFirstWord.deepEquivalent() == endOfSelection.deepEquivalent())
507 return;
508 }
509
510 // If doNotRemoveIfSelectionAtWordBoundary is true, and last word begins at
511 // the end of selection, we choose previous word as the last word.
512 if (doNotRemoveIfSelectionAtWordBoundary &&
513 startOfLastWord.deepEquivalent() == endOfSelection.deepEquivalent()) {
514 startOfLastWord = previousWordPosition(startOfLastWord);
515 endOfLastWord = endOfWord(startOfLastWord, RightWordIfOnBoundary);
516 if (endOfLastWord.deepEquivalent() == startOfSelection.deepEquivalent())
517 return;
518 }
519
520 if (startOfFirstWord.isNull() || endOfFirstWord.isNull() ||
521 startOfLastWord.isNull() || endOfLastWord.isNull())
522 return;
523
524 const Position& removeMarkerStart = startOfFirstWord.deepEquivalent();
525 const Position& removeMarkerEnd = endOfLastWord.deepEquivalent();
526 if (removeMarkerStart > removeMarkerEnd) {
527 // editing/inserting/insert-br-008.html and more reach here.
528 // TODO(yosin): To avoid |DCHECK(removeMarkerStart <= removeMarkerEnd)|
529 // in |EphemeralRange| constructor, we have this if-statement. Once we
530 // fix |startOfWord()| and |endOfWord()|, we should remove this
531 // if-statement.
532 return;
533 }
534
535 // Now we remove markers on everything between startOfFirstWord and
536 // endOfLastWord. However, if an autocorrection change a single word to
537 // multiple words, we want to remove correction mark from all the resulted
538 // words even we only edit one of them. For example, assuming autocorrection
539 // changes "avantgarde" to "avant garde", we will have CorrectionIndicator
540 // marker on both words and on the whitespace between them. If we then edit
541 // garde, we would like to remove the marker from word "avant" and whitespace
542 // as well. So we need to get the continous range of of marker that contains
543 // the word in question, and remove marker on that whole range.
544 const EphemeralRange wordRange(removeMarkerStart, removeMarkerEnd);
545 document->markers().removeMarkers(
546 wordRange, markerTypes,
547 DocumentMarkerController::RemovePartiallyOverlappingMarker);
548 }
549
372 void DocumentMarkerController::repaintMarkers( 550 void DocumentMarkerController::repaintMarkers(
373 DocumentMarker::MarkerTypes markerTypes) { 551 DocumentMarker::MarkerTypes markerTypes) {
374 HeapHashSet<Member<Node>> nodesToRepaint; 552 HeapHashSet<Member<Node>> nodesToRepaint;
375 for (DocumentMarker::MarkerType type : markerTypes) { 553 for (DocumentMarker::MarkerType type : markerTypes) {
376 MarkerMap& markerMap = markerMapForType(type); 554 MarkerMap& markerMap = markerMapForType(type);
377 for (auto& nodeMarkers : markerMap) { 555 for (auto& nodeMarkers : markerMap) {
378 if (!nodeMarkers.value->empty()) 556 if (!nodeMarkers.value->empty())
379 nodesToRepaint.insert(nodeMarkers.key.get()); 557 nodesToRepaint.insert(nodeMarkers.key.get());
380 } 558 }
381 } 559 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 DocumentMarker::MarkerType type) { 680 DocumentMarker::MarkerType type) {
503 switch (type) { 681 switch (type) {
504 case DocumentMarker::Spelling: 682 case DocumentMarker::Spelling:
505 return new SpellCheckMarkerList(DocumentMarker::Spelling); 683 return new SpellCheckMarkerList(DocumentMarker::Spelling);
506 case DocumentMarker::Grammar: 684 case DocumentMarker::Grammar:
507 return new SpellCheckMarkerList(DocumentMarker::Grammar); 685 return new SpellCheckMarkerList(DocumentMarker::Grammar);
508 case DocumentMarker::TextMatch: 686 case DocumentMarker::TextMatch:
509 return new TextMatchMarkerList(); 687 return new TextMatchMarkerList();
510 case DocumentMarker::Composition: 688 case DocumentMarker::Composition:
511 return new CompositionMarkerList(); 689 return new CompositionMarkerList();
690 case DocumentMarker::Suggestion:
691 return new SuggestionMarkerList();
692 case DocumentMarker::SuggestionHighlight:
693 return new SuggestionHighlightMarkerList();
512 default: 694 default:
513 // MSVC thinks this method doesn't handle all enum values even though it 695 // MSVC thinks this method doesn't handle all enum values even though it
514 // does. So we have to return something for the default case to avoid a 696 // does. So we have to return something for the default case to avoid a
515 // C4715 warning. 697 // C4715 warning.
516 UNREACHABLE(); 698 UNREACHABLE();
517 return nullptr; 699 return nullptr;
518 } 700 }
519 } 701 }
520 702
521 HeapVector<Member<DocumentMarkerList>> 703 HeapVector<Member<DocumentMarkerList>>
(...skipping 24 matching lines...) Expand all
546 DocumentMarker::MarkerType type) const { 728 DocumentMarker::MarkerType type) const {
547 switch (type) { 729 switch (type) {
548 case DocumentMarker::Spelling: 730 case DocumentMarker::Spelling:
549 return m_spelling; 731 return m_spelling;
550 case DocumentMarker::Grammar: 732 case DocumentMarker::Grammar:
551 return m_grammar; 733 return m_grammar;
552 case DocumentMarker::TextMatch: 734 case DocumentMarker::TextMatch:
553 return m_textMatches; 735 return m_textMatches;
554 case DocumentMarker::Composition: 736 case DocumentMarker::Composition:
555 return m_compositions; 737 return m_compositions;
738 case DocumentMarker::Suggestion:
739 return m_suggestions;
740 case DocumentMarker::SuggestionHighlight:
741 return m_suggestionHighlights;
556 default: 742 default:
557 // MSVC thinks this method doesn't handle all enum values even though it 743 // MSVC thinks this method doesn't handle all enum values even though it
558 // does. So we have to return something for the default case to avoid a 744 // does. So we have to return something for the default case to avoid a
559 // C4715 warning. 745 // C4715 warning.
560 UNREACHABLE(); 746 UNREACHABLE();
561 return m_spelling; 747 return m_spelling;
562 } 748 }
563 } 749 }
564 750
565 void DocumentMarkerController::removeMarkers( 751 void DocumentMarkerController::removeMarkers(
566 TextIterator& markedText, 752 TextIterator& markedText,
567 DocumentMarker::MarkerTypes markerTypes, 753 DocumentMarker::MarkerTypes markerTypes,
568 RemovePartiallyOverlappingMarkerOrNot 754 RemovePartiallyOverlappingMarkerOrNot
569 shouldRemovePartiallyOverlappingMarker) { 755 shouldRemovePartiallyOverlappingMarker) {
570 for (; !markedText.atEnd(); markedText.advance()) { 756 for (; !markedText.atEnd(); markedText.advance()) {
757 LOG(INFO) << "removing markers from " << markedText.currentContainer() << " from offsets " << markedText.startOffsetInCurrentContainer() << " to " << marked Text.endOffsetInCurrentContainer();
571 int startOffset = markedText.startOffsetInCurrentContainer(); 758 int startOffset = markedText.startOffsetInCurrentContainer();
572 int endOffset = markedText.endOffsetInCurrentContainer(); 759 int endOffset = markedText.endOffsetInCurrentContainer();
573 removeMarkers(markedText.currentContainer(), startOffset, 760 removeMarkers(markedText.currentContainer(), startOffset,
574 endOffset - startOffset, markerTypes, 761 endOffset - startOffset, markerTypes,
575 shouldRemovePartiallyOverlappingMarker); 762 shouldRemovePartiallyOverlappingMarker);
576 } 763 }
577 } 764 }
578 765
579 // SynchronousMutationObserver 766 // SynchronousMutationObserver
580 void DocumentMarkerController::didUpdateCharacterData(CharacterData* node, 767 void DocumentMarkerController::didUpdateCharacterData(CharacterData* node,
(...skipping 24 matching lines...) Expand all
605 } 792 }
606 793
607 } // namespace blink 794 } // namespace blink
608 795
609 #ifndef NDEBUG 796 #ifndef NDEBUG
610 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { 797 void showDocumentMarkers(const blink::DocumentMarkerController* controller) {
611 if (controller) 798 if (controller)
612 controller->showMarkers(); 799 controller->showMarkers();
613 } 800 }
614 #endif 801 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698