Mouse-select then Cut, results in preceding character being lost
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Aug 2012 04:45:23 +0000 (04:45 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Aug 2012 04:45:23 +0000 (04:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=60830

Patch by Sukolsak Sakshuwong <sukolsak@google.com> on 2012-08-09
Reviewed by Ryosuke Niwa.

Source/WebCore:

This bug happened only in text fields and text areas, not in other
content-editable elements. That's because when we cut or copied text
in a text control, we called Pasteboard::writePlainText instead of
Pasteboard::writeSelection. writePlainText did not record the smart replace
information. Make writePlainText record the smart replace information.

Test: editing/pasteboard/smart-paste-in-text-control.html

* editing/Editor.cpp:
(WebCore::Editor::cut):
(WebCore::Editor::copy):
* inspector/InjectedScriptHost.cpp:
(WebCore::InjectedScriptHost::copyText):
* inspector/InspectorFrontendHost.cpp:
(WebCore::InspectorFrontendHost::copyText):
* platform/Pasteboard.h:
* platform/blackberry/PasteboardBlackBerry.cpp:
(WebCore::Pasteboard::writePlainText):
* platform/chromium/PasteboardChromium.cpp:
(WebCore::Pasteboard::writePlainText):
* platform/efl/PasteboardEfl.cpp:
(WebCore::Pasteboard::writePlainText):
* platform/gtk/PasteboardGtk.cpp:
(WebCore::Pasteboard::writePlainText):
* platform/mac/ClipboardMac.mm:
(WebCore::ClipboardMac::writePlainText):
* platform/mac/PasteboardMac.mm:
(WebCore::Pasteboard::writePlainText):
* platform/qt/PasteboardQt.cpp:
(WebCore::Pasteboard::writePlainText):
* platform/win/PasteboardWin.cpp:
(WebCore::Pasteboard::writePlainText):
* platform/wince/PasteboardWinCE.cpp:
(WebCore::Pasteboard::writePlainText):
* platform/wx/ClipboardWx.cpp:
(WebCore::ClipboardWx::writePlainText):
* platform/wx/PasteboardWx.cpp:
(WebCore::Pasteboard::writePlainText):

LayoutTests:

* editing/pasteboard/smart-paste-in-text-control-expected.txt: Added.
* editing/pasteboard/smart-paste-in-text-control.html: Added.
* platform/chromium/TestExpectations:

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

20 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/smart-paste-in-text-control-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/smart-paste-in-text-control.html [new file with mode: 0644]
LayoutTests/platform/chromium/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/editing/Editor.cpp
Source/WebCore/inspector/InjectedScriptHost.cpp
Source/WebCore/inspector/InspectorFrontendHost.cpp
Source/WebCore/platform/Pasteboard.h
Source/WebCore/platform/blackberry/PasteboardBlackBerry.cpp
Source/WebCore/platform/chromium/PasteboardChromium.cpp
Source/WebCore/platform/efl/PasteboardEfl.cpp
Source/WebCore/platform/gtk/PasteboardGtk.cpp
Source/WebCore/platform/mac/ClipboardMac.mm
Source/WebCore/platform/mac/PasteboardMac.mm
Source/WebCore/platform/qt/PasteboardQt.cpp
Source/WebCore/platform/win/PasteboardWin.cpp
Source/WebCore/platform/wince/PasteboardWinCE.cpp
Source/WebCore/platform/wx/ClipboardWx.cpp
Source/WebCore/platform/wx/PasteboardWx.cpp

index 1edf168..58d1e26 100644 (file)
@@ -1,3 +1,14 @@
+2012-08-09  Sukolsak Sakshuwong  <sukolsak@google.com>
+
+        Mouse-select then Cut, results in preceding character being lost
+        https://bugs.webkit.org/show_bug.cgi?id=60830
+
+        Reviewed by Ryosuke Niwa.
+
+        * editing/pasteboard/smart-paste-in-text-control-expected.txt: Added.
+        * editing/pasteboard/smart-paste-in-text-control.html: Added.
+        * platform/chromium/TestExpectations:
+
 2012-08-09  Joone Hur  <joone.hur@intel.com>
 
         [EFL] Unreviewed gardening
diff --git a/LayoutTests/editing/pasteboard/smart-paste-in-text-control-expected.txt b/LayoutTests/editing/pasteboard/smart-paste-in-text-control-expected.txt
new file mode 100644 (file)
index 0000000..0d599b9
--- /dev/null
@@ -0,0 +1,3 @@
+This tests smart pasting in a text control. To manually test, double click the middle word in the text area below. Then cut and paste. It should result in the original text. The space before the middle word should not be lost.
+
+PASS: Smart cutting and pasting result in the original text.
diff --git a/LayoutTests/editing/pasteboard/smart-paste-in-text-control.html b/LayoutTests/editing/pasteboard/smart-paste-in-text-control.html
new file mode 100644 (file)
index 0000000..308376a
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html> 
+<head>
+<style>
+#textarea {
+    font-family: Ahem;
+    font-size: 16px;
+    color: rgba(0, 0, 0, 0.2);
+    -webkit-font-smoothing: none;
+}
+</style>
+</head>
+<body>
+This tests smart pasting in a text control.
+To manually test, double click the middle word in the text area below. Then cut and paste.
+It should result in the original text. The space before the middle word should not be lost.
+<div>
+<textarea id="textarea">Hello world test</textarea>
+</div>
+
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+if (window.eventSender) {
+    function doubleClick(x, y) {
+        eventSender.mouseMoveTo(x, y);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+        
+    var target = document.getElementById("textarea");
+    var x = target.offsetLeft + 120;
+    var y = target.offsetTop + 10;
+    doubleClick(x, y);
+
+    document.execCommand("Cut");
+    document.execCommand("Paste");
+
+    if (target.value == "Hello world test")
+        document.write("PASS: Smart cutting and pasting result in the original text.");
+    else
+        document.write("FAIL: Smart cutting and pasting do not result in the original text.");
+} else {
+    document.write("This test can't run automatically in web browser without eventSender.");
+}
+</script>
+</body>
+</html>
index 6fdf59a..84bfa0a 100644 (file)
@@ -152,6 +152,9 @@ BUGWK85262 SKIP : fast/css/image-resolution = PASS
 // CSS image-orientation is not yet enabled.
 BUGWK89052 SKIP : fast/css/image-orientation = PASS
 
+// Chromium does not support smart pasting in text controls yet.
+BUGWK60830 SKIP : editing/pasteboard/smart-paste-in-text-control.html = PASS
+
 // Chromium needs larger media files to test buffering this way.
 BUGWK88172 SKIP : http/tests/media/video-buffered.html = PASS
 
index b1b2a4c..84a29fb 100644 (file)
@@ -1,3 +1,49 @@
+2012-08-09  Sukolsak Sakshuwong  <sukolsak@google.com>
+
+        Mouse-select then Cut, results in preceding character being lost
+        https://bugs.webkit.org/show_bug.cgi?id=60830
+
+        Reviewed by Ryosuke Niwa.
+
+        This bug happened only in text fields and text areas, not in other
+        content-editable elements. That's because when we cut or copied text
+        in a text control, we called Pasteboard::writePlainText instead of
+        Pasteboard::writeSelection. writePlainText did not record the smart replace
+        information. Make writePlainText record the smart replace information.
+
+        Test: editing/pasteboard/smart-paste-in-text-control.html
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::cut):
+        (WebCore::Editor::copy):
+        * inspector/InjectedScriptHost.cpp:
+        (WebCore::InjectedScriptHost::copyText):
+        * inspector/InspectorFrontendHost.cpp:
+        (WebCore::InspectorFrontendHost::copyText):
+        * platform/Pasteboard.h:
+        * platform/blackberry/PasteboardBlackBerry.cpp:
+        (WebCore::Pasteboard::writePlainText):
+        * platform/chromium/PasteboardChromium.cpp:
+        (WebCore::Pasteboard::writePlainText):
+        * platform/efl/PasteboardEfl.cpp:
+        (WebCore::Pasteboard::writePlainText):
+        * platform/gtk/PasteboardGtk.cpp:
+        (WebCore::Pasteboard::writePlainText):
+        * platform/mac/ClipboardMac.mm:
+        (WebCore::ClipboardMac::writePlainText):
+        * platform/mac/PasteboardMac.mm:
+        (WebCore::Pasteboard::writePlainText):
+        * platform/qt/PasteboardQt.cpp:
+        (WebCore::Pasteboard::writePlainText):
+        * platform/win/PasteboardWin.cpp:
+        (WebCore::Pasteboard::writePlainText):
+        * platform/wince/PasteboardWinCE.cpp:
+        (WebCore::Pasteboard::writePlainText):
+        * platform/wx/ClipboardWx.cpp:
+        (WebCore::ClipboardWx::writePlainText):
+        * platform/wx/PasteboardWx.cpp:
+        (WebCore::Pasteboard::writePlainText):
+
 2012-08-09  Kentaro Hara  <haraken@chromium.org>
 
         Unreviewed. Updated run-binding-tests results.
index 9f33299..20b6af9 100644 (file)
@@ -985,9 +985,10 @@ void Editor::cut()
     RefPtr<Range> selection = selectedRange();
     if (shouldDeleteRange(selection.get())) {
         updateMarkersForWordsAffectedByEditing(true);
-        if (enclosingTextFormControl(m_frame->selection()->start()))
-            Pasteboard::generalPasteboard()->writePlainText(selectedText());
-        else
+        if (enclosingTextFormControl(m_frame->selection()->start())) {
+            Pasteboard::generalPasteboard()->writePlainText(selectedText(),
+                canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
+        } else
             Pasteboard::generalPasteboard()->writeSelection(selection.get(), canSmartCopyOrDelete(), m_frame);
         didWriteSelectionToPasteboard();
         deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
@@ -1003,9 +1004,10 @@ void Editor::copy()
         return;
     }
 
-    if (enclosingTextFormControl(m_frame->selection()->start()))
-        Pasteboard::generalPasteboard()->writePlainText(selectedText());
-    else {
+    if (enclosingTextFormControl(m_frame->selection()->start())) {
+        Pasteboard::generalPasteboard()->writePlainText(selectedText(),
+            canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
+    } else {
         Document* document = m_frame->document();
         if (HTMLImageElement* imageElement = imageElementFromImageDocument(document))
             Pasteboard::generalPasteboard()->writeImage(imageElement, document->url(), document->title());
index e49f993..2e634d4 100644 (file)
@@ -120,7 +120,7 @@ void InjectedScriptHost::clearConsoleMessages()
 
 void InjectedScriptHost::copyText(const String& text)
 {
-    Pasteboard::generalPasteboard()->writePlainText(text);
+    Pasteboard::generalPasteboard()->writePlainText(text, Pasteboard::CannotSmartReplace);
 }
 
 ScriptValue InjectedScriptHost::InspectableObject::get(ScriptState*)
index c9f9ac9..e7b0220 100644 (file)
@@ -222,7 +222,7 @@ String InspectorFrontendHost::hiddenPanels()
 
 void InspectorFrontendHost::copyText(const String& text)
 {
-    Pasteboard::generalPasteboard()->writePlainText(text);
+    Pasteboard::generalPasteboard()->writePlainText(text, Pasteboard::CannotSmartReplace);
 }
 
 void InspectorFrontendHost::openInNewTab(const String& url)
index cc0809c..bfdb01c 100644 (file)
@@ -76,6 +76,11 @@ class SharedBuffer;
 class Pasteboard {
     WTF_MAKE_NONCOPYABLE(Pasteboard); WTF_MAKE_FAST_ALLOCATED;
 public:
+    enum SmartReplaceOption {
+        CanSmartReplace,
+        CannotSmartReplace
+    };
+
 #if PLATFORM(MAC)
     // This is required to support OS X services.
     void writeSelectionForTypes(const Vector<String>& pasteboardTypes, bool canSmartCopyOrDelete, Frame*);
@@ -86,7 +91,7 @@ public:
     
     static Pasteboard* generalPasteboard();
     void writeSelection(Range*, bool canSmartCopyOrDelete, Frame*);
-    void writePlainText(const String&);
+    void writePlainText(const String&, SmartReplaceOption);
     void writeURL(const KURL&, const String&, Frame* = 0);
     void writeImage(Node*, const KURL&, const String& title);
     void writeClipboard(Clipboard*);
index 9159c12..24d2007 100644 (file)
@@ -76,7 +76,7 @@ void Pasteboard::writeURL(KURL const& url, String const&, Frame*)
     BlackBerry::Platform::Clipboard::writeURL(url.string().utf8().data());
 }
 
-void Pasteboard::writePlainText(const String& text)
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption)
 {
     BlackBerry::Platform::Clipboard::writePlainText(text.utf8().data());
 }
index da8f16e..94cc4f1 100644 (file)
@@ -98,8 +98,9 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
     WebKit::Platform::current()->clipboard()->writeHTML(html, url, plainText, canSmartCopyOrDelete);
 }
 
-void Pasteboard::writePlainText(const String& text)
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption)
 {
+    // FIXME: add support for smart replace
 #if OS(WINDOWS)
     String plainText(text);
     replaceNewlinesWithWindowsStyleNewlines(plainText);
index 08004a5..95b2a34 100644 (file)
@@ -46,7 +46,7 @@ Pasteboard::Pasteboard()
     notImplemented();
 }
 
-void Pasteboard::writePlainText(const String&)
+void Pasteboard::writePlainText(const String&, SmartReplaceOption)
 {
     notImplemented();
 }
index bd6e029..fe5a1f1 100644 (file)
@@ -68,14 +68,15 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
     helper->writeClipboardContents(clipboard, canSmartCopyOrDelete ? PasteboardHelper::IncludeSmartPaste : PasteboardHelper::DoNotIncludeSmartPaste);
 }
 
-void Pasteboard::writePlainText(const String& text)
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
 {
     GtkClipboard* clipboard = gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD);
     DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
     dataObject->clearAll();
 
     dataObject->setText(text);
-    PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(clipboard);
+    PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(clipboard,
+        (smartReplaceOption == CanSmartReplace) ? PasteboardHelper::IncludeSmartPaste : PasteboardHelper::DoNotIncludeSmartPaste);
 }
 
 void Pasteboard::writeURL(const KURL& url, const String& label, Frame* frame)
