Add support for Undo/Redo
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Sep 2010 19:18:03 +0000 (19:18 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Sep 2010 19:18:03 +0000 (19:18 +0000)
<rdar://problem/7660519>
https://bugs.webkit.org/show_bug.cgi?id=42781

Reviewed by Darin Adler.

Adds platform independent parts of Undo/Redo support and the mac
platform support.

To work around the common assumption made by platforms, that a redo
item will be added synchronously while an undo is in progress, we
ignore the calls from WebCore to add redo items, and instead add add
them after telling WebCore to unapply the EditCommand. We similarly
need to ignore undos, that take place during a redo, and force the
addition ourselves.

* Shared/CoreIPCSupport/WebPageMessageKinds.h:
* Shared/CoreIPCSupport/WebPageProxyMessageKinds.h:
Add new messages.

* UIProcess/API/mac/PageClientImpl.h:
* UIProcess/API/mac/PageClientImpl.mm:
(-[WebEditCommandObjC initWithWebEditCommandProxy:WebKit::]):
(-[WebEditCommandObjC WebKit::]):
(-[WebEditorUndoTargetObjC undoEditing:]):
(-[WebEditorUndoTargetObjC redoEditing:]):
(WebKit::PageClientImpl::PageClientImpl):
(WebKit::nameForEditAction):
(WebKit::PageClientImpl::registerEditCommand):
(WebKit::PageClientImpl::clearAllEditCommands):
* UIProcess/API/qt/qwkpage.cpp:
(QWKPagePrivate::registerEditCommand):
(QWKPagePrivate::clearAllEditCommands):
* UIProcess/API/qt/qwkpage_p.h:
* UIProcess/PageClient.h:
* UIProcess/win/WebView.cpp:
(WebKit::WebView::registerEditCommand):
(WebKit::WebView::clearAllEditCommands):
* UIProcess/win/WebView.h:
Add platform specific hooks for undo/redo.

* UIProcess/WebEditCommandProxy.cpp: Added.
(WebKit::WebEditCommandProxy::WebEditCommandProxy):
(WebKit::WebEditCommandProxy::~WebEditCommandProxy):
(WebKit::WebEditCommandProxy::unapply):
(WebKit::WebEditCommandProxy::reapply):
* UIProcess/WebEditCommandProxy.h: Added.
(WebKit::WebEditCommandProxy::create):
(WebKit::WebEditCommandProxy::commandID):
(WebKit::WebEditCommandProxy::editAction):
(WebKit::WebEditCommandProxy::invalidate):
A proxy for the WebEditCommands in the WebProcess. These are owned
by the platform back/forward list, with a weak reference back to the
WebPageProxy (which holds a weakset of live WebEditCommandProxys).

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::close):
(WebKit::WebPageProxy::didReceiveMessage):
(WebKit::WebPageProxy::registerEditCommandForUndo):
(WebKit::WebPageProxy::clearAllEditCommands):
(WebKit::WebPageProxy::registerEditCommandForRedo):
(WebKit::WebPageProxy::addEditCommand):
(WebKit::WebPageProxy::removeEditCommand):
(WebKit::WebPageProxy::processDidExit):
* UIProcess/WebPageProxy.h:
Forward messages.

* WebProcess/WebCoreSupport/WebEditorClient.cpp:
(WebKit::WebEditorClient::registerCommandForUndo):
(WebKit::WebEditorClient::registerCommandForRedo):
(WebKit::WebEditorClient::clearUndoRedoOperations):
Send undo/redo registration and clearing to the UIProcess.

* WebProcess/WebPage/WebEditCommand.cpp: Added.
(WebKit::generateCommandID):
(WebKit::WebEditCommand::WebEditCommand):
* WebProcess/WebPage/WebEditCommand.h: Added.
(WebKit::WebEditCommand::create):
(WebKit::WebEditCommand::command):
(WebKit::WebEditCommand::commandID):
Wrapper for WebCore::EditCommand, with an added unique ID.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::WebPage):
(WebKit::WebPage::webEditCommand):
(WebKit::WebPage::addWebEditCommand):
(WebKit::WebPage::removeWebEditCommand):
(WebKit::WebPage::unapplyEditCommand):
(WebKit::WebPage::reapplyEditCommand):
(WebKit::WebPage::didRemoveEditCommand):
(WebKit::WebPage::didReceiveMessage):
* WebProcess/WebPage/WebPage.h:
(WebKit::WebPage::isInRedo):
Forward messages.

* WebKit2.pro:
* WebKit2.xcodeproj/project.pbxproj:
* win/WebKit2.vcproj:
Add new files.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66897 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
WebKit2/ChangeLog
WebKit2/Shared/CoreIPCSupport/WebPageMessageKinds.h
WebKit2/Shared/CoreIPCSupport/WebPageProxyMessageKinds.h
WebKit2/UIProcess/API/mac/PageClientImpl.h
WebKit2/UIProcess/API/mac/PageClientImpl.mm
WebKit2/UIProcess/API/qt/qwkpage.cpp
WebKit2/UIProcess/API/qt/qwkpage_p.h
WebKit2/UIProcess/PageClient.h
WebKit2/UIProcess/WebEditCommandProxy.cpp [new file with mode: 0644]
WebKit2/UIProcess/WebEditCommandProxy.h [new file with mode: 0644]
WebKit2/UIProcess/WebPageProxy.cpp
WebKit2/UIProcess/WebPageProxy.h
WebKit2/UIProcess/win/WebView.cpp
WebKit2/UIProcess/win/WebView.h
WebKit2/WebKit2.pro
WebKit2/WebKit2.xcodeproj/project.pbxproj
WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp
WebKit2/WebProcess/WebPage/WebEditCommand.cpp [new file with mode: 0644]
WebKit2/WebProcess/WebPage/WebEditCommand.h [new file with mode: 0644]
WebKit2/WebProcess/WebPage/WebPage.cpp
WebKit2/WebProcess/WebPage/WebPage.h
WebKit2/win/WebKit2.vcproj

