From c5536577b29cd0bcd401f7ecd143a921acdb4eb6 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Thu, 22 Aug 2019 09:32:46 -0400 Subject: [PATCH] Add two scriptlets: setTimeout-if and setInterval-if Usage is similar to that of raf-if introduced in commit 6831967f5f9d64412a9c063f3b64104d9dce7b07. The two new scriptlets are meant to replace: - setTimeout-defuser - setTimeout-logger - setInterval-defuser - setInterval-logger setTimeout-logger and setInterval-logger have been removed, since they are not to be used in production. To log setTimeout and setInterval usage, respectively (using aliases): - ##+js(stif) - ##+js(siif) To defuse setTimeout unconditionally: - ##+js(stif, !) Usage of setTimeout-defuser and setInterval-defuser is deprecated and will be removed in some future when they are no longer in use. Keep in mind that the new scriptlets function on a whitelist basis, whereas the deprecated ones function on a blacklist basis. Prefixing the needle with `!` allow to use the new scriptlets on a blacklist basis. --- assets/resources/scriptlets.js | 70 ++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/assets/resources/scriptlets.js b/assets/resources/scriptlets.js index 211174406..6411b15c6 100644 --- a/assets/resources/scriptlets.js +++ b/assets/resources/scriptlets.js @@ -407,12 +407,10 @@ needle = new RegExp(needle); window.requestAnimationFrame = new Proxy(window.requestAnimationFrame, { apply: function(target, thisArg, args) { - const a = args[0]; - const s = a.toString(); + const a = String(args[0]); if ( log !== undefined ) { - log('uBO: requestAnimationFrame("%s")', s); - } - if ( needle.test(s) === not ) { + log('uBO: requestAnimationFrame("%s")', a); + } else if ( needle.test(a) === not ) { args[0] = function(){}; } return target.apply(thisArg, args); @@ -528,15 +526,36 @@ })(); -/// setInterval-logger.js -/// alias sil.js +/// setInterval-if.js +/// alias siif.js (function() { - const log = console.log.bind(console); + let needle = '{{1}}'; + const not = needle.charAt(0) === '!'; + if ( not ) { needle = needle.slice(1); } + const delay = parseInt('{{2}}', 10); + if ( needle === '' || needle === '{{1}}' ) { + needle = '.?'; + } else if ( needle.startsWith('/') && needle.endsWith('/') ) { + needle = needle.slice(1,-1); + } else { + needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + } + const log = not === false && needle === '.?' && isNaN(delay) + ? console.log + : undefined; + needle = new RegExp(needle); window.setInterval = new Proxy(window.setInterval, { apply: function(target, thisArg, args) { - const a = args[0]; + const a = String(args[0]); const b = args[1]; - log('uBO: setInterval("%s", %s)', a.toString(), b); + if ( log !== undefined ) { + log('uBO: setInterval("%s", %s)', a, b); + } else if ( + (isNaN(delay) || b === delay) && + needle.test(a) === not + ) { + args[0] = function(){}; + } return target.apply(thisArg, args); } }); @@ -569,15 +588,36 @@ })(); -/// setTimeout-logger.js -/// alias stl.js +/// setTimeout-if.js +/// alias stif.js (function() { - const log = console.log.bind(console); + let needle = '{{1}}'; + const not = needle.charAt(0) === '!'; + if ( not ) { needle = needle.slice(1); } + const delay = parseInt('{{2}}', 10); + if ( needle === '' || needle === '{{1}}' ) { + needle = '.?'; + } else if ( needle.startsWith('/') && needle.endsWith('/') ) { + needle = needle.slice(1,-1); + } else { + needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + } + const log = not === false && needle === '.?' && isNaN(delay) + ? console.log + : undefined; + needle = new RegExp(needle); window.setTimeout = new Proxy(window.setTimeout, { apply: function(target, thisArg, args) { - const a = args[0]; + const a = String(args[0]); const b = args[1]; - log('uBO: setTimeout("%s", %s)', a.toString(), b); + if ( log !== undefined ) { + log('uBO: setTimeout("%s", %s)', a, b); + } else if ( + (isNaN(delay) || b === delay) && + needle.test(a) === not + ) { + args[0] = function(){}; + } return target.apply(thisArg, args); } });