index dfe58f2..1af14df 100644 (file)
@@ -384,7 +384,7 @@ void ClipboardMac::writeRange(Range* range, Frame* frame)
 void ClipboardMac::writePlainText(const String& text)
 {
     Pasteboard pasteboard(m_pasteboardName);
-    pasteboard.writePlainText(text);
+    pasteboard.writePlainText(text, Pasteboard::CannotSmartReplace);
 }
 
 void ClipboardMac::writeURL(const KURL& url, const String& title, Frame* frame)
index 604aa7f..750130f 100644 (file)
@@ -204,12 +204,17 @@ void Pasteboard::writeSelectionForTypes(const Vector<String>& pasteboardTypes, b
         platformStrategies()->pasteboardStrategy()->setBufferForType(0, WebSmartPastePboardType, m_pasteboardName);
 }
 
-void Pasteboard::writePlainText(const String& text)
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
 {
     Vector<String> types;
     types.append(NSStringPboardType);
+    if (smartReplaceOption == CanSmartReplace)
+        types.append(WebSmartPastePboardType);
+
     platformStrategies()->pasteboardStrategy()->setTypes(types, m_pasteboardName);
     platformStrategies()->pasteboardStrategy()->setStringForType(text, NSStringPboardType, m_pasteboardName);
+    if (smartReplaceOption == CanSmartReplace)
+        platformStrategies()->pasteboardStrategy()->setBufferForType(0, WebSmartPastePboardType, m_pasteboardName);
 }
     
 void Pasteboard::writeSelection(Range*, bool canSmartCopyOrDelete, Frame* frame)
