Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clipboard API] Clipboard Web Custom Formats implementation. #34117

Merged
merged 1 commit into from
Jun 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 36 additions & 14 deletions clipboard-apis/async-custom-formats-write-read.tentative.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,19 @@
promise_test(async t => {
await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
const format1 = 'application/x-custom-format-clipboard-test-format-1';
const format2 = 'application/x-custom-format-clipboard-test-format-2';
const format1 = 'web application/x-custom-format-clipboard-test-format-1';
const format2 = 'web application/x-custom-format-clipboard-test-format-2';
const blobInput1 = new Blob(['input data 1'], {type: format1});
const blobInput2 = new Blob(['input data 2'], {type: format2});
const clipboardItemInput = new ClipboardItem(
{[format1]: blobInput1, [format2]: blobInput2},
{unsanitized: [format1, format2]});
{[format1]: blobInput1, [format2]: blobInput2});
await waitForUserActivation();
await navigator.clipboard.write([clipboardItemInput]);

// Items may not be readable on the sanitized clipboard after custom format
// write.
await promise_rejects_dom(t, 'DataError',
navigator.clipboard.read());

// Items should be readable on a custom format clipboard after custom format
// write.
await waitForUserActivation();
const clipboardItems = await navigator.clipboard.read(
{unsanitized: [format1, format2]});
const clipboardItems = await navigator.clipboard.read();
assert_equals(clipboardItems.length, 1);
const clipboardItem = clipboardItems[0];
assert_true(clipboardItem instanceof ClipboardItem);
Expand All @@ -58,15 +51,44 @@
const customFormatArray = [];
const customFormatMap = {};
for (let i = 0; i <= 100; i++) {
customFormatArray.push("CustomFormat" + i);
customFormatArray.push("web text/CustomFormat" + i);
const blobInput = new Blob(['input data'], {type: customFormatArray[i]});
customFormatMap[customFormatArray[i]] = blobInput;
}
const clipboardItemInput = new ClipboardItem(customFormatMap,
{unsanitized: customFormatArray});
const clipboardItemInput = new ClipboardItem(customFormatMap);
await waitForUserActivation();
await promise_rejects_dom(t, 'NotAllowedError',
navigator.clipboard.write([clipboardItemInput]));
}, 'navigator.clipboard.write() fails for more than 100 custom formats');

promise_test(async t => {
await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
await test_driver.set_permission({name: 'clipboard-write'}, 'granted');

const format1 = 'application/x-custom-format-clipboard-test-format-1';
const format2 = 'application/x-custom-format-clipboard-test-format-2';
const blobInput1 = new Blob(['input data 1'], {type: format1});
const blobInput2 = new Blob(['input data 2'], {type: format2});
const clipboardItemInput = new ClipboardItem(
{[format1]: blobInput1, [format2]: blobInput2});
await waitForUserActivation();
await promise_rejects_dom(t, 'NotAllowedError',
navigator.clipboard.write([clipboardItemInput]));
}, 'navigator.clipboard.write() fails for custom formats without web prefix');

promise_test(async t => {
await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
await test_driver.set_permission({name: 'clipboard-write'}, 'granted');

const format1 = 'web ';
const format2 = 'web a';
const blobInput1 = new Blob(['input data 1'], {type: format1});
const blobInput2 = new Blob(['input data 2'], {type: format2});
const clipboardItemInput = new ClipboardItem(
{[format1]: blobInput1, [format2]: blobInput2});
await waitForUserActivation();
await promise_rejects_dom(t, 'NotAllowedError',
navigator.clipboard.write([clipboardItemInput]));
}, 'navigator.clipboard.write() fails for custom formats with web prefix, but invalid MIME types');

</script>
6 changes: 5 additions & 1 deletion clipboard-apis/async-html-script-removal.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
Async Clipboard write ([text/html ClipboardItem]) -> readHtml (and remove scripts) tests
</title>
<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
<body>Body needed for test_driver.click()</body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>
<script>
'use strict';
// This function removes extra spaces between tags in html. For example, the
Expand Down Expand Up @@ -36,8 +38,10 @@
await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
const blobInput = new Blob([html_with_script], {type: 'text/html'});
const clipboardItem = new ClipboardItem({'text/html': blobInput});
await waitForUserActivation();
await navigator.clipboard.write([clipboardItem]);
const clipboardItems = await navigator.clipboard.read({type: 'text/html'});
await waitForUserActivation();
const clipboardItems = await navigator.clipboard.read();

const html = clipboardItems[0];
assert_equals(html.types.length, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>

<body>Body needed for test_driver.click()
<p><button id="button">Put payload in the clipboard</button></p>
<div id="output"></div>

Expand All @@ -27,6 +29,7 @@
await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
await test_driver.click(button);

await waitForUserActivation();
const items = await navigator.clipboard.read();
const htmlBlob = await items[0].getType("text/html");
const html = await htmlBlob.text();
Expand All @@ -38,3 +41,4 @@
assert_false(loadObserved, 'Should not observe resource loading');
});
</script>
</body>
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>

