diff options
Diffstat (limited to 'test/data/html/js/html-test-utilities.js')
-rw-r--r-- | test/data/html/js/html-test-utilities.js | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/test/data/html/js/html-test-utilities.js b/test/data/html/js/html-test-utilities.js new file mode 100644 index 00000000..da3e753a --- /dev/null +++ b/test/data/html/js/html-test-utilities.js @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2023 Yomitan Authors + * Copyright (C) 2021-2022 Yomichan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +class HtmlTestUtilities { + /** + * @param {Element} element + */ + static requestFullscreen(element) { + if (element.requestFullscreen) { + element.requestFullscreen(); + // @ts-expect-error - Browser compatibility + } else if (element.mozRequestFullScreen) { + // @ts-expect-error - Browser compatibility + element.mozRequestFullScreen(); + // @ts-expect-error - Browser compatibility + } else if (element.webkitRequestFullscreen) { + // @ts-expect-error - Browser compatibility + element.webkitRequestFullscreen(); + // @ts-expect-error - Browser compatibility + } else if (element.msRequestFullscreen) { + // @ts-expect-error - Browser compatibility + element.msRequestFullscreen(); + } + } + + /** */ + static exitFullscreen() { + if (document.exitFullscreen) { + document.exitFullscreen(); + // @ts-expect-error - Browser compatibility + } else if (document.mozCancelFullScreen) { + // @ts-expect-error - Browser compatibility + document.mozCancelFullScreen(); + // @ts-expect-error - Browser compatibility + } else if (document.webkitExitFullscreen) { + // @ts-expect-error - Browser compatibility + document.webkitExitFullscreen(); + // @ts-expect-error - Browser compatibility + } else if (document.msExitFullscreen) { + // @ts-expect-error - Browser compatibility + document.msExitFullscreen(); + } + } + + /** + * @returns {?Element} + */ + static getFullscreenElement() { + return ( + document.fullscreenElement || + // @ts-expect-error - Browser compatibility + document.msFullscreenElement || + // @ts-expect-error - Browser compatibility + document.mozFullScreenElement || + // @ts-expect-error - Browser compatibility + document.webkitFullscreenElement || + null + ); + } + + /** + * @param {Element} element + */ + static toggleFullscreen(element) { + if (this.getFullscreenElement()) { + this.exitFullscreen(); + } else { + this.requestFullscreen(element); + } + } + + /** + * @param {string} string + * @returns {Uint8Array} + */ + static stringToTypedArray(string) { + const array = new Uint8Array(string.length); + for (let i = 0; i < string.length; ++i) { + array[i] = string.charCodeAt(i); + } + return array; + } + + /** + * @param {string} dataUrl + * @returns {{content: string, type: string}} + * @throws {Error} + */ + static dataUrlToContent(dataUrl) { + const match = /^data:([^;]*);(base64,)?([\w\W]*)$/.exec(dataUrl); + if (match === null) { throw new Error('Invalid input'); } + const [, type, isBase64, data] = match; + const content = ( + isBase64 ? + new TextDecoder().decode(this.stringToTypedArray(atob(data))) : + data + ); + return {content, type}; + } + + /** + * @param {string} dataUrl + * @returns {Blob} + */ + static dataUrlToBlob(dataUrl) { + const {content, type} = this.dataUrlToContent(dataUrl); + return new Blob([content], {type}); + } + + /** + * @param {?Element} element + * @returns {string} + * @throws {Error} + */ + static getIframeSrc(element) { + if (!(element instanceof HTMLIFrameElement)) { + throw new Error('Element is not an iframe'); + } + return element.src; + } + + /** + * @param {Element|DocumentFragment} container + * @param {?Element} [fullscreenElement] + */ + static setupTest(container, fullscreenElement = null) { + const fullscreenLink = container.querySelector('.fullscreen-link'); + if (fullscreenLink !== null) { + if (fullscreenElement === null) { + fullscreenElement = container.querySelector('.fullscreen-element'); + } + fullscreenLink.addEventListener('click', (e) => { + if (fullscreenElement === null) { return; } + this.toggleFullscreen(fullscreenElement); + e.preventDefault(); + return false; + }, false); + } + + const template = container.querySelector('template'); + const templateContentContainer = container.querySelector('.template-content-container'); + if (template !== null && templateContentContainer !== null) { + const mode = (container instanceof HTMLElement ? container.dataset.shadowMode : void 0); + const shadow = templateContentContainer.attachShadow({ + mode: (mode === 'open' || mode === 'closed' ? mode : 'open') + }); + + const containerStyles = document.querySelector('#container-styles'); + if (containerStyles !== null) { + shadow.appendChild(containerStyles.cloneNode(true)); + } + + const content = document.importNode(template.content, true); + this.setupTest(content); + shadow.appendChild(content); + } + } + + /** + * @param {() => void} main + */ + static runMain(main) { + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => { main(); }); + } else { + main(); + } + } +} |