Skip to content
This repository has been archived by the owner on Jun 24, 2022. It is now read-only.

Commit

Permalink
Consolidate the code to normalize MIME type in DataTransfer
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=175810

Reviewed by Wenson Hsieh.

Source/WebCore:

Factored out the code to convert MIME type to lowercase after stripping whitespace,
and treat "text" as "text/plain" and "url" as "text/uri-list".

Specifications:
https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-getdata-2
https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-setdata-2
https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-cleardata-2

Stripping of whitespace only happens in WebKit/Blink but it's probably required for compatbility.
Spec bug: whatwg/html#2946

Test: editing/pasteboard/datatransfer-getdata-plaintext.html

* dom/DataTransfer.cpp:
(WebCore::normalizeType):
(WebCore::DataTransfer::clearData):
(WebCore::DataTransfer::getData const):
(WebCore::DataTransfer::setData):
* platform/gtk/PasteboardGtk.cpp:
(WebCore::selectionDataTypeFromHTMLClipboardType):
* platform/ios/PasteboardIOS.mm:
(WebCore::cocoaTypeFromHTMLClipboardType):
* platform/mac/PasteboardMac.mm:
(WebCore::cocoaTypeFromHTMLClipboardType):
* platform/win/PasteboardWin.cpp:
(WebCore::clipboardTypeFromMIMEType):

LayoutTests:

Added a regression test. Some test cases were failing on some platforms.

* editing/pasteboard/datatransfer-getdata-plaintext-expected.txt: Added.
* editing/pasteboard/datatransfer-getdata-plaintext.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@221063 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
rniwa@webkit.org committed Aug 23, 2017
1 parent c75a0c9 commit 3a241fb
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 44 deletions.
12 changes: 12 additions & 0 deletions LayoutTests/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
2017-08-21 Ryosuke Niwa <rniwa@webkit.org>

Consolidate the code to normalize MIME type in DataTransfer
https://bugs.webkit.org/show_bug.cgi?id=175810

Reviewed by Wenson Hsieh.

Added a regression test. Some test cases were failing on some platforms.

* editing/pasteboard/datatransfer-getdata-plaintext-expected.txt: Added.
* editing/pasteboard/datatransfer-getdata-plaintext.html: Added.

2017-08-22 Matt Lewis <jlewis3@apple.com>

Unreviewed, rolling out r221033.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
This tests peeks plain text using dataTransfer.getDAta. To manually test, click on "Copy text".

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS clipboardData.setData(" text/PLAIN ", "hello"); clipboardData.getData("text/plain") is "hello"
PASS clipboardData.setData(" tEXT/pLaIN", "world"); clipboardData.getData("text/plain") is "world"
PASS clipboardData.setData("text/plain; charset=utf-8", "hello"); clipboardData.getData("text/plain; charset=Shift_JIS") is "hello"
PASS successfullyParsed is true

TEST COMPLETE

38 changes: 38 additions & 0 deletions LayoutTests/editing/pasteboard/datatransfer-getdata-plaintext.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<body>
<script src="../../resources/js-test-pre.js"></script>
<script>

description('This tests peeks plain text using dataTransfer.getDAta. To manually test, click on "Copy text".');

function copyText()
{
document.getElementById('source').focus();
document.execCommand('SelectAll', false, null);
document.execCommand('Copy', false, null);
}

function copy(event)
{
clipboardData = event.clipboardData;
shouldBeEqualToString('clipboardData.setData(" text/PLAIN ", "hello"); clipboardData.getData("text/plain")', 'hello');
shouldBeEqualToString('clipboardData.setData(" tEXT/pLaIN", "world"); clipboardData.getData("text/plain")', 'world');
shouldBeEqualToString('clipboardData.setData("text/plain; charset=utf-8", "hello"); clipboardData.getData("text/plain; charset=Shift_JIS")', 'hello');
document.getElementById('container').style.display = 'none';
finishJSTest();
}

if (window.testRunner)
window.onload = copyText;
jsTestIsAsync = true;
successfullyParsed = true;

</script>
<div id="container">
<button onclick="copyText();">Copy text</button>
<div id="source" oncopy="copy(event)" contenteditable="true">hello, world</div>
</div>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
34 changes: 34 additions & 0 deletions Source/WebCore/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
2017-08-21 Ryosuke Niwa <rniwa@webkit.org>

