diff options
Diffstat (limited to 'data/extensions/uBlock0@raymondhill.net/js/resources/prevent-innerHTML.js')
-rw-r--r-- | data/extensions/uBlock0@raymondhill.net/js/resources/prevent-innerHTML.js | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/data/extensions/uBlock0@raymondhill.net/js/resources/prevent-innerHTML.js b/data/extensions/uBlock0@raymondhill.net/js/resources/prevent-innerHTML.js new file mode 100644 index 0000000..587ea20 --- /dev/null +++ b/data/extensions/uBlock0@raymondhill.net/js/resources/prevent-innerHTML.js @@ -0,0 +1,82 @@ +/******************************************************************************* + + 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 prevent-innerHTML + * + * @description + * Conditionally prevent assignment to `innerHTML` property. + * + * @param [selector] + * Optional. The element must matches `selector` for the prevention to take + * place. + * + * @param [pattern] + * Optional. A pattern to match against the assigned value. The pattern can be + * a plain string, or a regex. Prepend with `!` to reverse the match condition. + * + * */ + +export function preventInnerHTML( + selector = '', + pattern = '' +) { + const safe = safeSelf(); + const logPrefix = safe.makeLogPrefix('prevent-innerHTML', selector, pattern); + const matcher = safe.initPattern(pattern, { canNegate: true }); + const current = safe.Object_getOwnPropertyDescriptor(Element.prototype, 'innerHTML'); + if ( current === undefined ) { return; } + const shouldPreventSet = (elem, a) => { + if ( selector !== '' ) { + if ( typeof elem.matches !== 'function' ) { return false; } + if ( elem.matches(selector) === false ) { return false; } + } + return safe.testPattern(matcher, a); + }; + Object.defineProperty(Element.prototype, 'innerHTML', { + get: function() { + return current.get + ? current.get.call(this) + : current.value; + }, + set: function(a) { + if ( shouldPreventSet(this, a) ) { + safe.uboLog(logPrefix, 'Prevented'); + } else if ( current.set ) { + current.set.call(this, a); + } + if ( safe.logLevel > 1 ) { + safe.uboLog(logPrefix, `Assigned:\n${a}`); + } + current.value = a; + }, + }); +} +registerScriptlet(preventInnerHTML, { + name: 'prevent-innerHTML.js', + dependencies: [ + safeSelf, + ], +}); |