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

`/*******************************************************************************

`