WebCore:
authorkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Apr 2004 18:41:51 +0000 (18:41 +0000)
committerkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Apr 2004 18:41:51 +0000 (18:41 +0000)
        Reviewed by Dave

        Added execCommand support for cut/copy/paste.

        * khtml/xml/dom_docimpl.cpp:
        (DocumentImpl::execCommand): Added cut/copy/paste atoms and added else if cases
        for the commands.
        * kwq/KWQKHTMLPart.h:
        * kwq/KWQKHTMLPart.mm:
        (KWQKHTMLPart::issueCutCommand): Glue for calling from WebCore to do a cut in Cocoa.
        (KWQKHTMLPart::issueCopyCommand): Same as above, but for copy.
        (KWQKHTMLPart::issuePasteCommand): Same as above, but for paste.
        * kwq/WebCoreBridge.h: Declared issueCutCommand, issueCopyCommand, and issuePasteCommand
        to be implemented on the WebKit side of the bridge.
        * layout-tests/editing/editing.js: Added cut/copy/paste support to js library to support
        making layout tests.
        * layout-tests/editing/pasteboard/copy-paste-text-001-expected.txt: Added.
        * layout-tests/editing/pasteboard/copy-paste-text-001.html: Added.
        * layout-tests/editing/pasteboard/cut-paste-text-002-expected.txt: Added.
        * layout-tests/editing/pasteboard/cut-paste-text-002.html: Added.
        * layout-tests/editing/pasteboard/cut-text-001-expected.txt: Added.
        * layout-tests/editing/pasteboard/cut-text-001.html: Added.

WebKit:

        Reviewed by Dave

        Added execCommand support for cut/copy/paste.

        * WebCoreSupport.subproj/WebBridge.m:
        (-[WebBridge issueCutCommand]): Glue for calling from WebCore to do a cut in Cocoa.
        (-[WebBridge issueCopyCommand]): Same as above, but for copy.
        (-[WebBridge issuePasteCommand]): Same as above, but for paste.
        * WebView.subproj/WebHTMLView.m:
        (-[WebHTMLView copy:]): Move this to private implementation category so the bridge can see it.
        (-[WebHTMLView cut:]): Ditto.
        (-[WebHTMLView paste:]): Ditto.
        * WebView.subproj/WebHTMLViewPrivate.h: Move copy;, cut:, and paste: to private implementation
        category so the bridge can see it.
        * WebView.subproj/WebView.m:
        (-[WebView copy:]): Implemented by calling WebHTMLView to do the work.
        (-[WebView cut:]): Ditto.
        (-[WebView paste:]): Ditto.
        * WebView.subproj/WebViewPrivate.h: Added all the NSReponder methods we plan to implement as
        part of the WebKit editing API.

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

18 files changed:
LayoutTests/editing/editing.js
LayoutTests/editing/pasteboard/copy-paste-text-001-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/copy-paste-text-001.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/cut-paste-text-002-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/cut-paste-text-002.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/cut-text-001-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/cut-text-001.html [new file with mode: 0644]
WebCore/ChangeLog-2005-08-23
WebCore/khtml/xml/dom_docimpl.cpp
WebCore/kwq/KWQKHTMLPart.h
WebCore/kwq/KWQKHTMLPart.mm
WebCore/kwq/WebCoreBridge.h
WebKit/ChangeLog
WebKit/WebCoreSupport.subproj/WebBridge.m
WebKit/WebView.subproj/WebHTMLView.m
WebKit/WebView.subproj/WebHTMLViewPrivate.h
WebKit/WebView.subproj/WebView.m
WebKit/WebView.subproj/WebViewPrivate.h

