{"version":3,"file":"yett.min.js","sources":["../src/checks.js","../src/variables.js","../src/observer.js","../src/monkey.js","../src/unblock.js"],"sourcesContent":["import { patterns, TYPE_ATTRIBUTE } from './variables'\n\nexport const isOnBlacklist = (src, type) => (\n src &&\n (!type || type !== TYPE_ATTRIBUTE) &&\n (\n (!patterns.blacklist || patterns.blacklist.some(pattern => pattern.test(src))) &&\n (!patterns.whitelist || patterns.whitelist.every(pattern => !pattern.test(src)))\n )\n)\n\nexport const willBeUnblocked = function(script) {\n const src = script.getAttribute('src')\n return (\n patterns.blacklist && patterns.blacklist.every(entry => !entry.test(src)) ||\n patterns.whitelist && patterns.whitelist.some(entry => entry.test(src))\n )\n}","export const TYPE_ATTRIBUTE = 'javascript/blocked'\n\nexport const patterns = {\n blacklist: window.YETT_BLACKLIST,\n whitelist: window.YETT_WHITELIST\n}\n\n// Backup list containing the original blacklisted script elements\nexport const backupScripts = {\n blacklisted: []\n}","import { backupScripts, TYPE_ATTRIBUTE } from './variables'\nimport { isOnBlacklist } from './checks'\n\n// Setup a mutation observer to track DOM insertion\nexport const observer = new MutationObserver(mutations => {\n for (let i = 0; i < mutations.length; i++) {\n const { addedNodes } = mutations[i];\n for(let i = 0; i < addedNodes.length; i++) {\n const node = addedNodes[i]\n // For each added script tag\n if(node.nodeType === 1 && node.tagName === 'SCRIPT') {\n const src = node.src\n const type = node.type\n // If the src is inside the blacklist and is not inside the whitelist\n if(isOnBlacklist(src, type)) {\n // We backup the node\n backupScripts.blacklisted.push([node, node.type])\n\n // Blocks inline script execution in Safari & Chrome\n node.type = TYPE_ATTRIBUTE\n\n // Firefox has this additional event which prevents scripts from beeing executed\n const beforeScriptExecuteListener = function (event) {\n // Prevent only marked scripts from executing\n if(node.getAttribute('type') === TYPE_ATTRIBUTE)\n event.preventDefault()\n node.removeEventListener('beforescriptexecute', beforeScriptExecuteListener)\n }\n node.addEventListener('beforescriptexecute', beforeScriptExecuteListener)\n\n // Remove the node from the DOM\n node.parentElement && node.parentElement.removeChild(node)\n }\n }\n }\n }\n})\n\n// Starts the monitoring\nobserver.observe(document.documentElement, {\n childList: true,\n subtree: true\n})","import { TYPE_ATTRIBUTE } from './variables'\nimport { isOnBlacklist } from './checks'\n\nconst createElementBackup = document.createElement\n\nconst originalDescriptors = {\n src: Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'src'),\n type: Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'type')\n}\n\n// Monkey patch the createElement method to prevent dynamic scripts from executing\ndocument.createElement = function(...args) {\n // If this is not a script tag, bypass\n if(args[0].toLowerCase() !== 'script')\n return createElementBackup.bind(document)(...args)\n\n const scriptElt = createElementBackup.bind(document)(...args)\n\n // Define getters / setters to ensure that the script type is properly set\n try {\n Object.defineProperties(scriptElt, {\n 'src': {\n get() {\n return originalDescriptors.src.get.call(this)\n },\n set(value) {\n if(isOnBlacklist(value, scriptElt.type)) {\n originalDescriptors.type.set.call(this, TYPE_ATTRIBUTE)\n }\n originalDescriptors.src.set.call(this, value)\n }\n },\n 'type': {\n set(value) {\n const typeValue = isOnBlacklist(scriptElt.src, scriptElt.type) ? TYPE_ATTRIBUTE : value\n originalDescriptors.type.set.call(this, typeValue)\n }\n }\n })\n\n // Monkey patch the setAttribute function so that the setter is called instead\n scriptElt.setAttribute = function(name, value) {\n if(name === 'type' || name === 'src')\n scriptElt[name] = value\n else\n HTMLScriptElement.prototype.setAttribute.call(scriptElt, name, value)\n }\n } catch (error) {\n // eslint-disable-next-line\n console.warn(\n 'Yett: unable to prevent script execution for script src ', scriptElt.src, '.\\n',\n 'A likely cause would be because you are using a third-party browser extension that monkey patches the \"document.createElement\" function.'\n )\n }\n return scriptElt\n}","import {\n patterns,\n backupScripts,\n TYPE_ATTRIBUTE\n} from './variables'\n\nimport {\n willBeUnblocked\n} from './checks'\n\nimport {\n observer\n} from './observer'\n\nconst URL_REPLACER_REGEXP = new RegExp('[|\\\\{}()[\\\\]^$+*?.]', 'g')\n\n// Unblocks all (or a selection of) blacklisted scripts.\nexport const unblock = function(...scriptUrlsOrRegexes) {\n if(scriptUrlsOrRegexes.length < 1) {\n patterns.blacklist = []\n patterns.whitelist = []\n } else {\n if(patterns.blacklist) {\n patterns.blacklist = patterns.blacklist.filter(pattern => (\n scriptUrlsOrRegexes.every(urlOrRegexp => {\n if(typeof urlOrRegexp === 'string')\n return !pattern.test(urlOrRegexp)\n else if(urlOrRegexp instanceof RegExp)\n return pattern.toString() !== urlOrRegexp.toString()\n })\n ))\n }\n if(patterns.whitelist) {\n patterns.whitelist = [\n ...patterns.whitelist,\n ...scriptUrlsOrRegexes\n .map(urlOrRegexp => {\n if(typeof urlOrRegexp === 'string') {\n const escapedUrl = urlOrRegexp.replace(URL_REPLACER_REGEXP, '\\\\$&')\n const permissiveRegexp = '.*' + escapedUrl + '.*'\n if(patterns.whitelist.every(p => p.toString() !== permissiveRegexp.toString())) {\n return new RegExp(permissiveRegexp)\n }\n } else if(urlOrRegexp instanceof RegExp) {\n if(patterns.whitelist.every(p => p.toString() !== urlOrRegexp.toString())) {\n return urlOrRegexp\n }\n }\n return null\n })\n .filter(Boolean)\n ]\n }\n }\n\n\n // Parse existing script tags with a marked type\n const tags = document.querySelectorAll(`script[type=\"${TYPE_ATTRIBUTE}\"]`)\n for(let i = 0; i < tags.length; i++) {\n const script = tags[i]\n if(willBeUnblocked(script)) {\n backupScripts.blacklisted.push([script, 'application/javascript'])\n script.parentElement.removeChild(script)\n }\n }\n\n // Exclude 'whitelisted' scripts from the blacklist and append them to \n let indexOffset = 0;\n [...backupScripts.blacklisted].forEach(([script, type], index) => {\n if(willBeUnblocked(script)) {\n const scriptNode = document.createElement('script')\n scriptNode.setAttribute('src', script.src)\n scriptNode.setAttribute('type', type || 'application/javascript')\n for(let key in script) {\n if(key.startsWith(\"on\")) {\n scriptNode[key] = script[key]\n }\n }\n document.head.appendChild(scriptNode)\n backupScripts.blacklisted.splice(index - indexOffset, 1)\n indexOffset++\n }\n })\n\n // Disconnect the observer if the blacklist is empty for performance reasons\n if(patterns.blacklist && patterns.blacklist.length < 1) {\n observer.disconnect()\n }\n}"],"names":["isOnBlacklist","src","type","TYPE_ATTRIBUTE","patterns","blacklist","some","pattern","test","whitelist","every","willBeUnblocked","script","getAttribute","entry","window","YETT_BLACKLIST","YETT_WHITELIST","backupScripts","blacklisted","observer","MutationObserver","mutations","i","length","addedNodes","node","nodeType","tagName","push","addEventListener","beforeScriptExecuteListener","event","preventDefault","removeEventListener","parentElement","removeChild","observe","document","documentElement","childList","subtree","createElementBackup","createElement","originalDescriptors","Object","getOwnPropertyDescriptor","HTMLScriptElement","prototype","args","toLowerCase","bind","scriptElt","defineProperties","get","call","this","set","value","typeValue","setAttribute","name","error","console","warn","URL_REPLACER_REGEXP","RegExp","scriptUrlsOrRegexes","filter","urlOrRegexp","toString","map","permissiveRegexp","replace","p","Boolean","tags","querySelectorAll","indexOffset","forEach","index","scriptNode","key","startsWith","head","appendChild","splice","disconnect"],"mappings":"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"}