Skip to content

Commit 91237d0

Browse files
committed
Implement ClipboardItem.supports
https://bugs.webkit.org/show_bug.cgi?id=279712 rdar://136008522 Reviewed by Wenson Hsieh. Adds ClipboardItem.supports() Adds also text/uri-lists per spec to the list of types in WPT Defers custom web format implementation to <https://webkit.org/b/280664> Defers support for image/svg+xml to <https://webkit.org/b/280726> * LayoutTests/editing/async-clipboard/clipboard-interfaces-expected.txt: Removed. * LayoutTests/editing/async-clipboard/clipboard-interfaces.html: Removed. These are covered by WPT * LayoutTests/editing/async-clipboard/clipboard-write-basic-expected.txt: * LayoutTests/editing/async-clipboard/clipboard-write-basic.html: Removed the invalid case of an empty clipboardItem() * LayoutTests/imported/w3c/web-platform-tests/clipboard-apis/clipboard-item.https-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/clipboard-apis/clipboard-item.https.html: Fixing the tests. Needs to be exported back to WPT * LayoutTests/platform/mac-wk1/TestExpectations: * Source/WebCore/Modules/async-clipboard/ClipboardItem.cpp: (WebCore::ClipboardItem::create): (WebCore::ClipboardItem::supports): * Source/WebCore/Modules/async-clipboard/ClipboardItem.h: * Source/WebCore/Modules/async-clipboard/ClipboardItem.idl: Canonical link: https://commits.webkit.org/284593@main
1 parent 7fd4754 commit 91237d0

File tree

10 files changed

+79
-131
lines changed

10 files changed

+79
-131
lines changed

LayoutTests/editing/async-clipboard/clipboard-interfaces-expected.txt

Lines changed: 0 additions & 51 deletions
This file was deleted.

LayoutTests/editing/async-clipboard/clipboard-interfaces.html

Lines changed: 0 additions & 68 deletions
This file was deleted.

LayoutTests/editing/async-clipboard/clipboard-write-basic-expected.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ Testing thirdItem:
1717
PASS thirdItem.types is ['text/uri-list', 'text/plain']
1818
PASS getType("text/uri-list") resolved to ""
1919
PASS getType("text/plain") resolved to ""
20-
Testing fourthItem:
21-
PASS fourthItem.types is []
2220
PASS successfullyParsed is true
2321

2422
TEST COMPLETE

LayoutTests/editing/async-clipboard/clipboard-write-basic.html

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
}), new ClipboardItem({
3535
"text/uri-list" : Promise.resolve(""),
3636
"text/plain" : Promise.resolve(textBlob(""))
37-
}), new ClipboardItem({ })
37+
})
3838
]);
3939
doneWritingItems = true;
4040
});
@@ -59,9 +59,6 @@
5959
await checkClipboardItemString(thirdItem, "text/uri-list", "");
6060
await checkClipboardItemString(thirdItem, "text/plain", "");
6161

62-
debug("Testing fourthItem:");
63-
shouldBe("fourthItem.types", "[]");
64-
6562
copyButton.remove();
6663
pasteButton.remove();
6764
finishJSTest();
Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11