index 2e30e8c5262b3ec003ebaa63cf23db1f7fd23d28..9ba56a7aafe3734569590e319a869b4c850bb229 100644 (file)
@@ -1,3 +1,105 @@
+2010-09-07  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Darin Adler.
+
+        Add support for Undo/Redo
+        <rdar://problem/7660519>
+        https://bugs.webkit.org/show_bug.cgi?id=42781
+
+        Adds platform independent parts of Undo/Redo support and the mac
+        platform support.
+
+        To work around the common assumption made by platforms, that a redo
+        item will be added synchronously while an undo is in progress, we
+        ignore the calls from WebCore to add redo items, and instead add add
+        them after telling WebCore to unapply the EditCommand. We similarly
+        need to ignore undos, that take place during a redo, and force the
+        addition ourselves.
+
+        * Shared/CoreIPCSupport/WebPageMessageKinds.h:
+        * Shared/CoreIPCSupport/WebPageProxyMessageKinds.h:
+        Add new messages.
+
+        * UIProcess/API/mac/PageClientImpl.h:
+        * UIProcess/API/mac/PageClientImpl.mm:
+        (-[WebEditCommandObjC initWithWebEditCommandProxy:WebKit::]):
+        (-[WebEditCommandObjC WebKit::]):
+        (-[WebEditorUndoTargetObjC undoEditing:]):
+        (-[WebEditorUndoTargetObjC redoEditing:]):
+        (WebKit::PageClientImpl::PageClientImpl):
+        (WebKit::nameForEditAction):
+        (WebKit::PageClientImpl::registerEditCommand):
+        (WebKit::PageClientImpl::clearAllEditCommands):
+        * UIProcess/API/qt/qwkpage.cpp:
+        (QWKPagePrivate::registerEditCommand):
+        (QWKPagePrivate::clearAllEditCommands):
+        * UIProcess/API/qt/qwkpage_p.h:
+        * UIProcess/PageClient.h:
+        * UIProcess/win/WebView.cpp:
+        (WebKit::WebView::registerEditCommand):
+        (WebKit::WebView::clearAllEditCommands):
+        * UIProcess/win/WebView.h:
+        Add platform specific hooks for undo/redo.
+
+        * UIProcess/WebEditCommandProxy.cpp: Added.
+        (WebKit::WebEditCommandProxy::WebEditCommandProxy):
+        (WebKit::WebEditCommandProxy::~WebEditCommandProxy):
+        (WebKit::WebEditCommandProxy::unapply):
+        (WebKit::WebEditCommandProxy::reapply):
+        * UIProcess/WebEditCommandProxy.h: Added.
+        (WebKit::WebEditCommandProxy::create):
+        (WebKit::WebEditCommandProxy::commandID):
+        (WebKit::WebEditCommandProxy::editAction):
+        (WebKit::WebEditCommandProxy::invalidate):
+        A proxy for the WebEditCommands in the WebProcess. These are owned
+        by the platform back/forward list, with a weak reference back to the
+        WebPageProxy (which holds a weakset of live WebEditCommandProxys).
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::close):
+        (WebKit::WebPageProxy::didReceiveMessage):
+        (WebKit::WebPageProxy::registerEditCommandForUndo):
+        (WebKit::WebPageProxy::clearAllEditCommands):
+        (WebKit::WebPageProxy::registerEditCommandForRedo):
+        (WebKit::WebPageProxy::addEditCommand):
+        (WebKit::WebPageProxy::removeEditCommand):
+        (WebKit::WebPageProxy::processDidExit):
+        * UIProcess/WebPageProxy.h:
+        Forward messages.
+
+        * WebProcess/WebCoreSupport/WebEditorClient.cpp:
+        (WebKit::WebEditorClient::registerCommandForUndo):
+        (WebKit::WebEditorClient::registerCommandForRedo):
+        (WebKit::WebEditorClient::clearUndoRedoOperations):
+        Send undo/redo registration and clearing to the UIProcess.
+
+        * WebProcess/WebPage/WebEditCommand.cpp: Added.
+        (WebKit::generateCommandID):
+        (WebKit::WebEditCommand::WebEditCommand):
+        * WebProcess/WebPage/WebEditCommand.h: Added.
+        (WebKit::WebEditCommand::create):
+        (WebKit::WebEditCommand::command):
+        (WebKit::WebEditCommand::commandID):
+        Wrapper for WebCore::EditCommand, with an added unique ID.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::WebPage):
+        (WebKit::WebPage::webEditCommand):
+        (WebKit::WebPage::addWebEditCommand):
+        (WebKit::WebPage::removeWebEditCommand):
+        (WebKit::WebPage::unapplyEditCommand):
+        (WebKit::WebPage::reapplyEditCommand):
+        (WebKit::WebPage::didRemoveEditCommand):
+        (WebKit::WebPage::didReceiveMessage):
+        * WebProcess/WebPage/WebPage.h:
+        (WebKit::WebPage::isInRedo):
+        Forward messages.
+
+        * WebKit2.pro:
+        * WebKit2.xcodeproj/project.pbxproj:
+        * win/WebKit2.vcproj:
+        Add new files.
+
 2010-09-07  Jessie Berlin  <jberlin@apple.com>
 
         Reviewed by Darin Adler.
