Add remove-node-text.js scriptlet · gorhill/uBlock@2bb4467 (original) (raw)
`@@ -527,6 +527,93 @@ function setConstantCore(
`
527
527
`}, options);
`
528
528
`}
`
529
529
``
``
530
`+
/******************************************************************************/
`
``
531
+
``
532
`+
builtinScriptlets.push({
`
``
533
`+
name: 'replace-node-text-core.fn',
`
``
534
`+
fn: replaceNodeTextCore,
`
``
535
`+
dependencies: [
`
``
536
`+
'get-extra-args.fn',
`
``
537
`+
'pattern-to-regex.fn',
`
``
538
`+
'run-at.fn',
`
``
539
`+
'safe-self.fn',
`
``
540
`+
],
`
``
541
`+
});
`
``
542
`+
function replaceNodeTextCore(
`
``
543
`+
nodeName = '',
`
``
544
`+
pattern = '',
`
``
545
`+
replacement = ''
`
``
546
`+
) {
`
``
547
`+
const reNodeName = patternToRegex(nodeName, 'i');
`
``
548
`+
const rePattern = patternToRegex(pattern, 'gms');
`
``
549
`+
const extraArgs = getExtraArgs(Array.from(arguments), 3);
`
``
550
`+
const shouldLog = scriptletGlobals.has('canDebug') && extraArgs.log || 0;
`
``
551
`+
const reCondition = patternToRegex(extraArgs.condition || '', 'gms');
`
``
552
`+
const safe = safeSelf();
`
``
553
`+
const stop = (takeRecord = true) => {
`
``
554
`+
if ( takeRecord ) {
`
``
555
`+
handleMutations(observer.takeRecords());
`
``
556
`+
}
`
``
557
`+
observer.disconnect();
`
``
558
`+
if ( shouldLog !== 0 ) {
`
``
559
`` +
safe.uboLog(sed.js: quitting "${pattern}" => "${replacement}");
``
``
560
`+
}
`
``
561
`+
};
`
``
562
`+
let sedCount = extraArgs.sedCount || 0;
`
``
563
`+
const handleNode = node => {
`
``
564
`+
const before = node.textContent;
`
``
565
`+
if ( safe.RegExp_test.call(rePattern, before) === false ) { return true; }
`
``
566
`+
if ( safe.RegExp_test.call(reCondition, before) === false ) { return true; }
`
``
567
`+
const after = pattern !== ''
`
``
568
`+
? before.replace(rePattern, replacement)
`
``
569
`+
: replacement;
`
``
570
`+
node.textContent = after;
`
``
571
`+
if ( shouldLog !== 0 ) {
`
``
572
`+
safe.uboLog('sed.js before:\n', before);
`
``
573
`+
safe.uboLog('sed.js after:\n', after);
`
``
574
`+
}
`
``
575
`+
return sedCount === 0 || (sedCount -= 1) !== 0;
`
``
576
`+
};
`
``
577
`+
const handleMutations = mutations => {
`
``
578
`+
for ( const mutation of mutations ) {
`
``
579
`+
for ( const node of mutation.addedNodes ) {
`
``
580
`+
if ( reNodeName.test(node.nodeName) === false ) { continue; }
`
``
581
`+
if ( handleNode(node) ) { continue; }
`
``
582
`+
stop(false); return;
`
``
583
`+
}
`
``
584
`+
}
`
``
585
`+
};
`
``
586
`+
const observer = new MutationObserver(handleMutations);
`
``
587
`+
observer.observe(document, { childList: true, subtree: true });
`
``
588
`+
if ( document.documentElement ) {
`
``
589
`+
const treeWalker = document.createTreeWalker(
`
``
590
`+
document.documentElement,
`
``
591
`+
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT
`
``
592
`+
);
`
``
593
`+
let count = 0;
`
``
594
`+
for (;;) {
`
``
595
`+
const node = treeWalker.nextNode();
`
``
596
`+
count += 1;
`
``
597
`+
if ( node === null ) { break; }
`
``
598
`+
if ( reNodeName.test(node.nodeName) === false ) { continue; }
`
``
599
`+
if ( handleNode(node) ) { continue; }
`
``
600
`+
stop(); break;
`
``
601
`+
}
`
``
602
`+
if ( shouldLog !== 0 ) {
`
``
603
`` +
safe.uboLog(sed.js ${count} nodes present before installing mutation observer);
``
``
604
`+
}
`
``
605
`+
}
`
``
606
`+
if ( extraArgs.stay ) { return; }
`
``
607
`+
runAt(( ) => {
`
``
608
`+
const quitAfter = extraArgs.quitAfter || 0;
`
``
609
`+
if ( quitAfter !== 0 ) {
`
``
610
`+
setTimeout(( ) => { stop(); }, quitAfter);
`
``
611
`+
} else {
`
``
612
`+
stop();
`
``
613
`+
}
`
``
614
`+
}, 'interactive');
`
``
615
`+
}
`
``
616
+
530
617
`/*******************************************************************************
`
531
618
``
532
619
` Injectable scriptlets
`
`@@ -2304,6 +2391,25 @@ function spoofCSS(
`
2304
2391
`});
`
2305
2392
`}
`
2306
2393
``
``
2394
`+
/******************************************************************************/
`
``
2395
+
``
2396
`+
builtinScriptlets.push({
`
``
2397
`+
name: 'remove-node-text.js',
`
``
2398
`+
aliases: [ 'rmnt.js' ],
`
``
2399
`+
fn: removeNodeText,
`
``
2400
`+
world: 'ISOLATED',
`
``
2401
`+
dependencies: [
`
``
2402
`+
'replace-node-text-core.fn',
`
``
2403
`+
],
`
``
2404
`+
});
`
``
2405
`+
function removeNodeText(
`
``
2406
`+
nodeName,
`
``
2407
`+
condition,
`
``
2408
`+
...extraArgs
`
``
2409
`+
) {
`
``
2410
`+
replaceNodeTextCore(nodeName, '', '', 'condition', condition || '', ...extraArgs);
`
``
2411
`+
}
`
``
2412
+
2307
2413
`/*******************************************************************************
`
2308
2414
` *
`
2309
2415
` * Scriplets below this section are only available for filter lists from
`
`@@ -2343,87 +2449,20 @@ function spoofCSS(
`
2343
2449
`builtinScriptlets.push({
`
2344
2450
`name: 'replace-node-text.js',
`
2345
2451
`requiresTrust: true,
`
2346
``
`-
aliases: [ 'rnt.js', 'sed.js' /* to be removed */ ],
`
``
2452
`+
aliases: [ 'rpnt.js', 'sed.js' /* to be removed */ ],
`
2347
2453
`fn: replaceNodeText,
`
2348
2454
`world: 'ISOLATED',
`
2349
2455
`dependencies: [
`
2350
``
`-
'get-extra-args.fn',
`
2351
``
`-
'pattern-to-regex.fn',
`
2352
``
`-
'run-at.fn',
`
2353
``
`-
'safe-self.fn',
`
``
2456
`+
'replace-node-text-core.fn',
`
2354
2457
`],
`
2355
2458
`});
`
2356
2459
`function replaceNodeText(
`
2357
``
`-
nodeName = '',
`
2358
``
`-
pattern = '',
`
2359
``
`-
replacement = ''
`
``
2460
`+
nodeName,
`
``
2461
`+
pattern,
`
``
2462
`+
replacement,
`
``
2463
`+
...extraArgs
`
2360
2464
`) {
`
2361
``
`-
const reNodeName = patternToRegex(nodeName, 'i');
`
2362
``
`-
const rePattern = patternToRegex(pattern, 'gms');
`
2363
``
`-
const extraArgs = getExtraArgs(Array.from(arguments), 3);
`
2364
``
`-
const shouldLog = scriptletGlobals.has('canDebug') && extraArgs.log || 0;
`
2365
``
`-
const reCondition = patternToRegex(extraArgs.condition || '', 'gms');
`
2366
``
`-
const safe = safeSelf();
`
2367
``
`-
const stop = (takeRecord = true) => {
`
2368
``
`-
if ( takeRecord ) {
`
2369
``
`-
handleMutations(observer.takeRecords());
`
2370
``
`-
}
`
2371
``
`-
observer.disconnect();
`
2372
``
`-
if ( shouldLog !== 0 ) {
`
2373
``
`` -
safe.uboLog(sed.js: quitting "${pattern}" => "${replacement}");
``
2374
``
`-
}
`
2375
``
`-
};
`
2376
``
`-
let sedCount = extraArgs.sedCount || 0;
`
2377
``
`-
const handleNode = node => {
`
2378
``
`-
const before = node.textContent;
`
2379
``
`-
if ( safe.RegExp_test.call(rePattern, before) === false ) { return true; }
`
2380
``
`-
if ( safe.RegExp_test.call(reCondition, before) === false ) { return true; }
`
2381
``
`-
const after = before.replace(rePattern, replacement);
`
2382
``
`-
node.textContent = after;
`
2383
``
`-
if ( shouldLog !== 0 ) {
`
2384
``
`-
safe.uboLog('sed.js before:\n', before);
`
2385
``
`-
safe.uboLog('sed.js after:\n', after);
`
2386
``
`-
}
`
2387
``
`-
return sedCount === 0 || (sedCount -= 1) !== 0;
`
2388
``
`-
};
`
2389
``
`-
const handleMutations = mutations => {
`
2390
``
`-
for ( const mutation of mutations ) {
`
2391
``
`-
for ( const node of mutation.addedNodes ) {
`
2392
``
`-
if ( reNodeName.test(node.nodeName) === false ) { continue; }
`
2393
``
`-
if ( handleNode(node) ) { continue; }
`
2394
``
`-
stop(false); return;
`
2395
``
`-
}
`
2396
``
`-
}
`
2397
``
`-
};
`
2398
``
`-
const observer = new MutationObserver(handleMutations);
`
2399
``
`-
observer.observe(document, { childList: true, subtree: true });
`
2400
``
`-
if ( document.documentElement ) {
`
2401
``
`-
const treeWalker = document.createTreeWalker(
`
2402
``
`-
document.documentElement,
`
2403
``
`-
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT
`
2404
``
`-
);
`
2405
``
`-
let count = 0;
`
2406
``
`-
for (;;) {
`
2407
``
`-
const node = treeWalker.nextNode();
`
2408
``
`-
count += 1;
`
2409
``
`-
if ( node === null ) { break; }
`
2410
``
`-
if ( reNodeName.test(node.nodeName) === false ) { continue; }
`
2411
``
`-
if ( handleNode(node) ) { continue; }
`
2412
``
`-
stop(); break;
`
2413
``
`-
}
`
2414
``
`-
if ( shouldLog !== 0 ) {
`
2415
``
`` -
safe.uboLog(sed.js ${count} nodes present before installing mutation observer);
``
2416
``
`-
}
`
2417
``
`-
}
`
2418
``
`-
if ( extraArgs.stay ) { return; }
`
2419
``
`-
runAt(( ) => {
`
2420
``
`-
const quitAfter = extraArgs.quitAfter || 0;
`
2421
``
`-
if ( quitAfter !== 0 ) {
`
2422
``
`-
setTimeout(( ) => { stop(); }, quitAfter);
`
2423
``
`-
} else {
`
2424
``
`-
stop();
`
2425
``
`-
}
`
2426
``
`-
}, 'interactive');
`
``
2465
`+
replaceNodeTextCore(nodeName, pattern, replacement, ...extraArgs);
`
2427
2466
`}
`
2428
2467
``
2429
2468
`/*******************************************************************************
`