Consolidate the code to normalize MIME type in DataTransfer
https://bugs.webkit.org/show_bug.cgi?id=175810

Reviewed by Wenson Hsieh.

Factored out the code to convert MIME type to lowercase after stripping whitespace,
and treat "text" as "text/plain" and "url" as "text/uri-list".

Specifications:
https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-getdata-2
https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-setdata-2
https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-cleardata-2

Stripping of whitespace only happens in WebKit/Blink but it's probably required for compatbility.
Spec bug: https://github.com/whatwg/html/issues/2946

Test: editing/pasteboard/datatransfer-getdata-plaintext.html

* dom/DataTransfer.cpp:
(WebCore::normalizeType):
(WebCore::DataTransfer::clearData):
(WebCore::DataTransfer::getData const):
(WebCore::DataTransfer::setData):
* platform/gtk/PasteboardGtk.cpp:
(WebCore::selectionDataTypeFromHTMLClipboardType):
* platform/ios/PasteboardIOS.mm:
(WebCore::cocoaTypeFromHTMLClipboardType):
* platform/mac/PasteboardMac.mm:
(WebCore::cocoaTypeFromHTMLClipboardType):
* platform/win/PasteboardWin.cpp:
(WebCore::clipboardTypeFromMIMEType):

2017-08-22 Matt Lewis <jlewis3@apple.com>

Unreviewed, rolling out r221033.
Expand Down
24 changes: 21 additions & 3 deletions Source/WebCore/dom/DataTransfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,28 @@ bool DataTransfer::canWriteData() const
return m_storeMode == StoreMode::ReadWrite;
}

static String normalizeType(const String& type)
{
if (type.isNull())
return type;

String lowercaseType = type.stripWhiteSpace().convertToASCIILowercase();
if (lowercaseType == "text" || lowercaseType.startsWithIgnoringASCIICase("text/plain;"))
return "text/plain";
if (lowercaseType == "url" || lowercaseType.startsWithIgnoringASCIICase("text/uri-list;"))
return "text/uri-list";
if (lowercaseType.startsWithIgnoringASCIICase("text/html;"))
return "text/html";

return lowercaseType;
}

void DataTransfer::clearData(const String& type)
{
if (!canWriteData())
return;

String normalizedType = normalizeType(type);
if (type.isNull())
m_pasteboard->clear();
else
Expand All @@ -124,7 +141,7 @@ String DataTransfer::getData(const String& type) const
return String();
#endif

return m_pasteboard->readString(type);
return m_pasteboard->readString(normalizeType(type));
}

void DataTransfer::setData(const String& type, const String& data)
Expand All @@ -137,9 +154,10 @@ void DataTransfer::setData(const String& type, const String& data)
return;
#endif

m_pasteboard->writeString(type, data);
String normalizedType = normalizeType(type);
m_pasteboard->writeString(normalizedType, data);
if (m_itemList)
m_itemList->didSetStringData(type);
m_itemList->didSetStringData(normalizedType);
}

DataTransferItemList& DataTransfer::items()
Expand Down
16 changes: 4 additions & 12 deletions Source/WebCore/platform/gtk/PasteboardGtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,15 @@ const SelectionData& Pasteboard::selectionData() const
return m_selectionData.get();
}