index b92cc750a353c1da3291400d9c464c5729919189..1fa72040c259afaf6d6a5f065584db9ac3efdd45 100644 (file)
@@ -35,6 +35,7 @@ namespace WebPageMessage {
 enum Kind {
     Close,
     DidReceivePolicyDecision,
+    DidRemoveEditCommand,
     GetRenderTreeExternalRepresentation,
     GoBack,
     GoForward,
@@ -44,6 +45,7 @@ enum Kind {
     LoadURLRequest,
     MouseEvent,
     PreferencesDidChange,
+    ReapplyEditCommand,
     Reload,
     RunJavaScriptInMainFrame,
     SetActive,
@@ -52,6 +54,7 @@ enum Kind {
     SetIsInWindow,
     StopLoading,
     TryClose,
+    UnapplyEditCommand,
     WheelEvent
 #if ENABLE(TOUCH_EVENTS)
     , TouchEvent
index 2a1f1f342bcea4ba2ea05046d830a08dc9c0e9de..9b0858baff3f9d76c6e1282005436cb379c6ab86 100644 (file)
@@ -67,7 +67,7 @@ enum Kind {
     SetToolTip,
     TakeFocus,
     WillSubmitForm,
-    
+
     BackForwardAddItem,
     BackForwardGoToItem,
     BackForwardBackItem,
@@ -77,6 +77,9 @@ enum Kind {
     BackForwardBackListCount,
     BackForwardForwardListCount,
 
+    RegisterEditCommandForUndo,
+    ClearAllEditCommands,
+
 #if USE(ACCELERATED_COMPOSITING)
     DidChangeAcceleratedCompositing,
 #endif
index 1ff36bbf4d397add44df4e90b9e779752e097b4f..d4123c5dcb53939dcf4308c91032a87c4ca9062d 100644 (file)
 #define PageClientImpl_h
 
 #include "PageClient.h"
+#include <wtf/RetainPtr.h>
 
 @class WKView;
+@class WebEditorUndoTargetObjC;
 
 namespace WebKit {
 
@@ -50,12 +52,16 @@ private:
     virtual void toolTipChanged(const WTF::String& oldToolTip, const WTF::String& newToolTip);
     virtual void setCursor(const WebCore::Cursor&);
 
+    void registerEditCommand(PassRefPtr<WebEditCommandProxy>, UndoOrRedo);
+    void clearAllEditCommands();
+
 #if USE(ACCELERATED_COMPOSITING)
     void pageDidEnterAcceleratedCompositing();
     void pageDidLeaveAcceleratedCompositing();
 #endif
 
     WKView* m_wkView;
+    RetainPtr<WebEditorUndoTargetObjC> m_undoTarget;
 };
 
 } // namespace WebKit
index b612e4b5ee641dba679f36765f5a245f5f92d619..0e2aa51b3a144f61820e43f3cee444cdf49d7b7a 100644 (file)
@@ -28,6 +28,7 @@
 #import "WKAPICast.h"
 #import "WKStringCF.h"
 #import "WKViewInternal.h"
+#import "WebEditCommandProxy.h"
 #import <WebCore/Cursor.h>
 #import <WebCore/FoundationExtras.h>
 #import <wtf/PassOwnPtr.h>
 
 using namespace WebCore;
 
+@interface WebEditCommandObjC : NSObject
+{
+    RefPtr<WebKit::WebEditCommandProxy> m_command;   
+}
+
+- (id)initWithWebEditCommandProxy:(PassRefPtr<WebKit::WebEditCommandProxy>)command;
+- (WebKit::WebEditCommandProxy*)command;
+
+@end
+
+@implementation WebEditCommandObjC
+
+- (id)initWithWebEditCommandProxy:(PassRefPtr<WebKit::WebEditCommandProxy>)command
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    m_command = command;
+    return self;
+}
+
+- (WebKit::WebEditCommandProxy*)command
+{
+    return m_command.get();
+}
+
+@end
+
+@interface WebEditorUndoTargetObjC : NSObject
+
+- (void)undoEditing:(id)arg;
+- (void)redoEditing:(id)arg;
+
+@end
+
+@implementation WebEditorUndoTargetObjC
+
+- (void)undoEditing:(id)sender
+{
+    ASSERT([sender isKindOfClass:[WebEditCommandObjC class]]);
+    [sender command]->unapply();
+}
+
+- (void)redoEditing:(id)sender
+{
+    ASSERT([sender isKindOfClass:[WebEditCommandObjC class]]);
+    [sender command]->reapply();
+}
+
+@end
+
+
 namespace WebKit {
 
 NSString* nsStringFromWebCoreString(const WTF::String& string)
@@ -49,6 +103,7 @@ PassOwnPtr<PageClientImpl> PageClientImpl::create(WKView* wkView)
 
 PageClientImpl::PageClientImpl(WKView* wkView)
     : m_wkView(wkView)
+    , m_undoTarget(AdoptNS, [[WebEditorUndoTargetObjC alloc] init])
 {
 }
 
@@ -81,6 +136,71 @@ void PageClientImpl::setCursor(const WebCore::Cursor& cursor)
     [m_wkView _setCursor:cursor.platformCursor()];
 }
 
+static NSString* nameForEditAction(EditAction editAction)
+{
+    // FIXME: Use localized strings.
+    // FIXME: Move this to a platform independent location.
+
+    switch (editAction) {
+    case EditActionUnspecified: return nil;
+    case EditActionSetColor: return @"Set Color";
+    case EditActionSetBackgroundColor: return @"Set Background Color";
+    case EditActionTurnOffKerning: return @"Turn Off Kerning";
+    case EditActionTightenKerning: return @"Tighten Kerning";
+    case EditActionLoosenKerning: return @"Loosen Kerning";
+    case EditActionUseStandardKerning: return @"Use Standard Kerning";
+    case EditActionTurnOffLigatures: return @"Turn Off Ligatures";
+    case EditActionUseStandardLigatures: return @"Use Standard Ligatures";
+    case EditActionUseAllLigatures: return @"Use All Ligatures";
+    case EditActionRaiseBaseline: return @"Raise Baseline";
+    case EditActionLowerBaseline: return @"Lower Baseline";
+    case EditActionSetTraditionalCharacterShape: return @"Set Traditional Character Shape";
+    case EditActionSetFont: return @"Set Font";
+    case EditActionChangeAttributes: return @"Change Attributes";
+    case EditActionAlignLeft: return @"Align Left";
+    case EditActionAlignRight: return @"Align Right";
+    case EditActionCenter: return @"Center";
+    case EditActionJustify: return @"Justify";
+    case EditActionSetWritingDirection: return @"Set Writing Direction";
+    case EditActionSubscript: return @"Subscript";
+    case EditActionSuperscript: return @"Superscript";
+    case EditActionUnderline: return @"Underline";
+    case EditActionOutline: return @"Outline";
+    case EditActionUnscript: return @"Unscript";
+    case EditActionDrag: return @"Drag";
+    case EditActionCut: return @"Cut";
+    case EditActionPaste: return @"Paste";
+    case EditActionPasteFont: return @"Paste Font";
+    case EditActionPasteRuler: return @"Paste Ruler";
+    case EditActionTyping: return @"Typing";
+    case EditActionCreateLink: return @"Create Link";
+    case EditActionUnlink: return @"Unlink";
+    case EditActionInsertList: return @"Insert List";
+    case EditActionFormatBlock: return @"Formatting";
+    case EditActionIndent: return @"Indent";
+    case EditActionOutdent: return @"Outdent";
+    }
+    return nil;
+}
+
+void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, UndoOrRedo undoOrRedo)
+{
+    RefPtr<WebEditCommandProxy> command = prpCommand;
+
+    RetainPtr<WebEditCommandObjC> commandObjC(AdoptNS, [[WebEditCommandObjC alloc] initWithWebEditCommandProxy:command]);
+    NSString *actionName = nameForEditAction(command->editAction());
+
+    NSUndoManager *undoManager = [m_wkView undoManager];
+    [undoManager registerUndoWithTarget:m_undoTarget.get() selector:((undoOrRedo == Undo) ? @selector(undoEditing:) : @selector(redoEditing:)) object:commandObjC.get()];
+    if (actionName)
+        [undoManager setActionName:actionName];
+}
+
+void PageClientImpl::clearAllEditCommands()
+{
+    [[m_wkView undoManager] removeAllActionsWithTarget:m_undoTarget.get()];
+}
+
 #if USE(ACCELERATED_COMPOSITING)
 void PageClientImpl::pageDidEnterAcceleratedCompositing()
 {
index 54a3f4432c0fb0612dd4a384f8fcf60ceb43c092..7d7dabe67a8a783a65fa4a9350e5f82d8e6e179c 100644 (file)
@@ -72,6 +72,14 @@ void QWKPagePrivate::toolTipChanged(const String&, const String& newTooltip)
     emit q->statusBarMessage(QString(newTooltip));
 }
 
+void QWKPagePrivate::registerEditCommand(PassRefPtr<WebEditCommandProxy>, UndoOrRedo)
+{
+}
+
+void QWKPagePrivate::clearAllEditCommands()
+{
+}
+
 void QWKPagePrivate::paint(QPainter* painter, QRect area)
 {
     painter->save();
index 01ed102259cb8498f88eb7a45e11590e3e96258b..437348cb8718386f40f28c70173eb48ae9605ca0 100644 (file)
@@ -51,6 +51,8 @@ public:
     virtual void setCursor(const WebCore::Cursor&);
     virtual void takeFocus(bool direction) { }
     virtual void toolTipChanged(const WTF::String&, const WTF::String&);
+    virtual void registerEditCommand(PassRefPtr<WebKit::WebEditCommandProxy>, UndoOrRedo);
+    virtual void clearAllEditCommands();
 
     void paint(QPainter* painter, QRect);
 
index a583da188ac7301002de79e2e91c7dfe7de3c1c5..1b04b9d82a0b8710e123e88737c3065d0ae1607d 100644 (file)
@@ -34,6 +34,8 @@ namespace WebCore {
 
 namespace WebKit {
 
+class WebEditCommandProxy;
+
 class PageClient {
 public:
     virtual ~PageClient() { }
@@ -46,6 +48,10 @@ public:
 
     virtual void setCursor(const WebCore::Cursor&) = 0;
 
+    enum UndoOrRedo { Undo, Redo };
+    virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, UndoOrRedo) = 0;
+    virtual void clearAllEditCommands() = 0;
+
 #if USE(ACCELERATED_COMPOSITING)
     virtual void pageDidEnterAcceleratedCompositing() = 0;
     virtual void pageDidLeaveAcceleratedCompositing() = 0;
diff --git a/WebKit2/UIProcess/WebEditCommandProxy.cpp b/WebKit2/UIProcess/WebEditCommandProxy.cpp
new file mode 100644 (file)
index 0000000..6395685
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 "WebEditCommandProxy.h"
+
+#include "WebPageMessageKinds.h"
+#include "WebPageProxy.h"
+#include "WebProcessProxy.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebEditCommandProxy::WebEditCommandProxy(uint64_t commandID, WebCore::EditAction editAction, WebPageProxy* page)
+    : m_commandID(commandID)
+    , m_editAction(editAction)
+    , m_page(page)
+{
+    m_page->addEditCommand(this);
+}
+
+WebEditCommandProxy::~WebEditCommandProxy()
+{
+    if (m_page)
+        m_page->removeEditCommand(this);
+}
+
+void WebEditCommandProxy::unapply()
+{
+    if (!m_page || !m_page->isValid())
+        return;
+
+    m_page->process()->connection()->send(WebPageMessage::UnapplyEditCommand, m_page->pageID(), CoreIPC::In(m_commandID));
+    m_page->registerEditCommandForRedo(this);
+}
+
+void WebEditCommandProxy::reapply()
+{
+    if (!m_page || !m_page->isValid())
+        return;
+
+    m_page->process()->connection()->send(WebPageMessage::ReapplyEditCommand, m_page->pageID(), CoreIPC::In(m_commandID));
+    m_page->registerEditCommandForUndo(this);
+}
+
+} // namespace WebKit
diff --git a/WebKit2/UIProcess/WebEditCommandProxy.h b/WebKit2/UIProcess/WebEditCommandProxy.h
new file mode 100644 (file)
index 0000000..9524d55
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 WebEditCommandProxy_h
+#define WebEditCommandProxy_h
+
+#include <WebCore/EditAction.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class WebEditCommandProxy : public RefCounted<WebEditCommandProxy> {
+public:
+    static PassRefPtr<WebEditCommandProxy> create(uint64_t commandID, WebCore::EditAction editAction, WebPageProxy* page)
+    {
+        return adoptRef(new WebEditCommandProxy(commandID, editAction, page));
+    }
+
+    uint64_t commandID() const { return m_commandID; }
+    WebCore::EditAction editAction() const { return m_editAction; }
+
+    void invalidate() { m_page = 0; }
+
+    void unapply();
+    void reapply();
+
+private:
+    friend class RefCounted<WebEditCommandProxy>;
+
+    WebEditCommandProxy(uint64_t commandID, WebCore::EditAction, WebPageProxy*);
+    ~WebEditCommandProxy();
+
+    uint64_t m_commandID;
+    WebCore::EditAction m_editAction;
+    WebPageProxy* m_page;
+};
+
+} // namespace WebKit
+
+#endif // WebEditCommandProxy_h
index 5995f055f9a6574358bfcd13843236f154c7620c..b712dc3f8f3d0ebec95cb23f9d601289bf7b2bcd 100644 (file)
@@ -34,6 +34,7 @@
 #include "WebContextUserMessageCoders.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebData.h"
+#include "WebEditCommandProxy.h"
 #include "WebEvent.h"
 #include "WebFormSubmissionListenerProxy.h"
 #include "WebFramePolicyListenerProxy.h"
@@ -187,6 +188,12 @@ void WebPageProxy::close()
         renderTreeExternalRepresentationCallbacks[i]->invalidate();
     m_renderTreeExternalRepresentationCallbacks.clear();
 
+    Vector<WebEditCommandProxy*> editCommandVector;
+    copyToVector(m_editCommandSet, editCommandVector);
+    m_editCommandSet.clear();
+    for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
+        editCommandVector[i]->invalidate();
+
     m_estimatedProgress = 0.0;
     
     m_loaderClient.initialize(0);
@@ -648,6 +655,18 @@ void WebPageProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::M
             contentsSizeChanged(process()->webFrame(frameID), size);
             break;
         }
+        case WebPageProxyMessage::RegisterEditCommandForUndo: {
+            uint64_t commandID;
+            uint32_t editAction;
+            if (!arguments->decode(CoreIPC::Out(commandID, editAction)))
+                return;
+                
+            registerEditCommandForUndo(commandID, static_cast<EditAction>(editAction));
+            break;
+        }
+        case WebPageProxyMessage::ClearAllEditCommands:
+            clearAllEditCommands();
+            break;
         default:
             ASSERT_NOT_REACHED();
             break;
@@ -937,6 +956,42 @@ void WebPageProxy::goToItemInBackForwardList(WebBackForwardListItem* item)
     m_backForwardList->goToItem(item);
 }
 
+// Undo management
+
+void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, EditAction editAction)
+{
+    registerEditCommandForUndo(WebEditCommandProxy::create(commandID, editAction, this));
+}
+
+void WebPageProxy::clearAllEditCommands()
+{
+    m_pageClient->clearAllEditCommands();
+}
+
+void WebPageProxy::registerEditCommandForUndo(PassRefPtr<WebEditCommandProxy> commandProxy)
+{
+    m_pageClient->registerEditCommand(commandProxy, PageClient::Undo);
+}
+
+void WebPageProxy::registerEditCommandForRedo(PassRefPtr<WebEditCommandProxy> commandProxy)
+{
+    m_pageClient->registerEditCommand(commandProxy, PageClient::Redo);
+}
+
+void WebPageProxy::addEditCommand(WebEditCommandProxy* command)
+{
+    m_editCommandSet.add(command);
+}
+
+void WebPageProxy::removeEditCommand(WebEditCommandProxy* command)
+{
+    m_editCommandSet.remove(command);
+
+    if (!isValid())
+        return;
+    process()->send(WebPageMessage::DidRemoveEditCommand, m_pageID, command->commandID());
+}
+
 // Other
 
 void WebPageProxy::takeFocus(bool direction)