index c6e3d01..66b0e40 100644 (file)
@@ -127,7 +127,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
     return 0;
 }
 
-void Pasteboard::writePlainText(const String& text)
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
 {
 #ifndef QT_NO_CLIPBOARD
     QMimeData* md = new QMimeData;
@@ -135,6 +135,8 @@ void Pasteboard::writePlainText(const String& text)
     qtext.replace(QChar(0xa0), QLatin1Char(' '));
     md->setText(qtext);
     QGuiApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard);
+    if (smartReplaceOption == CanSmartReplace)
+        md->setData(QLatin1String("application/vnd.qtwebkit.smartpaste"), QByteArray());
 #endif
 }
 
index 065e3a8..f9fe00d 100644 (file)
@@ -149,7 +149,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
     }
 }
 
-void Pasteboard::writePlainText(const String& text)
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
 {
     clear();
 
@@ -162,6 +162,14 @@ void Pasteboard::writePlainText(const String& text)
             ::GlobalFree(cbData);
         ::CloseClipboard();
     }
+
+    // enable smart-replacing later on by putting dummy data on the pasteboard
+    if (smartReplaceOption == CanSmartReplace) {
+        if (::OpenClipboard(m_owner)) {
+            ::SetClipboardData(WebSmartPasteFormat, 0);
+            ::CloseClipboard();
+        }
+    }
 }
 
 void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