static ClipboardDataType selectionDataTypeFromHTMLClipboardType(const String& rawType)
static ClipboardDataType selectionDataTypeFromHTMLClipboardType(const String& type)
{
String type(rawType.stripWhiteSpace());

// Two special cases for IE compatibility
if (type == "Text" || type == "text")
return ClipboardDataTypeText;
if (type == "URL")
return ClipboardDataTypeURL;

// From the Mac port: Ignore any trailing charset - JS strings are
// Unicode, which encapsulates the charset issue.
if (type == "text/plain" || type.startsWith("text/plain;"))
if (type == "text/plain")
return ClipboardDataTypeText;
if (type == "text/html" || type.startsWith("text/html;"))
if (type == "text/html")
return ClipboardDataTypeMarkup;
if (type == "Files" || type == "text/uri-list" || type.startsWith("text/uri-list;"))
if (type == "Files" || type == "text/uri-list")
return ClipboardDataTypeURIList;

// Not a known type, so just default to using the text portion.
Expand Down
15 changes: 4 additions & 11 deletions Source/WebCore/platform/ios/PasteboardIOS.mm
Original file line number Diff line number Diff line change
Expand Up @@ -324,27 +324,20 @@ static String utiTypeFromCocoaType(NSString *type)

static RetainPtr<NSString> cocoaTypeFromHTMLClipboardType(const String& type)
{
String strippedType = type.stripWhiteSpace();

if (strippedType == "Text")
return (NSString *)kUTTypeText;
if (strippedType == "URL")
return (NSString *)kUTTypeURL;

// Ignore any trailing charset - JS strings are Unicode, which encapsulates the charset issue.
if (strippedType.startsWith("text/plain"))
if (type == "text/plain")
return (NSString *)kUTTypeText;

// Special case because UTI doesn't work with Cocoa's URL type.
if (strippedType == "text/uri-list")
if (type == "text/uri-list")
return (NSString *)kUTTypeURL;

// Try UTI now.
if (NSString *utiType = utiTypeFromCocoaType(strippedType))
if (NSString *utiType = utiTypeFromCocoaType(type))
return utiType;

// No mapping, just pass the whole string though.
return (NSString *)strippedType;
return (NSString *)type;
}

void Pasteboard::clear(const String& type)
Expand Down
18 changes: 5 additions & 13 deletions Source/WebCore/platform/mac/PasteboardMac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -463,34 +463,26 @@ static void writeFileWrapperAsRTFDAttachment(NSFileWrapper *wrapper, const Strin

static String cocoaTypeFromHTMLClipboardType(const String& type)
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dom-datatransfer-setdata
String lowercasedType = type.convertToASCIILowercase();

if (lowercasedType == "text")
lowercasedType = ASCIILiteral("text/plain");
if (lowercasedType == "url")
lowercasedType = ASCIILiteral("text/uri-list");

// Ignore any trailing charset - strings are already UTF-16, and the charset issue has already been dealt with.
if (lowercasedType == "text/plain" || lowercasedType.startsWith("text/plain;"))
if (type == "text/plain")
return NSStringPboardType;
if (lowercasedType == "text/uri-list") {
if (type == "text/uri-list") {
// Special case because UTI doesn't work with Cocoa's URL type.
return NSURLPboardType;
}

// Blacklist types that might contain subframe information.
if (lowercasedType == "text/rtf" || lowercasedType == "public.rtf" || lowercasedType == "com.apple.traditional-mac-plain-text")
if (type == "text/rtf" || type == "public.rtf" || type == "com.apple.traditional-mac-plain-text")
return String();

auto utiType = UTIFromMIMEType(lowercasedType);
auto utiType = UTIFromMIMEType(type);
if (!utiType.isEmpty()) {
if (auto pbType = adoptCF(UTTypeCopyPreferredTagWithClass(utiType.createCFString().get(), kUTTagClassNSPboardType)))
return pbType.get();
}

// No mapping, just pass the whole string though
return lowercasedType;
return type;
}

void Pasteboard::clear(const String& type)
Expand Down
8 changes: 3 additions & 5 deletions Source/WebCore/platform/win/PasteboardWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,12 @@ enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardD

static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
{
String strippedType = type.stripWhiteSpace();

// two special cases for IE compatibility
if (equalLettersIgnoringASCIICase(strippedType, "text") || equalLettersIgnoringASCIICase(strippedType, "text/plain") || strippedType.startsWith("text/plain;", false))
if (equalLettersIgnoringASCIICase(type, "text/plain"))
return ClipboardDataTypeText;
if (equalLettersIgnoringASCIICase(strippedType, "url") || equalLettersIgnoringASCIICase(strippedType, "text/uri-list"))
if (equalLettersIgnoringASCIICase(type, "text/uri-list"))
return ClipboardDataTypeURL;
if (equalLettersIgnoringASCIICase(strippedType, "text/html"))
if (equalLettersIgnoringASCIICase(type, "text/html"))
return ClipboardDataTypeTextHTML;

return ClipboardDataTypeNone;
Expand Down

0 comments on commit 3a241fb

Please sign in to comment.