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

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

Powered by Google App Engine
This is Rietveld 408576698