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

Side by Side Diff: third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp

Issue 2202933002: Remove some further grammar checking code from SpellChecker (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 if (spellingSearchStart == spellingSearchEnd) 219 if (spellingSearchStart == spellingSearchEnd)
220 return; // nothing to search in 220 return; // nothing to search in
221 221
222 // We go to the end of our first range instead of the start of it, just to b e sure 222 // We go to the end of our first range instead of the start of it, just to b e sure
223 // we don't get foiled by any word boundary problems at the start. It means we might 223 // we don't get foiled by any word boundary problems at the start. It means we might
224 // do a tiny bit more searching. 224 // do a tiny bit more searching.
225 Node* searchEndNodeAfterWrap = spellingSearchEnd.computeContainerNode(); 225 Node* searchEndNodeAfterWrap = spellingSearchEnd.computeContainerNode();
226 int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode(); 226 int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode();
227 227
228 int misspellingOffset = 0; 228 int misspellingOffset = 0;
229 GrammarDetail grammarDetail; 229 String misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSea rchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false);
230 int grammarPhraseOffset = 0;
231 Position grammarSearchStart, grammarSearchEnd;
232 String badGrammarPhrase;
233 String misspelledWord;
234 230
235 bool isSpelling = true; 231 // If we did not find a misspelled word, wrap and try again (but don't bothe r if we started at the beginning of the
236 int foundOffset = 0;
237 String foundItem;
238 if (unifiedTextCheckerEnabled()) {
239 grammarSearchStart = spellingSearchStart;
240 grammarSearchEnd = spellingSearchEnd;
241 foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart , spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffset, g rammarDetail);
242 if (isSpelling) {
243 misspelledWord = foundItem;
244 misspellingOffset = foundOffset;
245 } else {
246 badGrammarPhrase = foundItem;
247 grammarPhraseOffset = foundOffset;
248 }
249 } else {
250 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearch Start, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false);
251 grammarSearchStart = spellingSearchStart;
252 grammarSearchEnd = spellingSearchEnd;
253 if (!misspelledWord.isEmpty()) {
254 // Stop looking at start of next misspelled word
255 CharacterIterator chars(grammarSearchStart, grammarSearchEnd);
256 chars.advance(misspellingOffset);
257 grammarSearchEnd = chars.startPosition();
258 }
259
260 badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearc hStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset , false);
261 }
262
263 // If we found neither bad grammar nor a misspelled word, wrap and try again (but don't bother if we started at the beginning of the
264 // block rather than at a selection). 232 // block rather than at a selection).
265 if (startedWithSelection && !misspelledWord && !badGrammarPhrase) { 233 if (startedWithSelection && !misspelledWord) {
266 spellingSearchStart = Position::editingPositionOf(topNode, 0); 234 spellingSearchStart = Position::editingPositionOf(topNode, 0);
267 // going until the end of the very first chunk we tested is far enough 235 // going until the end of the very first chunk we tested is far enough
268 spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap, searchEndOffsetAfterWrap); 236 spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap, searchEndOffsetAfterWrap);
269 237 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearch Start, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false);
270 if (unifiedTextCheckerEnabled()) {
271 grammarSearchStart = spellingSearchStart;
272 grammarSearchEnd = spellingSearchEnd;
273 foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchS tart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffse t, grammarDetail);
274 if (isSpelling) {
275 misspelledWord = foundItem;
276 misspellingOffset = foundOffset;
277 } else {
278 badGrammarPhrase = foundItem;
279 grammarPhraseOffset = foundOffset;
280 }
281 } else {
282 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSe archStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false);
283 grammarSearchStart = spellingSearchStart;
284 grammarSearchEnd = spellingSearchEnd;
285 if (!misspelledWord.isEmpty()) {
286 // Stop looking at start of next misspelled word
287 CharacterIterator chars(grammarSearchStart, grammarSearchEnd);
288 chars.advance(misspellingOffset);
289 grammarSearchEnd = chars.startPosition();
290 }
291
292 badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarS earchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOf fset, false);
293 }
294 } 238 }
295 239
296 if (!badGrammarPhrase.isEmpty()) { 240 if (!misspelledWord.isEmpty()) {
297 // We found bad grammar. Since we only searched for bad grammar up to th e first misspelled word, the bad grammar
298 // takes precedence and we ignore any potential misspelled word. Select the grammar detail, update the spelling
299 // panel, and store a marker so we draw the green squiggle later.
300
301 DCHECK_GT(badGrammarPhrase.length(), 0u);
302 DCHECK_NE(grammarDetail.location, -1);
303 DCHECK_GT(grammarDetail.length, 0);
304
305 // FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph
306 const EphemeralRange badGrammarRange = calculateCharacterSubrange(Epheme ralRange(grammarSearchStart, grammarSearchEnd), grammarPhraseOffset + grammarDet ail.location, grammarDetail.length);
307 frame().selection().setSelection(VisibleSelection(badGrammarRange));
308 frame().selection().revealSelection();
309 frame().document()->markers().addMarker(badGrammarRange.startPosition(), badGrammarRange.endPosition(), DocumentMarker::Grammar, grammarDetail.userDescr iption);
310 } else if (!misspelledWord.isEmpty()) {
311 // We found a misspelling, but not any earlier bad grammar. Select the m isspelling, update the spelling panel, and store 241 // We found a misspelling, but not any earlier bad grammar. Select the m isspelling, update the spelling panel, and store
312 // a marker so we draw the red squiggle later. 242 // a marker so we draw the red squiggle later.
313 243
314 const EphemeralRange misspellingRange = calculateCharacterSubrange(Ephem eralRange(spellingSearchStart, spellingSearchEnd), misspellingOffset, misspelled Word.length()); 244 const EphemeralRange misspellingRange = calculateCharacterSubrange(Ephem eralRange(spellingSearchStart, spellingSearchEnd), misspellingOffset, misspelled Word.length());
315 frame().selection().setSelection(VisibleSelection(misspellingRange)); 245 frame().selection().setSelection(VisibleSelection(misspellingRange));
316 frame().selection().revealSelection(); 246 frame().selection().revealSelection();
317 spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord); 247 spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord);
318 frame().document()->markers().addMarker(misspellingRange.startPosition() , misspellingRange.endPosition(), DocumentMarker::Spelling); 248 frame().document()->markers().addMarker(misspellingRange.startPosition() , misspellingRange.endPosition(), DocumentMarker::Spelling);
319 } 249 }
320 } 250 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 if (request->rootEditableElement()->document() != frame().selection().docume nt()) { 505 if (request->rootEditableElement()->document() != frame().selection().docume nt()) {
576 // we ignore |request| made for another document. 506 // we ignore |request| made for another document.
577 // "editing/spelling/spellcheck-sequencenum.html" and others reach here. 507 // "editing/spelling/spellcheck-sequencenum.html" and others reach here.
578 return; 508 return;
579 } 509 }
580 510
581 TextCheckingTypeMask textCheckingOptions = request->data().mask(); 511 TextCheckingTypeMask textCheckingOptions = request->data().mask();
582 TextCheckingParagraph paragraph(request->checkingRange(), request->paragraph Range()); 512 TextCheckingParagraph paragraph(request->checkingRange(), request->paragraph Range());
583 513
584 bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling; 514 bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling;
585 bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
586 515
587 // Expand the range to encompass entire paragraphs, since text checking need s that much context. 516 // Expand the range to encompass entire paragraphs, since text checking need s that much context.
588 int selectionOffset = 0; 517 int selectionOffset = 0;
589 int ambiguousBoundaryOffset = -1; 518 int ambiguousBoundaryOffset = -1;
590 bool selectionChanged = false; 519 bool selectionChanged = false;
591 bool restoreSelectionAfterChange = false; 520 bool restoreSelectionAfterChange = false;
592 bool adjustSelectionForParagraphBoundaries = false; 521 bool adjustSelectionForParagraphBoundaries = false;
593 522
594 if (shouldMarkSpelling) { 523 if (shouldMarkSpelling) {
595 if (frame().selection().isCaret()) { 524 if (frame().selection().isCaret()) {
(...skipping 25 matching lines...) Expand all
621 // Only mark misspelling if: 550 // Only mark misspelling if:
622 // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false. 551 // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false.
623 // 2. Result falls within spellingRange. 552 // 2. Result falls within spellingRange.
624 // 3. The word in question doesn't end at an ambiguous boundary. For instance, we would not mark 553 // 3. The word in question doesn't end at an ambiguous boundary. For instance, we would not mark
625 // "wouldn'" as misspelled right after apostrophe is typed. 554 // "wouldn'" as misspelled right after apostrophe is typed.
626 if (shouldMarkSpelling && result->decoration == TextDecorationTypeSp elling && resultLocation >= paragraph.checkingStart() && resultLocation + result Length <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) { 555 if (shouldMarkSpelling && result->decoration == TextDecorationTypeSp elling && resultLocation >= paragraph.checkingStart() && resultLocation + result Length <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) {
627 DCHECK_GT(resultLength, 0); 556 DCHECK_GT(resultLength, 0);
628 DCHECK_GE(resultLocation, 0); 557 DCHECK_GE(resultLocation, 0);
629 const EphemeralRange misspellingRange = calculateCharacterSubran ge(paragraph.paragraphRange(), resultLocation, resultLength); 558 const EphemeralRange misspellingRange = calculateCharacterSubran ge(paragraph.paragraphRange(), resultLocation, resultLength);
630 frame().document()->markers().addMarker(misspellingRange.startPo sition(), misspellingRange.endPosition(), DocumentMarker::Spelling, result->repl acement, result->hash); 559 frame().document()->markers().addMarker(misspellingRange.startPo sition(), misspellingRange.endPosition(), DocumentMarker::Spelling, result->repl acement, result->hash);
631 } else if (shouldMarkGrammar && result->decoration == TextDecoration TypeGrammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) {
632 DCHECK_GT(resultLength, 0);
633 DCHECK_GE(resultLocation, 0);
634 for (unsigned j = 0; j < result->details.size(); j++) {
635 const GrammarDetail* detail = &result->details[j];
636 DCHECK_GT(detail->length, 0);
637 DCHECK_GE(detail->location, 0);
638 if (paragraph.checkingRangeCovers(resultLocation + detail->l ocation, detail->length)) {
639 const EphemeralRange badGrammarRange = calculateCharacte rSubrange(paragraph.paragraphRange(), resultLocation + detail->location, detail- >length);
640 frame().document()->markers().addMarker(badGrammarRange. startPosition(), badGrammarRange.endPosition(), DocumentMarker::Grammar, detail- >userDescription, result->hash);
641 }
642 }
643 } else if (result->decoration == TextDecorationTypeInvisibleSpellche ck && resultLocation >= paragraph.checkingStart() && resultLocation + resultLeng th <= spellingRangeEndOffset) { 560 } else if (result->decoration == TextDecorationTypeInvisibleSpellche ck && resultLocation >= paragraph.checkingStart() && resultLocation + resultLeng th <= spellingRangeEndOffset) {
644 DCHECK_GT(resultLength, 0); 561 DCHECK_GT(resultLength, 0);
645 DCHECK_GE(resultLocation, 0); 562 DCHECK_GE(resultLocation, 0);
646 const EphemeralRange invisibleSpellcheckRange = calculateCharact erSubrange(paragraph.paragraphRange(), resultLocation, resultLength); 563 const EphemeralRange invisibleSpellcheckRange = calculateCharact erSubrange(paragraph.paragraphRange(), resultLocation, resultLength);
647 frame().document()->markers().addMarker(invisibleSpellcheckRange .startPosition(), invisibleSpellcheckRange.endPosition(), DocumentMarker::Invisi bleSpellcheck, result->replacement, result->hash); 564 frame().document()->markers().addMarker(invisibleSpellcheckRange .startPosition(), invisibleSpellcheckRange.endPosition(), DocumentMarker::Invisi bleSpellcheck, result->replacement, result->hash);
648 } 565 }
649 } 566 }
650 } 567 }
651 568
652 if (selectionChanged) { 569 if (selectionChanged) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 void SpellChecker::didEndEditingOnTextField(Element* e) 687 void SpellChecker::didEndEditingOnTextField(Element* e)
771 { 688 {
772 TRACE_EVENT0("blink", "SpellChecker::didEndEditingOnTextField"); 689 TRACE_EVENT0("blink", "SpellChecker::didEndEditingOnTextField");
773 690
774 // Remove markers when deactivating a selection in an <input type="text"/>. 691 // Remove markers when deactivating a selection in an <input type="text"/>.
775 // Prevent new ones from appearing too. 692 // Prevent new ones from appearing too.
776 m_spellCheckRequester->cancelCheck(); 693 m_spellCheckRequester->cancelCheck();
777 HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlEl ement(e); 694 HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlEl ement(e);
778 HTMLElement* innerEditor = textFormControlElement->innerEditorElement(); 695 HTMLElement* innerEditor = textFormControlElement->innerEditorElement();
779 DocumentMarker::MarkerTypes markerTypes(DocumentMarker::Spelling); 696 DocumentMarker::MarkerTypes markerTypes(DocumentMarker::Spelling);
780 if (unifiedTextCheckerEnabled())
781 markerTypes.add(DocumentMarker::Grammar);
782 for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor)) 697 for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor))
783 frame().document()->markers().removeMarkers(&node, markerTypes); 698 frame().document()->markers().removeMarkers(&node, markerTypes);
784 } 699 }
785 700
786 void SpellChecker::replaceMisspelledRange(const String& text) 701 void SpellChecker::replaceMisspelledRange(const String& text)
787 { 702 {
788 EphemeralRange caretRange = frame().selection().selection().toNormalizedEphe meralRange(); 703 EphemeralRange caretRange = frame().selection().selection().toNormalizedEphe meralRange();
789 if (caretRange.isNull()) 704 if (caretRange.isNull())
790 return; 705 return;
791 DocumentMarkerVector markers = frame().document()->markers().markersInRange( caretRange, DocumentMarker::MisspellingMarkers()); 706 DocumentMarkerVector markers = frame().document()->markers().markersInRange( caretRange, DocumentMarker::MisspellingMarkers());
(...skipping 20 matching lines...) Expand all
812 727
813 void SpellChecker::respondToChangedSelection(const VisibleSelection& oldSelectio n, FrameSelection::SetSelectionOptions options) 728 void SpellChecker::respondToChangedSelection(const VisibleSelection& oldSelectio n, FrameSelection::SetSelectionOptions options)
814 { 729 {
815 TRACE_EVENT0("blink", "SpellChecker::respondToChangedSelection"); 730 TRACE_EVENT0("blink", "SpellChecker::respondToChangedSelection");
816 if (!isSpellCheckingEnabledFor(oldSelection)) 731 if (!isSpellCheckingEnabledFor(oldSelection))
817 return; 732 return;
818 733
819 // When continuous spell checking is off, existing markers disappear after t he selection changes. 734 // When continuous spell checking is off, existing markers disappear after t he selection changes.
820 if (!isContinuousSpellCheckingEnabled()) { 735 if (!isContinuousSpellCheckingEnabled()) {
821 frame().document()->markers().removeMarkers(DocumentMarker::Spelling); 736 frame().document()->markers().removeMarkers(DocumentMarker::Spelling);
822 frame().document()->markers().removeMarkers(DocumentMarker::Grammar);
823 return; 737 return;
824 } 738 }
825 739
826 if (!(options & FrameSelection::CloseTyping)) 740 if (!(options & FrameSelection::CloseTyping))
827 return; 741 return;
828 if (!shouldCheckOldSelection(oldSelection)) 742 if (!shouldCheckOldSelection(oldSelection))
829 return; 743 return;
830 744
831 VisibleSelection newAdjacentWords; 745 VisibleSelection newAdjacentWords;
832 const VisibleSelection newSelection = frame().selection().selection(); 746 const VisibleSelection newSelection = frame().selection().selection();
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 } 877 }
964 878
965 void SpellChecker::cancelCheck() 879 void SpellChecker::cancelCheck()
966 { 880 {
967 m_spellCheckRequester->cancelCheck(); 881 m_spellCheckRequester->cancelCheck();
968 } 882 }
969 883
970 void SpellChecker::requestTextChecking(const Element& element) 884 void SpellChecker::requestTextChecking(const Element& element)
971 { 885 {
972 const EphemeralRange rangeToCheck = EphemeralRange::rangeOfContents(element) ; 886 const EphemeralRange rangeToCheck = EphemeralRange::rangeOfContents(element) ;
973 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec kingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToChe ck, rangeToCheck)); 887 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec kingTypeSpelling, TextCheckingProcessBatch, rangeToCheck, rangeToCheck));
974 } 888 }
975 889
976 DEFINE_TRACE(SpellChecker) 890 DEFINE_TRACE(SpellChecker)
977 { 891 {
978 visitor->trace(m_frame); 892 visitor->trace(m_frame);
979 visitor->trace(m_spellCheckRequester); 893 visitor->trace(m_spellCheckRequester);
980 } 894 }
981 895
982 void SpellChecker::prepareForLeakDetection() 896 void SpellChecker::prepareForLeakDetection()
983 { 897 {
984 m_spellCheckRequester->prepareForLeakDetection(); 898 m_spellCheckRequester->prepareForLeakDetection();
985 } 899 }
986 900
987 } // namespace blink 901 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698