index 43e9284..0ba011d 100644 (file)
@@ -144,6 +144,51 @@ function changeRootSize() {
 
 //-------------------------------------------------------------------------------------------------------
 
+function execCutCommand() {
+    document.execCommand("Cut");
+}
+function cutCommand() {
+    if (commandDelay > 0) {
+        window.setTimeout(execCutCommand, commandCount * commandDelay);
+        commandCount++;
+    }
+    else {
+        execCutCommand();
+    }
+}
+
+//-------------------------------------------------------------------------------------------------------
+
+function execCopyCommand() {
+    document.execCommand("Copy");
+}
+function copyCommand() {
+    if (commandDelay > 0) {
+        window.setTimeout(execCopyCommand, commandCount * commandDelay);
+        commandCount++;
+    }
+    else {
+        execCopyCommand();
+    }
+}
+
+//-------------------------------------------------------------------------------------------------------
+
+function execPasteCommand() {
+    document.execCommand("Paste");
+}
+function pasteCommand() {
+    if (commandDelay > 0) {
+        window.setTimeout(execPasteCommand, commandCount * commandDelay);
+        commandCount++;
+    }
+    else {
+        execPasteCommand();
+    }
+}
+
+//-------------------------------------------------------------------------------------------------------
+
 function execDeleteCommand() {
     document.execCommand("Delete");
 }
diff --git a/LayoutTests/editing/pasteboard/copy-paste-text-001-expected.txt b/LayoutTests/editing/pasteboard/copy-paste-text-001-expected.txt
new file mode 100644 (file)
index 0000000..9f662af
--- /dev/null
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x72
+  RenderBlock {HTML} at (0,0) size 800x72
+    RenderBody {BODY} at (8,8) size 784x56
+      RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
+        RenderInline {SPAN} at (0,0) size 140x28
+          RenderText {TEXT} at (14,14) size 109x28
+            text run at (14,14) width 109: "foo bar baz"
+          RenderInline {SPAN} at (0,0) size 31x28
+            RenderText {TEXT} at (123,14) size 31x28
+              text run at (123,14) width 31: "bar"
+selection is CARET:
+start:      position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of root {DIV}
+upstream:   position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of root {DIV}
+downstream: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of root {DIV}
diff --git a/LayoutTests/editing/pasteboard/copy-paste-text-001.html b/LayoutTests/editing/pasteboard/copy-paste-text-001.html
new file mode 100644 (file)
index 0000000..32446e0
--- /dev/null
@@ -0,0 +1,40 @@
+<html> 
+<head>
+
+<style>
+.editing { 
+    border: 2px solid red; 
+    padding: 12px; 
+    font-size: 24px; 
+}
+</style>
+<script src=../editing.js language="JavaScript" type="text/JavaScript" ></script>
+
+<script>
+
+function editingTest() {
+    for (i = 0; i < 4; i++)
+        moveSelectionForwardByCharacterCommand();
+    for (i = 0; i < 3; i++)
+        extendSelectionForwardByCharacterCommand();
+    copyCommand();
+    for (i = 0; i < 5; i++)
+        moveSelectionForwardByCharacterCommand();
+    pasteCommand();
+}
+
+</script>
+
+<title>Editing Test</title> 
+</head> 
+<body>
+<div contenteditable id="root" class="editing">
+<span id="test">foo bar baz</span>
+</div>
+
+<script>
+runEditingTest();
+</script>
+
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/cut-paste-text-002-expected.txt b/LayoutTests/editing/pasteboard/cut-paste-text-002-expected.txt
new file mode 100644 (file)
index 0000000..0e46da1
--- /dev/null
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x72
+  RenderBlock {HTML} at (0,0) size 800x72
+    RenderBody {BODY} at (8,8) size 784x56
+      RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
+        RenderInline {SPAN} at (0,0) size 109x28
+          RenderText {TEXT} at (14,14) size 78x28
+            text run at (14,14) width 78: "foo  baz"
+          RenderInline {SPAN} at (0,0) size 31x28
+            RenderText {TEXT} at (92,14) size 31x28
+              text run at (92,14) width 31: "bar"
+selection is CARET:
+start:      position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of root {DIV}
+upstream:   position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of root {DIV}
+downstream: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of root {DIV}
diff --git a/LayoutTests/editing/pasteboard/cut-paste-text-002.html b/LayoutTests/editing/pasteboard/cut-paste-text-002.html
new file mode 100644 (file)
index 0000000..429b5cf
--- /dev/null
@@ -0,0 +1,40 @@
+<html> 
+<head>
+
+<style>
+.editing { 
+    border: 2px solid red; 
+    padding: 12px; 
+    font-size: 24px; 
+}
+</style>
+<script src=../editing.js language="JavaScript" type="text/JavaScript" ></script>
+
+<script>
+
+function editingTest() {
+    for (i = 0; i < 4; i++)
+        moveSelectionForwardByCharacterCommand();
+    for (i = 0; i < 3; i++)
+        extendSelectionForwardByCharacterCommand();
+    cutCommand();
+    for (i = 0; i < 4; i++)
+        moveSelectionForwardByCharacterCommand();
+    pasteCommand();
+}
+
+</script>
+
+<title>Editing Test</title> 
+</head> 
+<body>
+<div contenteditable id="root" class="editing">
+<span id="test">foo bar baz</span>
+</div>
+
+<script>
+runEditingTest();
+</script>
+
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/cut-text-001-expected.txt b/LayoutTests/editing/pasteboard/cut-text-001-expected.txt
new file mode 100644 (file)
index 0000000..de9e52b
--- /dev/null
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x72
+  RenderBlock {HTML} at (0,0) size 800x72
+    RenderBody {BODY} at (8,8) size 784x56
+      RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
+        RenderInline {SPAN} at (0,0) size 78x28
+          RenderText {TEXT} at (14,14) size 78x28
+            text run at (14,14) width 78: "foo  baz"
+        RenderText {TEXT} at (0,0) size 0x0
+selection is CARET:
+start:      position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
diff --git a/LayoutTests/editing/pasteboard/cut-text-001.html b/LayoutTests/editing/pasteboard/cut-text-001.html
new file mode 100644 (file)
index 0000000..e49b766
--- /dev/null
@@ -0,0 +1,37 @@
+<html> 
+<head>
+
+<style>
+.editing { 
+    border: 2px solid red; 
+    padding: 12px; 
+    font-size: 24px; 
+}
+</style>
+<script src=../editing.js language="JavaScript" type="text/JavaScript" ></script>
+
+<script>
+
+function editingTest() {
+    for (i = 0; i < 4; i++)
+        moveSelectionForwardByCharacterCommand();
+    for (i = 0; i < 3; i++)
+        extendSelectionForwardByCharacterCommand();
+    cutCommand();
+}
+
+</script>
+
+<title>Editing Test</title> 
+</head> 
+<body>
+<div contenteditable id="root" class="editing">
+<span id="test">foo bar baz</span>
+</div>
+
+<script>
+runEditingTest();
+</script>
+
+</body>
+</html>
index 8d492a6..23d20e6 100644 (file)
@@ -1,5 +1,30 @@
 2004-04-12  Ken Kocienda  <kocienda@apple.com>
 
+        Reviewed by Dave
+
+        Added execCommand support for cut/copy/paste.
+        
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::execCommand): Added cut/copy/paste atoms and added else if cases
+        for the commands.
+        * kwq/KWQKHTMLPart.h:
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::issueCutCommand): Glue for calling from WebCore to do a cut in Cocoa.
+        (KWQKHTMLPart::issueCopyCommand): Same as above, but for copy.
+        (KWQKHTMLPart::issuePasteCommand): Same as above, but for paste.
+        * kwq/WebCoreBridge.h: Declared issueCutCommand, issueCopyCommand, and issuePasteCommand
+        to be implemented on the WebKit side of the bridge.
+        * layout-tests/editing/editing.js: Added cut/copy/paste support to js library to support
+        making layout tests.
+        * layout-tests/editing/pasteboard/copy-paste-text-001-expected.txt: Added.
+        * layout-tests/editing/pasteboard/copy-paste-text-001.html: Added.
+        * layout-tests/editing/pasteboard/cut-paste-text-002-expected.txt: Added.
+        * layout-tests/editing/pasteboard/cut-paste-text-002.html: Added.
+        * layout-tests/editing/pasteboard/cut-text-001-expected.txt: Added.
+        * layout-tests/editing/pasteboard/cut-text-001.html: Added.
+
+2004-04-12  Ken Kocienda  <kocienda@apple.com>
+
         Reviewed by John
         
         Some delete and insert cleanups.
