async-write-html-read-html.https.html (3158B)
1 <!doctype html> 2 <meta charset="utf-8"> 3 <title> 4 Async Clipboard write ([text/html ClipboardItem]) -> readHtml tests 5 </title> 6 <link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> 7 <body>Body needed for test_driver.click()</body> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="/resources/testdriver.js"></script> 11 <script src="/resources/testdriver-vendor.js"></script> 12 <script src="resources/user-activation.js"></script> 13 <script> 14 'use strict'; 15 // This function removes extra spaces between tags in html. For example, the 16 // following html: "<p> Hello </p> <body> World </body>" would turn into this 17 // html: "<p> Hello </p> <body> World </body>" 18 // We remove the extra spaces because in html they are considered equivalent, 19 // but when we are comparing for equality the spaces make a difference. 20 function reformatHtml(html) { 21 const parser = new DOMParser(); 22 const parsedHtml = parser.parseFromString(html, 'text/html') 23 24 // FIXME: The specification is ambiguous on what needs to be preserved. 25 // see https://github.com/w3c/clipboard-apis/issues/233 26 // This is an attempt at a more canonical form. 27 // Remove the head - not visible to users. 28 // Remove the styling attribute if present. 29 const headElement = parsedHtml.head; 30 if (headElement) { headElement.remove(); } 31 // Remove the eventual style attributes 32 const elementsWithStyleAttribute = parsedHtml.querySelectorAll('[style]'); 33 elementsWithStyleAttribute.forEach((element) => { element.removeAttribute('style'); }); 34 const htmlString = parsedHtml.documentElement.innerHTML; 35 // Remove multiple spaces and returns and replacing by one 36 // trim leading and tailing white spaces 37 const reformattedString = htmlString.replace(/\>[\s\n]*\</g, '> <').trim(); 38 return reformattedString; 39 } 40 41 async function readWriteTest(textInput) { 42 await tryGrantReadPermission(); 43 await tryGrantWritePermission(); 44 const blobInput = new Blob([textInput], {type: 'text/html'}); 45 const clipboardItem = new ClipboardItem({'text/html': blobInput}); 46 await waitForUserActivation(); 47 await navigator.clipboard.write([clipboardItem]); 48 await waitForUserActivation(); 49 const clipboardItems = await navigator.clipboard.read({type: 'text/html'}); 50 51 const html = clipboardItems[0]; 52 assert_equals(html.types.length, 1); 53 assert_equals(html.types[0], 'text/html'); 54 55 const blobOutput = await html.getType('text/html'); 56 assert_equals(blobOutput.type, 'text/html'); 57 58 const blobText = await (new Response(blobOutput)).text(); 59 60 const outputHtml = reformatHtml(blobText); 61 const inputHtml = reformatHtml(textInput); 62 assert_equals(outputHtml, inputHtml); 63 } 64 const testCases = [`<!doctype html> <html> <head> <title>Title of the 65 document</title> </head> <body> <p>Hello World</p> 66 </body> </html>`, 67 '<title>Title of the document</title> <p>Hello World</p>']; 68 69 promise_test(async t => { 70 for (const testCase of testCases) { 71 await readWriteTest(testCase); 72 } 73 }, 'Verify read and write of some text/html content'); 74 75 </script>