aboutsummaryrefslogtreecommitdiff
path: root/test/data/html/js
diff options
context:
space:
mode:
Diffstat (limited to 'test/data/html/js')
-rw-r--r--test/data/html/js/html-test-utilities.js184
-rw-r--r--test/data/html/js/performance-frames.js63
-rw-r--r--test/data/html/js/popup-tests-frame1.js21
-rw-r--r--test/data/html/js/popup-tests.js33
4 files changed, 301 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();
+ }
+ }
+}
diff --git a/test/data/html/js/performance-frames.js b/test/data/html/js/performance-frames.js
new file mode 100644
index 00000000..7484f971
--- /dev/null
+++ b/test/data/html/js/performance-frames.js
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 Yomitan 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/>.
+ */
+
+HtmlTestUtilities.runMain(() => {
+ let totalCount = 0;
+ const container = document.querySelector('#container');
+ const counter = document.querySelector('#counter');
+
+ /**
+ * @param {number} count
+ * @param {Event} event
+ */
+ function addElements(count, event) {
+ event.preventDefault();
+
+ if (container !== null) {
+ for (let i = 0; i < count; ++i) {
+ const element = document.createElement('div');
+ element.textContent = 'ありがとう';
+ container.appendChild(element);
+ }
+ }
+
+ totalCount += count;
+ if (counter !== null) {
+ counter.textContent = `${totalCount}`;
+ }
+ }
+
+ for (const element of document.querySelectorAll('.add-elements')) {
+ if (!(element instanceof HTMLElement)) { continue; }
+ const {count} = element.dataset;
+ if (typeof count !== 'string') { continue; }
+ const countValue = Number.parseInt(count, 10);
+ if (!Number.isFinite(countValue)) { continue; }
+ element.addEventListener('click', addElements.bind(null, countValue));
+ }
+
+ const shadowIframeContainer = document.querySelector('#shadow-iframe-container-open');
+ if (shadowIframeContainer !== null) {
+ const shadow = shadowIframeContainer.attachShadow({mode: 'open'});
+ const templateElement = document.querySelector('#shadow-iframe-container-open-content-template');
+ if (templateElement instanceof HTMLTemplateElement) {
+ const template = templateElement.content;
+ const content = document.importNode(template, true);
+ shadow.appendChild(content);
+ }
+ }
+});
diff --git a/test/data/html/js/popup-tests-frame1.js b/test/data/html/js/popup-tests-frame1.js
new file mode 100644
index 00000000..b1dc2756
--- /dev/null
+++ b/test/data/html/js/popup-tests-frame1.js
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 Yomitan 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/>.
+ */
+
+HtmlTestUtilities.runMain(() => {
+ const {body} = document;
+ HtmlTestUtilities.setupTest(body, body);
+});
diff --git a/test/data/html/js/popup-tests.js b/test/data/html/js/popup-tests.js
new file mode 100644
index 00000000..3a46a045
--- /dev/null
+++ b/test/data/html/js/popup-tests.js
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 Yomitan 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/>.
+ */
+
+HtmlTestUtilities.runMain(() => {
+ for (const element of document.querySelectorAll('test-case')) {
+ HtmlTestUtilities.setupTest(element);
+ }
+
+ const iframeWithDataUrl = document.querySelector('#iframe-with-data-url');
+ const src = HtmlTestUtilities.getIframeSrc(iframeWithDataUrl);
+ const iframeWithBlobUrl = document.querySelector('#iframe-with-blob-url');
+ if (iframeWithBlobUrl instanceof HTMLIFrameElement) {
+ iframeWithBlobUrl.src = URL.createObjectURL(HtmlTestUtilities.dataUrlToBlob(src));
+ }
+ for (const iframeWithSrcdoc of document.querySelectorAll('.iframe-with-srcdoc')) {
+ if (!(iframeWithSrcdoc instanceof HTMLIFrameElement)) { continue; }
+ iframeWithSrcdoc.srcdoc = HtmlTestUtilities.dataUrlToContent(src).content;
+ }
+});