/******************************************************************************* uBlock Origin - a browser extension to block requests. Copyright (C) 2019-present Raymond Hill This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see {http://www.gnu.org/licenses/}. Home: https://github.com/gorhill/uBlock The scriptlets below are meant to be injected only into a web page context. */ /* jshint esversion:11 */ 'use strict'; /******************************************************************************/ /// name no-fetch-if /******************************************************************************/ // Important! // Isolate from global scope (function uBOL_noFetchIf() { /******************************************************************************/ // $rulesetId$ const argsList = self.$argsList$; const hostnamesMap = new Map(self.$hostnamesMap$); /******************************************************************************/ const scriptlet = ( conditions = '' ) => { const needles = []; for ( const condition of conditions.split(/\s+/) ) { if ( condition === '' ) { continue; } const pos = condition.indexOf(':'); let key, value; if ( pos !== -1 ) { key = condition.slice(0, pos); value = condition.slice(pos + 1); } else { key = 'url'; value = condition; } if ( value === '' ) { value = '^'; } else if ( value.startsWith('/') && value.endsWith('/') ) { value = value.slice(1, -1); } else { value = value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } needles.push({ key, re: new RegExp(value) }); } self.fetch = new Proxy(self.fetch, { apply: function(target, thisArg, args) { let proceed = true; try { let details; if ( args[0] instanceof self.Request ) { details = args[0]; } else { details = Object.assign({ url: args[0] }, args[1]); } const props = new Map(); for ( const prop in details ) { let v = details[prop]; if ( typeof v !== 'string' ) { try { v = JSON.stringify(v); } catch(ex) { } } if ( typeof v !== 'string' ) { continue; } props.set(prop, v); } proceed = needles.length === 0; for ( const { key, re } of needles ) { if ( props.has(key) === false || re.test(props.get(key)) === false ) { proceed = true; break; } } } catch(ex) { } return proceed ? Reflect.apply(target, thisArg, args) : Promise.resolve(new Response()); } }); }; /******************************************************************************/ let hn; try { hn = document.location.hostname; } catch(ex) { } while ( hn ) { if ( hostnamesMap.has(hn) ) { let argsIndices = hostnamesMap.get(hn); if ( typeof argsIndices === 'number' ) { argsIndices = [ argsIndices ]; } for ( const argsIndex of argsIndices ) { const details = argsList[argsIndex]; if ( details.n && details.n.includes(hn) ) { continue; } try { scriptlet(...details.a); } catch(ex) {} } } if ( hn === '*' ) { break; } const pos = hn.indexOf('.'); if ( pos !== -1 ) { hn = hn.slice(pos + 1); } else { hn = '*'; } } argsList.length = 0; hostnamesMap.clear(); /******************************************************************************/ })(); /******************************************************************************/