PNG  IHDR>a"IDATx]}PTW?w?#(1`@5b- (akl6V%5Im6:Sq 1A HԠD_~w:&1tݯiޯxϽ;s&!(SnVnZGN)S&c_d{a[-gϞ744hdYKKJJ\ ="nW _}(=22Rk.}M&]lEī*C$IM)ͱc4͜,ˏ D(..=3"0s"TL\q7`Zd 68RSSoh4-خ`b)>j߯ = hUUe<ms$~mcc#vCI%KH%%%ne8Q [G$Iza6a͚5#3gδB~Ʋ+EQ|{pp'/-- *++GZOQ`(BDY%7ȲUWn޼i8|3g΄+WڦMf'0Ѯ 'O _|a`` 8uT())qɲ,jF*Wz"v+ AH^p`0 ly~"v[t>˲J vn>R00g`d2;#T,Y e|Gep\qpj fIOOF#v/,{:!!`(s`Xe^/eYfeYB)e)&D(ze9Kr(zf۷4CCC044$d!!99N*&%%9F#tFz|!Dzъ>a2 cYqR cw/^xn7,˂NN 0 h4ِ"Y>hnnV5a|>l`قa4izz :&4hHPobt"4Ä$&jONlZP@ńh0P*(@P*TPP18 0p[9T P:*&jTLD,\Dk6W_}5O `4yx<`/_>N8 O0L`(**Z-hZX, eee`٠BZk'C0w\`Y6(FJKKaѢEphjja?H,5 aڵj"eY?>A}}=twwGFu ;6m6תlٲ/_ъ8 ǁ+Vs=hA5 yyyPSSqK0τ< rssaٲeܡ8݃Nr >u:$''CFFlH֭[s A L\0444ܹoj*D@Dx<a&wށ2{Rw}Kz=,^8f,?'ZZZ.vÇ~~.^t:]$,`_CBSJp…1 -`9 2 ^0߿?,9Rؽ{7c[TTxXȲlB>VvÑ#G,c2 --MwBD8-F+.̙3ӌ ދdYs)2/2tvvY&55UzHg%Yx&_lw$%%)JY= ,x&`d  wA_|&6ɾLA8B&u.؆ @) ,$$$DMLDgX,, C:Xud,O۷[˲B&!dR6-T(,,T$%0 YF;M&:lVl(hفl6C~~~߫%:Y8o4iJoWZl P^^>f `tcKx`0h`:vB@V`ƍa jjjd2Y]ѭdz Zv^^޸ʗ@mmmPÁ P[[ .[ӊM15t!|$B1cƍ~ PXX8n3͞=^x(..(``۶m~|V45 zvYf5ܺu v#6m<~P^4RRR ///(?܁֭e˖s, w8[oJ)+~)c=,_ l@`3))@ʲ gϞ%K APZZ awȑV$`3 Rҙ"*ǏGdä4ѣkԩ.BHRRRJ5p@SSSĔq!X}]]]{ bX|p1lCt$&&jYU ض61c"Y*ķP^^\J)@cccĔϲ,L2E $U'Z,͛7={(F.سge477Ý;w :NػwoDMdYY \J~dΝp5(++ ۊpĉ}/ŋzpi8|0m4$3mxy|ƌO>}Z5RhmmsE`ܹAphmm1&A>38y$,ZjB{{;8qBy~1cMb*V7|3?8L>, h4'7napp0(!--[ęLogZΝ;W\8&^rƍV -FQk0"pYa``ԩSR 7n𛥌5 0 Z86xTrА <"NAvjW&]bYެ,V=9,qdffr U233A/ "v+i,..v][(..9{QVaeee%7TZ-<08WzJ=@2F0o?uFE [lqr"̰ieSRR.^ڣJTTTxMvpdN Ȫ‹b s%mV^UaBnn.tB"bXO !KkjjF-¿_SS !pWcCij՛7ovdeeZ P[[ #"'J(zct$I ӷ9sB*D!pN"Sn'?֍Lhzrdff Ɣ#F)%^eY_njjҶ-R@D3g0;< "c܉L{^g)))qFlj, Iz^}CC&XtpB`Yv{(KU|<&y .T۳gurWh!uO8ORZ"-3ܹs'ILLj{jjFsDlPD)$I?.466j]=n<K,KJJ$~0ہϯ D0_QJ|'OiEE h4DøHPJDQ|oddd޽{ԓׯL/5͏k]\e(e(~p膇"`0@yy#''Ny㸝gqEQ"UyX xVX!!oK.8ZĢ" 0Es^%2DHx { // >>>>>>>> start of private namespace /******************************************************************************/ if ( typeof vAPI !== 'object' ) { return; } if ( vAPI.domWatcher instanceof Object === false ) { return; } const reHasCSSCombinators = /[ >+~]/; const simpleDeclarativeSet = new Set(); let simpleDeclarativeStr; const complexDeclarativeSet = new Set(); let complexDeclarativeStr; const proceduralDict = new Map(); const exceptionDict = new Map(); let exceptionStr; const proceduralExceptionDict = new Map(); const nodesToProcess = new Set(); const loggedSelectors = new Set(); /******************************************************************************/ const rePseudoElements = /:(?::?after|:?before|:[a-z-]+)$/; function hasSelector(selector, context = document) { try { return context.querySelector(selector) !== null; } catch(ex) { } return false; } function safeMatchSelector(selector, context) { const safeSelector = rePseudoElements.test(selector) ? selector.replace(rePseudoElements, '') : selector; try { return context.matches(safeSelector); } catch(ex) { } return false; } function safeQuerySelector(selector, context = document) { const safeSelector = rePseudoElements.test(selector) ? selector.replace(rePseudoElements, '') : selector; try { return context.querySelector(safeSelector); } catch(ex) { } return null; } function safeGroupSelectors(selectors) { const arr = Array.isArray(selectors) ? selectors : Array.from(selectors); return arr.map(s => { return rePseudoElements.test(s) ? s.replace(rePseudoElements, '') : s; }).join(',\n'); } /******************************************************************************/ function processDeclarativeSimple(node, out) { if ( simpleDeclarativeSet.size === 0 ) { return; } if ( simpleDeclarativeStr === undefined ) { simpleDeclarativeStr = safeGroupSelectors(simpleDeclarativeSet); } if ( (node === document || node.matches(simpleDeclarativeStr) === false) && (hasSelector(simpleDeclarativeStr, node) === false) ) { return; } for ( const selector of simpleDeclarativeSet ) { if ( (node === document || safeMatchSelector(selector, node) === false) && (safeQuerySelector(selector, node) === null) ) { continue; } out.push(`##${selector}`); simpleDeclarativeSet.delete(selector); simpleDeclarativeStr = undefined; loggedSelectors.add(selector); } } /******************************************************************************/ function processDeclarativeComplex(out) { if ( complexDeclarativeSet.size === 0 ) { return; } if ( complexDeclarativeStr === undefined ) { complexDeclarativeStr = safeGroupSelectors(complexDeclarativeSet); } if ( hasSelector(complexDeclarativeStr) === false ) { return; } for ( const selector of complexDeclarativeSet ) { if ( safeQuerySelector(selector) === null ) { continue; } out.push(`##${selector}`); complexDeclarativeSet.delete(selector); complexDeclarativeStr = undefined; loggedSelectors.add(selector); } } /******************************************************************************/ function processProcedural(out) { if ( proceduralDict.size === 0 ) { return; } for ( const [ raw, pselector ] of proceduralDict ) { if ( pselector.converted ) { if ( safeQuerySelector(pselector.selector) === null ) { continue; } } else if ( pselector.hit === false && pselector.exec().length === 0 ) { continue; } out.push(`##${raw}`); proceduralDict.delete(raw); } } /******************************************************************************/ function processExceptions(out) { if ( exceptionDict.size === 0 ) { return; } if ( exceptionStr === undefined ) { exceptionStr = safeGroupSelectors(exceptionDict.keys()); } if ( hasSelector(exceptionStr) === false ) { return; } for ( const [ selector, raw ] of exceptionDict ) { if ( safeQuerySelector(selector) === null ) { continue; } out.push(`#@#${raw}`); exceptionDict.delete(selector); exceptionStr = undefined; loggedSelectors.add(raw); } } /******************************************************************************/ function processProceduralExceptions(out) { if ( proceduralExceptionDict.size === 0 ) { return; } for ( const exception of proceduralExceptionDict.values() ) { if ( exception.test() === false ) { continue; } out.push(`#@#${exception.raw}`); proceduralExceptionDict.delete(exception.raw); } } /******************************************************************************/ const processTimer = new vAPI.SafeAnimationFrame(( ) => { //console.time('dom logger/scanning for matches'); processTimer.clear(); if ( nodesToProcess.size === 0 ) { return; } if ( nodesToProcess.size !== 1 && nodesToProcess.has(document) ) { nodesToProcess.clear(); nodesToProcess.add(document); } const toLog = []; if ( simpleDeclarativeSet.size !== 0 ) { for ( const node of nodesToProcess ) { processDeclarativeSimple(node, toLog); } } processDeclarativeComplex(toLog); processProcedural(toLog); processExceptions(toLog); processProceduralExceptions(toLog); nodesToProcess.clear(); if ( toLog.length === 0 ) { return; } const location = vAPI.effectiveSelf.location; vAPI.messaging.send('scriptlets', { what: 'logCosmeticFilteringData', frameURL: location.href, frameHostname: location.hostname, matchedSelectors: toLog, }); //console.timeEnd('dom logger/scanning for matches'); }); /******************************************************************************/ const attributeObserver = new MutationObserver(mutations => { if ( nodesToProcess.has(document) ) { return; } for ( const mutation of mutations ) { const node = mutation.target; if ( node.nodeType !== 1 ) { continue; } nodesToProcess.add(node); } if ( nodesToProcess.size !== 0 ) { processTimer.start(100); } }); /******************************************************************************/ const handlers = { onFiltersetChanged: function(changes) { //console.time('dom logger/filterset changed'); for ( const block of (changes.declarative || []) ) { for ( const selector of block.split(',\n') ) { if ( loggedSelectors.has(selector) ) { continue; } if ( reHasCSSCombinators.test(selector) ) { complexDeclarativeSet.add(selector); complexDeclarativeStr = undefined; } else { simpleDeclarativeSet.add(selector); simpleDeclarativeStr = undefined; } } } if ( Array.isArray(changes.procedural) && changes.procedural.length !== 0 ) { for ( const selector of changes.procedural ) { proceduralDict.set(selector.raw, selector); } } if ( Array.isArray(changes.exceptions) ) { for ( const selector of changes.exceptions ) { if ( loggedSelectors.has(selector) ) { continue; } if ( selector.charCodeAt(0) !== 0x7B /* '{' */ ) { exceptionDict.set(selector, selector); continue; } const details = JSON.parse(selector); if ( details.action !== undefined && details.tasks === undefined && details.action[0] === 'style' ) { exceptionDict.set(details.selector, details.raw); continue; } proceduralExceptionDict.set( details.raw, vAPI.domFilterer.createProceduralFilter(details) ); } exceptionStr = undefined; } nodesToProcess.clear(); nodesToProcess.add(document); processTimer.start(1); //console.timeEnd('dom logger/filterset changed'); }, onDOMCreated: function() { if ( vAPI.domFilterer instanceof Object === false ) { return shutdown(); } handlers.onFiltersetChanged(vAPI.domFilterer.getAllSelectors()); vAPI.domFilterer.addListener(handlers); attributeObserver.observe(document.body, { attributes: true, subtree: true }); }, onDOMChanged: function(addedNodes) { if ( nodesToProcess.has(document) ) { return; } for ( const node of addedNodes ) { if ( node.parentNode === null ) { continue; } nodesToProcess.add(node); } if ( nodesToProcess.size !== 0 ) { processTimer.start(100); } } }; vAPI.domWatcher.addListener(handlers); /******************************************************************************/ const broadcastHandler = msg => { if ( msg.what === 'loggerDisabled' ) { shutdown(); } }; browser.runtime.onMessage.addListener(broadcastHandler); /******************************************************************************/ function shutdown() { browser.runtime.onMessage.removeListener(broadcastHandler); processTimer.clear(); attributeObserver.disconnect(); if ( typeof vAPI !== 'object' ) { return; } if ( vAPI.domFilterer instanceof Object ) { vAPI.domFilterer.removeListener(handlers); } if ( vAPI.domWatcher instanceof Object ) { vAPI.domWatcher.removeListener(handlers); } } /******************************************************************************/ // <<<<<<<< end of private namespace })(); /******************************************************************************* DO NOT: - Remove the following code - Add code beyond the following code Reason: - https://github.com/gorhill/uBlock/pull/3721 - uBO never uses the return value from injected content scripts **/ void 0;