@@ -1042,6 +1097,13 @@ void WebPageProxy::processDidExit()
         renderTreeExternalRepresentationCallbacks[i]->invalidate();
     m_renderTreeExternalRepresentationCallbacks.clear();
 
+    Vector<WebEditCommandProxy*> editCommandVector;
+    copyToVector(m_editCommandSet, editCommandVector);
+    m_editCommandSet.clear();
+    for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
+        editCommandVector[i]->invalidate();
+    m_pageClient->clearAllEditCommands();
+
     m_estimatedProgress = 0.0;
 
     m_pageClient->processDidExit();
index baf2d751bdfe804102ed588aa90ed8afc509d368..c66ef8794688c9de4dac9987a00021b53bfa7f29 100644 (file)
 #include "WebLoaderClient.h"
 #include "WebPolicyClient.h"
 #include "WebUIClient.h"
+#include <WebCore/EditAction.h>
 #include <WebCore/FrameLoaderTypes.h>
 #include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
 #include <wtf/PassRefPtr.h>
@@ -65,6 +67,7 @@ class PageClient;
 class WebBackForwardList;
 class WebBackForwardListItem;
 class WebData;
+class WebEditCommandProxy;
 class WebKeyboardEvent;
 class WebMouseEvent;
 class WebPageNamespace;
