WebCore:
authorcblu <cblu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Feb 2005 02:34:08 +0000 (02:34 +0000)
committercblu <cblu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Feb 2005 02:34:08 +0000 (02:34 +0000)
Fixed: <rdar://problem/3976872> Pasted plain text doesn't get the proper style if pasted into newlines

        Reviewed by mjs.

        * khtml/editing/htmlediting.cpp:
        (khtml::ReplaceSelectionCommand::doApply): don't clear the typing style when matching style
        (khtml::ReplaceSelectionCommand::completeHTMLReplacement): apply the typing style when matching style
        * khtml/editing/jsediting.cpp:
        * khtml/khtml_part.cpp:
        (KHTMLPart::pasteAndMatchStyle): new
        * khtml/khtml_part.h:
        * kwq/KWQKHTMLPart.h:
        * kwq/KWQKHTMLPart.mm:
        (KWQKHTMLPart::issuePasteAndMatchStyleCommand): new
        * kwq/WebCoreBridge.h:
        * layout-tests/editing/editing.js:

WebKit:

        Reviewed by mjs.

        * WebCoreSupport.subproj/WebBridge.m:
        (-[WebBridge issuePasteAndMatchStyleCommand]): support for new "PasteAndMatchStyle" exec command

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

15 files changed:
LayoutTests/editing/editing.js
LayoutTests/editing/pasteboard/paste-match-style-001-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/paste-match-style-001.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/paste-match-style-002-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/paste-match-style-002.html [new file with mode: 0644]
WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/htmlediting.cpp
WebCore/khtml/editing/jsediting.cpp
WebCore/khtml/khtml_part.cpp
WebCore/khtml/khtml_part.h
WebCore/kwq/KWQKHTMLPart.h
WebCore/kwq/KWQKHTMLPart.mm
WebCore/kwq/WebCoreBridge.h
WebKit/ChangeLog
WebKit/WebCoreSupport.subproj/WebBridge.m

