1const allowContentElementButtons = document.querySelectorAll('.bw-cb-blocked button') 2const blockedContentElements = document.querySelectorAll('.bw-cb-blocked') 3 4/** 5 * Allows a new hostname 6 * 7 * @param {string} hostname The hostname 8 */ 9const addHostToAllowlist = (hostname) => { 10 let hostnames = getAllowedHosts() 11 12 if (!hostnames.includes(hostname)) { 13 hostnames.push(hostname) 14 } 15 16 persistHostnamesInCookie(hostnames) 17} 18 19/** 20 * Removes a hostname from the allowlist 21 * 22 * @param {string} hostname The hostname 23 */ 24const removeHostFromAllowlist = (hostname) => { 25 let hostnames = getAllowedHosts() 26 27 hostnames = hostnames.filter((value, index, arr) => { 28 if (value !== hostname) { 29 return value 30 } 31 }) 32 33 persistHostnamesInCookie(hostnames) 34} 35 36/** 37 * Returns the allowed hostnames 38 * 39 * @returns {array} The allowed hostnames 40 */ 41const getAllowedHosts = () => { 42 const cookies = document.cookie.split('; ') 43 let allowedHostnames = [] 44 45 cookies.forEach(cookie => { 46 const name = cookie.split('=')[0] 47 const value = cookie.split('=')[1] 48 49 if (name === 'allow_list') { 50 allowedHostnames = JSON.parse(value) 51 } 52 }) 53 54 return allowedHostnames 55} 56 57/** 58 * Writes a cookie with the given hostnames 59 * 60 * @param {array} hostnames 61 */ 62const persistHostnamesInCookie = (hostnames) => { 63 const date = new Date() 64 date.setTime(date.getTime() + 31536000000) // One year 65 document.cookie = `allow_list=${JSON.stringify(hostnames)}; expires=${date.toGMTString()}; path=/` 66} 67 68if (allowContentElementButtons && blockedContentElements) { 69 allowContentElementButtons.forEach(element => { 70 element.addEventListener('click', event => { 71 // Add original attributes to new element 72 const tagName = event.target.parentElement.parentElement.getAttribute('data-node-name') 73 const attributes = event.target.parentElement.parentElement.attributes 74 const element = document.createElement(tagName) 75 76 for (let i = 0; i < attributes.length; i++) { 77 element.setAttribute( 78 attributes[i].nodeName.replace('data-attribute-', ''), 79 attributes[i].nodeValue 80 ) 81 } 82 83 event.target.parentElement.parentElement.replaceWith(element) 84 85 // Allow all other elements with that domain 86 if (event.isTrusted) { 87 const hostname = event.target.parentElement.querySelector('.bw-cb-blocked-host').innerText 88 addHostToAllowlist(hostname) 89 90 blockedContentElements.forEach(element => { 91 const host = element.querySelector('.bw-cb-blocked-host').innerText 92 const allowButton = element.querySelector('button') 93 94 // Restore css for iframe styling 95 if (element.parentElement) { 96 if (element.parentElement.classList.contains('video-embed')) { 97 element.parentElement.classList.remove('blocked') 98 } 99 } 100 101 if (host === hostname) { 102 allowButton.click() 103 } 104 }) 105 } 106 }) 107 }) 108 109 const allowedHostnames = getAllowedHosts() 110 blockedContentElements.forEach(element => { 111 // Enable all previously allowed elements 112 const hostname = element.querySelector('.bw-cb-blocked-host').textContent 113 114 if (allowedHostnames.includes(hostname)) { 115 116 element.querySelector('button').click() 117 } 118 }) 119}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.