Changeset 83344 in webkit
- Timestamp:
- Apr 8, 2011 2:21:44 PM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 2 added
- 1 deleted
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r83342 r83344 675 675 editing/SmartReplace.cpp 676 676 editing/SpellChecker.cpp 677 editing/SpellingCorrectionController.cpp 677 678 editing/SplitElementCommand.cpp 678 679 editing/SplitTextNodeCommand.cpp -
trunk/Source/WebCore/ChangeLog
r83342 r83344 1 2011-04-06 MORITA Hajime <morrita@google.com> 2 3 Reviewed by Darin Adler. 4 5 [Refactoring] Auto correction panel should be handled by its own class. 6 https://bugs.webkit.org/show_bug.cgi?id=55571 7 8 Extracted code inside SUPPORT_AUTOCORRECTION_PANEL into 9 SpellingCorrectionController class. 10 This change also remove some SUPPORT_AUTOCORRECTION_PANEL guard if 11 code paths inside the never reached without autocorrection support. 12 Removing guards reduces unintentional build breakage. 13 14 No new tests, no behavior chagne. 15 16 * CMakeLists.txt: 17 * GNUmakefile.am: 18 * WebCore.gypi: 19 * WebCore.pro: 20 * WebCore.vcproj/WebCore.vcproj: 21 * WebCore.xcodeproj/project.pbxproj: 22 * editing/CorrectionPanelInfo.h: Removed. 23 * editing/EditingAllInOne.cpp: 24 * editing/Editor.cpp: 25 (WebCore::Editor::respondToChangedSelection): 26 (WebCore::Editor::respondToChangedContents): 27 (WebCore::Editor::appliedEditing): 28 (WebCore::Editor::Editor): 29 (WebCore::Editor::~Editor): 30 (WebCore::Editor::insertTextWithoutSendingTextEvent): 31 (WebCore::Editor::insertLineBreak): 32 (WebCore::Editor::insertParagraphSeparator): 33 (WebCore::Editor::cut): 34 (WebCore::Editor::paste): 35 (WebCore::Editor::pasteAsPlainText): 36 (WebCore::Editor::isAutomaticSpellingCorrectionEnabled): 37 (WebCore::Editor::markMisspellingsAfterTypingToWord): 38 (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): 39 (WebCore::Editor::changeBackToReplacedString): 40 (WebCore::Editor::unappliedSpellCorrection): 41 (WebCore::Editor::updateMarkersForWordsAffectedByEditing): 42 (WebCore::Editor::startCorrectionPanelTimer): 43 (WebCore::Editor::handleCorrectionPanelResult): 44 (WebCore::Editor::dismissCorrectionPanelAsIgnored): 45 * editing/Editor.h: 46 * editing/SpellingCorrectionCommand.cpp: 47 * editing/SpellingCorrectionController.cpp: Added. 48 (WebCore::markerTypesForAutocorrection): 49 (WebCore::markerTypesForReplacement): 50 (WebCore::markersHaveIdenticalDescription): 51 (WebCore::SpellingCorrectionController::SpellingCorrectionController): 52 (WebCore::SpellingCorrectionController::~SpellingCorrectionController): 53 (WebCore::SpellingCorrectionController::startCorrectionPanelTimer): 54 (WebCore::SpellingCorrectionController::stopCorrectionPanelTimer): 55 (WebCore::SpellingCorrectionController::stopPendingCorrection): 56 (WebCore::SpellingCorrectionController::applyPendingCorrection): 57 (WebCore::SpellingCorrectionController::hasPendingCorrection): 58 (WebCore::SpellingCorrectionController::isSpellingMarkerAllowed): 59 (WebCore::SpellingCorrectionController::show): 60 (WebCore::SpellingCorrectionController::handleCancelOperation): 61 (WebCore::SpellingCorrectionController::dismiss): 62 (WebCore::SpellingCorrectionController::dismissSoon): 63 (WebCore::SpellingCorrectionController::applyCorrectionPanelInfo): 64 (WebCore::SpellingCorrectionController::applyAutocorrectionBeforeTypingIfAppropriate): 65 (WebCore::SpellingCorrectionController::respondToUnappliedSpellCorrection): 66 (WebCore::SpellingCorrectionController::correctionPanelTimerFired): 67 (WebCore::SpellingCorrectionController::handleCorrectionPanelResult): 68 (WebCore::SpellingCorrectionController::isAutomaticSpellingCorrectionEnabled): 69 (WebCore::SpellingCorrectionController::windowRectForRange): 70 (WebCore::SpellingCorrectionController::respondToChangedSelection): 71 (WebCore::SpellingCorrectionController::respondToAppliedEditing): 72 (WebCore::SpellingCorrectionController::client): 73 (WebCore::SpellingCorrectionController::textChecker): 74 (WebCore::SpellingCorrectionController::recordAutocorrectionResponseReversed): 75 (WebCore::SpellingCorrectionController::markReversed): 76 (WebCore::SpellingCorrectionController::markCorrection): 77 (WebCore::SpellingCorrectionController::recordSpellcheckerResponseForModifiedCorrection): 78 * editing/SpellingCorrectionController.h: Added. 79 (WebCore::SpellingCorrectionController::UNLESS_ENABLED): 80 (WebCore::SpellingCorrectionController::shouldStartTimeFor): 81 (WebCore::SpellingCorrectionController::shouldRemoveMarkersUponEditing): 82 * editing/TypingCommand.cpp: 83 (WebCore::TypingCommand::insertText): 84 (WebCore::TypingCommand::markMisspellingsAfterTyping): 85 (WebCore::TypingCommand::deleteKeyPressed): 86 (WebCore::TypingCommand::forwardDeleteKeyPressed): 87 * editing/htmlediting.h: 88 (WebCore::isAmbiguousBoundaryCharacter): 89 * page/EditorClient.h: 90 * page/Frame.cpp: 91 (WebCore::Frame::setPageAndTextZoomFactors): 92 1 93 2011-04-08 Alpha Lam <hclam@chromium.org> 2 94 -
trunk/Source/WebCore/GNUmakefile.list.am
r83287 r83344 1383 1383 Source/WebCore/editing/SpellChecker.cpp \ 1384 1384 Source/WebCore/editing/SpellChecker.h \ 1385 Source/WebCore/editing/SpellingCorrectionController.cpp \ 1386 Source/WebCore/editing/SpellingCorrectionController.h \ 1385 1387 Source/WebCore/editing/SpellingCorrectionCommand.h \ 1386 1388 Source/WebCore/editing/SplitElementCommand.cpp \ -
trunk/Source/WebCore/WebCore.gypi
r83342 r83344 2650 2650 'editing/SmartReplaceICU.cpp', 2651 2651 'editing/SpellChecker.cpp', 2652 'editing/SpellChecker.h', 2653 'editing/SpellingCorrectionController.cpp', 2654 'editing/SpellingCorrectionController.h', 2652 2655 'editing/SpellingCorrectionCommand.cpp', 2653 2656 'editing/SpellingCorrectionCommand.h', -
trunk/Source/WebCore/WebCore.pro
r83287 r83344 601 601 editing/SmartReplaceICU.cpp \ 602 602 editing/SpellChecker.cpp \ 603 editing/SpellingCorrectionController.cpp \ 603 604 editing/SplitElementCommand.cpp \ 604 605 editing/SplitTextNodeCommand.cpp \ -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r83296 r83344 50475 50475 </File> 50476 50476 <File 50477 RelativePath="..\editing\SpellingCorrectionController.cpp" 50478 > 50479 <FileConfiguration 50480 Name="Debug|Win32" 50481 ExcludedFromBuild="true" 50482 > 50483 <Tool 50484 Name="VCCLCompilerTool" 50485 /> 50486 </FileConfiguration> 50487 <FileConfiguration 50488 Name="Release|Win32" 50489 ExcludedFromBuild="true" 50490 > 50491 <Tool 50492 Name="VCCLCompilerTool" 50493 /> 50494 </FileConfiguration> 50495 <FileConfiguration 50496 Name="Debug_Cairo_CFLite|Win32" 50497 ExcludedFromBuild="true" 50498 > 50499 <Tool 50500 Name="VCCLCompilerTool" 50501 /> 50502 </FileConfiguration> 50503 <FileConfiguration 50504 Name="Release_Cairo_CFLite|Win32" 50505 ExcludedFromBuild="true" 50506 > 50507 <Tool 50508 Name="VCCLCompilerTool" 50509 /> 50510 </FileConfiguration> 50511 <FileConfiguration 50512 Name="Debug_All|Win32" 50513 ExcludedFromBuild="true" 50514 > 50515 <Tool 50516 Name="VCCLCompilerTool" 50517 /> 50518 </FileConfiguration> 50519 <FileConfiguration 50520 Name="Release_LTCG|Win32" 50521 ExcludedFromBuild="true" 50522 > 50523 <Tool 50524 Name="VCCLCompilerTool" 50525 /> 50526 </FileConfiguration> 50527 </File> 50528 <File 50529 RelativePath="..\editing\SpellingCorrectionController.h" 50530 > 50531 </File> 50532 <File 50477 50533 RelativePath="..\editing\SplitElementCommand.cpp" 50478 50534 > -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r83342 r83344 3199 3199 A6D169621346B49B000EB770 /* ShadowRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6D169611346B49B000EB770 /* ShadowRoot.cpp */; }; 3200 3200 A6D169641346B4C1000EB770 /* ShadowRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = A6D169631346B4C1000EB770 /* ShadowRoot.h */; settings = {ATTRIBUTES = (Private, ); }; }; 3201 A7005CCC1330C4BA000CC0BA /* SpellingCorrectionController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7005CCA1330C4BA000CC0BA /* SpellingCorrectionController.cpp */; }; 3202 A7005CCD1330C4BA000CC0BA /* SpellingCorrectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = A7005CCB1330C4BA000CC0BA /* SpellingCorrectionController.h */; settings = {ATTRIBUTES = (Private, ); }; }; 3201 3203 A7151BD812F1558F005A0F64 /* TextCheckerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A7151BD712F1558F005A0F64 /* TextCheckerClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 3202 3204 A715E652134BBBEC00D8E713 /* ProgressShadowElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A715E650134BBBEC00D8E713 /* ProgressShadowElement.cpp */; }; … … 4809 4811 B885E8D411E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B885E8D211E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp */; }; 4810 4812 B885E8D511E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = B885E8D311E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h */; settings = {ATTRIBUTES = (); }; }; 4811 B8A6A6D5127B338D008673BA /* CorrectionPanelInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = B8A6A6D4127B338D008673BA /* CorrectionPanelInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };4812 4813 B8DBDB4B130B0F8A00F5CDB1 /* SetSelectionCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B8DBDB47130B0F8A00F5CDB1 /* SetSelectionCommand.cpp */; }; 4813 4814 B8DBDB4C130B0F8A00F5CDB1 /* SetSelectionCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B8DBDB48130B0F8A00F5CDB1 /* SetSelectionCommand.h */; }; … … 9739 9740 A6D169611346B49B000EB770 /* ShadowRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowRoot.cpp; sourceTree = "<group>"; }; 9740 9741 A6D169631346B4C1000EB770 /* ShadowRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowRoot.h; sourceTree = "<group>"; }; 9742 A7005CCA1330C4BA000CC0BA /* SpellingCorrectionController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpellingCorrectionController.cpp; sourceTree = "<group>"; }; 9743 A7005CCB1330C4BA000CC0BA /* SpellingCorrectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpellingCorrectionController.h; sourceTree = "<group>"; }; 9741 9744 A7151BD712F1558F005A0F64 /* TextCheckerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCheckerClient.h; sourceTree = "<group>"; }; 9742 9745 A715E650134BBBEC00D8E713 /* ProgressShadowElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProgressShadowElement.cpp; sourceTree = "<group>"; }; … … 11259 11262 B885E8D211E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorApplicationCacheAgent.cpp; sourceTree = "<group>"; }; 11260 11263 B885E8D311E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorApplicationCacheAgent.h; sourceTree = "<group>"; }; 11261 B8A6A6D4127B338D008673BA /* CorrectionPanelInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CorrectionPanelInfo.h; sourceTree = "<group>"; };11262 11264 B8DBDB47130B0F8A00F5CDB1 /* SetSelectionCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetSelectionCommand.cpp; sourceTree = "<group>"; }; 11263 11265 B8DBDB48130B0F8A00F5CDB1 /* SetSelectionCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetSelectionCommand.h; sourceTree = "<group>"; }; … … 15575 15577 93309D8D099E64910056E581 /* CompositeEditCommand.cpp */, 15576 15578 93309D8E099E64910056E581 /* CompositeEditCommand.h */, 15577 B8A6A6D4127B338D008673BA /* CorrectionPanelInfo.h */,15578 15579 D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */, 15579 15580 D0B0556609C6700100307E43 /* CreateLinkCommand.h */, … … 15657 15658 B8DBDB49130B0F8A00F5CDB1 /* SpellingCorrectionCommand.cpp */, 15658 15659 B8DBDB4A130B0F8A00F5CDB1 /* SpellingCorrectionCommand.h */, 15660 A7005CCA1330C4BA000CC0BA /* SpellingCorrectionController.cpp */, 15661 A7005CCB1330C4BA000CC0BA /* SpellingCorrectionController.h */, 15659 15662 93309DC2099E64910056E581 /* SplitElementCommand.cpp */, 15660 15663 93309DC3099E64910056E581 /* SplitElementCommand.h */, … … 20019 20022 7EE6846412D26E3800E79415 /* CookieStorageCFNet.h in Headers */, 20020 20023 FE6FD4880F676E5700092873 /* Coordinates.h in Headers */, 20021 B8A6A6D5127B338D008673BA /* CorrectionPanelInfo.h in Headers */,20022 20024 A80E6D040A1989CA007FB8C5 /* Counter.h in Headers */, 20023 20025 BC5EB9790E82069200B25965 /* CounterContent.h in Headers */, … … 22342 22344 A78FE13C12366B1000ACE8D0 /* SpellChecker.h in Headers */, 22343 22345 B8DBDB4E130B0F8A00F5CDB1 /* SpellingCorrectionCommand.h in Headers */, 22346 A7005CCD1330C4BA000CC0BA /* SpellingCorrectionController.h in Headers */, 22344 22347 93309E12099E64920056E581 /* SplitElementCommand.h in Headers */, 22345 22348 93309E14099E64920056E581 /* SplitTextNodeCommand.h in Headers */, … … 25167 25170 A78FE13B12366B1000ACE8D0 /* SpellChecker.cpp in Sources */, 25168 25171 B8DBDB4D130B0F8A00F5CDB1 /* SpellingCorrectionCommand.cpp in Sources */, 25172 A7005CCC1330C4BA000CC0BA /* SpellingCorrectionController.cpp in Sources */, 25169 25173 93309E11099E64920056E581 /* SplitElementCommand.cpp in Sources */, 25170 25174 93309E13099E64920056E581 /* SplitTextNodeCommand.cpp in Sources */, -
trunk/Source/WebCore/editing/EditingAllInOne.cpp
r73888 r83344 64 64 #include <SmartReplace.cpp> 65 65 #include <SmartReplaceCF.cpp> 66 #include <SpellingCorrectionController.cpp> 66 67 #include <SpellChecker.cpp> 67 68 #include <SplitElementCommand.cpp> -
trunk/Source/WebCore/editing/Editor.cpp
r83245 r83344 39 39 #include "ClipboardEvent.h" 40 40 #include "CompositionEvent.h" 41 #include "SpellingCorrectionController.h" 41 42 #include "CreateLinkCommand.h" 42 43 #include "DeleteButtonController.h" … … 94 95 using namespace Unicode; 95 96 96 static inline bool isAmbiguousBoundaryCharacter(UChar character)97 {98 // These are characters that can behave as word boundaries, but can appear within words.99 // If they are just typed, i.e. if they are immediately followed by a caret, we want to delay text checking until the next character has been typed.100 // FIXME: this is required until 6853027 is fixed and text checking can do this for us.101 return character == '\'' || character == rightSingleQuotationMark || character == hebrewPunctuationGershayim;102 }103 104 static const Vector<DocumentMarker::MarkerType>& markerTypesForAutocorrection()105 {106 DEFINE_STATIC_LOCAL(Vector<DocumentMarker::MarkerType>, markerTypesForAutoCorrection, ());107 if (markerTypesForAutoCorrection.isEmpty()) {108 markerTypesForAutoCorrection.append(DocumentMarker::Replacement);109 markerTypesForAutoCorrection.append(DocumentMarker::CorrectionIndicator);110 markerTypesForAutoCorrection.append(DocumentMarker::SpellCheckingExemption);111 markerTypesForAutoCorrection.append(DocumentMarker::Autocorrected);112 }113 return markerTypesForAutoCorrection;114 }115 116 static const Vector<DocumentMarker::MarkerType>& markerTypesForReplacement()117 {118 DEFINE_STATIC_LOCAL(Vector<DocumentMarker::MarkerType>, markerTypesForReplacement, ());119 if (markerTypesForReplacement.isEmpty()) {120 markerTypesForReplacement.append(DocumentMarker::Replacement);121 markerTypesForReplacement.append(DocumentMarker::SpellCheckingExemption);122 }123 return markerTypesForReplacement;124 }125 126 #if SUPPORT_AUTOCORRECTION_PANEL127 static bool markersHaveIdenticalDescription(const Vector<DocumentMarker>& markers)128 {129 if (markers.isEmpty())130 return true;131 132 const String& description = markers[0].description;133 for (size_t i = 1; i < markers.size(); ++i) {134 if (description != markers[i].description)135 return false;136 }137 return true;138 }139 #endif140 141 97 // When an event handler has moved the selection outside of a text control 142 98 // we should use the target control's selection for this editing operation. … … 539 495 client()->respondToChangedSelection(); 540 496 m_deleteButtonController->respondToChangedSelection(oldSelection); 541 542 #if SUPPORT_AUTOCORRECTION_PANEL 543 VisibleSelection currentSelection(frame()->selection()->selection()); 544 // When user moves caret to the end of autocorrected word and pauses, we show the panel 545 // containing the original pre-correction word so that user can quickly revert the 546 // undesired autocorrection. Here, we start correction panel timer once we confirm that 547 // the new caret position is at the end of a word. 548 if (!currentSelection.isCaret() || currentSelection == oldSelection) 549 return; 550 551 VisiblePosition selectionPosition = currentSelection.start(); 552 VisiblePosition endPositionOfWord = endOfWord(selectionPosition, LeftWordIfOnBoundary); 553 if (selectionPosition != endPositionOfWord) 554 return; 555 556 Position position = endPositionOfWord.deepEquivalent(); 557 if (position.anchorType() != Position::PositionIsOffsetInAnchor) 558 return; 559 560 Node* node = position.containerNode(); 561 int endOffset = position.offsetInContainerNode(); 562 Vector<DocumentMarker> markers = node->document()->markers()->markersForNode(node); 563 size_t markerCount = markers.size(); 564 for (size_t i = 0; i < markerCount; ++i) { 565 const DocumentMarker& marker = markers[i]; 566 if (((marker.type == DocumentMarker::Replacement && !marker.description.isNull()) || marker.type == DocumentMarker::Spelling) && static_cast<int>(marker.endOffset) == endOffset) { 567 RefPtr<Range> wordRange = Range::create(frame()->document(), node, marker.startOffset, node, marker.endOffset); 568 String currentWord = plainText(wordRange.get()); 569 if (currentWord.length()) { 570 m_correctionPanelInfo.rangeToBeReplaced = wordRange; 571 m_correctionPanelInfo.replacedString = currentWord; 572 if (marker.type == DocumentMarker::Spelling) 573 startCorrectionPanelTimer(CorrectionPanelInfo::PanelTypeSpellingSuggestions); 574 else { 575 m_correctionPanelInfo.replacementString = marker.description; 576 startCorrectionPanelTimer(CorrectionPanelInfo::PanelTypeReversion); 577 } 578 } 579 break; 580 } 581 } 582 #endif // SUPPORT_AUTOCORRECTION_PANEL 497 m_spellingCorrector->respondToChangedSelection(oldSelection); 583 498 } 584 499 … … 591 506 } 592 507 593 #if REMOVE_MARKERS_UPON_EDITING 594 removeSpellAndCorrectionMarkersFromWordsToBeEdited(true); 595 #endif 508 updateMarkersForWordsAffectedByEditing(true); 596 509 597 510 if (client()) … … 1080 993 VisibleSelection newSelection(cmd->endingSelection()); 1081 994 1082 #if SUPPORT_AUTOCORRECTION_PANEL 1083 if (cmd->isTopLevelCommand() && !cmd->shouldRetainAutocorrectionIndicator()) 1084 m_frame->document()->markers()->removeMarkers(DocumentMarker::CorrectionIndicator); 1085 #endif 995 m_spellingCorrector->respondToAppliedEditing(cmd.get()); 1086 996 1087 997 // Don't clear the typing style with this selection change. We do those things elsewhere if necessary. … … 1142 1052 , m_shouldStyleWithCSS(false) 1143 1053 , m_killRing(adoptPtr(new KillRing)) 1144 , m_spellChecker( new SpellChecker(frame, frame->page() ? frame->page()->editorClient()->textChecker() : 0))1145 , m_ correctionPanelTimer(this, &Editor::correctionPanelTimerFired)1054 , m_spellChecker(adoptPtr(new SpellChecker(frame, frame->page() ? frame->page()->editorClient()->textChecker() : 0))) 1055 , m_spellingCorrector(adoptPtr(new SpellingCorrectionController(frame))) 1146 1056 , m_areMarkedTextMatchesHighlighted(false) 1147 1057 { … … 1150 1060 Editor::~Editor() 1151 1061 { 1152 #if SUPPORT_AUTOCORRECTION_PANEL1153 dismissCorrectionPanel(ReasonForDismissingCorrectionPanelIgnored);1154 #endif1155 1062 } 1156 1063 … … 1185 1092 return true; 1186 1093 1187 #if REMOVE_MARKERS_UPON_EDITING1188 1094 if (!text.isEmpty()) 1189 removeSpellAndCorrectionMarkersFromWordsToBeEdited(isSpaceOrNewline(text[0])); 1190 #endif 1095 updateMarkersForWordsAffectedByEditing(text[0]); 1191 1096 1192 1097 bool shouldConsiderApplyingAutocorrection = false; … … 1197 1102 shouldConsiderApplyingAutocorrection = true; 1198 1103 1199 bool autocorrectionWasApplied = shouldConsiderApplyingAutocorrection && applyAutocorrectionBeforeTypingIfAppropriate();1104 bool autocorrectionWasApplied = shouldConsiderApplyingAutocorrection && m_spellingCorrector->applyAutocorrectionBeforeTypingIfAppropriate(); 1200 1105 1201 1106 // Get the selection to use for the event that triggered this insertText. … … 1233 1138 return true; 1234 1139 1235 bool autocorrectionIsApplied = applyAutocorrectionBeforeTypingIfAppropriate();1140 bool autocorrectionIsApplied = m_spellingCorrector->applyAutocorrectionBeforeTypingIfAppropriate(); 1236 1141 TypingCommand::insertLineBreak(m_frame->document(), autocorrectionIsApplied ? TypingCommand::RetainAutocorrectionIndicator : 0); 1237 1142 revealSelectionAfterEditingOperation(); … … 1251 1156 return true; 1252 1157 1253 bool autocorrectionIsApplied = applyAutocorrectionBeforeTypingIfAppropriate();1158 bool autocorrectionIsApplied = m_spellingCorrector->applyAutocorrectionBeforeTypingIfAppropriate(); 1254 1159 TypingCommand::insertParagraphSeparator(m_frame->document(), autocorrectionIsApplied ? TypingCommand::RetainAutocorrectionIndicator : 0); 1255 1160 revealSelectionAfterEditingOperation(); … … 1268 1173 RefPtr<Range> selection = selectedRange(); 1269 1174 if (shouldDeleteRange(selection.get())) { 1270 #if REMOVE_MARKERS_UPON_EDITING 1271 removeSpellAndCorrectionMarkersFromWordsToBeEdited(true); 1272 #endif 1175 updateMarkersForWordsAffectedByEditing(true); 1273 1176 if (isNodeInTextFormControl(m_frame->selection()->start().deprecatedNode())) 1274 1177 Pasteboard::generalPasteboard()->writePlainText(selectedText()); … … 1309 1212 if (!canPaste()) 1310 1213 return; 1311 #if REMOVE_MARKERS_UPON_EDITING 1312 removeSpellAndCorrectionMarkersFromWordsToBeEdited(false); 1313 #endif 1214 updateMarkersForWordsAffectedByEditing(false); 1314 1215 CachedResourceLoader* loader = m_frame->document()->cachedResourceLoader(); 1315 1216 loader->setAllowStaleResources(true); … … 1327 1228 if (!canPaste()) 1328 1229 return; 1329 #if REMOVE_MARKERS_UPON_EDITING 1330 removeSpellAndCorrectionMarkersFromWordsToBeEdited(false); 1331 #endif 1230 updateMarkersForWordsAffectedByEditing(false); 1332 1231 pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard()); 1333 1232 } … … 1482 1381 bool Editor::isAutomaticSpellingCorrectionEnabled() 1483 1382 { 1484 return client() && client()->isAutomaticSpellingCorrectionEnabled();1383 return m_spellingCorrector->isAutomaticSpellingCorrectionEnabled(); 1485 1384 } 1486 1385 … … 2074 1973 { 2075 1974 #if USE(UNIFIED_TEXT_CHECKING) 2076 #if SUPPORT_AUTOCORRECTION_PANEL 2077 // Apply pending autocorrection before next round of spell checking. 2078 bool doApplyCorrection = true; 2079 VisiblePosition startOfSelection = selectionAfterTyping.visibleStart(); 2080 VisibleSelection currentWord = VisibleSelection(startOfWord(startOfSelection, LeftWordIfOnBoundary), endOfWord(startOfSelection, RightWordIfOnBoundary)); 2081 if (currentWord.visibleEnd() == startOfSelection) { 2082 String wordText = plainText(currentWord.toNormalizedRange().get()); 2083 if (wordText.length() > 0 && isAmbiguousBoundaryCharacter(wordText[wordText.length() - 1])) 2084 doApplyCorrection = false; 2085 } 2086 if (doApplyCorrection) 2087 handleCorrectionPanelResult(dismissCorrectionPanelSoon(ReasonForDismissingCorrectionPanelAccepted)); 2088 else 2089 m_correctionPanelInfo.rangeToBeReplaced.clear(); 2090 #else 2091 UNUSED_PARAM(selectionAfterTyping); 2092 #endif 1975 m_spellingCorrector->applyPendingCorrection(selectionAfterTyping); 1976 2093 1977 TextCheckingOptions textCheckingOptions = 0; 2094 1978 if (isContinuousSpellCheckingEnabled()) … … 2119 2003 2120 2004 #else 2121 UNUSED_PARAM(selectionAfterTyping);2122 2005 if (!isContinuousSpellCheckingEnabled()) 2123 2006 return; … … 2228 2111 #if USE(UNIFIED_TEXT_CHECKING) 2229 2112 // There shouldn't be pending autocorrection at this moment. 2230 ASSERT(!m_ correctionPanelInfo.rangeToBeReplaced);2113 ASSERT(!m_spellingCorrector->hasPendingCorrection()); 2231 2114 2232 2115 bool shouldMarkSpelling = textCheckingOptions & MarkSpelling; … … 2287 2170 2288 2171 2289 #if SUPPORT_AUTOCORRECTION_PANEL2290 2172 // If this checking is only for showing correction panel, we shouldn't bother to mark misspellings. 2291 2173 if (shouldShowCorrectionPanel) 2292 2174 shouldMarkSpelling = false; 2293 #endif2294 2175 2295 2176 int offsetDueToReplacement = 0; … … 2310 2191 ASSERT(resultLength > 0 && resultLocation >= 0); 2311 2192 RefPtr<Range> misspellingRange = spellingParagraph.subrange(resultLocation, resultLength); 2312 #if SUPPORT_AUTOCORRECTION_PANEL 2313 if (m_frame->document()->markers()->hasMarkers(misspellingRange.get(), DocumentMarker::SpellCheckingExemption)) 2193 if (!m_spellingCorrector->isSpellingMarkerAllowed(misspellingRange)) 2314 2194 continue; 2315 #endif // SUPPORT_AUTOCORRECTION_PANEL2316 2195 misspellingRange->startContainer(ec)->document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling); 2317 2196 } else if (shouldMarkGrammar && result->type == TextCheckingTypeGrammar && grammarParagraph.checkingRangeCovers(resultLocation, resultLength)) { … … 2359 2238 if (markers->hasMarkers(rangeToReplace.get(), DocumentMarker::Replacement)) { 2360 2239 doReplacement = false; 2361 recordSpellcheckerResponseForModifiedCorrection(rangeToReplace.get(), replacedString, result->replacement);2240 m_spellingCorrector->recordSpellcheckerResponseForModifiedCorrection(rangeToReplace.get(), replacedString, result->replacement); 2362 2241 } else if (markers->hasMarkers(rangeToReplace.get(), DocumentMarker::RejectedCorrection)) 2363 2242 doReplacement = false; … … 2367 2246 continue; 2368 2247 2369 #if SUPPORT_AUTOCORRECTION_PANEL2370 2248 if (shouldShowCorrectionPanel) { 2249 ASSERT(SUPPORT_AUTOCORRECTION_PANEL); 2250 // shouldShowCorrectionPanel can be true only when the panel is available. 2371 2251 if (resultLocation + resultLength == spellingRangeEndOffset) { 2372 2252 // We only show the correction panel on the last word. 2373 FloatRect boundingBox = windowRectForRange(rangeToReplace.get()); 2374 if (boundingBox.isEmpty()) 2375 break; 2376 m_correctionPanelInfo.rangeToBeReplaced = rangeToReplace; 2377 m_correctionPanelInfo.replacedString = plainText(rangeToReplace.get()); 2378 m_correctionPanelInfo.replacementString = result->replacement; 2379 m_correctionPanelInfo.isActive = true; 2380 client()->showCorrectionPanel(m_correctionPanelInfo.panelType, boundingBox, m_correctionPanelInfo.replacedString, result->replacement, Vector<String>()); 2253 m_spellingCorrector->show(rangeToReplace, result->replacement); 2381 2254 break; 2382 2255 } … … 2384 2257 continue; 2385 2258 } 2386 #endif2387 2259 2388 2260 if (selectionToReplace != m_frame->selection()->selection()) { … … 2398 2270 applyCommand(CreateLinkCommand::create(m_frame->document(), result->replacement)); 2399 2271 } else if (canEdit() && shouldInsertText(result->replacement, rangeToReplace.get(), EditorInsertActionTyped)) { 2400 bool useSpellingCorrectionCommand = false;2401 #if SUPPORT_AUTOCORRECTION_PANEL2402 2272 if (result->type == TextCheckingTypeCorrection) 2403 useSpellingCorrectionCommand = true;2404 #endif2405 if (useSpellingCorrectionCommand)2406 2273 applyCommand(SpellingCorrectionCommand::create(rangeToReplace, result->replacement)); 2407 2274 else { … … 2423 2290 } 2424 2291 2425 if (result->type == TextCheckingTypeCorrection) { 2426 // Add a marker so that corrections can easily be undone and won't be re-corrected. 2427 RefPtr<Range> replacedRange = spellingParagraph.subrange(resultLocation, replacementLength); 2428 Vector<DocumentMarker::MarkerType> markerTypesToAdd = markerTypesForAutocorrection(); 2429 DocumentMarkerController* markers = replacedRange->startContainer()->document()->markers(); 2430 for (size_t i = 0; i < markerTypesToAdd.size(); ++i) { 2431 DocumentMarker::MarkerType markerType = markerTypesToAdd[i]; 2432 if (markerType == DocumentMarker::Replacement || markerType == DocumentMarker::Autocorrected) 2433 markers->addMarker(replacedRange.get(), markerType, replacedString); 2434 else 2435 markers->addMarker(replacedRange.get(), markerType); 2436 } 2437 } 2292 // Add a marker so that corrections can easily be undone and won't be re-corrected. 2293 if (result->type == TextCheckingTypeCorrection) 2294 m_spellingCorrector->markCorrection(spellingParagraph.subrange(resultLocation, replacementLength), replacedString); 2438 2295 } 2439 2296 } … … 2462 2319 } 2463 2320 2464 void Editor::recordSpellcheckerResponseForModifiedCorrection(Range* rangeOfCorrection, const String& corrected, const String& correction)2465 {2466 #if SUPPORT_AUTOCORRECTION_PANEL2467 if (!rangeOfCorrection)2468 return;2469 DocumentMarkerController* markers = rangeOfCorrection->startContainer()->document()->markers();2470 Vector<DocumentMarker> correctedOnceMarkers = markers->markersInRange(rangeOfCorrection, DocumentMarker::Autocorrected);2471 if (correctedOnceMarkers.isEmpty())2472 return;2473 2474 // Spelling corrected text has been edited. We need to determine whether user has reverted it to original text or2475 // edited it to something else, and notify spellchecker accordingly.2476 if (markersHaveIdenticalDescription(correctedOnceMarkers) && correctedOnceMarkers[0].description == corrected)2477 client()->recordAutocorrectionResponse(EditorClient::AutocorrectionReverted, corrected, correction);2478 else2479 client()->recordAutocorrectionResponse(EditorClient::AutocorrectionEdited, corrected, correction);2480 markers->removeMarkers(rangeOfCorrection, DocumentMarker::Autocorrected, DocumentMarkerController::RemovePartiallyOverlappingMarker);2481 #else2482 UNUSED_PARAM(rangeOfCorrection);2483 UNUSED_PARAM(corrected);2484 UNUSED_PARAM(correction);2485 #endif2486 }2487 2488 2321 void Editor::changeBackToReplacedString(const String& replacedString) 2489 2322 { … … 2496 2329 return; 2497 2330 2498 #if SUPPORT_AUTOCORRECTION_PANEL 2499 String replacement = plainText(selection.get()); 2500 client()->recordAutocorrectionResponse(EditorClient::AutocorrectionReverted, replacedString, replacement); 2501 #endif 2331 m_spellingCorrector->recordAutocorrectionResponseReversed(replacedString, selection); 2502 2332 TextCheckingParagraph paragraph(selection); 2503 2333 replaceSelectionWithText(replacedString, false, false); 2504 2334 RefPtr<Range> changedRange = paragraph.subrange(paragraph.checkingStart(), replacedString.length()); 2505 2335 changedRange->startContainer()->document()->markers()->addMarker(changedRange.get(), DocumentMarker::Replacement, String()); 2506 #if SUPPORT_AUTOCORRECTION_PANEL 2507 changedRange->startContainer()->document()->markers()->removeMarkers(changedRange.get(), DocumentMarker::Autocorrected, DocumentMarkerController::RemovePartiallyOverlappingMarker); 2508 changedRange->startContainer()->document()->markers()->addMarker(changedRange.get(), DocumentMarker::SpellCheckingExemption); 2509 #endif 2336 m_spellingCorrector->markReversed(changedRange.get()); 2510 2337 #else 2511 2338 ASSERT_NOT_REACHED(); … … 2532 2359 } 2533 2360 2534 void Editor::correctionPanelTimerFired(Timer<Editor>*) 2535 { 2536 #if SUPPORT_AUTOCORRECTION_PANEL 2537 m_correctionPanelIsDismissedByEditor = false; 2538 switch (m_correctionPanelInfo.panelType) { 2539 case CorrectionPanelInfo::PanelTypeCorrection: { 2540 VisibleSelection selection(frame()->selection()->selection()); 2541 VisiblePosition start(selection.start(), selection.affinity()); 2542 VisiblePosition p = startOfWord(start, LeftWordIfOnBoundary); 2543 VisibleSelection adjacentWords = VisibleSelection(p, start); 2544 markAllMisspellingsAndBadGrammarInRanges(MarkSpelling | ShowCorrectionPanel, adjacentWords.toNormalizedRange().get(), 0); 2545 } 2546 break; 2547 case CorrectionPanelInfo::PanelTypeReversion: { 2548 m_correctionPanelInfo.isActive = true; 2549 m_correctionPanelInfo.replacedString = plainText(m_correctionPanelInfo.rangeToBeReplaced.get()); 2550 FloatRect boundingBox = windowRectForRange(m_correctionPanelInfo.rangeToBeReplaced.get()); 2551 if (!boundingBox.isEmpty()) 2552 client()->showCorrectionPanel(m_correctionPanelInfo.panelType, boundingBox, m_correctionPanelInfo.replacedString, m_correctionPanelInfo.replacementString, Vector<String>()); 2553 } 2554 break; 2555 case CorrectionPanelInfo::PanelTypeSpellingSuggestions: { 2556 if (plainText(m_correctionPanelInfo.rangeToBeReplaced.get()) != m_correctionPanelInfo.replacedString) 2557 break; 2558 String paragraphText = plainText(TextCheckingParagraph(m_correctionPanelInfo.rangeToBeReplaced).paragraphRange().get()); 2559 Vector<String> suggestions; 2560 textChecker()->getGuessesForWord(m_correctionPanelInfo.replacedString, paragraphText, suggestions); 2561 if (suggestions.isEmpty()) { 2562 m_correctionPanelInfo.rangeToBeReplaced.clear(); 2563 break; 2564 } 2565 String topSuggestion = suggestions.first(); 2566 suggestions.remove(0); 2567 m_correctionPanelInfo.isActive = true; 2568 FloatRect boundingBox = windowRectForRange(m_correctionPanelInfo.rangeToBeReplaced.get()); 2569 if (!boundingBox.isEmpty()) 2570 client()->showCorrectionPanel(m_correctionPanelInfo.panelType, boundingBox, m_correctionPanelInfo.replacedString, topSuggestion, suggestions); 2571 } 2572 break; 2573 } 2574 #endif 2575 } 2576 2577 void Editor::handleCorrectionPanelResult(const String& correction) 2578 { 2579 Range* replacedRange = m_correctionPanelInfo.rangeToBeReplaced.get(); 2580 if (!replacedRange || m_frame->document() != replacedRange->ownerDocument()) 2581 return; 2582 2583 String currentWord = plainText(m_correctionPanelInfo.rangeToBeReplaced.get()); 2584 // Check to see if the word we are about to correct has been changed between timer firing and callback being triggered. 2585 if (currentWord != m_correctionPanelInfo.replacedString) 2586 return; 2587 2588 m_correctionPanelInfo.isActive = false; 2589 2590 switch (m_correctionPanelInfo.panelType) { 2591 case CorrectionPanelInfo::PanelTypeCorrection: 2592 if (correction.length()) { 2593 m_correctionPanelInfo.replacementString = correction; 2594 applyCorrectionPanelInfo(markerTypesForAutocorrection()); 2595 } else { 2596 if (!m_correctionPanelIsDismissedByEditor) 2597 replacedRange->startContainer()->document()->markers()->addMarker(replacedRange, DocumentMarker::RejectedCorrection, m_correctionPanelInfo.replacedString); 2598 } 2599 break; 2600 case CorrectionPanelInfo::PanelTypeReversion: 2601 case CorrectionPanelInfo::PanelTypeSpellingSuggestions: 2602 if (correction.length()) { 2603 m_correctionPanelInfo.replacementString = correction; 2604 applyCorrectionPanelInfo(markerTypesForReplacement()); 2605 } 2606 break; 2607 } 2608 2609 m_correctionPanelInfo.rangeToBeReplaced.clear(); 2610 } 2611 2612 void Editor::startCorrectionPanelTimer(CorrectionPanelInfo::PanelType type) 2613 { 2614 #if SUPPORT_AUTOCORRECTION_PANEL 2615 const double correctionPanelTimerInterval = 0.3; 2616 if (isAutomaticSpellingCorrectionEnabled()) { 2617 if (type == CorrectionPanelInfo::PanelTypeCorrection) 2618 // If type is PanelTypeReversion, then the new range has been set. So we shouldn't clear it. 2619 m_correctionPanelInfo.rangeToBeReplaced.clear(); 2620 m_correctionPanelInfo.panelType = type; 2621 m_correctionPanelTimer.startOneShot(correctionPanelTimerInterval); 2622 } 2623 #else 2624 UNUSED_PARAM(type); 2625 #endif 2626 } 2627 2628 void Editor::stopCorrectionPanelTimer() 2629 { 2630 #if SUPPORT_AUTOCORRECTION_PANEL 2631 m_correctionPanelTimer.stop(); 2632 m_correctionPanelInfo.rangeToBeReplaced.clear(); 2633 #endif 2634 } 2635 2636 void Editor::dismissCorrectionPanel(ReasonForDismissingCorrectionPanel reasonForDismissing) 2637 { 2638 #if SUPPORT_AUTOCORRECTION_PANEL 2639 if (!m_correctionPanelInfo.isActive) 2640 return; 2641 m_correctionPanelInfo.isActive = false; 2642 m_correctionPanelIsDismissedByEditor = true; 2643 if (client()) 2644 client()->dismissCorrectionPanel(reasonForDismissing); 2645 #else 2646 UNUSED_PARAM(reasonForDismissing); 2647 #endif 2648 } 2649 2650 String Editor::dismissCorrectionPanelSoon(ReasonForDismissingCorrectionPanel reasonForDismissing) 2651 { 2652 #if SUPPORT_AUTOCORRECTION_PANEL 2653 if (!m_correctionPanelInfo.isActive) 2654 return String(); 2655 m_correctionPanelInfo.isActive = false; 2656 m_correctionPanelIsDismissedByEditor = true; 2657 if (!client()) 2658 return String(); 2659 return client()->dismissCorrectionPanelSoon(reasonForDismissing); 2660 #else 2661 UNUSED_PARAM(reasonForDismissing); 2662 return String(); 2663 #endif 2664 } 2665 2666 void Editor::removeSpellAndCorrectionMarkersFromWordsToBeEdited(bool doNotRemoveIfSelectionAtWordBoundary) 2667 { 2361 void Editor::unappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction) 2362 { 2363 m_spellingCorrector->respondToUnappliedSpellCorrection(selectionOfCorrected, corrected, correction); 2364 } 2365 2366 void Editor::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSelectionAtWordBoundary) 2367 { 2368 if (!m_spellingCorrector->shouldRemoveMarkersUponEditing()) 2369 return; 2370 2668 2371 // We want to remove the markers from a word if an editing command will change the word. This can happen in one of 2669 2372 // several scenarios: … … 2731 2434 } 2732 2435 2733 void Editor::applyCorrectionPanelInfo(const Vector<DocumentMarker::MarkerType>& markerTypesToAdd)2734 {2735 #if SUPPORT_AUTOCORRECTION_PANEL2736 if (!m_correctionPanelInfo.rangeToBeReplaced)2737 return;2738 2739 ExceptionCode ec = 0;2740 RefPtr<Range> paragraphRangeContainingCorrection = m_correctionPanelInfo.rangeToBeReplaced->cloneRange(ec);2741 if (ec)2742 return;2743 2744 setStart(paragraphRangeContainingCorrection.get(), startOfParagraph(m_correctionPanelInfo.rangeToBeReplaced->startPosition()));2745 setEnd(paragraphRangeContainingCorrection.get(), endOfParagraph(m_correctionPanelInfo.rangeToBeReplaced->endPosition()));2746 2747 // After we replace the word at range rangeToBeReplaced, we need to add markers to that range.2748 // However, once the replacement took place, the value of rangeToBeReplaced is not valid anymore.2749 // So before we carry out the replacement, we need to store the start position of rangeToBeReplaced2750 // relative to the start position of the containing paragraph. We use correctionStartOffsetInParagraph2751 // to store this value. In order to obtain this offset, we need to first create a range2752 // which spans from the start of paragraph to the start position of rangeToBeReplaced.2753 RefPtr<Range> correctionStartOffsetInParagraphAsRange = Range::create(paragraphRangeContainingCorrection->startContainer(ec)->document(), paragraphRangeContainingCorrection->startPosition(), paragraphRangeContainingCorrection->startPosition());2754 if (ec)2755 return;2756 2757 Position startPositionOfRangeToBeReplaced = m_correctionPanelInfo.rangeToBeReplaced->startPosition();2758 correctionStartOffsetInParagraphAsRange->setEnd(startPositionOfRangeToBeReplaced.containerNode(), startPositionOfRangeToBeReplaced.computeOffsetInContainerNode(), ec);2759 if (ec)2760 return;2761 2762 // Take note of the location of autocorrection so that we can add marker after the replacement took place.2763 int correctionStartOffsetInParagraph = TextIterator::rangeLength(correctionStartOffsetInParagraphAsRange.get());2764 2765 // Clone the range, since the caller of this method may want to keep the original range around.2766 RefPtr<Range> rangeToBeReplaced = m_correctionPanelInfo.rangeToBeReplaced->cloneRange(ec);2767 applyCommand(SpellingCorrectionCommand::create(rangeToBeReplaced, m_correctionPanelInfo.replacementString));2768 setEnd(paragraphRangeContainingCorrection.get(), m_frame->selection()->selection().start());2769 RefPtr<Range> replacementRange = TextIterator::subrange(paragraphRangeContainingCorrection.get(), correctionStartOffsetInParagraph, m_correctionPanelInfo.replacementString.length());2770 String newText = plainText(replacementRange.get());2771 2772 // Check to see if replacement succeeded.2773 if (newText != m_correctionPanelInfo.replacementString)2774 return;2775 2776 DocumentMarkerController* markers = replacementRange->startContainer()->document()->markers();2777 size_t size = markerTypesToAdd.size();2778 for (size_t i = 0; i < size; ++i) {2779 DocumentMarker::MarkerType markerType = markerTypesToAdd[i];2780 String description;2781 if (m_correctionPanelInfo.panelType != CorrectionPanelInfo::PanelTypeReversion && (markerType == DocumentMarker::Replacement || markerType == DocumentMarker::Autocorrected))2782 description = m_correctionPanelInfo.replacedString;2783 markers->addMarker(replacementRange.get(), markerType, description);2784 }2785 #else // SUPPORT_AUTOCORRECTION_PANEL2786 UNUSED_PARAM(markerTypesToAdd);2787 #endif // SUPPORT_AUTOCORRECTION_PANEL2788 }2789 2790 bool Editor::applyAutocorrectionBeforeTypingIfAppropriate()2791 {2792 if (!m_correctionPanelInfo.rangeToBeReplaced || !m_correctionPanelInfo.isActive)2793 return false;2794 2795 if (m_correctionPanelInfo.panelType != CorrectionPanelInfo::PanelTypeCorrection)2796 return false;2797 2798 Position caretPosition = m_frame->selection()->selection().start();2799 2800 if (m_correctionPanelInfo.rangeToBeReplaced->endPosition() == caretPosition) {2801 handleCorrectionPanelResult(dismissCorrectionPanelSoon(ReasonForDismissingCorrectionPanelAccepted));2802 return true;2803 }2804 2805 // Pending correction should always be where caret is. But in case this is not always true, we still want to dismiss the panel without accepting the correction.2806 ASSERT(m_correctionPanelInfo.rangeToBeReplaced->endPosition() == caretPosition);2807 dismissCorrectionPanel(ReasonForDismissingCorrectionPanelIgnored);2808 return false;2809 }2810 2811 void Editor::unappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction)2812 {2813 #if SUPPORT_AUTOCORRECTION_PANEL2814 client()->recordAutocorrectionResponse(EditorClient::AutocorrectionReverted, corrected, correction);2815 m_frame->document()->updateLayout();2816 m_frame->selection()->setSelection(selectionOfCorrected, SelectionController::CloseTyping | SelectionController::ClearTypingStyle | SelectionController::SpellCorrectionTriggered);2817 RefPtr<Range> range = Range::create(m_frame->document(), m_frame->selection()->selection().start(), m_frame->selection()->selection().end());2818 2819 DocumentMarkerController* markers = m_frame->document()->markers();2820 markers->removeMarkers(range.get(), DocumentMarker::Spelling | DocumentMarker::Autocorrected, DocumentMarkerController::RemovePartiallyOverlappingMarker);2821 markers->addMarker(range.get(), DocumentMarker::Replacement);2822 markers->addMarker(range.get(), DocumentMarker::SpellCheckingExemption);2823 #else // SUPPORT_AUTOCORRECTION_PANEL2824 UNUSED_PARAM(selectionOfCorrected);2825 UNUSED_PARAM(corrected);2826 UNUSED_PARAM(correction);2827 #endif // SUPPORT_AUTOCORRECTION_PANEL2828 }2829 2830 2436 PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint) 2831 2437 { … … 2948 2554 killRing()->append(text); 2949 2555 m_shouldStartNewKillRingSequence = false; 2556 } 2557 2558 void Editor::startCorrectionPanelTimer() 2559 { 2560 m_spellingCorrector->startCorrectionPanelTimer(CorrectionPanelInfo::PanelTypeCorrection); 2561 } 2562 2563 void Editor::handleCorrectionPanelResult(const String& correction) 2564 { 2565 m_spellingCorrector->handleCorrectionPanelResult(correction); 2566 } 2567 2568 2569 void Editor::dismissCorrectionPanelAsIgnored() 2570 { 2571 m_spellingCorrector->dismiss(ReasonForDismissingCorrectionPanelIgnored); 2950 2572 } 2951 2573 … … 3522 3144 void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, SelectionController::SetSelectionOptions options) 3523 3145 { 3524 #if SUPPORT_AUTOCORRECTION_PANEL 3525 // Make sure there's no pending autocorrection before we call markMisspellingsAndBadGrammar() below. 3526 VisibleSelection currentSelection(frame()->selection()->selection()); 3527 if (currentSelection != oldSelection) { 3528 stopCorrectionPanelTimer(); 3529 dismissCorrectionPanel(ReasonForDismissingCorrectionPanelIgnored); 3530 } 3531 #endif // SUPPORT_AUTOCORRECTION_PANEL 3146 m_spellingCorrector->stopPendingCorrection(oldSelection); 3532 3147 3533 3148 bool closeTyping = options & SelectionController::CloseTyping; … … 3545 3160 } 3546 3161 3547 bool shouldCheckSpellingAndGrammar = true;3548 #if SUPPORT_AUTOCORRECTION_PANEL3549 3162 // Don't check spelling and grammar if the change of selection is triggered by spelling correction itself. 3550 shouldCheckSpellingAndGrammar = !(options & SelectionController::SpellCorrectionTriggered); 3551 #endif 3163 bool shouldCheckSpellingAndGrammar = !(options & SelectionController::SpellCorrectionTriggered); 3552 3164 3553 3165 // When typing we check spelling elsewhere, so don't redo it here. -
trunk/Source/WebCore/editing/Editor.h
r83060 r83344 29 29 #include "ClipboardAccessPolicy.h" 30 30 #include "Color.h" 31 #include "CorrectionPanelInfo.h"32 31 #include "DocumentMarker.h" 33 32 #include "EditAction.h" … … 52 51 class CSSStyleDeclaration; 53 52 class Clipboard; 53 class SpellingCorrectionController; 54 54 class DeleteButtonController; 55 55 class EditCommand; … … 326 326 void addToKillRing(Range*, bool prepend); 327 327 328 void startCorrectionPanelTimer( CorrectionPanelInfo::PanelType);328 void startCorrectionPanelTimer(); 329 329 // If user confirmed a correction in the correction panel, correction has non-zero length, otherwise it means that user has dismissed the panel. 330 330 void handleCorrectionPanelResult(const String& correction); 331 void dismissCorrectionPanel (ReasonForDismissingCorrectionPanel);331 void dismissCorrectionPanelAsIgnored(); 332 332 333 333 void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle); … … 385 385 386 386 bool selectionStartHasMarkerFor(DocumentMarker::MarkerType, int from, int length) const; 387 void removeSpellAndCorrectionMarkersFromWordsToBeEdited(bool doNotRemoveIfSelectionAtWordBoundary);387 void updateMarkersForWordsAffectedByEditing(bool onlyHandleWordsContainingSelection); 388 388 389 389 private: … … 400 400 bool m_shouldStyleWithCSS; 401 401 OwnPtr<KillRing> m_killRing; 402 CorrectionPanelInfo m_correctionPanelInfo;403 402 OwnPtr<SpellChecker> m_spellChecker; 404 Timer<Editor> m_correctionPanelTimer; 405 bool m_correctionPanelIsDismissedByEditor; 403 OwnPtr<SpellingCorrectionController> m_spellingCorrector; 406 404 VisibleSelection m_mark; 407 405 bool m_areMarkedTextMatchesHighlighted; … … 418 416 void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange); 419 417 TextCheckingTypeMask textCheckingTypeMaskFor(TextCheckingOptions); 420 void recordSpellcheckerResponseForModifiedCorrection(Range*, const String& corrected, const String& correction);421 418 422 419 void selectComposition(); … … 429 426 430 427 void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle); 431 void correctionPanelTimerFired(Timer<Editor>*); 428 432 429 Node* findEventTargetFromSelection() const; 433 430 void stopCorrectionPanelTimer(); 434 String dismissCorrectionPanelSoon(ReasonForDismissingCorrectionPanel); 431 435 432 void applyCorrectionPanelInfo(const Vector<DocumentMarker::MarkerType>& markerTypesToAdd); 436 433 // Return true if correction was applied, false otherwise. -
trunk/Source/WebCore/editing/SpellingCorrectionCommand.cpp
r83060 r83344 27 27 #include "SpellingCorrectionCommand.h" 28 28 29 #include " CorrectionPanelInfo.h"29 #include "SpellingCorrectionController.h" 30 30 #include "DocumentFragment.h" 31 31 #include "Frame.h" -
trunk/Source/WebCore/editing/TypingCommand.cpp
r83245 r83344 155 155 ASSERT(frame); 156 156 157 #if REMOVE_MARKERS_UPON_EDITING158 157 if (!text.isEmpty()) 159 document->frame()->editor()->removeSpellAndCorrectionMarkersFromWordsToBeEdited(isSpaceOrNewline(text.characters()[0])); 160 #endif 161 158 document->frame()->editor()->updateMarkersForWordsAffectedByEditing(isSpaceOrNewline(text.characters()[0])); 159 162 160 insertText(document, text, frame->selection()->selection(), options, composition); 163 161 } … … 345 343 if (p1 != p2) 346 344 document()->frame()->editor()->markMisspellingsAfterTypingToWord(p1, endingSelection()); 347 #if SUPPORT_AUTOCORRECTION_PANEL348 345 else if (commandType == TypingCommand::InsertText) 349 document()->frame()->editor()->startCorrectionPanelTimer(CorrectionPanelInfo::PanelTypeCorrection); 350 #else 351 UNUSED_PARAM(commandType); 352 #endif 346 document()->frame()->editor()->startCorrectionPanelTimer(); 353 347 } 354 348 } … … 469 463 void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing) 470 464 { 471 #if REMOVE_MARKERS_UPON_EDITING 472 document()->frame()->editor()->removeSpellAndCorrectionMarkersFromWordsToBeEdited(false); 473 #endif 465 document()->frame()->editor()->updateMarkersForWordsAffectedByEditing(false); 466 474 467 VisibleSelection selectionToDelete; 475 468 VisibleSelection selectionAfterUndo; … … 568 561 void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool killRing) 569 562 { 570 #if REMOVE_MARKERS_UPON_EDITING 571 document()->frame()->editor()->removeSpellAndCorrectionMarkersFromWordsToBeEdited(false); 572 #endif 563 document()->frame()->editor()->updateMarkersForWordsAffectedByEditing(false); 564 573 565 VisibleSelection selectionToDelete; 574 566 VisibleSelection selectionAfterUndo; -
trunk/Source/WebCore/editing/htmlediting.h
r83247 r83344 225 225 return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t'; 226 226 } 227 228 inline bool isAmbiguousBoundaryCharacter(UChar character) 229 { 230 // These are characters that can behave as word boundaries, but can appear within words. 231 // If they are just typed, i.e. if they are immediately followed by a caret, we want to delay text checking until the next character has been typed. 232 // FIXME: this is required until 6853027 is fixed and text checking can do this for us. 233 return character == '\'' || character == rightSingleQuotationMark || character == hebrewPunctuationGershayim; 234 } 235 227 236 String stringWithRebalancedWhitespace(const String&, bool startIsStartOfParagraph, bool endIsEndOfParagraph); 228 237 const String& nonBreakingSpaceString(); -
trunk/Source/WebCore/page/EditorClient.h
r81847 r83344 28 28 #define EditorClient_h 29 29 30 #include " CorrectionPanelInfo.h"30 #include "SpellingCorrectionController.h" 31 31 #include "EditorInsertAction.h" 32 32 #include "FloatRect.h" -
trunk/Source/WebCore/page/Frame.cpp
r83201 r83344 969 969 return; 970 970 971 m_editor.dismissCorrectionPanel (ReasonForDismissingCorrectionPanelIgnored);971 m_editor.dismissCorrectionPanelAsIgnored(); 972 972 973 973 #if ENABLE(SVG) -
trunk/Source/WebKit/mac/WebCoreSupport/CorrectionPanel.h
r81847 r83344 29 29 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 30 30 #import <AppKit/NSTextChecker.h> 31 #import <WebCore/ CorrectionPanelInfo.h>31 #import <WebCore/SpellingCorrectionController.h> 32 32 #import <wtf/RetainPtr.h> 33 33 -
trunk/Source/WebKit2/UIProcess/mac/CorrectionPanel.h
r81847 r83344 29 29 #if !defined(BUILDING_ON_SNOW_LEOPARD) 30 30 #import <AppKit/NSTextChecker.h> 31 #import <WebCore/ CorrectionPanelInfo.h>31 #import <WebCore/SpellingCorrectionController.h> 32 32 #import <wtf/RetainPtr.h> 33 33
Note: See TracChangeset
for help on using the changeset viewer.