@@ -162,6 +165,11 @@ public:
     void didLeaveAcceleratedCompositing();
 #endif
 
+    void addEditCommand(WebEditCommandProxy*);
+    void removeEditCommand(WebEditCommandProxy*);
+    void registerEditCommandForUndo(PassRefPtr<WebEditCommandProxy>);
+    void registerEditCommandForRedo(PassRefPtr<WebEditCommandProxy>);
+
     WebProcessProxy* process() const;
     WebPageNamespace* pageNamespace() const { return m_pageNamespace.get(); }
 
@@ -210,9 +218,14 @@ private:
     WTF::String runJavaScriptPrompt(WebFrameProxy* frame, const WTF::String&, const WTF::String&);
     void contentsSizeChanged(WebFrameProxy*, const WebCore::IntSize&);
 
+    // Back/Forward list management
     void addItemToBackForwardList(WebBackForwardListItem*);
     void goToItemInBackForwardList(WebBackForwardListItem*);
 
+    // Undo management
+    void registerEditCommandForUndo(uint64_t commandID, WebCore::EditAction);
+    void clearAllEditCommands();
+
     void takeFocus(bool direction);
     void setToolTip(const WTF::String&);
     void setCursor(const WebCore::Cursor&);
@@ -239,6 +252,8 @@ private:
     HashMap<uint64_t, RefPtr<ScriptReturnValueCallback> > m_scriptReturnValueCallbacks;
     HashMap<uint64_t, RefPtr<RenderTreeExternalRepresentationCallback> > m_renderTreeExternalRepresentationCallbacks;
 
+    HashSet<WebEditCommandProxy*> m_editCommandSet;
+
     double m_estimatedProgress;
 
     // Whether the web page is contained in a top-level window.
index 4678c8277cd39f495b2588518edd6ff841bf870b..11fbdbc871e4e0ac4c27e467e3557fc016264bc8 100644 (file)
@@ -569,6 +569,14 @@ void WebView::setCursor(const WebCore::Cursor& cursor)
     ::SetCursor(platformCursor);
 }
 
+void WebView::registerEditCommand(PassRefPtr<WebEditCommandProxy>, UndoOrRedo)
+{
+}
+
+void WebView::clearAllEditCommands()
+{
+}
+
 #if USE(ACCELERATED_COMPOSITING)
 void WebView::pageDidEnterAcceleratedCompositing()
 {
index 2d536aa4f8599e17656aa011f922594b8c58ef1f..6815c916b572a57faa93c43ba299685f8ea27ff7 100644 (file)
@@ -95,6 +95,9 @@ private:
     virtual void takeFocus(bool direction);
     virtual void toolTipChanged(const WTF::String&, const WTF::String&);
     virtual void setCursor(const WebCore::Cursor&);
+    virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, UndoOrRedo);
+    virtual void clearAllEditCommands();
+
 #if USE(ACCELERATED_COMPOSITING)
     virtual void pageDidEnterAcceleratedCompositing();
     virtual void pageDidLeaveAcceleratedCompositing();
