Commit 5b42a264 authored by enrica@apple.com's avatar enrica@apple.com

REGRESSION: Dragging plain text into a styled text region does not acquire the correct style info.

<rdar://problem/7595685>
https://bugs.webkit.org/show_bug.cgi?id=34609

Reviewed by Oliver Hunt.

WebCore: 

Test: editing/pasteboard/drop-inputtext-acquires-style.html

The dragging code did not distinguish the case of dragging the content of an input control
as a special case. The markup placed in the pasteboard included the style information.
I've modified the Clipboard class interface adding a new method writePlainText to match the
behavior of the copy and cut commands and modified the drag code to detect the special case.
I've modified all the platform specific implementations of the Clipboard class.
        
* dom/Clipboard.h: Added writePlainText pure virtual function.
* editing/Editor.cpp:
(WebCore::Editor::cut): Renamed nodeIsTextFormControl to isNodeInTextFormControl.
(WebCore::Editor::copy): Renamed nodeIsTextFormControl to isNodeInTextFormControl.
* editing/htmlediting.cpp:
(WebCore::isNodeInTextFormControl): Added, after removing the implementation with the old name
in Editor.cpp
* editing/htmlediting.h:
* page/DragController.cpp:
(WebCore::DragController::startDrag):
* platform/Pasteboard.h:
* platform/android/ClipboardAndroid.cpp:
(WebCore::ClipboardAndroid::writePlainText): Added.
* platform/android/ClipboardAndroid.h:
* platform/chromium/ClipboardChromium.cpp:
(WebCore::ClipboardChromium::writePlainText): Added.
* platform/chromium/ClipboardChromium.h:
* platform/gtk/ClipboardGtk.cpp:
(WebCore::ClipboardGtk::writePlainText): Added.
* platform/gtk/ClipboardGtk.h:
* platform/haiku/ClipboardHaiku.cpp:
(WebCore::ClipboardHaiku::writePlainText): Added.
* platform/haiku/ClipboardHaiku.h:
* platform/mac/ClipboardMac.h:
* platform/mac/ClipboardMac.mm:
(WebCore::ClipboardMac::writePlainText): Added.
* platform/mac/PasteboardMac.mm:
(WebCore::Pasteboard::writePlainText): Added helper function.
* platform/qt/ClipboardQt.cpp:
(WebCore::ClipboardQt::writePlainText): Added.
* platform/qt/ClipboardQt.h:
* platform/win/ClipboardWin.cpp:
(WebCore::ClipboardWin::writePlainText): Added.
* platform/win/ClipboardWin.h:

LayoutTests: 