index e321b21..c1204bd 100644 (file)
@@ -2653,6 +2653,9 @@ bool DocumentImpl::execCommand(const DOMString &command, bool userInterface, con
     static AtomicString undoCommand("undo");
     static AtomicString redoCommand("redo");
     static AtomicString deleteCommand("delete");
+    static AtomicString cutCommand("cut");
+    static AtomicString copyCommand("copy");
+    static AtomicString pasteCommand("paste");
 
     updateLayout();
 
@@ -2687,6 +2690,24 @@ bool DocumentImpl::execCommand(const DOMString &command, bool userInterface, con
         TypingCommand::deleteKeyPressed(this);
         return true;
     }
+    else if (atom == cutCommand) {
+        if (!part() || part()->selection().state() != KHTMLSelection::RANGE)
+            return false;
+        KWQ(part())->issueCutCommand();
+        return true;
+    }
+    else if (atom == copyCommand) {
+        if (!part() || part()->selection().state() != KHTMLSelection::RANGE)
+            return false;
+        KWQ(part())->issueCopyCommand();
+        return true;
+    }
+    else if (atom == pasteCommand) {
+        if (!part() || part()->selection().isEmpty())
+            return false;
+        KWQ(part())->issuePasteCommand();
+        return true;
+    }
 
     return false;
 }
index b8118f8..79ad35d 100644 (file)
@@ -274,6 +274,9 @@ public:
     void editingKeyEvent();
     void issueUndoCommand();
     void issueRedoCommand();
+    void issueCutCommand();
+    void issueCopyCommand();
+    void issuePasteCommand();
     
 private:
     virtual void khtmlMousePressEvent(khtml::MousePressEvent *);
index 11eb7b7..9020d69 100644 (file)
@@ -2903,3 +2903,18 @@ void KWQKHTMLPart::issueRedoCommand()
 {
     [_bridge issueRedoCommand];
 }
+
+void KWQKHTMLPart::issueCutCommand()
+{
+    [_bridge issueCutCommand];
+}
+
+void KWQKHTMLPart::issueCopyCommand()
+{
+    [_bridge issueCopyCommand];
+}
+
+void KWQKHTMLPart::issuePasteCommand()
+{
+    [_bridge issuePasteCommand];
+}
index 37cf707..46c5ca6 100644 (file)
@@ -433,6 +433,9 @@ typedef enum {
 - (void)clearUndoRedoOperations;
 - (void)issueUndoCommand;
 - (void)issueRedoCommand;
+- (void)issueCutCommand;
+- (void)issueCopyCommand;
+- (void)issuePasteCommand;
 
 - (void)editingKeyDown:(NSEvent *)event;
 
index 8f964c7..d150795 100644 (file)
@@ -1,3 +1,26 @@
+2004-04-12  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by Dave
+        
+        Added execCommand support for cut/copy/paste.
+
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge issueCutCommand]): Glue for calling from WebCore to do a cut in Cocoa.
+        (-[WebBridge issueCopyCommand]): Same as above, but for copy.
+        (-[WebBridge issuePasteCommand]): Same as above, but for paste.
+        * WebView.subproj/WebHTMLView.m:
+        (-[WebHTMLView copy:]): Move this to private implementation category so the bridge can see it.
+        (-[WebHTMLView cut:]): Ditto.
+        (-[WebHTMLView paste:]): Ditto.
+        * WebView.subproj/WebHTMLViewPrivate.h: Move copy;, cut:, and paste: to private implementation 
+        category so the bridge can see it.
+        * WebView.subproj/WebView.m:
+        (-[WebView copy:]): Implemented by calling WebHTMLView to do the work.
+        (-[WebView cut:]): Ditto.
+        (-[WebView paste:]): Ditto.
+        * WebView.subproj/WebViewPrivate.h: Added all the NSReponder methods we plan to implement as
+        part of the WebKit editing API.
+
 2004-04-09  Ken Kocienda  <kocienda@apple.com>
 
         Reviewed by Darin
index 1fe7c56..3819c87 100644 (file)
@@ -1203,6 +1203,21 @@ static id <WebFormDelegate> formDelegate(WebBridge *self)
         [undoManager redo];
 }
 
