Commit 060d7a1a authored by darin@apple.com's avatar darin@apple.com

2011-02-15 Jia Pu <jpu@apple.com>

        Reviewed by Darin Adler.

        Autocorrection should respect undo.
        https://bugs.webkit.org/show_bug.cgi?id=52221
        <rdar://problem/8663399>

        Please see WebCore/ChangeLog for detailed description.

        * WebCoreSupport/WebEditorClient.cpp:
        (WebFrameImpl::replaceSelection): Adopted new signature of ReplaceSelectionCommand::create().
2011-02-15  Jia Pu  <jpu@apple.com>

        Reviewed by Darin Adler.

        Autocorrection should respect undo.
        https://bugs.webkit.org/show_bug.cgi?id=52221
        <rdar://problem/8663399>

        Please see WebCore/ChangeLog for detailed description.

        * WebCoreSupport/WebEditorClient.h: Updated for the new function declared in EditorClient.

        * WebCoreSupport/WebEditorClient.mm:
        (WebEditorClient::recordAutocorrectionResponse): Ditto.

        * WebView/WebFrame.mm:
        (-[WebFrame _replaceSelectionWithFragment:selectReplacement:smartReplace:matchStyle:]):
             Adopted new signature of ReplaceSelectionCommand::create().
2011-02-15  Jia Pu  <jpu@apple.com>

        Reviewed by Darin Adler.

        Autocorrection should respect undo.
        https://bugs.webkit.org/show_bug.cgi?id=52221
        <rdar://problem/8663399>

        Manual test: manual-tests/autocorrection/undo-autocorrection.html

        When user undoes an autocorrection, we need to do four things:
        1. Revert the change in text that has been made by correction.
        2. Revert the selection to pre-correction state so that user can immediately continue typing.
        3. Add appropriate markers to reverted text so that it won't be corrected again and/or shown
           as misspelled.
        4. If applicable, notify spell checking service to record this reversion.

        To achieve these, this patch introduces following changes:
        1. Created SpellingCorrectionCommand so that correction can be undone in similar way as any
           other editing command. SpellingCorrectionCommand is a composition of SetSelectionCommand,
           SpellingCorrectionRecordUndoCommand and ReplaceSelectionCommand.
        2. Created SetSelectionCommand so that undo command can restore selection state.
        3. Added member function recordAutocorrectionResponse() to editor client.

        To improve readability, this patch also consolidates various boolean arguments in SelectionController::setSelection()
        and ReplaceSelectionCommand::ReplaceSelectionCommand(). These boolean arguments have been
        replaced by enum variable.

        * WebCore.exp.in: Updated for changes in Editor and ReplaceSelectionCommand.

        * WebCore.xcodeproj/project.pbxproj: Updated for new source files.

        * editing/CompositeEditCommand.cpp:
        (WebCore::CompositeEditCommand::moveParagraphs): Adopted new signature of ReplaceSelectionCommand::create().

        * editing/Editor.cpp:
        (WebCore::Editor::replaceSelectionWithFragment): Ditto.
        (WebCore::Editor::unappliedEditing): Cleaned up trailing whitespace.
        (WebCore::Editor::reappliedEditing): Ditto.
        (WebCore::Editor::selectComposition): Adopted new signature of SelectionController::setSelection().
        (WebCore::Editor::confirmComposition): Ditto.
        (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): Rearranged code to reduce the
            level of deeply nested if statement. Adopted SpellingCorrectionCommand.
        (WebCore::Editor::applyCorrectionPanelInfo): Adopted SpellingCorrectionCommand.
        (WebCore::Editor::unappliedSpellCorrection): Function for adding markers to reverted text and
            for notifiying editor client about undone correction.
        (WebCore::Editor::changeSelectionAfterCommand): Adopted new signature of SelectionController::setSelection().
        (WebCore::Editor::respondToChangedSelection): Use SelectionController::SetSelectionOptions
            instead of boolean variables.

        * editing/Editor.h: Added Editor::unappliedSpellCorrection().

        * editing/EditorCommand.cpp:
        (WebCore::executeInsertFragment): Adopted new signature of ReplaceSelectionCommand::create().

        * editing/MoveSelectionCommand.cpp:
        (WebCore::MoveSelectionCommand::doApply): Ditto.

        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplaceSelectionCommand::ReplaceSelectionCommand): Replaced all boolean arguments
            with an enum value.

        * editing/ReplaceSelectionCommand.h:
        (WebCore::ReplaceSelectionCommand::create): Ditto.

        * editing/SelectionController.cpp: Adopted new signature of SelectionController::setSelection().
        (WebCore::SelectionController::moveTo):
        (WebCore::SelectionController::setSelection):
        (WebCore::SelectionController::respondToNodeModification):
        (WebCore::SelectionController::setBase):
        (WebCore::SelectionController::setExtent):
        (WebCore::SelectionController::setSelectedRange):

        * editing/SelectionController.h:
        (WebCore::SelectionController::setSelection): Replaced all boolean arguments with an enum value.

        * editing/SetSelectionCommand.cpp: Added.
        (WebCore::SetSelectionCommand::SetSelectionCommand):
        (WebCore::SetSelectionCommand::doApply):
        (WebCore::SetSelectionCommand::doUnapply):

        * editing/SetSelectionCommand.h: Added.
        (WebCore::SetSelectionCommand::create):

        * editing/mac/SpellingCorrectionCommand.cpp: Added.
        (WebCore::SpellingCorrectionRecordUndoCommand::create):
        (WebCore::SpellingCorrectionRecordUndoCommand::SpellingCorrectionRecordUndoCommand):
        (WebCore::SpellingCorrectionRecordUndoCommand::doApply):
        (WebCore::SpellingCorrectionRecordUndoCommand::doUnapply):
        (WebCore::SpellingCorrectionCommand::SpellingCorrectionCommand):
        (WebCore::SpellingCorrectionCommand::doApply):

        * editing/mac/SpellingCorrectionCommand.h: Added.
        (WebCore::SpellingCorrectionCommand::create):

        * loader/EmptyClients.h: Updated for the new function declared in EditorClient.
        (WebCore::EmptyEditorClient::recordAutocorrectionResponse):

        * manual-tests/autocorrection/undo-autocorrection.html: Added.

        * page/ContextMenuController.cpp:
        (WebCore::ContextMenuController::contextMenuItemSelected): Adopted new signature of ReplaceSelectionCommand::create().

        * page/DragController.cpp:
        (WebCore::DragController::concludeEditDrag): Ditto.

        * page/EditorClient.h: Added EditorClient::recordAutocorrectionResponse().
