|
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 | })();
|
0 commit comments