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
`})();
`