index 0f35979f8c257a357a7ab72e1522059da06b0124..ecca6ac2f4777a83f63b912a6fd254a83023cb2d 100644 (file)
@@ -207,6 +207,7 @@ HEADERS += \
     UIProcess/WebContext.h \
     UIProcess/WebContextInjectedBundleClient.h \
     UIProcess/WebContextUserMessageCoders.h \
+    UIProcess/WebEditCommandProxy.h \
     UIProcess/WebFormClient.h \
     UIProcess/WebFormSubmissionListenerProxy.h \
     UIProcess/WebFrameListenerProxy.h \
@@ -254,6 +255,7 @@ HEADERS += \
     WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h \
     WebProcess/WebPage/ChunkedUpdateDrawingArea.h \
     WebProcess/WebPage/DrawingArea.h \
+    WebProcess/WebPage/WebEditCommand.h \
     WebProcess/WebPage/WebFrame.h \
     WebProcess/WebPage/WebPage.h \
     WebProcess/WebProcess.h \
@@ -315,6 +317,7 @@ SOURCES += \
     UIProcess/WebBackForwardListItem.cpp \
     UIProcess/WebContext.cpp \
     UIProcess/WebContextInjectedBundleClient.cpp \
+    UIProcess/WebEditCommandProxy.cpp \
     UIProcess/WebFormClient.cpp \
     UIProcess/WebFormSubmissionListenerProxy.cpp \
     UIProcess/WebFrameListenerProxy.cpp \
@@ -363,6 +366,7 @@ SOURCES += \
     WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp \
     WebProcess/WebPage/ChunkedUpdateDrawingArea.cpp \
     WebProcess/WebPage/DrawingArea.cpp \
+    WebProcess/WebPage/WebEditCommand.cpp \
     WebProcess/WebPage/WebFrame.cpp \
     WebProcess/WebPage/WebPage.cpp \
     WebProcess/WebPage/WebBackForwardListProxy.cpp \
index c782296623de817de9cb5afa13b5a86d67857725..221ab33bc771464ab4584816c067a9705883f778 100644 (file)
                BC9E95D411449B0300870E71 /* UpdateChunk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9E95D211449B0300870E71 /* UpdateChunk.cpp */; };
                BC9E969A11457EDE00870E71 /* DrawingAreaProxyMessageKinds.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9E969911457EDE00870E71 /* DrawingAreaProxyMessageKinds.h */; };
                BC9E969C11457F3F00870E71 /* DrawingAreaMessageKinds.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9E969B11457F3F00870E71 /* DrawingAreaMessageKinds.h */; };
+               BCA0EF7F12331E78007D3CFB /* WebEditCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA0EF7D12331E78007D3CFB /* WebEditCommand.h */; };
+               BCA0EF8012331E78007D3CFB /* WebEditCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA0EF7E12331E78007D3CFB /* WebEditCommand.cpp */; };
+               BCA0EF9F12332642007D3CFB /* WebEditCommandProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA0EF9D12332642007D3CFB /* WebEditCommandProxy.h */; };
+               BCA0EFA012332642007D3CFB /* WebEditCommandProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA0EF9E12332642007D3CFB /* WebEditCommandProxy.cpp */; };
                BCA8C6A811E3BA5F00812FB7 /* InjectedBundlePageLoaderClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA8C6A611E3BA5F00812FB7 /* InjectedBundlePageLoaderClient.cpp */; };
                BCA8C6A911E3BA5F00812FB7 /* InjectedBundlePageLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA8C6A711E3BA5F00812FB7 /* InjectedBundlePageLoaderClient.h */; };
                BCA8C6AF11E3C08700812FB7 /* InjectedBundlePageUIClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA8C6AD11E3C08700812FB7 /* InjectedBundlePageUIClient.cpp */; };
                BC9E95D211449B0300870E71 /* UpdateChunk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UpdateChunk.cpp; sourceTree = "<group>"; };
                BC9E969911457EDE00870E71 /* DrawingAreaProxyMessageKinds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawingAreaProxyMessageKinds.h; sourceTree = "<group>"; };
                BC9E969B11457F3F00870E71 /* DrawingAreaMessageKinds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawingAreaMessageKinds.h; sourceTree = "<group>"; };
+               BCA0EF7D12331E78007D3CFB /* WebEditCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebEditCommand.h; sourceTree = "<group>"; };
+               BCA0EF7E12331E78007D3CFB /* WebEditCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebEditCommand.cpp; sourceTree = "<group>"; };
+               BCA0EF9D12332642007D3CFB /* WebEditCommandProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebEditCommandProxy.h; sourceTree = "<group>"; };
+               BCA0EF9E12332642007D3CFB /* WebEditCommandProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebEditCommandProxy.cpp; sourceTree = "<group>"; };
                BCA8C6A611E3BA5F00812FB7 /* InjectedBundlePageLoaderClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundlePageLoaderClient.cpp; sourceTree = "<group>"; };
                BCA8C6A711E3BA5F00812FB7 /* InjectedBundlePageLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundlePageLoaderClient.h; sourceTree = "<group>"; };
                BCA8C6AD11E3C08700812FB7 /* InjectedBundlePageUIClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundlePageUIClient.cpp; sourceTree = "<group>"; };
                                0F5265B211DD37680006D33C /* LayerBackedDrawingArea.h */,
                                BC72B9F811E6476B001EB4EA /* WebBackForwardListProxy.cpp */,
                                BC72B9F911E6476B001EB4EA /* WebBackForwardListProxy.h */,
+                               BCA0EF7E12331E78007D3CFB /* WebEditCommand.cpp */,
+                               BCA0EF7D12331E78007D3CFB /* WebEditCommand.h */,
                                BC111ADC112F5B9300337BAB /* WebFrame.cpp */,
                                BC032D8910F437A00058C15A /* WebFrame.h */,
                                BC963D6A113DD19200574BE2 /* WebPage.cpp */,
                                BCDE059A11CDA8AE00E41AF1 /* WebContextInjectedBundleClient.cpp */,
                                BCDE059911CDA8AE00E41AF1 /* WebContextInjectedBundleClient.h */,
                                BCB0B0DB12305A2500B1341E /* WebContextUserMessageCoders.h */,
