| function sampleBase64PNGImageData() { |
| // A 60 by 60 solid red square. |
| return "iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAAXNSR0IArs4c6QAAAJZlWElmTU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAACQAAAAAQAAAJAAAAABAASShgAHAAAAEgAAAISgAQADAAAAAQABAACgAgAEAAAAAQAAADygAwAEAAAAAQAAADwAAAAAQVNDSUkAAABTY3JlZW5zaG90CUg0mwAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAdRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpVc2VyQ29tbWVudD5TY3JlZW5zaG90PC9leGlmOlVzZXJDb21tZW50PgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NjA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4K9+BmbAAAABxpRE9UAAAAAgAAAAAAAAAeAAAAKAAAAB4AAAAeAAAAls/GUI8AAABiSURBVGgF7NIxAQAgDMRA6ogd/7pAQByEdPzt/zr37Ls+uqmwXDthOfBKOGHZAr20DBR1EsYksiBhGSjqJIxJZEHCMlDUSRiTyIKEZaCokzAmkQUJy0BRJ2FMIgsSloGizgMAAP//Y4b2JQAAAGBJREFU7dIxAQAgDMRA6ogd/7pAQByEdPzt/zr37Ls+uqmwXDthOfBKOGHZAr20DBR1EsYksiBhGSjqJIxJZEHCMlDUSRiTyIKEZaCokzAmkQUJy0BRJ2FMIgsSloGizgOl3pDZBBa0hwAAAABJRU5ErkJggg"; |
| } |
| |
| function imageBlob(base64String = sampleBase64PNGImageData()) { |
| return textBlob(atob(base64String), "image/png"); |
| } |
| |
| function textBlob(data, type = "text/plain") { |
| const array = [...data].map(char => char.charCodeAt(0)); |
| return new Blob([new Uint8Array(array)], { "type" : type }); |
| } |
| |
| function loadText(blob) { |
| return new Promise((resolve, reject) => { |
| const reader = new FileReader; |
| reader.addEventListener("load", () => resolve(reader.result), { once: true }); |
| reader.addEventListener("error", reject, { once: true }); |
| reader.readAsText(blob); |
| }); |
| } |
| |
| function loadImage(blob) { |
| return new Promise((resolve, reject) => { |
| const image = new Image; |
| image.addEventListener("load", () => resolve(image), { once: true }); |
| image.addEventListener("error", reject, { once: true }); |
| image.src = URL.createObjectURL(blob); |
| }); |
| } |
| |
| function loadDocument(blob) { |
| return new Promise(async resolve => { |
| resolve(new DOMParser().parseFromString(await loadText(blob), "text/html")); |
| }); |
| } |
| |
| function writeToClipboardUsingDataTransfer(data) { |
| const input = document.createElement("input"); |
| document.body.appendChild(input); |
| input.value = "a"; |
| input.setSelectionRange(0, 1); |
| input.addEventListener("copy", event => { |
| for (const type of Object.keys(data)) |
| event.clipboardData.setData(type, data[type]); |
| event.preventDefault(); |
| }, { once: true }); |
| document.execCommand("copy"); |
| input.remove(); |
| } |
| |
| |
| async function triggerProgrammaticPaste(locationOrElement, options = []) { |
| let x, y; |
| if (locationOrElement instanceof Element) |
| [x, y] = [locationOrElement.offsetLeft + locationOrElement.offsetWidth / 2, locationOrElement.offsetTop + locationOrElement.offsetHeight / 2]; |
| else |
| [x, y] = [locationOrElement.x, locationOrElement.y]; |
| |
| return new Promise(resolve => { |
| testRunner.runUIScript(` |
| (() => { |
| doneCount = 0; |
| function checkDone() { |
| if (++doneCount === 3) |
| uiController.uiScriptComplete(); |
| } |
| |
| uiController.didHideMenuCallback = checkDone; |
| |
| function resolveDOMPasteRequest() { |
| if (${options.includes("ChangePasteboardWhenGrantingAccess")}) |
| uiController.copyText("*** this text should never appear in a passing layout test ***"); |
| uiController.chooseMenuAction("Paste", checkDone); |
| } |
| |
| if (uiController.isShowingMenu) |
| resolveDOMPasteRequest(); |
| else |
| uiController.didShowMenuCallback = resolveDOMPasteRequest; |
| |
| uiController.activateAtPoint(${x}, ${y}, checkDone); |
| })()`, resolve); |
| }); |
| } |
| |
| async function checkClipboardItemString(item, type, expectedString) |
| { |
| const observedString = await loadText(await item.getType(type)); |
| if (observedString === expectedString) |
| testPassed(`getType("${type}") resolved to "${expectedString}"`); |
| else |
| testFailed(`getType("${type}") resolved to "${observedString}; expected "${expectedString}"`); |
| } |