index 13bbe48..cc8d18e 100644 (file)
@@ -144,7 +144,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
     }
 }
 
-void Pasteboard::writePlainText(const String& text)
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
 {
     clear();
 
@@ -157,6 +157,14 @@ void Pasteboard::writePlainText(const String& text)
             ::GlobalFree(cbData);
         ::CloseClipboard();
     }
+
+    // enable smart-replacing later on by putting dummy data on the pasteboard
+    if (smartReplaceOption == CanSmartReplace) {
+        if (::OpenClipboard(m_owner)) {
+            ::SetClipboardData(WebSmartPasteFormat, 0);
+            ::CloseClipboard();
+        }
+    }
 }
 
 void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
index 24220b9..9906621 100644 (file)
@@ -142,7 +142,7 @@ bool ClipboardWx::hasData()
 
 void ClipboardWx::writePlainText(const WTF::String& text)
 {
-    Pasteboard::generalPasteboard()->writePlainText(text);
+    Pasteboard::generalPasteboard()->writePlainText(text, Pasteboard::CannotSmartReplace);
 }
 
 }
index 48183fa..c45d1fc 100644 (file)
@@ -61,7 +61,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
     }
 }
 
-void Pasteboard::writePlainText(const String& text)
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption)
 {
     if (wxTheClipboard->Open()) {
         wxTheClipboard->SetData( new wxTextDataObject(text) );