+                               BCA0EF9E12332642007D3CFB /* WebEditCommandProxy.cpp */,
+                               BCA0EF9D12332642007D3CFB /* WebEditCommandProxy.h */,
                                BCE4694F1214E6CB000B98EB /* WebFormClient.cpp */,
                                BCE469501214E6CB000B98EB /* WebFormClient.h */,
                                BCE469511214E6CB000B98EB /* WebFormSubmissionListenerProxy.cpp */,
                                BCB0B0DC12305A2500B1341E /* WebContextUserMessageCoders.h in Headers */,
                                BCB0B0DE12305A8C00B1341E /* InjectedBundleUserMessageCoders.h in Headers */,
                                BCB0B0E012305AB100B1341E /* UserMessageCoders.h in Headers */,
+                               BCA0EF7F12331E78007D3CFB /* WebEditCommand.h in Headers */,
+                               BCA0EF9F12332642007D3CFB /* WebEditCommandProxy.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                BCB0AD33122F285800B1341E /* MutableArray.cpp in Sources */,
                                BCB0AEEA122F53E300B1341E /* MutableDictionary.cpp in Sources */,
                                BCB0AF3612301DFB00B1341E /* WKMutableDictionary.cpp in Sources */,
+                               BCA0EF8012331E78007D3CFB /* WebEditCommand.cpp in Sources */,
+                               BCA0EFA012332642007D3CFB /* WebEditCommandProxy.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index b96eff7a6a5b8c5fd1c377b9fe9ad4b796a05be9..357c66f1d6c5c9ace6454da8eab7c7d4b4148570 100644 (file)
@@ -30,6 +30,8 @@
 
 #include "WebFrameLoaderClient.h"
 #include "WebPage.h"
+#include "WebPageProxyMessageKinds.h"
+#include "WebProcess.h"
 #include <WebCore/EditCommand.h>
 #include <WebCore/Frame.h>
 #include <WebCore/HTMLInputElement.h>
@@ -196,19 +198,28 @@ void WebEditorClient::didSetSelectionTypesForPasteboard()
     notImplemented();
 }
 
-void WebEditorClient::registerCommandForUndo(PassRefPtr<EditCommand>)
+void WebEditorClient::registerCommandForUndo(PassRefPtr<EditCommand> command)
 {
-    notImplemented();
+    // FIXME: Add assertion that the command being reapplied is the same command that is
+    // being passed to us.
+    if (m_page->isInRedo())
+        return;
+
+    RefPtr<WebEditCommand> webCommand = WebEditCommand::create(command);
+    m_page->addWebEditCommand(webCommand->commandID(), webCommand.get());
+    uint32_t editAction = static_cast<uint32_t>(webCommand->command()->editingAction());
+
+    WebProcess::shared().connection()->send(WebPageProxyMessage::RegisterEditCommandForUndo, m_page->pageID(),
+                                            CoreIPC::In(webCommand->commandID(), editAction));
 }
 
 void WebEditorClient::registerCommandForRedo(PassRefPtr<EditCommand>)
 {
-    notImplemented();
 }
 
 void WebEditorClient::clearUndoRedoOperations()
 {
-    notImplemented();
+    WebProcess::shared().connection()->send(WebPageProxyMessage::ClearAllEditCommands, m_page->pageID(), CoreIPC::In());
 }
 
 bool WebEditorClient::canUndo() const
diff --git a/WebKit2/WebProcess/WebPage/WebEditCommand.cpp b/WebKit2/WebProcess/WebPage/WebEditCommand.cpp
new file mode 100644 (file)
index 0000000..198cb6d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 "WebEditCommand.h"
+
+namespace WebKit {
+
+static uint64_t generateCommandID()
+{
+    static uint64_t uniqueCommandID = 1;
+    return uniqueCommandID++;
+}
+
+PassRefPtr<WebEditCommand> WebEditCommand::create(PassRefPtr<WebCore::EditCommand> command)
+{
+    return adoptRef(new WebEditCommand(command, generateCommandID()));
+}
+
+} // namespace WebKit
diff --git a/WebKit2/WebProcess/WebPage/WebEditCommand.h b/WebKit2/WebProcess/WebPage/WebEditCommand.h
new file mode 100644 (file)
index 0000000..b6844a2
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 WebEditCommand_h
+#define WebEditCommand_h
+
+#include <WebCore/EditCommand.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebKit {
+
+class WebEditCommand : public RefCounted<WebEditCommand> {
+public:
+    static PassRefPtr<WebEditCommand> create(PassRefPtr<WebCore::EditCommand>);
+
+    WebCore::EditCommand* command() const { return m_command.get(); }
+    uint64_t commandID() const { return m_commandID; }
+
+private:
+    WebEditCommand(PassRefPtr<WebCore::EditCommand> command, uint64_t commandID)
+        : m_command(command)
+        , m_commandID(commandID)
+    {
+    }
+
+    RefPtr<WebCore::EditCommand> m_command;
+    uint64_t m_commandID;
+};
+
+} // namespace WebKit
+
+#endif // WebEditCommand_h
index dbd54d02d4cbdd1022d8581068cb5d3a8eac92e1..53834e99a703bb4f351c20deae4b12bbbcc38b47 100644 (file)
@@ -85,6 +85,7 @@ PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const IntSize& viewSize, co
 WebPage::WebPage(uint64_t pageID, const IntSize& viewSize, const WebPreferencesStore& store, const DrawingAreaBase::DrawingAreaInfo& drawingAreaInfo)
     : m_viewSize(viewSize)
     , m_drawingArea(DrawingArea::create(drawingAreaInfo.type, drawingAreaInfo.id, this))
+    , m_isInRedo(false)
     , m_pageID(pageID)
 {
     ASSERT(m_pageID);
@@ -533,6 +534,46 @@ bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
     return frame->editor()->insertText(evt->keyEvent()->text(), evt);
 }
 
+WebEditCommand* WebPage::webEditCommand(uint64_t commandID)
+{
+    return m_editCommandMap.get(commandID).get();
+}
+
+void WebPage::addWebEditCommand(uint64_t commandID, WebEditCommand* command)
+{
+    m_editCommandMap.set(commandID, command);
+}
+
+void WebPage::removeWebEditCommand(uint64_t commandID)
+{
+    m_editCommandMap.remove(commandID);
+}
+
+void WebPage::unapplyEditCommand(uint64_t commandID)
+{
+    WebEditCommand* command = webEditCommand(commandID);
+    if (!command)
+        return;
+
+    command->command()->unapply();
+}
+
+void WebPage::reapplyEditCommand(uint64_t commandID)
+{
+    WebEditCommand* command = webEditCommand(commandID);
+    if (!command)
+        return;
+
+    m_isInRedo = true;
+    command->command()->reapply();
+    m_isInRedo = false;
+}
+
+void WebPage::didRemoveEditCommand(uint64_t commandID)
+{
+    removeWebEditCommand(commandID);
+}
+
 void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
 {
     if (messageID.is<CoreIPC::MessageClassDrawingArea>()) {
@@ -692,6 +733,27 @@ void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::Messag
             setCustomUserAgent(customUserAgent);
             return;
         }
+        case WebPageMessage::UnapplyEditCommand: {
+            uint64_t commandID;
+            if (!arguments->decode(CoreIPC::Out(commandID)))
+                return;
+            unapplyEditCommand(commandID);
+            return;
+        }
+        case WebPageMessage::ReapplyEditCommand: {
+            uint64_t commandID;
+            if (!arguments->decode(CoreIPC::Out(commandID)))
+                return;
+            reapplyEditCommand(commandID);
+            return;
+        }
+        case WebPageMessage::DidRemoveEditCommand: {
+            uint64_t commandID;
+            if (!arguments->decode(CoreIPC::Out(commandID)))
+                return;
+            didRemoveEditCommand(commandID);
+            return;
+        }
     }
 
     ASSERT_NOT_REACHED();
index 0de7e5318ffa46b8ee40ec84084fa20635de4a15..460fd7e1d5d4b0f0cc18f150ac6e5a0bb52fdc9c 100644 (file)
@@ -32,6 +32,7 @@
 #include "InjectedBundlePageFormClient.h"
 #include "InjectedBundlePageLoaderClient.h"
 #include "InjectedBundlePageUIClient.h"
+#include "WebEditCommand.h"
 #include <WebCore/FrameLoaderTypes.h>
 #include <WebCore/IntRect.h>
 #include <WebCore/ZoomMode.h>
@@ -98,6 +99,11 @@ public:
     void show();
     String userAgent() const;
 
+    WebEditCommand* webEditCommand(uint64_t);
+    void addWebEditCommand(uint64_t, WebEditCommand*);
+    void removeWebEditCommand(uint64_t);
+    bool isInRedo() const { return m_isInRedo; }
+
     // -- Called from WebProcess.
     void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
 
@@ -167,6 +173,10 @@ private:
     void didReceivePolicyDecision(WebFrame*, uint64_t listenerID, WebCore::PolicyAction policyAction);
     void setCustomUserAgent(const WTF::String&);
 
+    void unapplyEditCommand(uint64_t commandID);
+    void reapplyEditCommand(uint64_t commandID);
+    void didRemoveEditCommand(uint64_t commandID);
+
     OwnPtr<WebCore::Page> m_page;
     RefPtr<WebFrame> m_mainFrame;
 
@@ -175,6 +185,9 @@ private:
     WebCore::IntSize m_viewSize;
     RefPtr<DrawingArea> m_drawingArea;
 
+    bool m_isInRedo;
+    HashMap<uint64_t, RefPtr<WebEditCommand> > m_editCommandMap;
+
     InjectedBundlePageEditorClient m_editorClient;
     InjectedBundlePageFormClient m_formClient;
     InjectedBundlePageLoaderClient m_loaderClient;
index 7d28104a4211d5873131141386ae9f1210b3ceaa..c7459019fb7918890d960445f5677552ef49d230 100755 (executable)
                                </File>\r
                                <File\r
                                        RelativePath="..\WebProcess\WebCoreSupport\WebSearchPopupMenu.h"\r
-                                       >
-                               </File>
-                               <Filter
-                                       Name="win"
-                                       >
-                                       <File
-                                               RelativePath="..\WebProcess\WebCoreSupport\win\WebErrorsWin.cpp"
-                                               >
-                                       </File>
-                                       <File
-                                               RelativePath="..\WebProcess\WebCoreSupport\win\WebFrameNetworkingContext.cpp"
-                                               >
-                                       </File>
-                                       <File
-                                               RelativePath="..\WebProcess\WebCoreSupport\win\WebFrameNetworkingContext.h"
-                                               >
-                                       </File>
-                               </Filter>
-                       </Filter>
-                       <Filter
-                               Name="WebPage"
-                               >
-                               <File
-                                       RelativePath="..\WebProcess\WebPage\ChunkedUpdateDrawingArea.cpp"
-                                       >
-                               </File>
+                                       >\r
+                               </File>\r
+                               <Filter\r
+                                       Name="win"\r
+                                       >\r
+                                       <File\r
+                                               RelativePath="..\WebProcess\WebCoreSupport\win\WebErrorsWin.cpp"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
+                                               RelativePath="..\WebProcess\WebCoreSupport\win\WebFrameNetworkingContext.cpp"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
+                                               RelativePath="..\WebProcess\WebCoreSupport\win\WebFrameNetworkingContext.h"\r
+                                               >\r
+                                       </File>\r
+                               </Filter>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="WebPage"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\WebProcess\WebPage\ChunkedUpdateDrawingArea.cpp"\r
+                                       >\r
+                               </File>\r
                                <File\r
                                        RelativePath="..\WebProcess\WebPage\ChunkedUpdateDrawingArea.h"\r
                                        >\r
                                        RelativePath="..\WebProcess\WebPage\WebBackForwardListProxy.h"\r
                                        >\r
                                </File>\r
+                               <File\r
+                                       RelativePath="..\WebProcess\WebPage\WebEditCommand.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\WebProcess\WebPage\WebEditCommand.h"\r
+                                       >\r
+                               </File>\r
                                <File\r
                                        RelativePath="..\WebProcess\WebPage\WebFrame.cpp"\r
                                        >\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\UIProcess\WebData.h"\r
+                               RelativePath="..\UIProcess\WebEditCommandProxy.cpp"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\UIProcess\WebError.h"\r
+                               RelativePath="..\UIProcess\WebEditCommandProxy.h"\r
                                >\r
                        </File>\r
                        <File\r