index 2494fe6a0d1650a37fa90b012b5d0ec4e7422f54..a1069ae2e2c56093dea50a1b1bad2c93730a0ad1 100644 (file)
@@ -484,6 +484,21 @@ function pasteCommand() {
 
 //-------------------------------------------------------------------------------------------------------
 
+function execPasteAndMatchStyleCommand() {
+    document.execCommand("PasteAndMatchStyle");
+}
+function pasteAndMatchStyleCommand() {
+    if (commandDelay > 0) {
+        window.setTimeout(execPasteAndMatchStyleCommand, commandCount * commandDelay);
+        commandCount++;
+    }
+    else {
+        execPasteAndMatchStyleCommand();
+    }
+}
+
+//-------------------------------------------------------------------------------------------------------
+
 function execDeleteCommand() {
     document.execCommand("Delete");
 }
diff --git a/LayoutTests/editing/pasteboard/paste-match-style-001-expected.txt b/LayoutTests/editing/pasteboard/paste-match-style-001-expected.txt
new file mode 100644 (file)
index 0000000..14c0310
--- /dev/null
@@ -0,0 +1,35 @@
+layer at (0,0) size 800x600
+  RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {DIV} at (0,0) size 784x212 [border: (2px solid #0000FF)]
+        RenderBlock {DIV} at (14,14) size 756x56
+          RenderText {TEXT} at (0,0) size 67x28
+            text run at (0,0) width 67: "Tests: "
+          RenderBR {BR} at (0,0) size 0x0
+          RenderText {TEXT} at (0,28) size 267x28
+            text run at (0,28) width 267: "Pasting and matching style."
+        RenderBlock {DIV} at (14,86) size 756x112
+          RenderText {TEXT} at (0,0) size 189x28
+            text run at (0,0) width 189: "Expected Results: "
+          RenderBR {BR} at (0,0) size 0x0
+          RenderText {TEXT} at (0,28) size 749x56
+            text run at (0,28) width 749: "The pasted letter should match the style of the preexisting bold letter. Should"
+            text run at (0,56) width 368: "see this content in the red box below: "
+          RenderBR {BR} at (0,0) size 0x0
+          RenderInline {B} at (0,0) size 25x28
+            RenderText {TEXT} at (0,84) size 25x28
+              text run at (0,84) width 25: "ab"
+          RenderText {TEXT} at (0,0) size 0x0
+      RenderBlock {DIV} at (0,236) size 784x32
+        RenderBlock {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
+          RenderInline {B} at (0,0) size 25x28
+            RenderText {TEXT} at (2,2) size 12x28
+              text run at (2,2) width 12: "a"
+            RenderText {TEXT} at (14,2) size 13x28
+              text run at (14,2) width 13: "b"
+selection is CARET:
+start:      position 1 of child 2 {TEXT} of child 1 {B} of child 1 {DIV} of root {DIV}
+upstream:   position 1 of child 2 {TEXT} of child 1 {B} of child 1 {DIV} of root {DIV}
+downstream: position 1 of child 2 {TEXT} of child 1 {B} of child 1 {DIV} of root {DIV}
diff --git a/LayoutTests/editing/pasteboard/paste-match-style-001.html b/LayoutTests/editing/pasteboard/paste-match-style-001.html
new file mode 100644 (file)
index 0000000..acd5178
--- /dev/null
@@ -0,0 +1,63 @@
+<html> 
+<head>
+
+<style>
+.editing { 
+    border: 2px solid red; 
+    font-size: 24px; 
+}
+.explanation { 
+    border: 2px solid blue; 
+    padding: 12px; 
+    font-size: 24px; 
+    margin-bottom: 24px;
+}
+.scenario { margin-bottom: 16px;}
+.scenario:first-line { font-weight: bold; margin-bottom: 16px;}
+.expected-results:first-line { font-weight: bold }
+</style>
+<script src=../editing.js language="JavaScript" type="text/JavaScript" ></script>
+
+<script>
+
+function editingTest() {
+    extendSelectionForwardByLineCommand();
+    cutCommand();
+    boldCommand();
+    typeCharacterCommand("a")
+    pasteAndMatchStyleCommand();
+}
+
+</script>
+
+<title>Editing Test</title> 
+</head> 
+<body>
+
+<div class="explanation">
+<div class="scenario">
+Tests: 
+<br>
+Pasting and matching style.
+</div>
+<div class="expected-results">
+Expected Results:
+<br>
+The pasted letter should match the style of the preexisting bold letter. Should see this content in the red box below:
+<BR>
+<b>ab</b>
+</div>
+</div>
+
+<div contenteditable id="root" style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space;">
+<div id="test" class="editing">
+b
+</div>
+</div>
+
+<script>
+runEditingTest();
+</script>
+
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/paste-match-style-002-expected.txt b/LayoutTests/editing/pasteboard/paste-match-style-002-expected.txt
new file mode 100644 (file)
index 0000000..8d8ac8d
--- /dev/null
@@ -0,0 +1,39 @@
+layer at (0,0) size 800x600
+  RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {DIV} at (0,0) size 784x240 [border: (2px solid #0000FF)]
+        RenderBlock {DIV} at (14,14) size 756x84
+          RenderText {TEXT} at (0,0) size 67x28
+            text run at (0,0) width 67: "Tests: "
+          RenderBR {BR} at (0,0) size 0x0
+          RenderText {TEXT} at (0,28) size 735x56
+            text run at (0,28) width 735: "Pasting and matching style when there is nothing typed, but the typing style"
+            text run at (0,56) width 459: "is set to bold. This test was created after fixing "
+          RenderInline {A} at (0,0) size 84x28 [color=#0000EE]
+            RenderText {TEXT} at (459,56) size 84x28
+              text run at (459,56) width 84: "3976872"
+          RenderText {TEXT} at (543,56) size 6x28
+            text run at (543,56) width 6: "."
+        RenderBlock {DIV} at (14,114) size 756x112
+          RenderText {TEXT} at (0,0) size 189x28
+            text run at (0,0) width 189: "Expected Results: "
+          RenderBR {BR} at (0,0) size 0x0
+          RenderText {TEXT} at (0,28) size 697x56
+            text run at (0,28) width 691: "The pasted word should match the current typing style. In this case, the"
+            text run at (0,56) width 697: "typing style is set to bold. Should see this content in the red box below: "
+          RenderBR {BR} at (0,0) size 0x0
+          RenderInline {B} at (0,0) size 50x28
+            RenderText {TEXT} at (0,84) size 50x28
+              text run at (0,84) width 50: "hello"
+          RenderText {TEXT} at (0,0) size 0x0
+      RenderBlock {DIV} at (0,264) size 784x32
+        RenderBlock {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
+          RenderInline {B} at (0,0) size 50x28
+            RenderText {TEXT} at (2,2) size 50x28
+              text run at (2,2) width 50: "hello"
+selection is CARET:
+start:      position 5 of child 1 {TEXT} of child 1 {B} of child 1 {DIV} of root {DIV}
+upstream:   position 5 of child 1 {TEXT} of child 1 {B} of child 1 {DIV} of root {DIV}
+downstream: position 5 of child 1 {TEXT} of child 1 {B} of child 1 {DIV} of root {DIV}
diff --git a/LayoutTests/editing/pasteboard/paste-match-style-002.html b/LayoutTests/editing/pasteboard/paste-match-style-002.html
new file mode 100644 (file)
index 0000000..f4b27cd
--- /dev/null
@@ -0,0 +1,62 @@
+<html> 
+<head>
+
+<style>
+.editing { 
+    border: 2px solid red; 
+    font-size: 24px; 
+}
+.explanation { 
+    border: 2px solid blue; 
+    padding: 12px; 
+    font-size: 24px; 
+    margin-bottom: 24px;
+}
+.scenario { margin-bottom: 16px;}
+.scenario:first-line { font-weight: bold; margin-bottom: 16px;}
+.expected-results:first-line { font-weight: bold }
+</style>
+<script src=../editing.js language="JavaScript" type="text/JavaScript" ></script>
+
+<script>
+
+function editingTest() {
+    extendSelectionForwardByLineCommand();
+    cutCommand();
+    boldCommand();
+    pasteAndMatchStyleCommand();
+}
+
+</script>
+
+<title>Editing Test</title> 
+</head> 
+<body>
+
+<div class="explanation">
+<div class="scenario">
+Tests: 
+<br>
+Pasting and matching style when there is nothing typed, but the typing style is set to bold. This test was created after fixing <A HREF="rdar://problem/3976872">3976872</A>.
+</div>
+<div class="expected-results">
+Expected Results:
+<br>
+The pasted word should match the current typing style. In this case, the typing style is set to bold. Should see this content in the red box below:
+<BR>
+<b>hello</b>
+</div>
+</div>
+
+<div contenteditable id="root" style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space;">
+<div id="test" class="editing">
+hello
+</div>
+</div>
+
+<script>
+runEditingTest();
+</script>
+
+</body>
+</html>
index 0a01253891bceac0d8ef7b2a22cbfca31e55b182..130fba5d3df03aed32797c1a1544ca9b9296614b 100644 (file)
@@ -1,3 +1,22 @@
+2005-02-22  Chris Blumenberg  <cblu@apple.com>
+
+       Fixed: <rdar://problem/3976872> Pasted plain text doesn't get the proper style if pasted into newlines
+
+        Reviewed by mjs.
+
+        * khtml/editing/htmlediting.cpp:
+        (khtml::ReplaceSelectionCommand::doApply): don't clear the typing style when matching style
+        (khtml::ReplaceSelectionCommand::completeHTMLReplacement): apply the typing style when matching style
+        * khtml/editing/jsediting.cpp:
+        * khtml/khtml_part.cpp:
+        (KHTMLPart::pasteAndMatchStyle): new
+        * khtml/khtml_part.h:
+        * kwq/KWQKHTMLPart.h:
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::issuePasteAndMatchStyleCommand): new
+        * kwq/WebCoreBridge.h:
+        * layout-tests/editing/editing.js:
+
 2005-02-22  Darin Adler  <darin@apple.com>
 
         Reviewed by Adele.
index 85d2df3d8bb7eb2850cae4857ab79fd7f8530a2b..9ed36862ec55219da2a7e14341263989a9b35551 100644 (file)
@@ -4495,12 +4495,14 @@ void ReplaceSelectionCommand::doApply()
     }
     endPos = selection.end().downstream(); 
     
-    // replacement command does not use any typing style that is set as a residual effect of the pre-delete
+    // If not matching style, clear typing style.
     // FIXME: Improve typing style.
     // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
     KHTMLPart *part = document()->part();
-    part->clearTypingStyle();
-    setTypingStyle(0);    
+    if (!m_matchStyle) {
+        part->clearTypingStyle();
+        setTypingStyle(0);    
+    }
     
     // done if there is nothing to add
     if (!m_fragment.firstChild())
@@ -4710,10 +4712,18 @@ void ReplaceSelectionCommand::completeHTMLReplacement(const Position &start, con
  {
     if (start.isNull() || !start.node()->inDocument() || end.isNull() || !end.node()->inDocument())
         return;
-    if (m_selectReplacement)
-        setEndingSelection(Selection(start, SEL_DEFAULT_AFFINITY, end, SEL_DEFAULT_AFFINITY));
-    else
+    
+    Selection replacementSelection(start, SEL_DEFAULT_AFFINITY, end, SEL_DEFAULT_AFFINITY);
+    setEndingSelection(replacementSelection);
+    
+    CSSMutableStyleDeclarationImpl *typingStyle = document()->part()->typingStyle();
+    if (m_matchStyle && typingStyle) {
+        applyStyle(typingStyle);
+    }    
+    
+    if (!m_selectReplacement)
         setEndingSelection(end, SEL_DEFAULT_AFFINITY);
+    
     rebalanceWhitespace();
 }
 
@@ -4743,16 +4753,7 @@ void ReplaceSelectionCommand::completeHTMLReplacement()
     
     Position start(firstLeaf, firstLeaf->caretMinOffset());
     Position end(lastLeaf, lastLeaf->caretMaxOffset());
-    Selection replacementSelection(start, SEL_DEFAULT_AFFINITY, end, SEL_DEFAULT_AFFINITY);
-    if (m_selectReplacement) {
-        // Select what was inserted.
-        setEndingSelection(replacementSelection);
-    } 
-    else {
-        // Place the cursor after what was inserted, and mark misspellings in the inserted content.
-        setEndingSelection(end, SEL_DEFAULT_AFFINITY);
-    }
-    rebalanceWhitespace();
+    completeHTMLReplacement(start, end);
 }
 
 EditAction ReplaceSelectionCommand::editingAction() const
index edbf0bfa86a7abd9ab7d7e162ba10dcf1be28a66..f9c847f047553dcdeedf6f87316ffa4f89a102a4 100644 (file)
@@ -302,6 +302,12 @@ bool execPaste(KHTMLPart *part, bool userInterface, const DOMString &value)
     return true;
 }
 
+bool execPasteAndMatchStyle(KHTMLPart *part, bool userInterface, const DOMString &value)
+{
+    part->pasteAndMatchStyle();
+    return true;
+}
+
 bool execPrint(KHTMLPart *part, bool userInterface, const DOMString &value)
 {
     part->print();
@@ -373,6 +379,11 @@ bool enabledPaste(KHTMLPart *part)
     return supportsPasteCommand && part->canPaste();
 }
 
+bool enabledPasteAndMatchStyle(KHTMLPart *part)
+{
+    return supportsPasteCommand && part->canPaste();
+}
+
 bool enabledRangeSelection(KHTMLPart *part)
 {
     return part->selection().isRange();
@@ -500,6 +511,7 @@ QDict<CommandImp> createCommandDictionary()
         { "JustifyRight", { execJustifyRight, enabledAnySelection, stateNone, valueNull } },
         { "Outdent", { execOutdent, enabledAnySelection, stateNone, valueNull } },
         { "Paste", { execPaste, enabledPaste, stateNone, valueNull } },
+        { "PasteAndMatchStyle", { execPasteAndMatchStyle, enabledPasteAndMatchStyle, stateNone, valueNull } },
         { "Print", { execPrint, enabled, stateNone, valueNull } },
         { "Redo", { execRedo, enabledRedo, stateNone, valueNull } },
         { "SelectAll", { execSelectAll, enabled, stateNone, valueNull } },
index 0cd62b17614e92c224c9b7ac2dbf0e4f2603cfe6..d8a1b767e8d2f61afc97bdb8362802693eeafe80 100644 (file)
@@ -5367,6 +5367,13 @@ void KHTMLPart::pasteFromPasteboard()
 #endif
 }
 
+void KHTMLPart::pasteAndMatchStyle()
+{
+#if APPLE_CHANGES
+    KWQ(this)->issuePasteAndMatchStyleCommand();
+#endif
+}
+
 void KHTMLPart::redo()
 {
 #if APPLE_CHANGES
index 0515cafa014fb7974822bfb4172570627d1ae7ef..8b615fcb299af94181684313e40f2dfa35f28269 100644 (file)
@@ -895,6 +895,7 @@ public:
   void copyToPasteboard();
   void cutToPasteboard();
   void pasteFromPasteboard();
+  void pasteAndMatchStyle();
   bool canPaste() const;
   void redo();
   void undo();
index 1ac67f70aff1610a94d38a99a742b0ef80151b74..6b0366ffc7e799d2dc2de851648cd73f6f651281 100644 (file)
@@ -336,6 +336,7 @@ public:
     void issueCutCommand();
     void issueCopyCommand();
     void issuePasteCommand();
+    void issuePasteAndMatchStyleCommand();
     void respondToChangedSelection(const khtml::Selection &oldSelection, bool closeTyping);
     void respondToChangedContents();
     virtual bool isContentEditable() const;
index 75a5a3091fed416ed6e666b29d7362b71c1dabd6..2b903c57b6c3873f55a6128efdc7c8102064a617 100644 (file)
@@ -3934,6 +3934,11 @@ void KWQKHTMLPart::issuePasteCommand()
     [_bridge issuePasteCommand];
 }
 
+void KWQKHTMLPart::issuePasteAndMatchStyleCommand()
+{
+    [_bridge issuePasteAndMatchStyleCommand];
+}
+
 bool KHTMLPart::canUndo() const
 {
     return [[KWQ(this)->_bridge undoManager] canUndo];
index 6c5cf5c8aaeb82df57541ce0cd9cf785690e29ee..d4fb5b51f97623a78c85fc4f0914f605112a7f73 100644 (file)
@@ -581,6 +581,7 @@ typedef enum {
 - (void)issueCutCommand;
 - (void)issueCopyCommand;
 - (void)issuePasteCommand;
+- (void)issuePasteAndMatchStyleCommand;
 - (void)respondToChangedSelection;
 - (void)respondToChangedContents;
 - (void)setIsSelected:(BOOL)isSelected forView:(NSView *)view;
index 04b22eb5cf826774a012d83012488ea3116ef927..d24ec43dbbe013a4f65bf538bc6ba4423dced9e6 100644 (file)
@@ -1,3 +1,10 @@
+2005-02-22  Chris Blumenberg  <cblu@apple.com>
+
+        Reviewed by mjs.
+
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge issuePasteAndMatchStyleCommand]): support for new "PasteAndMatchStyle" exec command
+
 === Safari-188 ===
 
 2005-02-21  David Harrison  <harrison@apple.com>
index 0e3b23ea2cecb70fe898660d87d18e04d75eb164..8ca6c9c77375f08936a1ee2d7b3dadaf936f97e1 100644 (file)
@@ -1347,6 +1347,11 @@ static id <WebFormDelegate> formDelegate(WebBridge *self)
     [[_frame webView] paste:nil];
 }
 
+- (void)issuePasteAndMatchStyleCommand
+{
+    [[_frame webView] pasteAsPlainText:nil];
+}
+
 - (BOOL)canPaste
 {
     return [[_frame webView] _canPaste];