* editing/pasteboard/drop-inputtext-acquires-style-expected.txt: Added.
* editing/pasteboard/drop-inputtext-acquires-style.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54368 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 786a5248
2010-02-04 Enrica Casucci <enrica@apple.com>
Reviewed by Oliver Hunt.
REGRESSION: Dragging plain text into a styled text region does not acquire the correct style info.
<rdar://problem/7595685>
https://bugs.webkit.org/show_bug.cgi?id=34609
* editing/pasteboard/drop-inputtext-acquires-style-expected.txt: Added.
* editing/pasteboard/drop-inputtext-acquires-style.html: Added.
2010-02-04 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
Reviewed by Xan Lopez.
......
This test checks that the plain text dropped into a styled text region will acquire the appropriate style.
To run this test manually, drag the text in the input element below into the bold text region. The dropped text should be bold. Click the verify button to check.
Drag the text from the above iDrag this textnput element into this bold text
<b contenteditable="true" id="destination">Drag the text from the above iDrag this textnput element into this bold text</b>
SUCCESS
<html>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
<div>This test checks that the plain text dropped into a styled text region will acquire the appropriate style.</div>
<p>To run this test manually, drag the text in the input element below into the bold text region. The dropped text should be bold.
Click the verify button to check.</p>
<input type="button" value="Verify" onClick="verifier()">
<br />
<input id="grabme" value="Drag this text" >
<br />
<b contenteditable="true" id="destination">Drag the text from the above input element into this bold text</b>
<ul id="console"></ul>
<script>
function log(message) {
var console = document.getElementById("console");
var li = document.createElement("li");
var pre = document.createElement("pre");
pre.appendChild(document.createTextNode(message));
li.appendChild(pre);
console.appendChild(li);
}
function runTest() {
var textToDrag = document.getElementById("grabme");
textToDrag.focus();
if (!window.layoutTestController)
return;
var x = textToDrag.offsetLeft + textToDrag.offsetWidth / 2;
var y = textToDrag.offsetTop + textToDrag.offsetHeight / 2;
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
// Wait a moment so that the mouseDown will kick off a drag
eventSender.leapForward(400);
var destinationObject = document.getElementById("destination");
var x = destinationObject.offsetLeft + destinationObject.offsetWidth / 2;
var y = destinationObject.offsetTop + destinationObject.offsetHeight / 2;
eventSender.mouseMoveTo(x, y);
eventSender.mouseUp();
verifier();
}
function verifier() {
log(document.getElementById("destination").outerHTML);
if (document.getElementById("destination").childNodes.length == 1)
log("SUCCESS");
else
log("FAILURE");
}
runTest();
</script>
</html>
2010-02-04 Enrica Casucci <enrica@apple.com>
Reviewed by Oliver Hunt.
REGRESSION: Dragging plain text into a styled text region does not acquire the correct style info.
<rdar://problem/7595685>
https://bugs.webkit.org/show_bug.cgi?id=34609
Test: editing/pasteboard/drop-inputtext-acquires-style.html
The dragging code did not distinguish the case of dragging the content of an input control
as a special case. The markup placed in the pasteboard included the style information.
I've modified the Clipboard class interface adding a new method writePlainText to match the
behavior of the copy and cut commands and modified the drag code to detect the special case.
I've modified all the platform specific implementations of the Clipboard class.
* dom/Clipboard.h: Added writePlainText pure virtual function.
* editing/Editor.cpp:
(WebCore::Editor::cut): Renamed nodeIsTextFormControl to isNodeInTextFormControl.
(WebCore::Editor::copy): Renamed nodeIsTextFormControl to isNodeInTextFormControl.
* editing/htmlediting.cpp:
(WebCore::isNodeInTextFormControl): Added, after removing the implementation with the old name
in Editor.cpp
* editing/htmlediting.h:
* page/DragController.cpp:
(WebCore::DragController::startDrag):
* platform/Pasteboard.h:
* platform/android/ClipboardAndroid.cpp:
(WebCore::ClipboardAndroid::writePlainText): Added.
* platform/android/ClipboardAndroid.h:
* platform/chromium/ClipboardChromium.cpp:
(WebCore::ClipboardChromium::writePlainText): Added.
* platform/chromium/ClipboardChromium.h:
* platform/gtk/ClipboardGtk.cpp:
(WebCore::ClipboardGtk::writePlainText): Added.
* platform/gtk/ClipboardGtk.h:
* platform/haiku/ClipboardHaiku.cpp:
(WebCore::ClipboardHaiku::writePlainText): Added.
* platform/haiku/ClipboardHaiku.h:
* platform/mac/ClipboardMac.h:
* platform/mac/ClipboardMac.mm:
(WebCore::ClipboardMac::writePlainText): Added.
* platform/mac/PasteboardMac.mm:
(WebCore::Pasteboard::writePlainText): Added helper function.
* platform/qt/ClipboardQt.cpp:
(WebCore::ClipboardQt::writePlainText): Added.
* platform/qt/ClipboardQt.h:
* platform/win/ClipboardWin.cpp:
(WebCore::ClipboardWin::writePlainText): Added.
* platform/win/ClipboardWin.h:
2010-02-04 Steve Block <steveblock@google.com>
Reviewed by Nate Chapin.
......
......@@ -69,6 +69,7 @@ namespace WebCore {
#endif
virtual void writeURL(const KURL&, const String&, Frame*) = 0;
virtual void writeRange(Range*, Frame*) = 0;
virtual void writePlainText(const String&) = 0;
virtual bool hasData() = 0;
......
......@@ -1004,16 +1004,6 @@ bool Editor::insertParagraphSeparator()
return true;
}
static bool nodeIsInTextFormControl(Node* node)
{
if (!node)
return false;
Node* ancestor = node->shadowAncestorNode();
if (ancestor == node)
return false;
return ancestor->isElementNode() && static_cast<Element*>(ancestor)->isTextFormControl();
}
void Editor::cut()
{
if (tryDHTMLCut())
......@@ -1024,7 +1014,7 @@ void Editor::cut()
}
RefPtr<Range> selection = selectedRange();
if (shouldDeleteRange(selection.get())) {
if (nodeIsInTextFormControl(m_frame->selection()->start().node()))
if (isNodeInTextFormControl(m_frame->selection()->start().node()))
Pasteboard::generalPasteboard()->writePlainText(m_frame->selectedText());
else
Pasteboard::generalPasteboard()->writeSelection(selection.get(), canSmartCopyOrDelete(), m_frame);
......@@ -1042,7 +1032,7 @@ void Editor::copy()
return;
}
if (nodeIsInTextFormControl(m_frame->selection()->start().node()))
if (isNodeInTextFormControl(m_frame->selection()->start().node()))
Pasteboard::generalPasteboard()->writePlainText(m_frame->selectedText());
else {
Document* document = m_frame->document();
......
......@@ -911,6 +911,16 @@ Node *tabSpanNode(const Node *node)
return isTabSpanTextNode(node) ? node->parentNode() : 0;
}
bool isNodeInTextFormControl(Node* node)
{
if (!node)
return false;
Node* ancestor = node->shadowAncestorNode();
if (ancestor == node)
return false;
return ancestor->isElementNode() && static_cast<Element*>(ancestor)->isTextFormControl();
}
Position positionBeforeTabSpan(const Position& pos)
{
Node *node = pos.node();
......
......@@ -93,7 +93,7 @@ bool isListElement(Node*);
bool isNodeRendered(const Node*);
bool isNodeVisiblyContainedWithin(Node*, const Range*);
bool isRenderedAsNonInlineTableImageOrHR(const Node*);
bool isNodeInTextFormControl(Node* node);
// -------------------------------------------------------------------------
// Position
......
......@@ -697,10 +697,16 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
}
doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
} else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
RefPtr<Range> selectionRange = src->selection()->toNormalizedRange();
ASSERT(selectionRange);
if (!clipboard->hasData())
clipboard->writeRange(selectionRange.get(), src);
if (!clipboard->hasData()) {
if (isNodeInTextFormControl(src->selection()->start().node()))
clipboard->writePlainText(src->selectedText());
else {
RefPtr<Range> selectionRange = src->selection()->toNormalizedRange();
ASSERT(selectionRange);
clipboard->writeRange(selectionRange.get(), src);
}
}
m_client->willPerformDragSourceAction(DragSourceActionSelection, dragOrigin, clipboard);
if (!dragImage) {
dragImage = createDragImageForSelection(src);
......
......@@ -82,6 +82,7 @@ public:
//Helper functions to allow Clipboard to share code
static void writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame);
static void writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& url, const String& titleStr, Frame* frame);
static void writePlainText(NSPasteboard* pasteboard, const String& text);
#endif
static Pasteboard* generalPasteboard();
......
......@@ -103,6 +103,10 @@ void ClipboardAndroid::writeRange(Range* selectedRange, Frame*)
ASSERT(selectedRange);
}
void ClipboardAndroid::writePlainText(const String&)
{
}
bool ClipboardAndroid::hasData()
{
return false;
......
......@@ -56,6 +56,7 @@ public:
virtual void declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*);
virtual void writeURL(const KURL&, const String&, Frame*);
virtual void writeRange(Range*, Frame*);
virtual void writePlainText(const String&);
virtual bool hasData();
};
......
......@@ -376,6 +376,19 @@ void ClipboardChromium::writeRange(Range* selectedRange, Frame* frame)
m_dataObject->plainText = str;
}
void ClipboardChromium::writePlainText(const String& text)
{
if (!m_dataObject)
return;
String str = text;
#if OS(WINDOWS)
replaceNewlinesWithWindowsStyleNewlines(str);
#endif
replaceNBSPWithSpace(str);
m_dataObject->plainText = str;
}
bool ClipboardChromium::hasData()
{
if (!m_dataObject)
......
......@@ -74,6 +74,7 @@ namespace WebCore {
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
virtual void writeURL(const KURL&, const String&, Frame*);
virtual void writeRange(Range*, Frame*);
virtual void writePlainText(const String&);
virtual bool hasData();
......
......@@ -176,6 +176,15 @@ void ClipboardGtk::writeRange(Range* range, Frame* frame)
gtk_clipboard_set_text(htmlClipboard, createMarkup(range, 0, AnnotateForInterchange).utf8().data(), -1);
}
void ClipboardGtk::writePlainText(const String& text)
{
GtkClipboard* textClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardText"));
gtk_clipboard_clear(textClipboard);
gtk_clipboard_set_text(textClipboard, text.utf8().data(), -1);
}
bool ClipboardGtk::hasData()
{
notImplemented();
......
......@@ -60,6 +60,7 @@ namespace WebCore {
virtual void declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*);
virtual void writeURL(const KURL&, const String&, Frame*);
virtual void writeRange(Range*, Frame*);
virtual void writePlainText(const String&);
virtual bool hasData();
......
......@@ -187,6 +187,11 @@ void ClipboardHaiku::writeRange(Range*, Frame*)
notImplemented();
}
void ClipboardHaiku::writePlainText(const String&)
{
notImplemented();
}
bool ClipboardHaiku::hasData()
{
bool result = false;
......
......@@ -61,6 +61,7 @@ namespace WebCore {
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
virtual void writeURL(const KURL&, const String&, Frame*);
virtual void writeRange(Range*, Frame*);
virtual void writePlainText(const String&);
virtual bool hasData();
......
......@@ -72,6 +72,7 @@ public:
#endif
virtual void writeRange(Range*, Frame* frame);
virtual void writeURL(const KURL&, const String&, Frame* frame);
virtual void writePlainText(const String&);
// Methods for getting info in Cocoa's type system
NSImage *dragNSImage(NSPoint&) const; // loc converted from dragLoc, based on whole image size
......
......@@ -367,7 +367,12 @@ void ClipboardMac::writeRange(Range* range, Frame* frame)
ASSERT(frame);
Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selectionGranularity() == WordGranularity, frame);
}
void ClipboardMac::writePlainText(const String& text)
{
Pasteboard::writePlainText(m_pasteboard.get(), text);
}
void ClipboardMac::writeURL(const KURL& url, const String& title, Frame* frame)
{
ASSERT(frame);
......
......@@ -197,6 +197,14 @@ void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange,
[pasteboard setData:nil forType:WebSmartPastePboardType];
}
}
void Pasteboard::writePlainText(NSPasteboard* pasteboard, const String& text)
{
NSArray *types = [NSArray arrayWithObject:NSStringPboardType];
[pasteboard declareTypes:types owner:nil];
[pasteboard setString:text forType:NSStringPboardType];
}
void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
......
......@@ -290,6 +290,17 @@ void ClipboardQt::writeRange(Range* range, Frame* frame)
#endif
}
void ClipboardQt::writePlainText(const String& str)
{
QString text = str;
text.replace(QChar(0xa0), QLatin1Char(' '));
m_writableData->setText(text);
#ifndef QT_NO_CLIPBOARD
if (!isForDragging())
QApplication::clipboard()->setMimeData(m_writableData);
#endif
}
bool ClipboardQt::hasData()
{
const QMimeData *data = m_readableData ? m_readableData : m_writableData;
......
......@@ -66,6 +66,7 @@ namespace WebCore {
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
virtual void writeURL(const KURL&, const String&, Frame*);
virtual void writeRange(Range*, Frame*);
virtual void writePlainText(const String&);
virtual bool hasData();
......
......@@ -776,6 +776,25 @@ void ClipboardWin::writeRange(Range* selectedRange, Frame* frame)
m_writableDataObject->SetData(smartPasteFormat(), &medium, TRUE);
}
void ClipboardWin::writePlainText(const String& text)
{
if (!m_writableDataObject)
return;
STGMEDIUM medium = {0};
medium.tymed = TYMED_HGLOBAL;
ExceptionCode ec = 0;
String str = text;
replaceNewlinesWithWindowsStyleNewlines(str);
replaceNBSPWithSpace(str);
medium.hGlobal = createGlobalData(str);
if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE)))
::GlobalFree(medium.hGlobal);
medium.hGlobal = 0;
}
bool ClipboardWin::hasData()
{
if (!m_dataObject)
......
......@@ -67,6 +67,7 @@ namespace WebCore {
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
virtual void writeURL(const KURL&, const String&, Frame*);
virtual void writeRange(Range*, Frame*);
virtual void writePlainText(const String&);
virtual bool hasData();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment