Add experimental href-from-text scriptlet · gorhill/uBlock@e123256 (original) (raw)

`@@ -1842,6 +1842,81 @@

`

1842

1842

``

1843

1843

``

1844

1844

``

``

1845

`+

/// href-from-text.js

`

``

1846

`+

(function() {

`

``

1847

`+

let selector = '{{1}}';

`

``

1848

`+

if ( selector === '{{1}}' ) { selector = ''; }

`

``

1849

`+

if ( selector === '' ) { return; }

`

``

1850

`+

const sanitizeCopycats = (href, text) => {

`

``

1851

`+

let elems = [];

`

``

1852

`+

try {

`

``

1853

`` +

elems = document.querySelectorAll(a[href="${href}");

``

``

1854

`+

}

`

``

1855

`+

catch(ex) {

`

``

1856

`+

}

`

``

1857

`+

for ( const elem of elems ) {

`

``

1858

`+

elem.setAttribute('href', text);

`

``

1859

`+

}

`

``

1860

`+

};

`

``

1861

`+

const sanitize = ( ) => {

`

``

1862

`+

let elems = [];

`

``

1863

`+

try {

`

``

1864

`+

elems = document.querySelectorAll(selector);

`

``

1865

`+

}

`

``

1866

`+

catch(ex) {

`

``

1867

`+

return false;

`

``

1868

`+

}

`

``

1869

`+

for ( const elem of elems ) {

`

``

1870

`+

if ( elem.localName !== 'a' ) { continue; }

`

``

1871

`+

if ( elem.hasAttribute('href') === false ) { continue; }

`

``

1872

`+

const href = elem.getAttribute('href');

`

``

1873

`+

const text = elem.textContent

`

``

1874

`+

.replace(/^[^\x21-\x7e]+/, '') // remove leading invalid characters

`

``

1875

`+

.replace(/[^\x21-\x7e]+$/, '') // remove trailing invalid characters

`

``

1876

`+

;

`

``

1877

`+

if ( /^https://./.test(text) === false ) { continue; }

`

``

1878

`+

if ( /[^\x21-\x7e]/.test(text) ) { continue; }

`

``

1879

`+

if ( href === text ) { continue; }

`

``

1880

`+

elem.setAttribute('href', text);

`

``

1881

`+

sanitizeCopycats(href, text);

`

``

1882

`+

}

`

``

1883

`+

return true;

`

``

1884

`+

};

`

``

1885

`+

let observer, timer;

`

``

1886

`+

const onDomChanged = mutations => {

`

``

1887

`+

if ( timer !== undefined ) { return; }

`

``

1888

`+

let shouldSanitize = false;

`

``

1889

`+

for ( const mutation of mutations ) {

`

``

1890

`+

if ( mutation.addedNodes.length === 0 ) { continue; }

`

``

1891

`+

for ( const node of mutation.addedNodes ) {

`

``

1892

`+

if ( node.nodeType !== 1 ) { continue; }

`

``

1893

`+

shouldSanitize = true;

`

``

1894

`+

break;

`

``

1895

`+

}

`

``

1896

`+

if ( shouldSanitize ) { break; }

`

``

1897

`+

}

`

``

1898

`+

if ( shouldSanitize === false ) { return; }

`

``

1899

`+

timer = self.requestAnimationFrame(( ) => {

`

``

1900

`+

timer = undefined;

`

``

1901

`+

sanitize();

`

``

1902

`+

});

`

``

1903

`+

};

`

``

1904

`+

const start = ( ) => {

`

``

1905

`+

if ( sanitize() === false ) { return; }

`

``

1906

`+

observer = new MutationObserver(onDomChanged);

`

``

1907

`+

observer.observe(document.body, {

`

``

1908

`+

subtree: true,

`

``

1909

`+

childList: true,

`

``

1910

`+

});

`

``

1911

`+

};

`

``

1912

`+

if ( document.readyState === 'loading' ) {

`

``

1913

`+

document.addEventListener('DOMContentLoaded', start, { once: true });

`

``

1914

`+

} else {

`

``

1915

`+

start();

`

``

1916

`+

}

`

``

1917

`+

})();

`

``

1918

+

``

1919

+

1845

1920

`// These lines below are skipped by the resource parser.

`

1846

1921

`// <<<< end of private namespace

`

1847

1922

`})();

`