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

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

Issue 2424383002: Make SpellChecker::respondToChangedSelection() to take Position instead of VisibleSelection (Closed)
Patch Set: 2016-10-18T18:31:02 Created 4 years, 2 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) 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 #include "core/page/SpellCheckerClient.h" 52 #include "core/page/SpellCheckerClient.h"
53 #include "platform/text/TextBreakIterator.h" 53 #include "platform/text/TextBreakIterator.h"
54 #include "platform/text/TextCheckerClient.h" 54 #include "platform/text/TextCheckerClient.h"
55 55
56 namespace blink { 56 namespace blink {
57 57
58 using namespace HTMLNames; 58 using namespace HTMLNames;
59 59
60 namespace { 60 namespace {
61 61
62 bool isSelectionInTextField(const VisibleSelection& selection) { 62 bool isSelectionInTextField(const Position& selectionStart) {
Xiaocheng 2016/10/19 02:08:58 nit: the function should be better renamed to "isP
yosin_UTC9 2016/10/19 03:55:26 Done
63 HTMLTextFormControlElement* textControl = 63 HTMLTextFormControlElement* textControl =
64 enclosingTextFormControl(selection.start()); 64 enclosingTextFormControl(selectionStart);
65 return isHTMLInputElement(textControl) && 65 return isHTMLInputElement(textControl) &&
66 toHTMLInputElement(textControl)->isTextField(); 66 toHTMLInputElement(textControl)->isTextField();
67 } 67 }
68 68
69 bool isSelectionInTextArea(const VisibleSelection& selection) { 69 bool isSelectionInTextArea(const Position& selectionStart) {
Xiaocheng 2016/10/19 02:08:58 nit: the function should be better renamed to "isP
yosin_UTC9 2016/10/19 03:55:26 Done.
70 HTMLTextFormControlElement* textControl = 70 HTMLTextFormControlElement* textControl =
71 enclosingTextFormControl(selection.start()); 71 enclosingTextFormControl(selectionStart);
72 return isHTMLTextAreaElement(textControl); 72 return isHTMLTextAreaElement(textControl);
73 } 73 }
74 74
75 bool isSelectionInTextFormControl(const VisibleSelection& selection) { 75 bool isSelectionInTextFormControl(const VisibleSelection& selection) {
76 return !!enclosingTextFormControl(selection.start()); 76 return !!enclosingTextFormControl(selection.start());
77 } 77 }
78 78
79 static bool isSpellCheckingEnabledFor(const VisibleSelection& selection) { 79 static bool isSpellCheckingEnabledFor(const Position& position) {
80 if (selection.isNone()) 80 if (position.isNull())
81 return false; 81 return false;
82 // TODO(tkent): The following password type check should be done in 82 // TODO(tkent): The following password type check should be done in
83 // HTMLElement::spellcheck(). crbug.com/371567 83 // HTMLElement::spellcheck(). crbug.com/371567
84 if (HTMLTextFormControlElement* textControl = 84 if (HTMLTextFormControlElement* textControl =
85 enclosingTextFormControl(selection.start())) { 85 enclosingTextFormControl(position)) {
86 if (isHTMLInputElement(textControl) && 86 if (isHTMLInputElement(textControl) &&
87 toHTMLInputElement(textControl)->type() == InputTypeNames::password) 87 toHTMLInputElement(textControl)->type() == InputTypeNames::password)
88 return false; 88 return false;
89 } 89 }
90 if (HTMLElement* element = Traversal<HTMLElement>::firstAncestorOrSelf( 90 if (HTMLElement* element =
91 *selection.start().anchorNode())) { 91 Traversal<HTMLElement>::firstAncestorOrSelf(*position.anchorNode())) {
92 if (element->isSpellCheckingEnabled()) 92 if (element->isSpellCheckingEnabled())
93 return true; 93 return true;
94 } 94 }
95 return false; 95 return false;
96 } 96 }
97 97
98 static bool isSpellCheckingEnabledFor(const VisibleSelection& selection) {
99 if (selection.isNone())
100 return false;
101 return isSpellCheckingEnabledFor(selection.start());
102 }
103
98 static EphemeralRange expandEndToSentenceBoundary(const EphemeralRange& range) { 104 static EphemeralRange expandEndToSentenceBoundary(const EphemeralRange& range) {
99 DCHECK(range.isNotNull()); 105 DCHECK(range.isNotNull());
100 const VisiblePosition& visibleEnd = 106 const VisiblePosition& visibleEnd =
101 createVisiblePosition(range.endPosition()); 107 createVisiblePosition(range.endPosition());
102 DCHECK(visibleEnd.isNotNull()); 108 DCHECK(visibleEnd.isNotNull());
103 const Position& sentenceEnd = endOfSentence(visibleEnd).deepEquivalent(); 109 const Position& sentenceEnd = endOfSentence(visibleEnd).deepEquivalent();
104 // TODO(xiaochengh): |sentenceEnd < range.endPosition()| is possible, 110 // TODO(xiaochengh): |sentenceEnd < range.endPosition()| is possible,
105 // which would trigger a DCHECK in EphemeralRange's constructor if we return 111 // which would trigger a DCHECK in EphemeralRange's constructor if we return
106 // it directly. However, this shouldn't happen and needs to be fixed. 112 // it directly. However, this shouldn't happen and needs to be fixed.
107 return EphemeralRange( 113 return EphemeralRange(
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 frame().selection().setSelection(createVisibleSelection(markerRange), 800 frame().selection().setSelection(createVisibleSelection(markerRange),
795 CharacterGranularity); 801 CharacterGranularity);
796 802
797 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 803 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
798 // needs to be audited. See http://crbug.com/590369 for more details. 804 // needs to be audited. See http://crbug.com/590369 for more details.
799 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); 805 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
800 806
801 frame().editor().replaceSelectionWithText(text, false, false); 807 frame().editor().replaceSelectionWithText(text, false, false);
802 } 808 }
803 809
804 static bool shouldCheckOldSelection(const VisibleSelection& oldSelection) { 810 static bool shouldCheckOldSelection(const Position& oldSelectionStart) {
805 if (!oldSelection.start().isConnected()) 811 if (!oldSelectionStart.isConnected())
806 return false; 812 return false;
807 if (isSelectionInTextField(oldSelection)) 813 if (isSelectionInTextField(oldSelectionStart))
808 return false; 814 return false;
809 if (isSelectionInTextArea(oldSelection)) 815 if (isSelectionInTextArea(oldSelectionStart))
810 return true; 816 return true;
811 817
812 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 818 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
813 // needs to be audited. See http://crbug.com/590369 for more details. 819 // needs to be audited. See http://crbug.com/590369 for more details.
814 // In the long term we should use idle time spell checker to prevent 820 // In the long term we should use idle time spell checker to prevent
815 // synchronous layout caused by spell checking (see crbug.com/517298). 821 // synchronous layout caused by spell checking (see crbug.com/517298).
816 oldSelection.start() 822 oldSelectionStart.document()->updateStyleAndLayoutIgnorePendingStylesheets();
817 .document()
818 ->updateStyleAndLayoutIgnorePendingStylesheets();
819 823
820 return oldSelection.isContentEditable(); 824 return isEditablePosition(oldSelectionStart);
821 } 825 }
822 826
823 void SpellChecker::respondToChangedSelection( 827 void SpellChecker::respondToChangedSelection(
824 const VisibleSelection& oldSelection, 828 const Position& oldSelectionStart,
825 FrameSelection::SetSelectionOptions options) { 829 FrameSelection::SetSelectionOptions options) {
826 TRACE_EVENT0("blink", "SpellChecker::respondToChangedSelection"); 830 TRACE_EVENT0("blink", "SpellChecker::respondToChangedSelection");
827 if (!isSpellCheckingEnabledFor(oldSelection)) 831 if (!isSpellCheckingEnabledFor(oldSelectionStart))
828 return; 832 return;
829 833
830 // When spell checking is off, existing markers disappear after the selection 834 // When spell checking is off, existing markers disappear after the selection
831 // changes. 835 // changes.
832 if (!isSpellCheckingEnabled()) { 836 if (!isSpellCheckingEnabled()) {
833 frame().document()->markers().removeMarkers(DocumentMarker::Spelling); 837 frame().document()->markers().removeMarkers(DocumentMarker::Spelling);
834 frame().document()->markers().removeMarkers(DocumentMarker::Grammar); 838 frame().document()->markers().removeMarkers(DocumentMarker::Grammar);
835 return; 839 return;
836 } 840 }
837 841
838 if (!(options & FrameSelection::CloseTyping)) 842 if (!(options & FrameSelection::CloseTyping))
839 return; 843 return;
840 if (!shouldCheckOldSelection(oldSelection)) 844 if (!shouldCheckOldSelection(oldSelectionStart))
841 return; 845 return;
842 846
843 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 847 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
844 // needs to be audited. See http://crbug.com/590369 for more details. 848 // needs to be audited. See http://crbug.com/590369 for more details.
845 // In the long term we should use idle time spell checker to prevent 849 // In the long term we should use idle time spell checker to prevent
846 // synchronous layout caused by spell checking (see crbug.com/517298). 850 // synchronous layout caused by spell checking (see crbug.com/517298).
847 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); 851 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
848 852
849 DocumentLifecycle::DisallowTransitionScope disallowTransition( 853 DocumentLifecycle::DisallowTransitionScope disallowTransition(
850 frame().document()->lifecycle()); 854 frame().document()->lifecycle());
(...skipping 12 matching lines...) Expand all
863 createVisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), 867 createVisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary),
864 endOfWord(newStart, RightWordIfOnBoundary)); 868 endOfWord(newStart, RightWordIfOnBoundary));
865 } 869 }
866 } 870 }
867 871
868 // When typing we check spelling elsewhere, so don't redo it here. 872 // When typing we check spelling elsewhere, so don't redo it here.
869 // If this is a change in selection resulting from a delete operation, 873 // If this is a change in selection resulting from a delete operation,
870 // oldSelection may no longer be in the document. 874 // oldSelection may no longer be in the document.
871 // FIXME(http://crbug.com/382809): if oldSelection is on a textarea 875 // FIXME(http://crbug.com/382809): if oldSelection is on a textarea
872 // element, we cause synchronous layout. 876 // element, we cause synchronous layout.
873 spellCheckOldSelection(oldSelection, newAdjacentWords); 877 spellCheckOldSelection(oldSelectionStart, newAdjacentWords);
874 } 878 }
875 879
876 void SpellChecker::removeSpellingMarkers() { 880 void SpellChecker::removeSpellingMarkers() {
877 frame().document()->markers().removeMarkers( 881 frame().document()->markers().removeMarkers(
878 DocumentMarker::MisspellingMarkers()); 882 DocumentMarker::MisspellingMarkers());
879 } 883 }
880 884
881 void SpellChecker::removeSpellingMarkersUnderWords( 885 void SpellChecker::removeSpellingMarkersUnderWords(
882 const Vector<String>& words) { 886 const Vector<String>& words) {
883 MarkerRemoverPredicate removerPredicate(words); 887 MarkerRemoverPredicate removerPredicate(words);
884 888
885 DocumentMarkerController& markerController = frame().document()->markers(); 889 DocumentMarkerController& markerController = frame().document()->markers();
886 markerController.removeMarkers(removerPredicate); 890 markerController.removeMarkers(removerPredicate);
887 markerController.repaintMarkers(); 891 markerController.repaintMarkers();
888 } 892 }
889 893
890 void SpellChecker::spellCheckAfterBlur() { 894 void SpellChecker::spellCheckAfterBlur() {
891 if (!frame().selection().selection().isContentEditable()) 895 if (!frame().selection().selection().isContentEditable())
892 return; 896 return;
893 897
894 if (isSelectionInTextField(frame().selection().selection())) { 898 if (isSelectionInTextField(frame().selection().selection().start())) {
895 // textFieldDidEndEditing() and textFieldDidBeginEditing() handle this. 899 // textFieldDidEndEditing() and textFieldDidBeginEditing() handle this.
896 return; 900 return;
897 } 901 }
898 902
899 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 903 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
900 // needs to be audited. See http://crbug.com/590369 for more details. 904 // needs to be audited. See http://crbug.com/590369 for more details.
901 // In the long term we should use idle time spell checker to prevent 905 // In the long term we should use idle time spell checker to prevent
902 // synchronous layout caused by spell checking (see crbug.com/517298). 906 // synchronous layout caused by spell checking (see crbug.com/517298).
903 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets(); 907 frame().document()->updateStyleAndLayoutIgnorePendingStylesheets();
904 908
905 DocumentLifecycle::DisallowTransitionScope disallowTransition( 909 DocumentLifecycle::DisallowTransitionScope disallowTransition(
906 frame().document()->lifecycle()); 910 frame().document()->lifecycle());
907 911
908 VisibleSelection empty; 912 VisibleSelection empty;
909 spellCheckOldSelection(frame().selection().selection(), empty); 913 spellCheckOldSelection(frame().selection().selection().start(), empty);
910 } 914 }
911 915
912 void SpellChecker::spellCheckOldSelection( 916 void SpellChecker::spellCheckOldSelection(
913 const VisibleSelection& oldSelection, 917 const Position& oldSelectionStart,
914 const VisibleSelection& newAdjacentWords) { 918 const VisibleSelection& newAdjacentWords) {
915 if (!isSpellCheckingEnabled()) 919 if (!isSpellCheckingEnabled())
916 return; 920 return;
917 921
918 TRACE_EVENT0("blink", "SpellChecker::spellCheckOldSelection"); 922 TRACE_EVENT0("blink", "SpellChecker::spellCheckOldSelection");
919 923
920 VisiblePosition oldStart(oldSelection.visibleStart()); 924 VisiblePosition oldStart = createVisiblePosition(oldSelectionStart);
921 VisibleSelection oldAdjacentWords = 925 VisibleSelection oldAdjacentWords =
922 createVisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), 926 createVisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary),
923 endOfWord(oldStart, RightWordIfOnBoundary)); 927 endOfWord(oldStart, RightWordIfOnBoundary));
924 if (oldAdjacentWords == newAdjacentWords) 928 if (oldAdjacentWords == newAdjacentWords)
925 return; 929 return;
926 markMisspellingsAndBadGrammar(oldAdjacentWords); 930 markMisspellingsAndBadGrammar(oldAdjacentWords);
927 } 931 }
928 932
929 static Node* findFirstMarkable(Node* node) { 933 static Node* findFirstMarkable(Node* node) {
930 while (node) { 934 while (node) {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 startOfNextParagraph(createVisiblePosition(paragraphEnd)); 1123 startOfNextParagraph(createVisiblePosition(paragraphEnd));
1120 paragraphStart = newParagraphStart.toParentAnchoredPosition(); 1124 paragraphStart = newParagraphStart.toParentAnchoredPosition();
1121 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPosition(); 1125 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPosition();
1122 firstIteration = false; 1126 firstIteration = false;
1123 totalLengthProcessed += currentLength; 1127 totalLengthProcessed += currentLength;
1124 } 1128 }
1125 return std::make_pair(firstFoundItem, firstFoundOffset); 1129 return std::make_pair(firstFoundItem, firstFoundOffset);
1126 } 1130 }
1127 1131
1128 } // namespace blink 1132 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698