<body>Body needed for test_driver.click()
<p><button id="button">Put payload in the clipboard</button></p>
<div id="output"></div>

Expand All @@ -29,6 +31,7 @@
await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
await test_driver.click(button);

await waitForUserActivation();
const items = await navigator.clipboard.read();
const htmlBlob = await items[0].getType("text/html");
const html = await htmlBlob.text();
Expand All @@ -42,3 +45,4 @@
assert_false(testFailed);
});
</script>
</body>
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
Async Clipboard write blobs -> read blobs with promise tests
</title>
<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
<body>Body needed for test_driver.click()</body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>

<script>
async function loadBlob(fileName) {
Expand All @@ -26,8 +28,9 @@

const clipboardItemInput = new ClipboardItem(
{'text/plain' : blobText, 'image/png' : promise1});

await waitForUserActivation();
await navigator.clipboard.write([clipboardItemInput]);
await waitForUserActivation();
const clipboardItems = await navigator.clipboard.read();

assert_equals(clipboardItems.length, 1);
Expand Down
4 changes: 4 additions & 0 deletions clipboard-apis/async-svg-script-removal.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
Async Clipboard write ([image/svg+xml ClipboardItem]) -> readSvg (and remove scripts) tests
</title>
<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
<body>Body needed for test_driver.click()</body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>
<script>
'use strict';
// This function removes extra spaces between tags in svg. For example, the
Expand Down Expand Up @@ -36,7 +38,9 @@
await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
const blobInput = new Blob([svg_with_script], {type: 'image/svg+xml'});
const clipboardItem = new ClipboardItem({'image/svg+xml': blobInput});
await waitForUserActivation();
await navigator.clipboard.write([clipboardItem]);
await waitForUserActivation();
const clipboardItems =
await navigator.clipboard.read({type: 'image/svg+xml'});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,18 @@

// Create and write unsanitized version of standard HTML and custom formats.
const format1 = 'text/html';
const format2 = 'application/x-custom-format-clipboard-test-format-2';
const format2 = 'web text/html';
const textInput = '<style>p {color:blue}</style><p>Hello World</p>';
const blobInput1 = new Blob([textInput], {type: 'text/html'});
const blobInput2 = new Blob(['input data 2'], {type: format2});
const blobInput1 = new Blob([textInput], {type: format1});
const blobInput2 = new Blob([textInput], {type: format2});
const clipboardItemInput = new ClipboardItem(
{[format1]: blobInput1, [format2]: blobInput2},
{unsanitized: [format1, format2]});
{[format1]: blobInput1, [format2]: blobInput2});
await waitForUserActivation();
await navigator.clipboard.write([clipboardItemInput]);

// Read unsanitized version of HTML format.
await waitForUserActivation();
const clipboardItems = await navigator.clipboard.read(
{unsanitized: [format1, format2]});
const clipboardItems = await navigator.clipboard.read();

assert_equals(clipboardItems.length, 1);
const clipboardItem = clipboardItems[0];
Expand All @@ -55,12 +53,20 @@
assert_equals(blobOutput1.type, format1);
const data1 = await (new Response(blobOutput1)).text();
const outputHtml = reformatHtml(data1);
const inputHtml = reformatHtml(textInput);
const expectedHtml = '<p style="color: blue; font-size: medium; font-style: normal; ' +
'font-variant-ligatures: normal; font-variant-caps: normal; ' +
'font-weight: 400; letter-spacing: normal; orphans: 2; ' +
'text-align: start; text-indent: 0px; text-transform: none; '+
'white-space: normal; widows: 2; word-spacing: 0px; ' +
'-webkit-text-stroke-width: 0px; text-decoration-thickness: initial; ' +
'text-decoration-style: initial; text-decoration-color: initial;">' +
'Hello World</p>';
const inputHtml = reformatHtml(expectedHtml);
assert_equals(outputHtml, inputHtml);

const blobOutput2 = await clipboardItem.getType(format2);
assert_equals(blobOutput2.type, format2);
const data2 = await (new Response(blobOutput2)).text();
assert_equals(data2, 'input data 2');
assert_equals(data2, textInput);
}, 'Verify write and read unsanitized content to the clipboard given text/html format as input');
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,35 @@
await test_driver.set_permission({name: 'clipboard-write'}, 'granted');

const dataToWrite = 'Test text.';
const format = 'text/plain';
const format1 = 'web text/plain';
const format2 = 'text/plain';

