diff options
Diffstat (limited to 'data/extensions/uBlock0@raymondhill.net/js/resources/create-html.js')
-rw-r--r-- | data/extensions/uBlock0@raymondhill.net/js/resources/create-html.js | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/data/extensions/uBlock0@raymondhill.net/js/resources/create-html.js b/data/extensions/uBlock0@raymondhill.net/js/resources/create-html.js new file mode 100644 index 0000000..c5732d3 --- /dev/null +++ b/data/extensions/uBlock0@raymondhill.net/js/resources/create-html.js @@ -0,0 +1,113 @@ +/******************************************************************************* + + uBlock Origin - a comprehensive, efficient content blocker + Copyright (C) 2025-present Raymond Hill + + 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 {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uBlock + +*/ + +import { registerScriptlet } from './base.js'; +import { safeSelf } from './safe-self.js'; + +/******************************************************************************/ + +/** + * @scriptlet trusted-create-html + * + * @description + * Element(s) from a parsed HTML string are added as child element(s) to a + * specific parent element in the DOM. + * + * @param parent + * A CSS selector identifying the element to which created element(s) will be + * added. + * + * @param html + * An HTML string to be parsed using DOMParser, and which resulting elements + * are to be added as child element(s). + * + * @param duration + * Optional. If specified, the time in ms after which the added elements will + * be removed. No removal will occur if not specified. + * + * */ + +function trustedCreateHTML( + parentSelector, + htmlStr = '', + durationStr = '' +) { + if ( parentSelector === '' ) { return; } + if ( htmlStr === '' ) { return; } + const safe = safeSelf(); + const logPrefix = safe.makeLogPrefix('trusted-create-html', parentSelector, htmlStr, durationStr); + // We do not want to recursively create elements + self.trustedCreateHTML = true; + let ancestor = self.frameElement; + while ( ancestor !== null ) { + const doc = ancestor.ownerDocument; + if ( doc === null ) { break; } + const win = doc.defaultView; + if ( win === null ) { break; } + if ( win.trustedCreateHTML ) { return; } + ancestor = ancestor.frameElement; + } + const duration = parseInt(durationStr, 10); + const domParser = new DOMParser(); + const externalDoc = domParser.parseFromString(htmlStr, 'text/html'); + const docFragment = new DocumentFragment(); + const toRemove = []; + while ( externalDoc.body.firstChild !== null ) { + const imported = document.adoptNode(externalDoc.body.firstChild); + docFragment.appendChild(imported); + if ( isNaN(duration) ) { continue; } + toRemove.push(imported); + } + if ( docFragment.firstChild === null ) { return; } + const remove = ( ) => { + for ( const node of toRemove ) { + if ( node.parentNode === null ) { continue; } + node.parentNode.removeChild(node); + } + safe.uboLog(logPrefix, 'Node(s) removed'); + }; + const append = ( ) => { + const parent = document.querySelector(parentSelector); + if ( parent === null ) { return false; } + parent.append(docFragment); + safe.uboLog(logPrefix, 'Node(s) appended'); + if ( toRemove.length === 0 ) { return true; } + setTimeout(remove, duration); + return true; + }; + if ( append() ) { return; } + const observer = new MutationObserver(( ) => { + if ( append() === false ) { return; } + observer.disconnect(); + }); + observer.observe(document, { childList: true, subtree: true }); +} +registerScriptlet(trustedCreateHTML, { + name: 'trusted-create-html.js', + requiresTrust: true, + dependencies: [ + safeSelf, + ], + world: 'ISOLATED', +}); + +/******************************************************************************/ |