22
PASS ClipboardItem({string, Blob}) succeeds with different types
33
PASS ClipboardItem() succeeds with empty options
4-
FAIL ClipboardItem({}) fails with empty dictionary input assert_throws_js: function "() => {new ClipboardItem({});}" did not throw
5-
FAIL ClipboardItem(Blob) fails assert_throws_js: function "() => {new ClipboardItem(blob);}" did not throw
6-
FAIL ClipboardItem() fails with null input assert_throws_js: function "() => {new ClipboardItem(null);}" did not throw
4+
PASS ClipboardItem({}) fails with empty dictionary input
5+
PASS ClipboardItem(Blob) fails
6+
PASS ClipboardItem() fails with null input
77
PASS ClipboardItem() fails with no input
88
PASS types() returns correct values
99
PASS getType(DOMString valid type) succeeds with correct output
1010
PASS getType(DOMString invalid type) succeeds with correct output
1111
PASS getType(DOMString type) rejects correctly when querying for missing type
1212
PASS getType(DOMString valid type) converts DOMString to Blob
1313
PASS getType(DOMString invalid type) converts DOMString to Blob
14+
PASS supports(text/plain) returns true
15+
PASS supports(text/html) returns true
16+
PASS supports(image/png) returns true
17+
PASS supports(text/uri-list) returns true
18+
FAIL supports(image/svg+xml) returns true assert_equals: expected true but got false
19+
FAIL supports(web foo/bar) returns true assert_equals: expected true but got false
20+
FAIL supports(web text/html) returns true assert_equals: expected true but got false
21+
PASS supports(web ) returns false
22+
PASS supports(web) returns false
23+
PASS supports(web foo) returns false
24+
PASS supports(foo/bar) returns false
25+
PASS supports(weB text/html) returns false
26+
PASS supports( web text/html) returns false
27+
PASS supports(not a/real type) returns false
28+
PASS supports() returns false
29+
PASS supports( ) returns false
1430

LayoutTests/imported/w3c/web-platform-tests/clipboard-apis/clipboard-item.https.html

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,30 @@
9595
const text = await (new Response(blob)).text();
9696
assert_equals(text, 'xxx');
9797
}, "getType(DOMString invalid type) converts DOMString to Blob");
98-
</script>
98+
99+
[
100+
// mandatory data types
101+
['text/plain', true],
102+
['text/html', true],
103+
['image/png', true],
104+
// optional data types
105+
['text/uri-list', true],
106+
['image/svg+xml', true],
107+
['web foo/bar', true],
108+
['web text/html', true],
109+
// invalid types
110+
['web ', false],
111+
['web', false],
112+
['web foo', false],
113+
['foo/bar', false],
114+
['weB text/html', false],
115+
[' web text/html', false],
116+
['not a/real type', false],
117+
['', false],
118+
[' ', false],
119+
].forEach(([type, result]) => {
120+
promise_test(async () => {
121+
assert_equals(ClipboardItem.supports(type), result);
122+
}, `supports(${type}) returns ${result ? "true" : "false"}`);
123+
});
124+
</script>

LayoutTests/platform/mac-wk1/TestExpectations

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2950,3 +2950,6 @@ imported/w3c/web-platform-tests/content-security-policy/reporting-api/reporting-
29502950

29512951
# webkit.org/b/280000 [ macOS wk1 Debug ] svg/zoom/page/zoom-svg-through-object-with-override-size.html is a flaky crash.
29522952
[ Debug ] svg/zoom/page/zoom-svg-through-object-with-override-size.html [ Pass Crash ]
2953+
2954+
# webkit.org/b/279712 Clipboard API not supported on WK1
2955+
imported/w3c/web-platform-tests/clipboard-apis/clipboard-item.https.html [ Skip ]

Source/WebCore/Modules/async-clipboard/ClipboardItem.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "Clipboard.h"
3131
#include "ClipboardItemBindingsDataSource.h"
3232
#include "ClipboardItemPasteboardDataSource.h"
33+
#include "CommonAtomStrings.h"
3334
#include "Navigator.h"
3435
#include "PasteboardCustomData.h"
3536
#include "PasteboardItemInfo.h"
@@ -58,6 +59,10 @@ static ClipboardItem::PresentationStyle clipboardItemPresentationStyle(const Pas
5859
return ClipboardItem::PresentationStyle::Unspecified;
5960
}
6061