const blobInput = new Blob([dataToWrite], {type: format});
const blobInput1 = new Blob([dataToWrite], {type: format1});
const blobInput2 = new Blob([dataToWrite], {type: format2});
// Blob types are automatically converted to lower-case.
assert_equals(blobInput.type, format.toLowerCase());
assert_equals(blobInput1.type, format1.toLowerCase());
assert_equals(blobInput2.type, format2.toLowerCase());
const clipboardItemInput = new ClipboardItem(
{[format]: blobInput}, {unsanitized: [format]});
{[format1]: blobInput1, [format2]: blobInput2});
await waitForUserActivation();
await navigator.clipboard.write([clipboardItemInput]);

// Items should be readable on a system clipboard after custom format write.
await waitForUserActivation();
const clipboardItems = await navigator.clipboard.read(
{unsanitized: [format]});
const clipboardItems = await navigator.clipboard.read();
assert_equals(clipboardItems.length, 1);
const clipboardItem = clipboardItems[0];
assert_true(clipboardItem instanceof ClipboardItem);

const blobOutput = await clipboardItem.getType(format);
assert_equals(blobOutput.type, format);
const data = await (new Response(blobOutput)).text();
assert_equals(data, dataToWrite);
const blobOutput1 = await clipboardItem.getType(format1);
assert_equals(blobOutput1.type, format1);
const data1 = await (new Response(blobOutput1)).text();
assert_equals(data1, dataToWrite);

// These examples use native text formats, so these formats should be
// accessible as text.
await waitForUserActivation();
const textOutput = await navigator.clipboard.readText();
assert_equals(textOutput, dataToWrite);
}, 'Verify write and read unsanitized content to the clipboard given standard format as input');
}, 'Verify write and read unsanitized content to the clipboard given standard and custom formats as input');
</script>
4 changes: 4 additions & 0 deletions clipboard-apis/async-write-blobs-read-blobs.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
Async Clipboard write blobs -> read blobs tests
</title>
<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
<body>Body needed for test_driver.click()</body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>

<script>
async function loadBlob(fileName) {
Expand All @@ -28,7 +30,9 @@
const clipboardItemInput = new ClipboardItem(
{'text/plain' : blobText, 'image/png' : blobImage});

await waitForUserActivation();
await navigator.clipboard.write([clipboardItemInput]);
await waitForUserActivation();
const clipboardItems = await navigator.clipboard.read();

assert_equals(clipboardItems.length, 1);
Expand Down
4 changes: 4 additions & 0 deletions clipboard-apis/async-write-html-read-html.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
Async Clipboard write ([text/html ClipboardItem]) -> readHtml tests
</title>
<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
<body>Body needed for test_driver.click()</body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>
<script>
'use strict';
// This function removes extra spaces between tags in html. For example, the
Expand All @@ -28,7 +30,9 @@
await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
const blobInput = new Blob([textInput], {type: 'text/html'});
const clipboardItem = new ClipboardItem({'text/html': blobInput});
await waitForUserActivation();
await navigator.clipboard.write([clipboardItem]);
await waitForUserActivation();
const clipboardItems = await navigator.clipboard.read({type: 'text/html'});

const html = clipboardItems[0];
Expand Down
6 changes: 6 additions & 0 deletions clipboard-apis/async-write-image-read-image.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>
<body>Body needed for test_driver.click()
<p>
<p>The bottom image should display the same image as the top image.</p>
<p>Original Image:</p>
Expand Down Expand Up @@ -47,7 +49,9 @@

assert_equals(blobInput.type, 'image/png');
const clipboardItemInput = new ClipboardItem({'image/png' : blobInput});
await waitForUserActivation();
await navigator.clipboard.write([clipboardItemInput]);
await waitForUserActivation();
const clipboardItems = await navigator.clipboard.read();

assert_equals(clipboardItems.length, 1);
Expand All @@ -73,7 +77,9 @@
const invalidPngBlob = new Blob(['this text is not a valid png image'],
{type: 'image/png'});
const clipboardItemInput = new ClipboardItem({'image/png' : invalidPngBlob});
await waitForUserActivation();
await promise_rejects_dom(t, 'DataError',
navigator.clipboard.write([clipboardItemInput]));
}, 'Verify write error on malformed data [image/png ClipboardItem]');
</script>
</body>
4 changes: 4 additions & 0 deletions clipboard-apis/async-write-svg-read-svg.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
Async Clipboard write ([image/svg+xml ClipboardItem]) -> read and write svg tests
</title>
<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api">
<body>Body needed for test_driver.click()</body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/user-activation.js"></script>
<script>
'use strict';
// This function removes extra spaces between tags in svg. For example, the
Expand All @@ -28,7 +30,9 @@
await test_driver.set_permission({name: 'clipboard-write'}, 'granted');
const blobInput = new Blob([textInput], {type: 'image/svg+xml'});
const clipboardItem = new ClipboardItem({'image/svg+xml': blobInput});
await waitForUserActivation();
await navigator.clipboard.write([clipboardItem]);
await waitForUserActivation();
const clipboardItems =
await navigator.clipboard.read({type: 'image/svg+xml'});

Expand Down
Loading