+- (void)issueCutCommand
+{
+    [[_frame webView] cut:nil];
+}
+
+- (void)issueCopyCommand
+{
+    [[_frame webView] copy:nil];
+}
+
+- (void)issuePasteCommand
+{
+    [[_frame webView] paste:nil];
+}
+
 - (void)setIsSelected:(BOOL)isSelected forView:(NSView *)view
 {
     if ([view conformsToProtocol:@protocol(WebPluginSelection)]) {
index 4a8305f..d2a7a25 100644 (file)
@@ -909,6 +909,22 @@ static WebHTMLView *lastHitView = nil;
     [self mouseDragged:fakeEvent];
 }
 
+- (void)copy:(id)sender
+{
+    [self _writeSelectionToPasteboard:[NSPasteboard generalPasteboard]];
+}
+
+- (void)cut:(id)sender
+{   
+    [self copy:sender];
+    [[self _bridge] deleteSelection];
+}
+
+- (void)paste:(id)sender
+{
+    [self _pasteFromPasteboard:[NSPasteboard generalPasteboard]];
+}
+
 @end
 
 @implementation NSView (WebHTMLViewPrivate)
index e1611c3..1fd2c4c 100644 (file)
@@ -92,4 +92,9 @@
 
 - (void)_startAutoscrollTimer:(NSEvent *)event;
 - (void)_stopAutoscrollTimer;
+
+- (void)cut:(id)sender;
+- (void)copy:(id)sender;
+- (void)paste:(id)sender;
+
 @end
index a67cde7..a623b3f 100644 (file)
@@ -28,6 +28,7 @@
 #import <WebKit/WebFrameViewPrivate.h>
 #import <WebKit/WebHistoryItemPrivate.h>
 #import <WebKit/WebHTMLView.h>
+#import <WebKit/WebHTMLViewPrivate.h>
 #import <WebKit/WebIconDatabase.h>
 #import <WebKit/WebKitErrors.h>
 #import <WebKit/WebKitLogging.h>
@@ -2575,7 +2576,10 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 - (void)copy:(id)sender
 {
     if ([self _currentSelectionIsEditable]) {
-        ERROR("unimplemented");
+        id <WebDocumentView> view = [[[self mainFrame] frameView] documentView];
+        if ([view isKindOfClass:[WebHTMLView class]]) {
+            [(WebHTMLView *)view copy:nil];
+        }
         return;
     }
     [[self nextResponder] tryToPerform:@selector(copy:) with:sender];
@@ -2584,7 +2588,10 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 - (void)cut:(id)sender
 {
     if ([self _currentSelectionIsEditable]) {
-        ERROR("unimplemented");
+        id <WebDocumentView> view = [[[self mainFrame] frameView] documentView];
+        if ([view isKindOfClass:[WebHTMLView class]]) {
+            [(WebHTMLView *)view cut:nil];
+        }
         return;
     }
     [[self nextResponder] tryToPerform:@selector(cut:) with:sender];
@@ -2593,7 +2600,10 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 - (void)paste:(id)sender
 {
     if ([self _currentSelectionIsEditable]) {
-        ERROR("unimplemented");
+        id <WebDocumentView> view = [[[self mainFrame] frameView] documentView];
+        if ([view isKindOfClass:[WebHTMLView class]]) {
+            [(WebHTMLView *)view paste:nil];
+        }
         return;
     }
     [[self nextResponder] tryToPerform:@selector(paste:) with:sender];
index 245c842..9b577e3 100644 (file)
@@ -370,6 +370,126 @@ extern NSString * const WebViewDidChangeSelectionNotification;
 - (NSUndoManager *)undoManagerForWebView:(WebView *)webView;
 @end
 
+@interface WebView (WebViewEditingActions)
+
+    /* Selection movement and scrolling */
+
+- (void)centerSelectionInVisibleArea:(id)sender;
+- (void)moveBackward:(id)sender;
+- (void)moveBackwardAndModifySelection:(id)sender;
+- (void)moveDown:(id)sender;
+- (void)moveDownAndModifySelection:(id)sender;
+- (void)moveForward:(id)sender;
+- (void)moveForwardAndModifySelection:(id)sender;
+- (void)moveLeft:(id)sender;
+- (void)moveLeftAndModifySelection:(id)sender;
+- (void)moveRight:(id)sender;
+- (void)moveRightAndModifySelection:(id)sender;
+- (void)moveToBeginningOfDocument:(id)sender;
+- (void)moveToBeginningOfLine:(id)sender;
+- (void)moveToBeginningOfParagraph:(id)sender;
+- (void)moveToEndOfDocument:(id)sender;
+- (void)moveToEndOfLine:(id)sender;
+- (void)moveToEndOfParagraph:(id)sender;
+- (void)moveUp:(id)sender;
+- (void)moveUpAndModifySelection:(id)sender;
+- (void)moveWordBackward:(id)sender;
+- (void)moveWordBackwardAndModifySelection:(id)sender;
+- (void)moveWordForward:(id)sender;
+- (void)moveWordForwardAndModifySelection:(id)sender;
+- (void)moveWordLeft:(id)sender;
+- (void)moveWordLeftAndModifySelection:(id)sender;
+- (void)moveWordRight:(id)sender;
+- (void)moveWordRightAndModifySelection:(id)sender;
+- (void)pageDown:(id)sender;
+- (void)pageUp:(id)sender;
+- (void)scrollLineDown:(id)sender;
+- (void)scrollLineUp:(id)sender;
+- (void)scrollPageDown:(id)sender;
+- (void)scrollPageUp:(id)sender;
+
+    /* Selections */
+
+- (void)selectAll:(id)sender;
+- (void)selectParagraph:(id)sender;
+- (void)selectLine:(id)sender;
+- (void)selectWord:(id)sender;
+
+    /* "Edit menu" actions */
+
+- (void)copy:(id)sender;
+- (void)cut:(id)sender;
+- (void)paste:(id)sender;
+- (void)copyFont:(id)sender;
+- (void)pasteFont:(id)sender;
+- (void)delete:(id)sender;
+- (void)pasteAsPlainText:(id)sender;
+- (void)pasteAsRichText:(id)sender;
+
+    /* Fonts */
+
+- (void)changeFont:(id)sender;
+- (void)changeAttributes:(id)sender;
+- (void)changeDocumentBackgroundColor:(id)sender;
+
+    /* Colors */
+
+- (void)changeColor:(id)sender;
+
+       /* Alignment */
+
+- (void)alignCenter:(id)sender;
+- (void)alignJustified:(id)sender;
+- (void)alignLeft:(id)sender;
+- (void)alignRight:(id)sender;
+
+    /* Insertions and Indentations */
+
+- (void)indent:(id)sender;
+- (void)insertTab:(id)sender;
+- (void)insertBacktab:(id)sender;
+- (void)insertNewline:(id)sender;
+- (void)insertParagraphSeparator:(id)sender;
+
+    /* Case changes */
+
+- (void)changeCaseOfLetter:(id)sender;
+- (void)uppercaseWord:(id)sender;
+- (void)lowercaseWord:(id)sender;
+- (void)capitalizeWord:(id)sender;
+
+    /* Deletions */
+
+- (void)deleteForward:(id)sender;
+- (void)deleteBackward:(id)sender;
+- (void)deleteBackwardByDecomposingPreviousCharacter:(id)sender;
+- (void)deleteWordForward:(id)sender;
+- (void)deleteWordBackward:(id)sender;
+- (void)deleteToBeginningOfLine:(id)sender;
+- (void)deleteToEndOfLine:(id)sender;
+- (void)deleteToBeginningOfParagraph:(id)sender;
+- (void)deleteToEndOfParagraph:(id)sender;
+
+    /* Completion */
+
+- (void)complete:(id)sender;
+
+    /* Spelling */
+
+- (void)checkSpelling:(id)sender;
+- (void)showGuessPanel:(id)sender;
+
+    /* Finding */
+    
+- (void)performFindPanelAction:(id)sender;
+
+       /* Speech */
+
+- (void)startSpeaking:(id)sender;
+- (void)stopSpeaking:(id)sender;
+
+@end
+
 @interface WebView (WebViewEditingExtras)
 - (void)_editingKeyDown:(NSEvent *)event;
 @end