62+
// FIXME: Custom format starts with `"web "`("web" followed by U+0020 SPACE) prefix
63+
// and suffix (after stripping out `"web "`) passes the parsing a MIME type check.
64+
// https://w3c.github.io/clipboard-apis/#optional-data-types
65+
// https://webkit.org/b/280664
6166
ClipboardItem::ClipboardItem(Vector<KeyValuePair<String, Ref<DOMPromise>>>&& items, const Options& options)
6267
: m_dataSource(makeUnique<ClipboardItemBindingsDataSource>(*this, WTFMove(items)))
6368
, m_presentationStyle(options.presentationStyle)
@@ -72,8 +77,10 @@ ClipboardItem::ClipboardItem(Clipboard& clipboard, const PasteboardItemInfo& inf
7277
{
7378
}
7479

75-
Ref<ClipboardItem> ClipboardItem::create(Vector<KeyValuePair<String, Ref<DOMPromise>>>&& data, const Options& options)
80+
ExceptionOr<Ref<ClipboardItem>> ClipboardItem::create(Vector<KeyValuePair<String, Ref<DOMPromise>>>&& data, const Options& options)
7681
{
82+
if (data.isEmpty())
83+
return Exception { ExceptionCode::TypeError, "ClipboardItem() can not be an empty array: {}"_s };
7784
return adoptRef(*new ClipboardItem(WTFMove(data), options));
7885
}
7986

@@ -92,6 +99,22 @@ void ClipboardItem::getType(const String& type, Ref<DeferredPromise>&& promise)
9299
m_dataSource->getType(type, WTFMove(promise));
93100
}
94101

102+
bool ClipboardItem::supports(const String& type)
103+
{
104+
// FIXME: Custom format starts with `"web "`("web" followed by U+0020 SPACE) prefix
105+
// and suffix (after stripping out `"web "`) passes the parsing a MIME type check.
106+
// https://webkit.org/b/280664
107+
// FIXME: add type == "image/svg+xml"_s when we have sanitized copy/paste for SVG data
108+
// https://webkit.org/b/280726
109+
if (type == textPlainContentTypeAtom()
110+
|| type == textHTMLContentTypeAtom()
111+
|| type == "image/png"_s
112+
|| type == "text/uri-list"_s) {
113+
return true;
114+
}
115+
return false;
116+
}
117+
95118
void ClipboardItem::collectDataForWriting(Clipboard& destination, CompletionHandler<void(std::optional<PasteboardCustomData>)>&& completion)
96119
{
97120
m_dataSource->collectDataForWriting(destination, WTFMove(completion));

Source/WebCore/Modules/async-clipboard/ClipboardItem.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#pragma once
2727

28+
#include "ExceptionOr.h"
2829
#include <wtf/KeyValuePair.h>
2930
#include <wtf/Ref.h>
3031
#include <wtf/RefCounted.h>
@@ -55,12 +56,13 @@ class ClipboardItem : public RefCounted<ClipboardItem>, public CanMakeWeakPtr<Cl
5556
PresentationStyle presentationStyle { PresentationStyle::Unspecified };
5657
};
5758

58-
static Ref<ClipboardItem> create(Vector<KeyValuePair<String, Ref<DOMPromise>>>&&, const Options&);
59+
static ExceptionOr<Ref<ClipboardItem>> create(Vector<KeyValuePair<String, Ref<DOMPromise>>>&&, const Options&);
5960
static Ref<ClipboardItem> create(Clipboard&, const PasteboardItemInfo&);
6061
static Ref<Blob> blobFromString(ScriptExecutionContext*, const String& stringData, const String& type);
6162

6263
Vector<String> types() const;
6364
void getType(const String&, Ref<DeferredPromise>&&);
65+
static bool supports(const String& type);
6466

6567
void collectDataForWriting(Clipboard& destination, CompletionHandler<void(std::optional<PasteboardCustomData>)>&&);
6668

Source/WebCore/Modules/async-clipboard/ClipboardItem.idl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,7 @@ dictionary ClipboardItemOptions {
4141

4242
readonly attribute FrozenArray<DOMString> types;
4343
[NewObject] Promise<Blob> getType(DOMString type);
44+
static boolean supports(DOMString type);
45+
4446
readonly attribute PresentationStyle presentationStyle;
4547
};

0 commit comments

Comments
 (0)