2011-02-15  Jia Pu  <jpu@apple.com>

        Reviewed by Darin Adler.

        Autocorrection should respect undo.
        https://bugs.webkit.org/show_bug.cgi?id=52221
        <rdar://problem/8663399>

        Please see WebCore/ChangeLog for detailed description.

        * WebProcess/WebCoreSupport/WebEditorClient.h: Updated for the new function declared in EditorClient.

        * WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm:
        (WebKit::WebEditorClient::recordAutocorrectionResponse): Ditto.

        * WebProcess/WebPage/WebPage.cpp:
        (WebKit::WebPage::replaceSelectionWithText): Adopted new signature of ReplaceSelectionCommand::create().


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@78632 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 312046e4
2011-02-15 Jia Pu <jpu@apple.com>
Reviewed by Darin Adler.
Autocorrection should respect undo.
https://bugs.webkit.org/show_bug.cgi?id=52221
<rdar://problem/8663399>
Manual test: manual-tests/autocorrection/undo-autocorrection.html
When user undoes an autocorrection, we need to do four things:
1. Revert the change in text that has been made by correction.
2. Revert the selection to pre-correction state so that user can immediately continue typing.
3. Add appropriate markers to reverted text so that it won't be corrected again and/or shown
as misspelled.
4. If applicable, notify spell checking service to record this reversion.
To achieve these, this patch introduces following changes:
1. Created SpellingCorrectionCommand so that correction can be undone in similar way as any
other editing command. SpellingCorrectionCommand is a composition of SetSelectionCommand,
SpellingCorrectionRecordUndoCommand and ReplaceSelectionCommand.
2. Created SetSelectionCommand so that undo command can restore selection state.
3. Added member function recordAutocorrectionResponse() to editor client.
To improve readability, this patch also consolidates various boolean arguments in SelectionController::setSelection()
and ReplaceSelectionCommand::ReplaceSelectionCommand(). These boolean arguments have been
replaced by enum variable.
* WebCore.exp.in: Updated for changes in Editor and ReplaceSelectionCommand.
* WebCore.xcodeproj/project.pbxproj: Updated for new source files.
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::moveParagraphs): Adopted new signature of ReplaceSelectionCommand::create().
* editing/Editor.cpp:
(WebCore::Editor::replaceSelectionWithFragment): Ditto.
(WebCore::Editor::unappliedEditing): Cleaned up trailing whitespace.
(WebCore::Editor::reappliedEditing): Ditto.
(WebCore::Editor::selectComposition): Adopted new signature of SelectionController::setSelection().
(WebCore::Editor::confirmComposition): Ditto.
(WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): Rearranged code to reduce the
level of deeply nested if statement. Adopted SpellingCorrectionCommand.
(WebCore::Editor::applyCorrectionPanelInfo): Adopted SpellingCorrectionCommand.
(WebCore::Editor::unappliedSpellCorrection): Function for adding markers to reverted text and
for notifiying editor client about undone correction.
(WebCore::Editor::changeSelectionAfterCommand): Adopted new signature of SelectionController::setSelection().
(WebCore::Editor::respondToChangedSelection): Use SelectionController::SetSelectionOptions
instead of boolean variables.
* editing/Editor.h: Added Editor::unappliedSpellCorrection().
* editing/EditorCommand.cpp:
(WebCore::executeInsertFragment): Adopted new signature of ReplaceSelectionCommand::create().
* editing/MoveSelectionCommand.cpp:
(WebCore::MoveSelectionCommand::doApply): Ditto.
* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::ReplaceSelectionCommand): Replaced all boolean arguments
with an enum value.
* editing/ReplaceSelectionCommand.h:
(WebCore::ReplaceSelectionCommand::create): Ditto.
* editing/SelectionController.cpp: Adopted new signature of SelectionController::setSelection().
(WebCore::SelectionController::moveTo):
(WebCore::SelectionController::setSelection):
(WebCore::SelectionController::respondToNodeModification):
(WebCore::SelectionController::setBase):
(WebCore::SelectionController::setExtent):
(WebCore::SelectionController::setSelectedRange):
* editing/SelectionController.h:
(WebCore::SelectionController::setSelection): Replaced all boolean arguments with an enum value.
* editing/SetSelectionCommand.cpp: Added.
(WebCore::SetSelectionCommand::SetSelectionCommand):
(WebCore::SetSelectionCommand::doApply):
(WebCore::SetSelectionCommand::doUnapply):
* editing/SetSelectionCommand.h: Added.
(WebCore::SetSelectionCommand::create):
* editing/mac/SpellingCorrectionCommand.cpp: Added.
(WebCore::SpellingCorrectionRecordUndoCommand::create):
(WebCore::SpellingCorrectionRecordUndoCommand::SpellingCorrectionRecordUndoCommand):
(WebCore::SpellingCorrectionRecordUndoCommand::doApply):
(WebCore::SpellingCorrectionRecordUndoCommand::doUnapply):
(WebCore::SpellingCorrectionCommand::SpellingCorrectionCommand):
(WebCore::SpellingCorrectionCommand::doApply):
* editing/mac/SpellingCorrectionCommand.h: Added.
(WebCore::SpellingCorrectionCommand::create):
* loader/EmptyClients.h: Updated for the new function declared in EditorClient.
(WebCore::EmptyEditorClient::recordAutocorrectionResponse):
* manual-tests/autocorrection/undo-autocorrection.html: Added.
* page/ContextMenuController.cpp:
(WebCore::ContextMenuController::contextMenuItemSelected): Adopted new signature of ReplaceSelectionCommand::create().
* page/DragController.cpp:
(WebCore::DragController::concludeEditDrag): Ditto.
* page/EditorClient.h: Added EditorClient::recordAutocorrectionResponse().
2011-02-15 Beth Dakin <bdakin@apple.com>
Reviewed by Darin Adler.
......@@ -489,7 +489,7 @@ __ZN7WebCore19ResourceRequestBase13setHTTPMethodERKN3WTF6StringE
__ZN7WebCore19ResourceRequestBase19addHTTPHeaderFieldsERKNS_13HTTPHeaderMapE
__ZN7WebCore19ResourceRequestBase6setURLERKNS_4KURLE
__ZN7WebCore19SelectionController10setFocusedEb
__ZN7WebCore19SelectionController12setSelectionERKNS_16VisibleSelectionEbbbNS0_19CursorAlignOnScrollENS_15TextGranularityENS_20DirectionalityPolicyE
__ZN7WebCore19SelectionController12setSelectionERKNS_16VisibleSelectionEjNS0_19CursorAlignOnScrollENS_15TextGranularityENS_20DirectionalityPolicyE
__ZN7WebCore19SelectionController15revealSelectionERKNS_15ScrollAlignmentEb
__ZN7WebCore19SelectionController16setSelectedRangeEPNS_5RangeENS_9EAffinityEb
__ZN7WebCore19SelectionController20setSelectionFromNoneEv
......@@ -535,9 +535,9 @@ __ZN7WebCore22counterValueForElementEPNS_7ElementE
__ZN7WebCore22createFragmentFromTextEPNS_5RangeERKN3WTF6StringE
__ZN7WebCore22externalRepresentationEPNS_5FrameEj
__ZN7WebCore23AuthenticationChallengeC1ERKNS_15ProtectionSpaceERKNS_10CredentialEjRKNS_16ResourceResponseERKNS_13ResourceErrorE
__ZN7WebCore23ReplaceSelectionCommandC1EPNS_8DocumentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbbbbNS_10EditActionE
__ZN7WebCore23createFragmentFromNodesEPNS_8DocumentERKN3WTF6VectorIPNS_4NodeELm0EEE
__ZN7WebCore23overrideDefaultLanguageERKN3WTF6StringE
__ZN7WebCore23ReplaceSelectionCommandC1EPNS_8DocumentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEjNS_10EditActionE
__ZN7WebCore24BinaryPropertyListWriter17writePropertyListEv
__ZN7WebCore24DocumentMarkerController13removeMarkersEj
__ZN7WebCore24DocumentMarkerController14markersForNodeEPNS_4NodeE
......
......@@ -4769,6 +4769,10 @@
B885E8D411E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B885E8D211E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp */; };
B885E8D511E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = B885E8D311E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h */; settings = {ATTRIBUTES = (); }; };
B8A6A6D5127B338D008673BA /* CorrectionPanelInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = B8A6A6D4127B338D008673BA /* CorrectionPanelInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
B8DBDB4B130B0F8A00F5CDB1 /* SetSelectionCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B8DBDB47130B0F8A00F5CDB1 /* SetSelectionCommand.cpp */; };
B8DBDB4C130B0F8A00F5CDB1 /* SetSelectionCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B8DBDB48130B0F8A00F5CDB1 /* SetSelectionCommand.h */; };
B8DBDB4D130B0F8A00F5CDB1 /* SpellingCorrectionCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B8DBDB49130B0F8A00F5CDB1 /* SpellingCorrectionCommand.cpp */; };
B8DBDB4E130B0F8A00F5CDB1 /* SpellingCorrectionCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B8DBDB4A130B0F8A00F5CDB1 /* SpellingCorrectionCommand.h */; };
BC00F0040E0A185500FD04E3 /* DOMFile.h in Headers */ = {isa = PBXBuildFile; fileRef = BC00EFFE0E0A185500FD04E3 /* DOMFile.h */; };
BC00F0050E0A185500FD04E3 /* DOMFile.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC00EFFF0E0A185500FD04E3 /* DOMFile.mm */; };
BC00F0060E0A185500FD04E3 /* DOMFileInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = BC00F0000E0A185500FD04E3 /* DOMFileInternal.h */; };
......@@ -11061,6 +11065,10 @@
B885E8D211E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorApplicationCacheAgent.cpp; sourceTree = "<group>"; };
B885E8D311E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorApplicationCacheAgent.h; sourceTree = "<group>"; };
B8A6A6D4127B338D008673BA /* CorrectionPanelInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CorrectionPanelInfo.h; sourceTree = "<group>"; };
B8DBDB47130B0F8A00F5CDB1 /* SetSelectionCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetSelectionCommand.cpp; sourceTree = "<group>"; };
B8DBDB48130B0F8A00F5CDB1 /* SetSelectionCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetSelectionCommand.h; sourceTree = "<group>"; };
B8DBDB49130B0F8A00F5CDB1 /* SpellingCorrectionCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpellingCorrectionCommand.cpp; sourceTree = "<group>"; };
B8DBDB4A130B0F8A00F5CDB1 /* SpellingCorrectionCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpellingCorrectionCommand.h; sourceTree = "<group>"; };
BC00EFFE0E0A185500FD04E3 /* DOMFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFile.h; sourceTree = "<group>"; };
BC00EFFF0E0A185500FD04E3 /* DOMFile.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMFile.mm; sourceTree = "<group>"; };
BC00F0000E0A185500FD04E3 /* DOMFileInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFileInternal.h; sourceTree = "<group>"; };
......@@ -15324,6 +15332,10 @@
93309DBF099E64910056E581 /* SelectionController.h */,
93309DC0099E64910056E581 /* SetNodeAttributeCommand.cpp */,
93309DC1099E64910056E581 /* SetNodeAttributeCommand.h */,
B8DBDB47130B0F8A00F5CDB1 /* SetSelectionCommand.cpp */,
B8DBDB48130B0F8A00F5CDB1 /* SetSelectionCommand.h */,
B8DBDB49130B0F8A00F5CDB1 /* SpellingCorrectionCommand.cpp */,
B8DBDB4A130B0F8A00F5CDB1 /* SpellingCorrectionCommand.h */,
4B6FA6F30C39E48C00087011 /* SmartReplace.cpp */,
4B6FA6F20C39E48C00087011 /* SmartReplace.h */,
4B6FA6F60C39E4A100087011 /* SmartReplaceCF.cpp */,
......@@ -22420,6 +22432,8 @@
975CA28B130365F800E99AD9 /* Crypto.h in Headers */,
975CA2A21303679D00E99AD9 /* JSCrypto.h in Headers */,
26E98A10130A9FCA008EB7B2 /* TextCodecASCIIFastPath.h in Headers */,
B8DBDB4C130B0F8A00F5CDB1 /* SetSelectionCommand.h in Headers */,
B8DBDB4E130B0F8A00F5CDB1 /* SpellingCorrectionCommand.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -25102,6 +25116,8 @@
A1E1154413015C3D0054AC8C /* DistantLightSource.cpp in Sources */,
A1E1154613015C4E0054AC8C /* PointLightSource.cpp in Sources */,
A1E1154813015C5D0054AC8C /* SpotLightSource.cpp in Sources */,
B8DBDB4B130B0F8A00F5CDB1 /* SetSelectionCommand.cpp in Sources */,
B8DBDB4D130B0F8A00F5CDB1 /* SpellingCorrectionCommand.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -1006,7 +1006,10 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
setEndingSelection(destination);
ASSERT(endingSelection().isCaretOrRange());
applyCommandToComposite(ReplaceSelectionCommand::create(document(), fragment, true, false, !preserveStyle, false, true));
ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MovingParagraph;
if (!preserveStyle)
options |= ReplaceSelectionCommand::MatchStyle;
applyCommandToComposite(ReplaceSelectionCommand::create(document(), fragment, options));
document()->frame()->editor()->markMisspellingsAndBadGrammar(endingSelection());
......
This diff is collapsed.
......@@ -35,6 +35,7 @@
#include "EditorDeleteAction.h"
#include "EditorInsertAction.h"
#include "FindOptions.h"
#include "SelectionController.h"
#include "Timer.h"
#include "VisibleSelection.h"
#include "WritingDirection.h"
......@@ -167,7 +168,8 @@ public:
void appliedEditing(PassRefPtr<EditCommand>);
void unappliedEditing(PassRefPtr<EditCommand>);
void reappliedEditing(PassRefPtr<EditCommand>);
void unappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction);
bool selectionStartHasStyle(CSSStyleDeclaration*) const;
bool clientIsEditable() const;
......@@ -353,7 +355,7 @@ public:
IntRect firstRectForRange(Range*) const;
void respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping);
void respondToChangedSelection(const VisibleSelection& oldSelection, SelectionController::SetSelectionOptions);
bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const;
......
......@@ -194,8 +194,7 @@ static bool executeApplyParagraphStyle(Frame* frame, EditorCommandSource source,
static bool executeInsertFragment(Frame* frame, PassRefPtr<DocumentFragment> fragment)
{
applyCommand(ReplaceSelectionCommand::create(frame->document(), fragment,
false, false, false, true, false, EditActionUnspecified));
applyCommand(ReplaceSelectionCommand::create(frame->document(), fragment, ReplaceSelectionCommand::PreventNesting, EditActionUnspecified));
return true;
}
......
......@@ -70,7 +70,10 @@ void MoveSelectionCommand::doApply()
// Document was modified out from under us.
return;
}
applyCommandToComposite(ReplaceSelectionCommand::create(document(), m_fragment, true, m_smartInsert));
ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::PreventNesting;
if (m_smartInsert)
options |= ReplaceSelectionCommand::SmartReplace;
applyCommandToComposite(ReplaceSelectionCommand::create(document(), m_fragment, options));
}
EditAction MoveSelectionCommand::editingAction() const
......
......@@ -340,18 +340,16 @@ void ReplacementFragment::removeInterchangeNodes(Node* container)
}
}
ReplaceSelectionCommand::ReplaceSelectionCommand(Document* document, PassRefPtr<DocumentFragment> fragment,
bool selectReplacement, bool smartReplace, bool matchStyle, bool preventNesting, bool movingParagraph,
EditAction editAction)
: CompositeEditCommand(document),
m_selectReplacement(selectReplacement),
m_smartReplace(smartReplace),
m_matchStyle(matchStyle),
m_documentFragment(fragment),
m_preventNesting(preventNesting),
m_movingParagraph(movingParagraph),
m_editAction(editAction),
m_shouldMergeEnd(false)
ReplaceSelectionCommand::ReplaceSelectionCommand(Document* document, PassRefPtr<DocumentFragment> fragment, CommandOptions options, EditAction editAction)
: CompositeEditCommand(document)
, m_selectReplacement(options & SelectReplacement)
, m_smartReplace(options & SmartReplace)
, m_matchStyle(options & MatchStyle)
, m_documentFragment(fragment)
, m_preventNesting(options & PreventNesting)
, m_movingParagraph(options & MovingParagraph)
, m_editAction(editAction)
, m_shouldMergeEnd(false)
{
}
......
......@@ -36,16 +36,23 @@ class ReplacementFragment;
class ReplaceSelectionCommand : public CompositeEditCommand {
public:
static PassRefPtr<ReplaceSelectionCommand> create(Document* document, PassRefPtr<DocumentFragment> fragment,
bool selectReplacement = true, bool smartReplace = false, bool matchStyle = false, bool preventNesting = true, bool movingParagraph = false,
EditAction action = EditActionPaste)
enum CommandOption {
SelectReplacement = 1 << 0,
SmartReplace = 1 << 1,
MatchStyle = 1 << 2,
PreventNesting = 1 << 3,
MovingParagraph = 1 << 4
};
typedef unsigned CommandOptions;
static PassRefPtr<ReplaceSelectionCommand> create(Document* document, PassRefPtr<DocumentFragment> fragment, CommandOptions options, EditAction action = EditActionPaste)
{
return adoptRef(new ReplaceSelectionCommand(document, fragment, selectReplacement, smartReplace, matchStyle, preventNesting, movingParagraph, action));
return adoptRef(new ReplaceSelectionCommand(document, fragment, options, action));
}
private:
ReplaceSelectionCommand(Document*, PassRefPtr<DocumentFragment>,
bool selectReplacement, bool smartReplace, bool matchStyle, bool preventNesting, bool movingParagraph, EditAction);
ReplaceSelectionCommand(Document*, PassRefPtr<DocumentFragment>, CommandOptions, EditAction);
virtual void doApply();
virtual EditAction editingAction() const;
......
......@@ -88,34 +88,53 @@ SelectionController::SelectionController(Frame* frame, bool isDragCaretControlle
void SelectionController::moveTo(const VisiblePosition &pos, bool userTriggered, CursorAlignOnScroll align)
{
setSelection(VisibleSelection(pos.deepEquivalent(), pos.deepEquivalent(), pos.affinity()), true, true, userTriggered, align);
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
setSelection(VisibleSelection(pos.deepEquivalent(), pos.deepEquivalent(), pos.affinity()), options, align);
}
void SelectionController::moveTo(const VisiblePosition &base, const VisiblePosition &extent, bool userTriggered)
{
setSelection(VisibleSelection(base.deepEquivalent(), extent.deepEquivalent(), base.affinity()), true, true, userTriggered);
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
setSelection(VisibleSelection(base.deepEquivalent(), extent.deepEquivalent(), base.affinity()), options);
}
void SelectionController::moveTo(const Position &pos, EAffinity affinity, bool userTriggered)
{
setSelection(VisibleSelection(pos, affinity), true, true, userTriggered);
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
setSelection(VisibleSelection(pos, affinity), options);
}
void SelectionController::moveTo(const Range *r, EAffinity affinity, bool userTriggered)
{
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
VisibleSelection selection = r ? VisibleSelection(r->startPosition(), r->endPosition(), affinity) : VisibleSelection(Position(), Position(), affinity);
setSelection(selection, true, true, userTriggered);
setSelection(selection, options);
}
void SelectionController::moveTo(const Position &base, const Position &extent, EAffinity affinity, bool userTriggered)
{
setSelection(VisibleSelection(base, extent, affinity), true, true, userTriggered);
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
setSelection(VisibleSelection(base, extent, affinity), options);
}
void SelectionController::setSelection(const VisibleSelection& s, bool closeTyping, bool shouldClearTypingStyle, bool userTriggered, CursorAlignOnScroll align, TextGranularity granularity, DirectionalityPolicy directionalityPolicy)
void SelectionController::setSelection(const VisibleSelection& s, SetSelectionOptions options, CursorAlignOnScroll align, TextGranularity granularity, DirectionalityPolicy directionalityPolicy)
{
m_granularity = granularity;
bool closeTyping = options & CloseTyping;
bool shouldClearTypingStyle = options & ClearTypingStyle;
bool userTriggered = options & UserTriggered;
setIsDirectional(directionalityPolicy == MakeDirectionalSelection);
if (m_isDragCaretController) {
......@@ -139,10 +158,10 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
// <http://bugs.webkit.org/show_bug.cgi?id=23464>: Infinite recursion at SelectionController::setSelection
// if document->frame() == m_frame we can get into an infinite loop
if (document && document->frame() && document->frame() != m_frame && document != m_frame->document()) {
document->frame()->selection()->setSelection(s, closeTyping, shouldClearTypingStyle, userTriggered);
document->frame()->selection()->setSelection(s, options);
return;
}
if (closeTyping)
TypingCommand::closeTyping(m_frame->editor()->lastEditCommand());
......@@ -168,7 +187,7 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;
selectFrameElementInParentIfFullySelected();
notifyRendererOfSelectionChange(userTriggered);
m_frame->editor()->respondToChangedSelection(oldSelection, closeTyping);
m_frame->editor()->respondToChangedSelection(oldSelection, options);
if (userTriggered) {
ScrollAlignment alignment;
......@@ -250,7 +269,7 @@ void SelectionController::respondToNodeModification(Node* node, bool baseRemoved
}
if (clearDOMTreeSelection)
setSelection(VisibleSelection(), false, false);
setSelection(VisibleSelection(), 0);
}
enum EndPointType { EndPointIsStart, EndPointIsEnd };
......@@ -942,22 +961,34 @@ void SelectionController::setEnd(const VisiblePosition &pos, bool userTriggered)
void SelectionController::setBase(const VisiblePosition &pos, bool userTriggered)
{
setSelection(VisibleSelection(pos.deepEquivalent(), m_selection.extent(), pos.affinity()), true, true, userTriggered);
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
setSelection(VisibleSelection(pos.deepEquivalent(), m_selection.extent(), pos.affinity()), options);
}
void SelectionController::setExtent(const VisiblePosition &pos, bool userTriggered)
{
setSelection(VisibleSelection(m_selection.base(), pos.deepEquivalent(), pos.affinity()), true, true, userTriggered);
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
setSelection(VisibleSelection(m_selection.base(), pos.deepEquivalent(), pos.affinity()), options);
}
void SelectionController::setBase(const Position &pos, EAffinity affinity, bool userTriggered)
{
setSelection(VisibleSelection(pos, m_selection.extent(), affinity), true, true, userTriggered);
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
setSelection(VisibleSelection(pos, m_selection.extent(), affinity), options);
}
void SelectionController::setExtent(const Position &pos, EAffinity affinity, bool userTriggered)
{
setSelection(VisibleSelection(m_selection.base(), pos, affinity), true, true, userTriggered);
SetSelectionOptions options = CloseTyping | ClearTypingStyle;
if (userTriggered)
options |= UserTriggered;
setSelection(VisibleSelection(m_selection.base(), pos, affinity), options);
}
void SelectionController::setCaretRectNeedsUpdate(bool flag)
......@@ -1389,7 +1420,10 @@ bool SelectionController::setSelectedRange(Range* range, EAffinity affinity, boo
// FIXME: Can we provide extentAffinity?
VisiblePosition visibleStart(startContainer, startOffset, collapsed ? affinity : DOWNSTREAM);
VisiblePosition visibleEnd(endContainer, endOffset, SEL_DEFAULT_AFFINITY);
setSelection(VisibleSelection(visibleStart, visibleEnd), closeTyping);
SetSelectionOptions options = ClearTypingStyle;
if (closeTyping)
options |= CloseTyping;
setSelection(VisibleSelection(visibleStart, visibleEnd), options);
return true;
}
......
......@@ -54,6 +54,13 @@ public:
enum EAlteration { AlterationMove, AlterationExtend };
enum CursorAlignOnScroll { AlignCursorOnScrollIfNeeded,
AlignCursorOnScrollAlways };
enum SetSelectionOption {
CloseTyping = 1 << 0,
ClearTypingStyle = 1 << 1,
UserTriggered = 1 << 2,
SpellCorrectionTriggered = 1 << 3,
};
typedef unsigned SetSelectionOptions;
SelectionController(Frame* = 0, bool isDragCaretController = false);
......@@ -69,8 +76,8 @@ public:
void moveTo(const Position&, const Position&, EAffinity, bool userTriggered = false);
const VisibleSelection& selection() const { return m_selection; }
void setSelection(const VisibleSelection&, bool closeTyping = true, bool clearTypingStyle = true, bool userTriggered = false, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity, DirectionalityPolicy = MakeDirectionalSelection);
void setSelection(const VisibleSelection& selection, TextGranularity granularity, DirectionalityPolicy directionality = MakeDirectionalSelection) { setSelection(selection, true, true, false, AlignCursorOnScrollIfNeeded, granularity, directionality); }
void setSelection(const VisibleSelection&, SetSelectionOptions = CloseTyping | ClearTypingStyle, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity, DirectionalityPolicy = MakeDirectionalSelection);
void setSelection(const VisibleSelection& selection, TextGranularity granularity, DirectionalityPolicy directionality = MakeDirectionalSelection) { setSelection(selection, CloseTyping | ClearTypingStyle, AlignCursorOnScrollIfNeeded, granularity, directionality); }
bool setSelectedRange(Range*, EAffinity, bool closeTyping);
void selectAll();
void clear();
......
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "SetSelectionCommand.h"
#include "Frame.h"
namespace WebCore {
SetSelectionCommand::SetSelectionCommand(const VisibleSelection& selection, SelectionController::SetSelectionOptions options)
: SimpleEditCommand(selection.base().node()->document())
, m_options(options)
, m_selectionToSet(selection)
{
}
void SetSelectionCommand::doApply()
{
SelectionController* selectionController = document()->frame()->selection();
ASSERT(selectionController);
if (selectionController->shouldChangeSelection(m_selectionToSet) && m_selectionToSet.isNonOrphanedCaretOrRange()) {
selectionController->setSelection(m_selectionToSet, m_options);
setEndingSelection(m_selectionToSet);
}
}
void SetSelectionCommand::doUnapply()
{
SelectionController* selectionController = document()->frame()->selection();
ASSERT(selectionController);
if (selectionController->shouldChangeSelection(startingSelection()) && startingSelection().isNonOrphanedCaretOrRange())
selectionController->setSelection(startingSelection(), m_options);
}
} // namespace WebCore
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SetSelectionCommand_h
#define SetSelectionCommand_h
#include "EditCommand.h"
#include "SelectionController.h"
namespace WebCore {
class SetSelectionCommand : public SimpleEditCommand {
public:
static PassRefPtr<SetSelectionCommand> create(const VisibleSelection& selection, SelectionController::SetSelectionOptions options)
{
return adoptRef(new SetSelectionCommand(selection, options));
}
private:
SetSelectionCommand(const VisibleSelection&, SelectionController::SetSelectionOptions);
virtual void doApply();
virtual void doUnapply();
SelectionController::SetSelectionOptions m_options;
VisibleSelection m_selectionToSet;
};
} // namespace WebCore
#endif // SetSelectionCommand_h
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "SpellingCorrectionCommand.h"
#include "CorrectionPanelInfo.h"
#include "DocumentFragment.h"
#include "Frame.h"
#include "ReplaceSelectionCommand.h"
#include "SetSelectionCommand.h"
#include "TextIterator.h"
#include "markup.h"
namespace WebCore {
#if SUPPORT_AUTOCORRECTION_PANEL
// On Mac OS X, we use this command to keep track of user undoing a correction for the first time.
// This information is needed by spell checking service to update user specific data.
class SpellingCorrectionRecordUndoCommand : public SimpleEditCommand {
public:
static PassRefPtr<SpellingCorrectionRecordUndoCommand> create(Document* document, const String& corrected, const String& correction)
{
return adoptRef(new SpellingCorrectionRecordUndoCommand(document, corrected, correction));
}
private:
SpellingCorrectionRecordUndoCommand(Document* document, const String& corrected, const String& correction)
: SimpleEditCommand(document)
, m_corrected(corrected)
, m_correction(correction)
, m_hasBeenUndone(false)
{
}
virtual void doApply()
{
}
virtual void doUnapply()
{
if (!m_hasBeenUndone) {
document()->frame()