diff --git a/package-lock.json b/package-lock.json index 2ddfd6131..997697b29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "core-js": "3.41.0", "date-fns": "2.30.0", "dompurify": "2.5.8", + "element-closest-polyfill": "1.0.7", "epubjs": "0.3.93", "escape-html": "1.0.3", "fast-text-encoding": "1.0.6", @@ -9715,6 +9716,11 @@ "dev": true, "license": "ISC" }, + "node_modules/element-closest-polyfill": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/element-closest-polyfill/-/element-closest-polyfill-1.0.7.tgz", + "integrity": "sha512-SX7RrUUEybUllkGjVf5XJR5I0Fl2L0iawK/caX/yJu94xW/WoRRD8Fky65gKpvqhU9PLBKOliIy4Ly2rDRzdUQ==" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -32305,6 +32311,11 @@ "integrity": "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==", "dev": true }, + "element-closest-polyfill": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/element-closest-polyfill/-/element-closest-polyfill-1.0.7.tgz", + "integrity": "sha512-SX7RrUUEybUllkGjVf5XJR5I0Fl2L0iawK/caX/yJu94xW/WoRRD8Fky65gKpvqhU9PLBKOliIy4Ly2rDRzdUQ==" + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", diff --git a/package.json b/package.json index 35d9ed76d..2294f3152 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "core-js": "3.41.0", "date-fns": "2.30.0", "dompurify": "2.5.8", + "element-closest-polyfill": "1.0.7", "epubjs": "0.3.93", "escape-html": "1.0.3", "fast-text-encoding": "1.0.6", diff --git a/src/lib/legacy/elementAppendPrepend.js b/src/lib/legacy/elementAppendPrepend.js new file mode 100644 index 000000000..53039f451 --- /dev/null +++ b/src/lib/legacy/elementAppendPrepend.js @@ -0,0 +1,75 @@ +/** + * MIT License + * + * Copyright (c) 2016-2025, jszhou + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// From https://gist.github.com/jickoo/7b4122829240cc415c098aab89d6f49d + +// Source: https://github.com/jserz/js_piece/blob/master/DOM/ParentNode/append()/append().md +(function (arr) { + arr.forEach(function (item) { + if (Object.prototype.hasOwnProperty.call(item, 'append')) { + return; + } + Object.defineProperty(item, 'append', { + configurable: true, + enumerable: true, + writable: true, + value: function append() { + const argArr = Array.prototype.slice.call(arguments); + const docFrag = document.createDocumentFragment(); + + argArr.forEach(function (argItem) { + const isNode = argItem instanceof Node; + docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); + }); + + this.appendChild(docFrag); + } + }); + }); +})([Element.prototype, Document.prototype, DocumentFragment.prototype]); + +// Source: https://github.com/jserz/js_piece/blob/master/DOM/ParentNode/prepend()/prepend().md +(function (arr) { + arr.forEach(function (item) { + if (Object.prototype.hasOwnProperty.call(item, 'prepend')) { + return; + } + Object.defineProperty(item, 'prepend', { + configurable: true, + enumerable: true, + writable: true, + value: function prepend() { + const argArr = Array.prototype.slice.call(arguments); + const docFrag = document.createDocumentFragment(); + + argArr.forEach(function (argItem) { + const isNode = argItem instanceof Node; + docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); + }); + + this.insertBefore(docFrag, this.firstChild); + } + }); + }); +})([Element.prototype, Document.prototype, DocumentFragment.prototype]); diff --git a/src/lib/legacy/index.ts b/src/lib/legacy/index.ts index 9a836578e..d8dcf9539 100644 --- a/src/lib/legacy/index.ts +++ b/src/lib/legacy/index.ts @@ -1,6 +1,7 @@ import 'core-js/stable'; import 'regenerator-runtime/runtime'; import 'jquery'; +import 'element-closest-polyfill'; import 'fast-text-encoding'; import 'intersection-observer'; import 'classlist.js'; @@ -9,6 +10,7 @@ import 'abortcontroller-polyfill'; // requires fetch import 'resize-observer-polyfill'; import './domParserTextHtml'; +import './elementAppendPrepend'; import './focusPreventScroll'; import './htmlMediaElement'; import './keyboardEvent';