├── .github ├── ISSUE_TEMPLATE.TXT ├── PULL_REQUEST_TEMPLATE.TXT └── pull.yml ├── .gitignore ├── .travis.yml ├── Extension Compiler ├── updates.json └── version-update.py ├── LICENSE ├── README.MD ├── docs ├── index.css └── index.html ├── domainExtractor.py ├── domainList.txt ├── list ├── 1-header.txt ├── 2-integration.txt ├── 3-rules.txt ├── 4-generichide.txt ├── 5-whitelist.txt └── 6-other.txt ├── notes ├── extension-development.md └── issue-reporter.md ├── screenshot.png ├── src ├── background │ ├── core.js │ ├── debug.js │ └── rules.js ├── common.js ├── content │ ├── core.js │ ├── debug.js │ ├── rules-common.js │ ├── rules-specific.js │ ├── rules-sticky.js │ └── ubo-extra.js ├── icon128.png ├── libdom.js ├── manifest.json ├── platform │ ├── chromium-vars.js │ ├── edge-content.js │ ├── edge-vars.js │ ├── firefox-background.js │ ├── firefox-content.js │ └── firefox-vars.js ├── popup │ ├── index.css │ ├── index.html │ └── index.js └── resources │ ├── blank.mp4 │ ├── fw.js │ ├── ima3.js │ └── jquery.js ├── tests ├── check-syntax.js ├── promise-fs.js └── tests-main.js └── uBlockProtectorList.txt /.github/ISSUE_TEMPLATE.TXT: -------------------------------------------------------------------------------- 1 | 5 | ### Test link (required): 6 | 9 | 10 | 11 | ### Screenshot of the web page (including address bar and extension icons) (required): 12 | 16 | 17 | 18 | ### Screenshot of the console (press `F12` to bring up the console) (required): 19 | 22 | 23 | 24 | ### Explain what was not right (optional if obvious): 25 | 26 | 27 | ### Reproduction steps (optional if trivial): 28 | 29 | 30 | ### Environment (Required): 31 | 32 | - Operating System and Version: 33 | - Browser and Version: 34 | - Adblocker and Version: 35 | - Nano Defender Version: 36 | 37 | 38 | #### Your filter lists (Required): 39 | 42 | 43 | 44 | #### Your custom filters (Required if you have any): 45 | 46 | 47 | #### Your other extensions (Required if you have any): 48 | 49 | 50 | ### Add everything else that you believe to be useful below (optional): 51 | 52 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.TXT: -------------------------------------------------------------------------------- 1 | ### Explain why is this change needed (required): 2 | 3 | 4 | ### Test link (if applicable): 5 | 6 | 7 | ### Screenshots and reproduction steps (if applicable): 8 | 9 | 10 | ### Issues that are related (if applicable): 11 | 12 | 13 | ### Add everything else that you believe to be useful below (optional): 14 | 15 | -------------------------------------------------------------------------------- /.github/pull.yml: -------------------------------------------------------------------------------- 1 | version: "1" 2 | rules: 3 | - base: master 4 | upstream: jspenguin2017:master 5 | autoMerge: false 6 | autoMergeHardReset: false 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | git: 2 | depth: 1 3 | language: node_js 4 | node_js: node 5 | cache: 6 | directories: 7 | - node_modules 8 | before_script: 9 | - npm install esprima 10 | script: 11 | - npm ls 12 | - node ./tests/tests-main.js 13 | -------------------------------------------------------------------------------- /Extension Compiler/updates.json: -------------------------------------------------------------------------------- 1 | { 2 | "addons": { 3 | "{f9cacf2e-cafc-4f0f-b6ad-8e1a01b4b4d0}": { 4 | "updates": [ 5 | { 6 | "version": "15.0.0.206", 7 | "applications": { "gecko": { "strict_min_version": "55.0" } }, 8 | "update_link": "https://github.com/LiCybora/NanoDefenderFirefox/releases/download/v15.0.0.206/nano_defender_pro-15.0.0.206-an+fx.xpi" 9 | } 10 | ] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Extension Compiler/version-update.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | moz_id = "{f9cacf2e-cafc-4f0f-b6ad-8e1a01b4b4d0}"; 4 | 5 | with open("updates.json", 'r') as v: 6 | data = v.read() 7 | info = json.loads(data) 8 | old_version = info["addons"][moz_id]["updates"][0]["version"] 9 | 10 | with open("../src/manifest.json", 'r') as f: 11 | new_version = json.load(f)["version"] 12 | 13 | data = data.replace(old_version, new_version) 14 | 15 | with open("updates.json", 'w') as v: 16 | v.write(data) 17 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Important Announcements Regarding Recent Changes 2 | 3 | **Important: As of v15.0.0.206, this port has NO RELATIONSHIP to upstream anymore. Any product released as Nano Defender on everywhere else other than AMO and this repository are not related to me! My account on both AMO and GitHub are LiCybora. Note that the product name is `Nano Defender for Firefox` and `Nano Defender Pro` on AMO and GitHub respectively, not `Nano Defender`!** 4 | 5 | The project is now 100% independent as upstream is archived. Any other product named Nano Defender has no relationship to me. 6 | 7 | For more information, please read [my thread](https://github.com/LiCybora/NanoDefenderFirefox/issues/187) and announcements from upstream [here](https://github.com/NanoAdblocker/NanoCore/issues/362) 8 | 9 | # Nano Defender for Firefox 10 | 11 | An anti-adblock defuser for Nano Adblocker and uBlock Origin on Firefox 12 | 13 | ![Popup Panel Screenshot](https://raw.githubusercontent.com/LiCybora/NanoDefenderFirefox/master/screenshot.png) 14 | 15 | ## About Firefox port 16 | 17 | The source code of this project is shared from [upstream](https://github.com/jspenguin2017/uBlockProtector). 18 | 19 | As of v15.0.0.206, Nano Defender for Firefox is independent from any entites or people. Note that the product name is `Nano Defender for Firefox` and `Nano Defender Pro` on AMO and GitHub respectively, not `Nano Defender`! 20 | 21 | For issues other than filter issues found on Firefox port, it is recommended to report [here](https://github.com/LiCybora/NanoDefenderFirefox/issues). 22 | 23 | ### Notable changes 24 | 25 | #### Disable console log (since v15.0.0.93) 26 | 27 | You may disable console log for this browser session in the popup (see the first row of screenshot). This option will turn on again when you restart browser session. Please note that console filtering with -[Nano] will **NOT** work for Firefox. 28 | 29 | ## Installation 30 | 31 | Nano Defender can only protect either [Nano Adblocker](https://github.com/LiCybora/NanoCoreFirefox) or [uBlock Origin](https://github.com/gorhill/ublock), and will prioritize Nano Adblocker. As of 17 Oct 2020, Nano Adblocker is no more. 32 | 33 | ### [Get Nano Defender Pro (for Waterfox/Firefox 55 or above)](https://github.com/LiCybora/NanoDefenderFirefox/releases/) 34 | 35 | ### [Get Nano Defender for Firefox on AMO (Recommend, ONLY for Firefox 60 or above)](https://addons.mozilla.org/en-US/firefox/addon/nano-defender-firefox/) 36 | 37 | The 'Pro' version will strictly follow the Pro version in upstream, while the 'for Firefox' version may add/replace rules with [Firefox-specific API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/filterResponseData), or [remove the potential dangerous rules](https://extensionworkshop.com/documentation/develop/build-a-secure-extension/). 38 | 39 | **IMPORTANT: DO NOT install both versions.** 40 | 41 | Note: If you are using uBlock Origin, there are a few [extra installation steps](https://ghcdn.rawgit.org/LiCybora/NanoDefenderFirefox/master/docs/index.html#extra-installation-steps-for-ublock-origin) to follow. 42 | 43 | As of uBO 1.30.0, Adblock Warning Removal List is bad listed by uBlock Origin and cannot be added. Just skip it for now. I will remove that instruction once I clone all required resources from upstream and host on my own. 44 | 45 | ### About Pre-quantum fork 46 | 47 | ONLY Waterfox 55 or above, or forks with equivalent gecko version and supporting WebExtension API can install the 'Pro' version. 48 | However, some functions are lacking (such as console switch and response data filtering). 49 | 50 | **No support for other pre-quantum forks without WebExtension API (such as Basilisk, Palemoon).** 51 | 52 | ## Building 53 | 54 | Nano Defender for Firefox is built using 55 | [Nano Build (Modded)](https://github.com/LiCybora/NanoBuild). 56 | 57 | ## Credits 58 | 59 | Nano Defender uses open source code from the following projects (alphabetical): 60 | 61 | [reek/anti-adblock-killer](https://github.com/reek/anti-adblock-killer) 62 | 63 | [primer/octicons](https://github.com/primer/octicons/) 64 | 65 | [uBlockOrigin/uAssets](https://github.com/uBlockOrigin/uAssets) 66 | 67 | [gorhill/uBlock](https://github.com/gorhill/uBlock) 68 | 69 | [gorhill/uBO-Extra](https://github.com/gorhill/uBO-Extra) 70 | 71 | ## Special Thanks 72 | 73 | Nano Defender is developed by **@jspenguin2017** with the help of the following 74 | individuals (alphabetical): 75 | 76 | **@lain566** 77 | -------------------------------------------------------------------------------- /docs/index.css: -------------------------------------------------------------------------------- 1 | code { 2 | background-color: rgba(255, 255, 255, 0.8); 3 | border-radius: 20px; 4 | font-family: Consolas, monospace; 5 | padding: 0px 8px 0px 8px; 6 | } 7 | 8 | p { 9 | line-height: 1.3em; 10 | } 11 | 12 | p.red { 13 | padding: 5px; 14 | } 15 | 16 | div.scroll { 17 | max-width: 100%; 18 | overflow-x: auto; 19 | } 20 | 21 | p.no-bot { 22 | margin-bottom: 0px; 23 | } 24 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Nano Defender for Firefox 13 | 14 | 15 | 16 | 17 | 18 |
19 |

Nano Defender for Firefox

20 | 21 |

An anti-adblock defuser for uBlock Origin

22 |
23 | 24 |

Warning: Do not install from unofficial sources! Any websites that are not linked below are considered to be unofficial.

25 |
26 | 27 |
28 |

Installation

29 | 30 |

Nano Defender can only protect uBlock Origin.

31 | 32 |

Get Nano Defender for Firefox

33 | 34 |

Tthere are a few extra installation steps to follow as well.

35 |
36 | 37 |

Note: Nano Defender will not attempt to prevent websites from knowing that you are using Firefox Private Browsing or Firefox Tracking Protection, it is up to Firefox to make those features undetectable.

38 |
39 | 40 |
41 |

Announcements

42 | 43 |

October 29, 2020

44 |

Upstream homepage is no more. This temporary page will be used until my new repository release.

45 |

October 15, 2020

46 |

Nano Defender and Nano Adblocker found anywhere other than this GitHub repository and AMO is not related to me.

47 |

The malicious Chromium version has no relation to me and that NEVER EXIST ON FIREFOX, that incident is upstream sold to unidentifiable "developer(s)" but nothing related to Firefox port.

48 |

Before spreading this extension is malicious, please exclude Firefox version.

49 |
50 |
51 | 52 |
53 |

Extra installation steps for uBlock Origin

54 | 55 |

Step 1. Subscribe to Nano Defender Integration filter list.

56 |

Step 2. Go to uBlock Origin dashboard, select Settings tab, check I am an advanced user, click the gears icon that shows up, replace unset after userResourcesLocation by:

57 |

https://gitcdn.xyz/repo/NanoAdblocker/NanoFilters/master/NanoFilters/NanoResources.txt

58 |

Warning: The resources file is not a filter list, do not load it as a filter list or things will break.

59 |

Step 3. Subscribe to Nano filters.

60 |
61 | 62 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /domainExtractor.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | domainMatcher = r'[\[, ]"([a-zA-Z\d-]+(?:\.[a-zA-Z\d-]+)+)"[,\]]' 4 | domainIncMatcher = r'domInc\(\[[\S\n]*?"(.*?)"' 5 | whiteListMatcher = r'Whitelist = \[([\S\n ]*?)\]' 6 | 7 | def getDomainsFromFile(filename): 8 | with open(filename, 'r') as f: 9 | script = f.read() 10 | # Remove whitelisted rule 11 | script = re.sub(whiteListMatcher, '', script) 12 | 13 | return re.findall(domainMatcher, script) + re.findall(domainIncMatcher, script) 14 | 15 | domains = getDomainsFromFile('src/content/rules-specific.js') 16 | domains += getDomainsFromFile('src/content/rules-common.js') 17 | 18 | domains = list(dict.fromkeys(domains)) 19 | 20 | with open('domainList.txt', 'w') as w: 21 | w.write('\n'.join(domains)) 22 | -------------------------------------------------------------------------------- /domainList.txt: -------------------------------------------------------------------------------- 1 | acortar.net 2 | crackhex.ch 3 | prisguide.no 4 | factoriadeficcion.com 5 | revealedtricks4u.com 6 | go4up.com 7 | uskip.me 8 | videozoo.me 9 | yorkpress.co.uk 10 | warforum.cz 11 | porosin.co.uk 12 | playstation.com 13 | wiltsglosstandard.co.uk 14 | firstrow1us.eu 15 | videolab.io 16 | pudelekx.pl 17 | jansatta.com 18 | cotswoldessence.co.uk 19 | hotmoney.pl 20 | superfilm.pl 21 | wstream.video 22 | mexashare.com 23 | lg-firmware-rom.com 24 | kodilive.eu 25 | oxfordmail.co.uk 26 | mil.ink 27 | dashcatch.xyz 28 | nosteam.ro 29 | jbzdy.pl 30 | online.ua 31 | myp2p.ws 32 | pudelek.pl 33 | vsports.pt 34 | atdhe.al 35 | dplay.com 36 | nulledvar.com 37 | globeslot.com 38 | catchcoin.pw 39 | energytv.es 40 | prestwichandwhitefieldguide.co.uk 41 | imageraider.com 42 | usapoliticstoday.com 43 | burytimes.co.uk 44 | rapidgrab.pl 45 | genbird.com 46 | gametrailers.com 47 | barryanddistrictnews.co.uk 48 | mega-estrenos.com 49 | whiskypreise.com 50 | gaybeeg.info 51 | play.bandit.se 52 | badgames.it 53 | adz.bz 54 | mofosex.com 55 | torrent-tv.ru 56 | infostrow.pl 57 | thepcspy.com 58 | mangahost.com 59 | thewestmorlandgazette.co.uk 60 | suttonguardian.co.uk 61 | webqc.org 62 | pc.online143.com 63 | biztok.pl 64 | xvideos.com 65 | leaguesecretary.com 66 | videohelp.com 67 | m.delfi.ee 68 | clasicotas.org 69 | vipleague.me 70 | stream.nbcsports.com 71 | discoveryrom.org 72 | europe1.fr 73 | darlingtonandstocktontimes.co.uk 74 | iiv.pl 75 | firstrow.co 76 | atdhe.to 77 | ajihezo.info 78 | grenchnertagblatt.ch 79 | livemint.com 80 | harwichandmanningtreestandard.co.uk 81 | agarabi.com 82 | maango.info 83 | northwichguardian.co.uk 84 | shqip24.tv 85 | alcpu.com 86 | filespace.com 87 | leecher.us 88 | bba1.us 89 | financialexpress.com 90 | apkmirror.com 91 | somersetcountygazette.co.uk 92 | eclypsia.com 93 | faqmozilla.org 94 | newsshopper.co.uk 95 | florydinvaslui.ro 96 | codepo8.github.io 97 | bhaskar.com 98 | richmondandtwickenhamtimes.co.uk 99 | nicematin.com 100 | prototurk.com 101 | newpct.com 102 | vidlox.tv 103 | ttela.se 104 | qoshe.com 105 | 10co 106 | letras.mus.br 107 | basellandschaftlichezeitung.ch 108 | thebadbuzz.com 109 | atdhe.bz 110 | explosm.net 111 | myp2p.com 112 | imgrock.info 113 | streathamguardian.co.uk 114 | fourchette-et-bikini.fr 115 | zoomtv.me 116 | linclik.com 117 | nowvideo.ec 118 | 3dgames.com.ar 119 | sledujserialy.sk 120 | folha.uol.com.br 121 | urly.mobi 122 | freebitcoins.nx.tc 123 | mensxp.com 124 | insuranceloansonline.com 125 | sandiegouniontribune.com 126 | stromstadstidning.se 127 | wimbledonguardian.co.uk 128 | eveningtimes.co.uk 129 | srt.am 130 | topzone.lt 131 | bournmouthecho.co.uk 132 | bonusbitcoin.co 133 | badtv.it 134 | pasted.co 135 | superdeporte.es 136 | shortify.pw 137 | sapib.ca 138 | multiup.org 139 | haringeyindependent.co.uk 140 | aargauerzeitung.ch 141 | wtfbit.ch 142 | next-episode.net 143 | shortin.ga 144 | cwtv.com 145 | laopinioncoruna.es 146 | laopiniondemalaga.es 147 | tvn.pl 148 | watfordobserver.co.uk 149 | jacquieetmicheltv.net 150 | elektroda.pl 151 | firstrowus.eu 152 | strikeout.me 153 | oddreaders.com 154 | hop.bz 155 | sofoot.com 156 | lolsy.tv 157 | fmovies.is 158 | tube8.com 159 | idlelivelink.blogspot.com 160 | nrj.fr 161 | cellmapper.net 162 | telerium.tv 163 | animezone.pl 164 | thurrockgazette.co.uk 165 | chorleycitizen.co.uk 166 | startclass.com 167 | cda.pl 168 | rockfile.eu 169 | scan-mx.com 170 | coolsoft.altervista.org 171 | sockshare.com 172 | mybank.pl 173 | pipocas.tv 174 | basildonrecorder.co.uk 175 | kozaczek.pl 176 | autoexchange.co.uk 177 | gearsuite.com 178 | l2s.io 179 | giallozafferano.it 180 | divyabhaskar.co.in 181 | infoua.biz 182 | eltiempohoy.es 183 | mtmad.es 184 | webcafe.bg 185 | moondoge.co.in 186 | vg.no 187 | tvgratuite.blogspot.com 188 | vidfile.net 189 | vipleague.mobi 190 | mtlblog.com 191 | myp2p.eu 192 | thumbzilla.com 193 | passionea300allora.it 194 | firstrowsportes.tv 195 | narkive.com 196 | tuxboard.com 197 | stalbansreview.co.uk 198 | dovathd.com 199 | vipbox.so 200 | wharfedaleobserver.co.uk 201 | adshort.co 202 | fotoblogia.pl 203 | zlshorte.net 204 | uploadboy.com 205 | tuba.pl 206 | strikeout.co 207 | wired.it 208 | alcodistillers.ru 209 | pornovoisines.com 210 | oneplaylist.eu.pn 211 | canalplus.fr 212 | maxdebrideur.com 213 | booogle.net 214 | tvregionalna24.pl 215 | insidetelecom.no 216 | letribunaldunet.fr 217 | javgay.co 218 | hillingdontimes.co.uk 219 | onvasortir.com 220 | o2.pl 221 | pg3dhacks.com 222 | whosampled.com 223 | maldonandburnhamstandard.co.uk 224 | firstsrowsports.eu 225 | happy-hack.ru 226 | thesimsresource.com 227 | linkkawy.com 228 | ttv.pl 229 | xvideos.works 230 | solidfiles.com 231 | onemanga2.com 232 | adshorte.com 233 | haaretz.com 234 | bknime.com 235 | nana10 236 | freeskier.com 237 | dasolo.org 238 | gadgetsnow.com 239 | cheminots.net 240 | cnbeta.com 241 | dbplanet.net 242 | thescottishfarmer.co.uk 243 | sthelensstar.co.uk 244 | yourlifeupdated.net 245 | backin.net 246 | chouhaa.info 247 | urlchecker.net 248 | 4downfiles.org 249 | pornmd.com 250 | vipbox.tv 251 | shink.me 252 | exashare.com 253 | karibusana.org 254 | vipflash.net 255 | linksh.top 256 | freezedownload.com 257 | bokepspot.com 258 | vipleague.sx 259 | streamlive.to 260 | topserialy.to 261 | gaana.com 262 | themarker.com 263 | 4tests.com 264 | sportsplays.com 265 | vipbox.eu 266 | temp-mail.org 267 | tf2center.com 268 | digitalpoint.com 269 | in.techradar.com 270 | snobka.pl 271 | wetter3.de 272 | gamingroom.tv 273 | tg007.net 274 | filmstreaming-hd.com 275 | bzbasel.ch 276 | u2s.io 277 | beinsports.com 278 | atdhe.se 279 | mangabird.com 280 | uptostream.com 281 | divinity.es 282 | stream4free.eu 283 | onepiece-mx.net 284 | eventosppv.me 285 | cuatro.com 286 | lewebtvbouquetfrancophone.overblog.com 287 | burning-feed.com 288 | hotslogs.com 289 | viasport.no 290 | freesportsbet.com 291 | samehadaku.net 292 | yeovilexpress.co.uk 293 | mangasproject.com.br 294 | dailyecho.co.uk 295 | halesowennews.co.uk 296 | banburycake.co.uk 297 | vipboxtv.co 298 | timesofindia.indiatimes.com 299 | wandsworthguardian.co.uk 300 | door2windows.com 301 | viasport.fi 302 | popcornflix.com 303 | guardian-series.co.uk 304 | gamejolt.net 305 | lachainemeteo.com 306 | gazetteseries.co.uk 307 | mangamint.com 308 | justfirstrowsports.com 309 | smallholder.co.uk 310 | vipapp.me 311 | fpabd.com 312 | short.am 313 | kuchniaplus.pl 314 | bojem3a.info 315 | 37.187.173.205 316 | jzrputtbut.net 317 | pornve.com 318 | gaara-fr.com 319 | monnsutogatya.com 320 | eurotransport.de 321 | leveldown.fr 322 | thememypc.com 323 | bigdownloader.com 324 | nova.cz 325 | laopiniondemurcia.es 326 | alein.org 327 | worcesternews.co.uk 328 | romseyadvertiser.co.uk 329 | clik.bz 330 | telecinco.es 331 | swissadspaysfaucet.com 332 | computerworlduk.com 333 | videowing.me 334 | eami.in 335 | str3am.altervista.org 336 | satoshiempire.com 337 | mwpaste.com 338 | gpro.net 339 | northyorkshireadvertiser.co.uk 340 | cotswoldjournal.co.uk 341 | ouo.today 342 | asianimage.co.uk 343 | rule34hentai.net 344 | wetplace.com 345 | moviemakeronline.com 346 | penarthtimes.co.uk 347 | campaignseries.co.uk 348 | totaldebrid.org 349 | regio7.cat 350 | yahmaib3ai.com 351 | wawalove.pl 352 | playok.com 353 | freealtsgenerator.es 354 | darkstars.org 355 | dasolo.me 356 | falmouthpacket.co.uk 357 | messengernewspapers.co.uk 358 | lesechos.com 359 | linx.cloud 360 | money.pl 361 | myp2p.ec 362 | vipleague.co 363 | debrid.us 364 | echirurgia.pl 365 | computerworm.net 366 | str3amtv.co.nr 367 | bicesteradvertiser.net 368 | histock.info 369 | revclouds.com 370 | referencemega.com 371 | atdhe.li 372 | cubeupload.com 373 | infojobs.com.br 374 | vipracing.biz 375 | translatica.pl 376 | lesechos.fr 377 | 15min.lt 378 | al.ly 379 | an1me.se 380 | koscian.net 381 | nhentai.net 382 | artesacro.org 383 | strefadb.pl 384 | kooora.com 385 | nyheter24.se 386 | moonbit.co.in 387 | planetatvonlinehd.blogspot 388 | keezmovies.com 389 | fastserver.me 390 | bridgwatermercury.co.uk 391 | reward-guide.co.uk 392 | easyvideo.me 393 | samayam.com 394 | vipboxsa.co 395 | hdblog.it 396 | streamcloud.eu 397 | watcharab.com 398 | dasolo.co 399 | srnk.co 400 | lol.moa.tw 401 | di.se 402 | citationmachine.net 403 | businessinsider.in 404 | adshort.im 405 | premiumst0re.blogspot.com 406 | acquavivalive.it 407 | animes-mangas-ddl.com 408 | bitvisits.com 409 | bizled.co.in 410 | identi.li 411 | tune.pk 412 | lancashiretelegraph.co.uk 413 | rimleno.com 414 | southendstandard.co.uk 415 | miniminiplus.pl 416 | myp2p.tv 417 | braintreeandwithamtimes.co.uk 418 | atdhe.me 419 | spankwire.com 420 | intoday.in 421 | badcomics.it 422 | redditchadvertiser.co.uk 423 | gum-gum-streaming.com 424 | vipleague.tv 425 | sledujufilmy.cz 426 | firstrows.co 427 | fullhdzevki.com 428 | wowtoken.info 429 | theargus.co.uk 430 | mallorcazeitung.es 431 | muyinteresante.es 432 | moondash.co.in 433 | play.rixfm.se 434 | titulky.com 435 | todayidol.com 436 | katfile.com 437 | lcpdfr.com 438 | peeperz.com 439 | adlinkme.com 440 | telegraph.co.uk 441 | ringmycellphone.com 442 | gamereactor 443 | exrapidleech.info 444 | adageindia.in 445 | xmovies8.es 446 | westerntelegraph.co.uk 447 | newstatesman.com 448 | arenabg.ch 449 | bitcoinker.com 450 | fileice.net 451 | manga-news.com 452 | laprovincia.es 453 | manga9.com 454 | demo-phoenix.com 455 | firstrows.org 456 | new-skys.net 457 | freeallmusic.info 458 | tv3play.tv3.ee 459 | ostrzeszowinfo.pl 460 | malverngazette.co.uk 461 | slideplayer 462 | autokrata.pl 463 | dogecatch.website 464 | 8bbit.com 465 | gamezhero.com 466 | essexcountystandard.co.uk 467 | listamais.com.br 468 | webtv.bloguez.com 469 | yooclick.com 470 | link.tl 471 | swindonadvertiser.co.uk 472 | cyberterminators.co 473 | vidoza.net 474 | jeu.info 475 | hackingwithphp.com 476 | videowood.tv 477 | tewkesburyadmag.co.uk 478 | keighleynews.co.uk 479 | bridportnews.co.uk 480 | redtube.com 481 | freetvall.com 482 | tvplay.skaties.lv 483 | heraldseries.co.uk 484 | urle.co 485 | kingmaker.news 486 | osoarcade.com 487 | acortalo.net 488 | droitwichadvertiser.co.uk 489 | micast.tv 490 | ewallstreeter.com 491 | tvn24bis.pl 492 | litecoiner.net 493 | extratorrent.cc 494 | play.radio1.se 495 | psarips.com 496 | zimuku.net 497 | picload.org 498 | bitcoinaliens.com 499 | anizm.com 500 | graphiq-stories.graphiq.com 501 | theboltonnews.co.uk 502 | ghame.ru 503 | bombaytimes.com 504 | angrybirdsnest.com 505 | thenational.scot 506 | ewingoset.info 507 | ally.sh 508 | pro-sport.ws 509 | globalreinsurance.com 510 | diarioinformacion.com 511 | borehamwoodtimes.co.uk 512 | turkanime.tv 513 | solothurnerzeitung.ch 514 | knutsfordguardian.co.uk 515 | sport365.live 516 | fox.com.tr 517 | youwatch.org 518 | megogo.net 519 | mellow.link 520 | popunderjs.com 521 | parenting.pl 522 | version2.dk 523 | wiziwig.sx 524 | pensions-insight.co.uk 525 | hahasport.me 526 | tgo-tv.com 527 | crackhex.com 528 | sport-show.fr 529 | knowlet3389.blogspot 530 | cloudwebcopy.com 531 | chefti.info 532 | 5278bbs.com 533 | wiziwig.ru 534 | player.radioloyalty.com 535 | naruto-mx.net 536 | debrido.com 537 | echo-news.co.uk 538 | bluesatoshi.com 539 | dudleynews.co.uk 540 | lifehacker.co.in 541 | filecore.co.nz 542 | pregen.net 543 | snsw.us 544 | multiup.eu 545 | debridfast.com 546 | clactonandfrintongazette.co.uk 547 | xmac.xyz 548 | ctrn.cc 549 | x-news.pl 550 | la-cosa.it 551 | wurstclient.net 552 | pembrokeshirecountyliving.co.uk 553 | ilkleygazette.co.uk 554 | portel.pl 555 | animeforce.org 556 | swissadspaysethfaucet.com 557 | mojeauto.pl 558 | vipleague.is 559 | extratorrent.com 560 | meteocity.com 561 | wp.tv 562 | tv3.co.nz 563 | thestrad.com 564 | vivo.sx 565 | crackacc.com 566 | pro-tect.ws 567 | chesterlestreetadvertiser.co.uk 568 | yovoyages.com 569 | wiltshiretimes.co.uk 570 | menshealth.pl 571 | litv.tv 572 | teknogods.com 573 | thailande-fr.com 574 | simply-debrid.com 575 | nbcsports.com 576 | ur.ly 577 | play.nova.bg 578 | doatoolsita.altervista.org 579 | hellsmedia.com 580 | happytrips.com 581 | megawrzuta.pl 582 | cutearn.net 583 | forum.pac-rom.com 584 | darlingtonaycliffesedgefieldadvertiser.co.uk 585 | pastebin.com 586 | v.qq.com 587 | nowvideo.li 588 | gelbooru.com 589 | thevideo.me 590 | getbitcoins.nx.tc 591 | homerun.re 592 | finalservers.net 593 | narutoshippudenvf.com 594 | paksociety.com 595 | vipleague.ws 596 | jagranjunction.com 597 | auto-motor-i-sport.pl 598 | wolink.in 599 | buzina.xyz 600 | kafeteria.tv 601 | bohuslaningen.se 602 | filmz.dk 603 | goodcast.co 604 | linkshrink.net 605 | durhamtimes.co.uk 606 | kafeteria.pl 607 | mangas-fr.com 608 | tv4play.se 609 | automobile-sportive.com 610 | zeusnews.it 611 | skiplimite.tv 612 | hallandsposten.se 613 | elahmad.com 614 | womenshealth.pl 615 | kingstonguardian.co.uk 616 | moonliteco.in 617 | mtv.fi 618 | 3dnews.ru 619 | firstrowsportes.com 620 | code.ptcong.com 621 | pro-ddl.ws 622 | cbs.com 623 | bemad.es 624 | videacesky.cz 625 | tek.no 626 | gadzetomania.pl 627 | italiatv.org 628 | pxstream.tv 629 | mobile-tracker-free.com 630 | thisisthewestcountry.co.uk 631 | yiv.com 632 | libertaddigital.com 633 | theweatherspace.com 634 | topshort.net 635 | southwalesguardian.co.uk 636 | surreycomet.co.uk 637 | oneadfaucet.com 638 | history.com 639 | wifihack.me 640 | stourbridgenews.co.uk 641 | hisse.net 642 | enfieldindependent.co.uk 643 | youporngay.com 644 | urbanplanet.org 645 | arenavision.us 646 | falter.at 647 | theinquirer.net 648 | whiskyprix.fr 649 | mufa.de 650 | cdn-surfline.com 651 | tv3sport.dk 652 | flashx.tv 653 | 1movies.tv 654 | komediowo.pl 655 | rimladi.com 656 | farmet.info 657 | ville-ideale.com 658 | bromsgroveadvertiser.co.uk 659 | topadnetworks.net 660 | epsomguardian.co.uk 661 | esmas.com 662 | dl-protect.com 663 | luxyad.com 664 | teknojobb.no 665 | tny.cz 666 | linkdrop.net 667 | gazette-news.co.uk 668 | jc-mp.com 669 | ahzahg6ohb.com 670 | laopiniondezamora.es 671 | armorgames.com 672 | outdoorpartner.net 673 | vipleague.ch 674 | levante-emv.com 675 | bildungsspender.de 676 | zrabatowani.pl 677 | myp2p.la 678 | kurnik.pl 679 | animmex.co 680 | latelegratuite.blogspot.com 681 | tvnturbo.pl 682 | ddlfrench.org 683 | mahobeachcam.com 684 | pinoy1tv 685 | mangas.zlx.com.br 686 | receive-sms-online.info 687 | vipbox.sx 688 | uplod.cc 689 | ledburyreporter.co.uk 690 | naturalbd.com 691 | buickforums.com 692 | tvnfabula.pl 693 | badenertagblatt.ch 694 | czechhq.net 695 | gamepedia.com 696 | bg-gledai.tv 697 | cda-online.pl 698 | antennesport.com 699 | free-movie-home.com 700 | wakeupcallme.com 701 | hentai.to 702 | omnipola.com 703 | iamgujarat.com 704 | irc-source.com 705 | privateinsta.com 706 | debrideurstream.fr 707 | middlewichguardian.co.uk 708 | wrzuta.pl 709 | hanime.tv 710 | diariodemallorca.es 711 | thebatavian.com 712 | debridnet.com 713 | gizmodo.in 714 | plej.tv 715 | lewat.id 716 | milfordmercury.co.uk 717 | he2eini7ka.com 718 | mwfiles.net 719 | anandabazar.com 720 | ptztv.com 721 | upshare.org 722 | wearvalleyadvertiser.co.uk 723 | vipbox.co 724 | gry.wp.pl 725 | str3amtv.altervista.org 726 | mid-day.com 727 | drivearabia.com 728 | runners-world.pl 729 | playbb.me 730 | getdebrid.com 731 | extremetube.com 732 | thomas-n-ruth.com 733 | tivysideadvertiser.co.uk 734 | indiatimes.com 735 | siliconinvestor.com 736 | putlocker.com 737 | business-standard.com 738 | businesstoday.in 739 | runcornandwidnesworld.co.uk 740 | lne.es 741 | flashx.to 742 | simple4alls.com 743 | eveshamjournal.co.uk 744 | urlaubspartner.net 745 | aidemu.fr 746 | jkanime.net 747 | vellenger.com 748 | serverhd.eu 749 | tusoft.org 750 | easybillets.com 751 | ludlowadvertiser.co.uk 752 | vipleague.se 753 | elfqrin.com 754 | oltnertagblatt.ch 755 | egobits.com 756 | bitcoiner.net 757 | news-fbe.com 758 | gamer.no 759 | betterdocs.net 760 | navegacom.com 761 | mac4ever.com 762 | molfettalive.it 763 | tlz.de 764 | komorkomania.pl 765 | jeu.video 766 | middevonstar.co.uk 767 | wtkplay.pl 768 | freecoins4.me 769 | openrunner.com 770 | hampshirechronicle.co.uk 771 | gntai.xyz 772 | play.lugnafavoriter.com 773 | securenetsystems.net 774 | wired.com 775 | tvn24.pl 776 | dailyuploads.net 777 | beta.speedtest.net 778 | corepacks.com 779 | url.vin 780 | basingstokegazette.co.uk 781 | 720pmkv.com 782 | hardware.no 783 | zap.in 784 | nsspot.net 785 | hn.se 786 | dobreprogramy.pl 787 | freedom-ip.com 788 | albgoal.com 789 | indianexpress.com 790 | aternos.org 791 | tny.ec 792 | diariodeibiza.es 793 | 4shared.com 794 | haber1903.com 795 | arenavision.in 796 | hackinformer.com 797 | superanimes.com 798 | crockolinks.com 799 | gaytube.com 800 | xnxx.com 801 | dorsetecho.co.uk 802 | atdhe.ru 803 | amobil.no 804 | vipbox.biz 805 | washingtonpost.com 806 | searchftps.net 807 | edition.pagesuite-professional.co.uk 808 | bolor-toli.com 809 | bakersfield.com 810 | memurlar.net 811 | comicallyincorrect.com 812 | myp2p.sx 813 | andoveradvertiser.co.uk 814 | dpstream.net 815 | 2site.me 816 | peliculasmega.info 817 | razercrypt.com 818 | onhax.me 819 | tvn7.pl 820 | strategic-risk-global.com 821 | viz.com 822 | boxingnewsonline.net 823 | teknofil.no 824 | techworld.com 825 | limmattalerzeitung.ch 826 | dramapassion.com 827 | pudelek.tv 828 | pinkrod.com 829 | kiss.com.tw 830 | primeshare.tv 831 | sadeempc.com 832 | s1community.com 833 | pro-zik.ws 834 | ilive.to 835 | dilidili.wang 836 | times-series.co.uk 837 | 3dzone.link 838 | harrowtimes.co.uk 839 | vgunetwork.com 840 | northernfarmer.co.uk 841 | bitcoinzebra.com 842 | gratisjuegos.co 843 | linternaute.com 844 | salisburyjournal.co.uk 845 | rmprepusb.com 846 | stocks.cafe 847 | leporno.org 848 | cleodesktop.com 849 | doramasflv.net 850 | oxfordtimes.co.uk 851 | s1jobs.com 852 | consettstanleyadvertiser.co.uk 853 | whiskyprices.co.uk 854 | notre-planete.info 855 | newsinlevels.com 856 | fmovies.to 857 | uploadshub.com 858 | croydonguardian.co.uk 859 | tvnow.de 860 | warringtonguardian.co.uk 861 | durhamadvertiser.co.uk 862 | agario.sx 863 | viasatsport.se 864 | redhillandreigatelife.co.uk 865 | v3.co.uk 866 | whiskyprijzen.com 867 | timesofindia.com 868 | dplay.se 869 | ekstrabladet.dk 870 | rapid8.com 871 | youporn.com 872 | engagedinvestor.co.uk 873 | ah-me.com 874 | myp2p.biz 875 | gamekit.com 876 | wp.pl 877 | itvnextra.pl 878 | southwalesargus.co.uk 879 | dato.porn 880 | thetelegraphandargus.co.uk 881 | witneygazette.co.uk 882 | beppegrillo.it 883 | halsteadgazette.co.uk 884 | mamahd.com 885 | arsopo.com 886 | knowyourmeme.com 887 | eventhubs.com 888 | onmeda.de 889 | brentwoodweeklynews.co.uk 890 | itvn.pl 891 | fullstuff.net 892 | filmy.to 893 | tzetze.it 894 | leighjournal.co.uk 895 | zdnet.de 896 | freegamehosting.nl 897 | nontonanime.org 898 | up-4ever.com 899 | myfxbook.com 900 | wiziwig.tv 901 | player.radiojazzfm.ru 902 | sports.qq.com 903 | hdpass.net 904 | kidderminstershuttle.co.uk 905 | game-debate.com 906 | freizeitpartnerweb.de 907 | monmouthshirecountylife.co.uk 908 | d3brid4y0u.info 909 | herefordtimes.com 910 | dplay.dk 911 | s1homes.com 912 | sfora.pl 913 | vipbox.nu 914 | southwestfarmer.co.uk 915 | allmyvideos.net 916 | mariage-franco-marocain.net 917 | firstrows.ru 918 | maketecheasier.com 919 | showsport-tv.com 920 | zeberka.pl 921 | filmvf.net 922 | skippyfile.com 923 | coinb.ink 924 | is.fi 925 | diskusjon.no 926 | darmowe-pornosy.pl 927 | youwatch.to 928 | firstrows.tv 929 | gazetteherald.co.uk 930 | userscloud.com 931 | docer.pl 932 | uforum.us 933 | preemlinks.com 934 | mrtzcmp3.net 935 | 29443kmq.video 936 | gamespowerita.com 937 | solowrestling.com 938 | freepressseries.co.uk 939 | fmovies.se 940 | wakfutemporada2subs.blogspot.com 941 | avmoo.com 942 | cravenherald.co.uk 943 | mangahost.org 944 | s1cars.com 945 | up-flow.org 946 | creweguardian.co.uk 947 | autokult.pl 948 | wunderground.com 949 | mangabee.co 950 | yes.fm 951 | 1tv.ru 952 | nekopoi.bid 953 | chardandilminsternews.co.uk 954 | generatorlinkpremium.com 955 | apkmod1.com 956 | bucksfreepress.co.uk 957 | idiva.com 958 | wirralglobe.co.uk 959 | epiotrkow.pl 960 | mellowads.com 961 | catcatyfaucet.xyz 962 | newsquest.co.uk 963 | phys.org 964 | lovesutras.com 965 | sharecast.to 966 | mega-debrid.eu 967 | emuparadise.me 968 | poczta.wp.pl 969 | cbox.ws 970 | thechive.com 971 | wakanim.tv 972 | tvnstyle.pl 973 | sports.fr 974 | pizzamaking.com 975 | cityam.com 976 | lolskinlistgenerator.com 977 | mtzfile.gq 978 | tweaktown.com 979 | ddlfr.pw 980 | voici.fr 981 | abczdrowie.pl 982 | generatupremium.biz 983 | thenorthernecho.co.uk 984 | btaia.com 985 | mangacanblog.com 986 | atdhe.top 987 | motocykl-online.pl 988 | farodevigo.es 989 | sc2casts.com 990 | s1rental.com 991 | wiziwig.to 992 | pcgames-download.net 993 | spox.fr 994 | xtube.com 995 | kardiolo.pl 996 | poczta.o2.pl 997 | emporda.info 998 | null-24.com 999 | badtaste.it 1000 | eb.dk 1001 | mangasproject.net.br 1002 | play.tv3.lt 1003 | filecom.net 1004 | palemoon.org 1005 | interfans.org 1006 | palolive.it 1007 | kitorelo.com 1008 | player.pl 1009 | netdna-storage.com 1010 | insurancetimes.co.uk 1011 | inn.co.il 1012 | ultrahorny.com 1013 | e24.no 1014 | atdhe.mx 1015 | binbucks.com 1016 | torrentfunk.com 1017 | freegameserverhost.com 1018 | europeup.com 1019 | vgtv.no 1020 | sawlive.tv 1021 | amvtv.net 1022 | ndtv.com 1023 | dailybitcoins.org 1024 | hdmotori.it 1025 | gp.se 1026 | chelmsfordweeklynews.co.uk 1027 | xstory-fr.com 1028 | heraldscotland.com 1029 | undeniable.info 1030 | zeiz.me 1031 | pseudo-flaw.net 1032 | diaridegirona.cat 1033 | shutterdowner.com 1034 | croco.site 1035 | firstrows.biz 1036 | hentaifr.net 1037 | wilmslowguardian.co.uk 1038 | workupload.com 1039 | infobae.net 1040 | vaughnlive.tv 1041 | planetatvonlinehd.com 1042 | burnhamandhighbridgeweeklynews.co.uk 1043 | akam.no 1044 | playrust.io 1045 | paidverts.com 1046 | ealingtimes.co.uk -------------------------------------------------------------------------------- /list/1-header.txt: -------------------------------------------------------------------------------- 1 | # Nano Defender Integration 2 | # This filter list is intended to be used with Nano Defender 3 | # Visit my home page for more information: https://jspenguin2017.github.io/uBlockProtector/ 4 | # This file is a compiled binary, any modification will be overwritten on the next build -------------------------------------------------------------------------------- /list/2-integration.txt: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------------------------------------------- # 2 | 3 | # These are filters for integration with Nano Defender, all whitelists in this section are handled by Nano Defender 4 | 5 | # ------------------------------------------------------------------------------------------------------------------- # 6 | 7 | # Special 8 | 9 | # Callback API placeholder, must be blocked, this file does not actually exist 10 | |https://legacy.hugoxu.com/uBlockProtector/Solutions/Blocked.php$important 11 | 12 | # Resource placeholder, these files do not actually exist 13 | |https://legacy.hugoxu.com/uBlockProtector/Solutions/ 14 | 15 | # ------------------------------------------------------------------------------------------------------------------- # 16 | 17 | # Generic 18 | 19 | @@|https://*.moatads.com/*/MoatFreeWheelJSPEM.js*$script 20 | @@|https://ads.korri.fr/index.js|$script 21 | @@|http://*.medianetworkinternational.com/js/advertisement.js*$script 22 | 23 | # ------------------------------------------------------------------------------------------------------------------- # 24 | 25 | # Specific 26 | 27 | # https://github.com/NanoMeow/QuickReports/issues/528 28 | # https://github.com/uBlockOrigin/uAssets/issues/4293 29 | @@||vd.l.qq.com/proxyhttp$xhr,domain=sports.qq.com|v.qq.com 30 | 31 | # https://github.com/uBlockOrigin/uAssets/issues/4290 32 | ani.gamer.com.tw##body > div:has(a[href="https://goo.gl/PmkwWS"]) 33 | 34 | # ------------------------------------------------------------------------------------------------------------------- # 35 | 36 | # Broken 37 | 38 | # IMA SDK surrogate integration 39 | # @@|https://imasdk.googleapis.com/js/sdkloader/ima3.js*$script,domain=~fox.com|~log.com.tr|~motorsport.tv|~pandora.com|~popcornflix.com|~streamable.com|~tv2.dk 40 | # @@|http://imasdk.googleapis.com/js/sdkloader/ima3.js*$script,domain=~fox.com|~log.com.tr|~motorsport.tv|~pandora.com|~popcornflix.com|~streamable.com|~tv2.dk 41 | # Their poster logic is broken, but the error is somehow suppressed by the original IMA SDK 42 | # ||cbsnews.com/news/*/[object%20object]$image,redirect=1x1-transparent.gif 43 | # ||cbsnews.com/news/*/undefined$image,redirect=1x1-transparent.gif 44 | 45 | # ------------------------------------------------------------------------------------------------------------------- # 46 | -------------------------------------------------------------------------------- /list/3-rules.txt: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------------------------------------------- # 2 | 3 | # Miners 4 | 5 | /coinhive.js 6 | /coinhive.min.js 7 | /c-hive.js 8 | /c-hive.min.js 9 | /cryptonight.wasm 10 | /cn.wasm 11 | 12 | # ------------------------------------------------------------------------------------------------------------------- # 13 | 14 | # Missed ads 15 | 16 | ||googlesyndication.com^$important,domain=short.am|clubedohardware.com.br 17 | ||doubleclick.net^$important,domain=aetv.com|history.com|mylifetime.com 18 | 19 | ||damoh.*$media 20 | 21 | ||zergnet.com^$script,third-party 22 | 23 | # https://github.com/jspenguin2017/uBlockProtector/issues/251 24 | ||a.optnmnstr.com^$third-party 25 | ||a.optnmstr.com^$third-party 26 | 27 | # https://github.com/jspenguin2017/uBlockProtector/issues/346 28 | ||adiode.com^$third-party 29 | 30 | # NSFW 31 | ||zmovs.com^$csp=sandbox allow-forms allow-presentation allow-scripts allow-top-navigation allow-orientation-lock allow-pointer-lock allow-same-origin 32 | zmovs.com##.tc-col-sm-offset-7.hidden-xs 33 | zmovs.com##.closeBtn 34 | zmovs.com##.inplayer_banners 35 | 36 | ||amazonaws.com^$domain=dailymotion.com 37 | 38 | # https://github.com/uBlockOrigin/uAssets/issues/442 39 | @@||louccrossc.com^$domain=tf1.fr,badfilter 40 | @@||foilpolyth.com^$domain=tf1.fr,badfilter 41 | ||foilpolyth.com^$xmlhttprequest,redirect=nooptext,important,domain=tf1.fr 42 | ||louccrossc.com^$xmlhttprequest,redirect=nooptext,important,domain=tf1.fr 43 | 44 | # ------------------------------------------------------------------------------------------------------------------- # 45 | 46 | # Common Solutions 47 | 48 | ###adblockBanner 49 | ###like-us-adblock-modal 50 | ##.admania_adblock_detector 51 | ##.o-AdhesionNotifier 52 | ##.popup-premium__apla 53 | 54 | /adblock-detector/* 55 | /adblock-popup. 56 | ||fastly.net/ads/$image,redirect=2x2-transparent.png 57 | ||fastly.net/ads/$script,redirect=noopjs 58 | ||fastly.net/ads/$xmlhttprequest,redirect=nooptext 59 | ||doubleclick.net/instream/ad_status.js$script,redirect=doubleclick.net/instream/ad_status.js 60 | 61 | # https://github.com/jspenguin2017/uBlockProtector/issues/254 62 | ||lukkr.com/website/pf.js 63 | 64 | # https://github.com/jspenguin2017/uBlockProtector/issues/978 65 | ||sixscissors.com^$third-party,domain=~itavisen.no 66 | 67 | # Adblock Identifier 68 | # Can cause crash, need to test each case 69 | /jquery.adi.css 70 | /jquery.adi.js$domain=123link.top 71 | 72 | # Admiral 73 | ||pelcro.com^$third-party 74 | 75 | # BlockAdBlock 76 | sectorsatoshi-amarillo.website,sectorsatoshi-azul.website,sectorsatoshi-blanco.website,sectorsatoshi-celeste.website,sectorsatoshi-gris.website,sectorsatoshi-naranja.website##+js(bab-defuser.js) 77 | sectorsatoshi-negro.website,sectorsatoshi-rosa.website,sectorsatoshi-verde.website,sectorsatoshi-violeta.website##+js(bab-defuser.js) 78 | futbolchile.net,freeomovie.com,appdrop.net,skmedix.pl,yalujailbreak.net,cloudwebcopy.com,milaulas.com,tout-bon.com,sznpaste.net,linkdrop.net,themeslide.com##+js(bab-defuser.js) 79 | android-zone.ws,cmacapps.com,l2network.eu,animes-mangas-ddl.net,fuckingsession.com,klartext-ne.de,forumcoin.win,androidemulator.in,forumcoin.win,arenavision.ru,gulshankumar.net##+js(bab-defuser.js) 80 | arenavision.in,arenavision.us,discudemy.com,practicetestgeeks.com,iptvbin.com,imojado.org,xossip.com,adyou.me,funcinema.ga,ddlfr.pw,freecoursesonline.us##+js(bab-defuser.js) 81 | 82 | # AdBlock Detector 83 | themarker.com,nachrichten.at##+js(abort-on-property-read.js, adblockDetector) 84 | 85 | # Social Locker 86 | megawarez.org,tipeo.net,compucalitv.com,intercambiosvirtuales.pro,tecmaxsoft.com,descargatelocorp.com,hackstore.net##div.onp-sl-content:style(display: block !important;) 87 | megawarez.org,tipeo.net,compucalitv.com,intercambiosvirtuales.pro,tecmaxsoft.com,descargatelocorp.com,hackstore.net##div.onp-sl-social-locker 88 | anonymousemail.me##div.onp-sociallocker-content:style(display: block !important;) 89 | anonymousemail.me##div.onp-sociallocker 90 | descargatelocorp.com##div[id^="informer"]:style(display: block !important; opacity: 1 !important; max-height: none !important;) 91 | descargatelocorp.com##div[class*="cool_ramka"] 92 | 93 | # ------------------------------------------------------------------------------------------------------------------- # 94 | 95 | # Specific solutions 96 | 97 | ! === cloudfront.net 98 | ||cloudfront.net^$domain=adbull.me|shink.in|dbzsuper.tv|croco.site|adshorte.com|pasteca.sh|cloudyfiles.org|cuturlink.com|wateranik.com|eagerse.com|estrenos10.com|palimas.tv|srt.am 99 | ! === wp.pl and related domains 100 | ||adv.wp.pl/$media,redirect=noopmp3-0.1s,important 101 | ||static-pilot.wp.pl/static/assets/js/ads.js$xmlhttprequest,redirect=noopjs 102 | ||adv.wp.pl/*/inline-videostar.js$xmlhttprequest,redirect=noopjs,important,domain=pilot.wp.pl 103 | ||adv.wp.pl/adverts*.js$xmlhttprequest,redirect=noopjs,important,domain=pilot.wp.pl 104 | ! === NSFW! zone-anime.net 105 | filez.tv###adblockinfo 106 | ! === video.gazeta.pl 107 | @@||video.gazeta.pl/cdn/ads/ad/banner/_adsense_/_adserver/_adview_.ad.json$xmlhttprequest,first-party 108 | ! === latimes.com 109 | ||tribdss.com/meter/assets$script,domain=www.latimes.com 110 | ! === thewindowsclub.com 111 | *$xmlhttprequest,domain=thewindowsclub.com 112 | @@||disquscdn.com^$script,domain=thewindowsclub.com 113 | @@|https://disqus.com/next/config.js$domain=thewindowsclub.com 114 | ! === NSFW! 8muses.com 115 | ||8muses.com^$inline-script 116 | @@||8muses.com/comix/picture^$inline-script 117 | ! === allmusic.com 118 | ||allmusic.com^$inline-script 119 | ! === xmovies8.org, moviezr.org 120 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/90 121 | xmovies8.org,moviezr.org##+js(abort-on-property-read.js, $.getScript) 122 | ! === tune.pk 123 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/92 124 | tune.pk###annoy-wrapper 125 | ! === NSFW! 29443kmq.video, dato.porn 126 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/93 127 | 29443kmq.video,dato.porn###a 128 | dato.porn##+js(abort-on-property-read.js, open) 129 | dato.porn##+js(noeval-if.js, var r3H4=window;for(var v4 in r3H4)) 130 | ! === engineeringtoolbox.com 131 | engineeringtoolbox.com##.adblo 132 | engineeringtoolbox.com##.contentDocumentAd 133 | ! === ps4news.com 134 | ps4news.com##+js(noeval.js) 135 | ps4news.com##body > *[id^="blockblock"]:style(visibility: visible !important; display: block !important;) 136 | ps4news.com##table[id^='blockblock'] 137 | ! === 7636ca6cb9fc.com 138 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/99 139 | ||7636ca6cb9fc.com^ 140 | ! === okazje.co 141 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/114 142 | okazje.co###AdBlockDetected 143 | ! === answers.com 144 | answers.com##.end_of_slideshow 145 | ! === gamereactor.dk and related domains 146 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/124 147 | ||openx.gamereactor.*/multi.php$script,important 148 | ! === animmex.* 149 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/125 150 | ||finalservers.net^$inline-script 151 | finalservers.net###babasbmsgx 152 | finalservers.net##+js(abort-on-property-read.js, _gunggo) 153 | animmex.*###M148617ScriptRootC75329 154 | animmex.*##a[href^="https://forum.animmex.com/viewtopic.php"] 155 | ! === gry.pl 156 | ||flakyfeast.com^$domain=gry.pl 157 | ! === pixiv.net 158 | pixiv.net##.popular-introduction-overlay 159 | ! === youtube.com 160 | youtube.com###companion 161 | ! === pogdesign.co.uk 162 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/149 163 | pogdesign.co.uk##.replace 164 | ! === ally.sh, al.ly 165 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/148 166 | ||p207208.clksite.com^$subdocument,redirect=noopframe,domain=ally.sh|al.ly 167 | ally.sh,al.ly##+js(popads.net.js) 168 | ! === hackintosh.zone, hackintosh.computer 169 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/35 170 | ||hackintosh.*/donate/donate.php 171 | ! === aftonbladet.se 172 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/163 173 | ||ooul.tv/contrib/se-aftonbladet/aab/aftonbladet_plugin.js$script,redirect=noopjs,domain=aftonbladet.se 174 | ||ooul.tv/nocache/se-aftonbladet/aab/aftonbladet_config.js$script,redirect=noopjs,domain=aftonbladet.se 175 | ! === filechoco.net, keezmovies.com, raptu.com, afreesms.com 176 | filechoco.net,keezmovies.com,raptu.com,afreesms.com##+js(noeval.js) 177 | ! === iframes of goodanime.co 178 | playbb.me#@#div[style^="width:"] 179 | easyvideo.me#@#div[style^="width:"] 180 | videowing.me#@#div[style^="width:"] 181 | videozoo.me#@#div[style^="width:"] 182 | ! === games.softgames.de 183 | ||games.softgames.de/assets/showads.js$script,redirect=noopjs 184 | ||softgames.de/sg-mc.js*$script,redirect=noopjs 185 | ! === exrapidleech.info 186 | ||bidvertiser.com$important,domain=exrapidleech.info 187 | ! === mmo-champion.com 188 | ||broadcastbed.com^$domain=mmo-champion.com 189 | ! === bracknellnews.co.uk 190 | bracknellnews.co.uk##+js(abort-on-property-write.js, _sp_) 191 | ! === u2s.io, l2s.io, linkhits.us 192 | u2s.io,l2s.io,linkhits.us#@#.myTestAd 193 | @@||solvemedia.com^$domain=u2s.io|l2s.io 194 | ||5g9quwq.com^$third-party 195 | ! === pwn.pl, vendiscuss.net, rufootballtv.org 196 | pwn.pl,vendiscuss.net,rufootballtv.org##+js(abort-on-property-read.js, adblock) 197 | ! === clubic.com 198 | ||tiptonvillepylesville.com^$domain=clubic.com 199 | ! === animeid.io and similar domains 200 | animeid.io,jkanime.co,gogoanime.ch,chiaanime.co,animeflv.co##+js(setTimeout-defuser.js, #player) 201 | ! === comicallyincorrect.com 202 | @@||comicincorrect.wpengine.netdna-cdn.com/wp-content/uploads/ 203 | ! === savetodrive.net 204 | savetodrive.net##+js(setTimeout-defuser.js, ad) 205 | ! === rarbgmirror.com, swfchan.net, swfchan.com, zippyshare.com, leech.ae, vizer.tv 206 | rarbgmirror.com,swfchan.net,swfchan.com,zippyshare.com,leech.ae,vizer.tv##+js(abort-on-property-read.js, open) 207 | ! === pipocas.tv 208 | ||googlesyndication.com^$script,redirect=noopjs,domain=pipocas.tv 209 | ! === steamcustomizer.com 210 | steamcustomizer.com###sadcat 211 | steamcustomizer.com##.notice.support-notice 212 | @@||steamcustomizer.com/cache/skin/ad/$image,first-party 213 | ! === iframes of shqiptvlive.net 214 | shqiperiatv.com,albtvhd.com,tvshqiphd.com,www.balkanweb.com,cdn.livestream.com,livestream.artmotion.al,shqip-tv.info##body > *[id^="blockblock"]:style(visibility: visible !important; display: block !important;) 215 | shqiperiatv.com,albtvhd.com,tvshqiphd.com,www.balkanweb.com,cdn.livestream.com,livestream.artmotion.al,shqip-tv.info##table[id^='blockblock'] 216 | ! === wordsense.eu 217 | wordsense.eu##+js(setTimeout-defuser.js, ad, 2000) 218 | ! === transparentcalifornia.com 219 | /magnific-popup.js/*$domain=transparentcalifornia.com 220 | ! === javsex.net 221 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/244 222 | @@||yamvideo.com/pop1/jwplayer.js$domain=javsex.net 223 | ! === nowvideo.ec, nowvideo.li, ewingoset.info 224 | ! === https://gitlab.com/xuhaiyang1234/NanoAdblockerSecretIssues/issues/2 225 | ||nowvideo.ec^$inline-script 226 | ||nowvideo.li^$inline-script 227 | ||ewingoset.info^$inline-script 228 | ! === nana10.co.il 229 | ||cloudvideoplatform.com/advert.jpg$image,redirect=1x1-transparent.gif,domain=nana10.co.il 230 | ! === newyorker.com 231 | newyorker.com##iframe[src*="/wp-content/assets/"] 232 | ! === politiken.dk 233 | @@||politiken.dk/*ad*$script,first-party 234 | ! === wholecloud.net 235 | ||wholecloud.net^$inline-script 236 | ! === link.tl 237 | link.tl##.adblockBox 238 | link.tl##.adblockOverlay 239 | ! === themelot.net 240 | *$third-party,script,domain=themelot.net 241 | ! === batchnime.net 242 | batchnime.net##+js(abort-on-property-read.js, killAdBlock) 243 | ! === uplod.ws 244 | uplod.ws##+js(abort-on-property-read.js, $.ready) 245 | ! === ilgazzettino.it 246 | ||utils.cedsdigital.it/checkSubscription/checkSubscription.js 247 | ! === windowsreport.com 248 | windowsreport.com##+js(silent-noeval.js) 249 | ! === haxmaps.com, haxrec.com, haxcolors.com 250 | haxmaps.com,haxrec.com,haxcolors.com##+js(setTimeout-defuser.js, /.*/, 10000) 251 | ! === animesync.tv 252 | animesync.tv##.modal-adblock 253 | ! === expansion.com 254 | ||active.cache.el-mundo.net/js/*_expansion.js$domain=expansion.com 255 | ! === watchfree.to 256 | watchfree.to##+js(abort-on-property-read.js, UAParser) 257 | ! === firstonetv.eu, firstone.tv 258 | firstonetv.eu,firstone.tv##+js(noeval-if.js, Please disable your Adblocker) 259 | ! === vooxe.com 260 | vooxe.com###blockedAddons 261 | ! === gentecheesisterealmente.com 262 | gentecheesisterealmente.com##+js(abort-on-property-read.js, admaniastchk) 263 | ! === litv.tv 264 | ||litv.tv/promo/ 265 | litv.tv##.fp-pausebn 266 | ||$third-party,script,domain=litv.tv 267 | ! === dailyuploads.net 268 | dailyuploads.net##+js(abort-on-property-read.js, popns) 269 | dailyuploads.net##+js(abort-on-property-read.js, adbClick) 270 | ! === buickforums.com 271 | ||madisonross.com/adblock.html$subdocument 272 | ! === sznpaste.net 273 | sznpaste.net##+js(abort-on-property-write.js, _pop) 274 | ! === linkdrop.net 275 | @@||ajax.googleapis.com/ajax/libs/jquery/$script,domain=linkdrop.net 276 | ! === leechgear.net 277 | leechgear.net###block_on 278 | ! === wiwo.de 279 | wiwo.de,handelsblatt.com##+js(abort-on-property-read.js, AdController) 280 | ! === tvregionalna24.pl 281 | tvregionalna24.pl##.diablo-placeholder 282 | ! === kitguru.net 283 | kitguru.net#@#div > a[class] > img[src] 284 | kitguru.net##.gofollow 285 | ! === vidnow.to 286 | vidnow.to###adplayer 287 | ! === gigaleecher.com 288 | ||gigaleecher.com/templates/plugmod/giga.js$script 289 | ! === diariodenavarra.es 290 | diariodenavarra.es###abMsgWrap 291 | ! === NSFW! darmowe-pornosy.pl, polskie-aktorki-porno.pl 292 | darmowe-pornosy.pl,polskie-aktorki-porno.pl#@#.myTestAd 293 | ! === themarker.com 294 | themarker.com###ad-block-wrapper 295 | ! === vidlox.tv 296 | @@*$csp,domain=vidlox.tv 297 | ! === zeusnews.it 298 | ||zeusnews.it/antiadb.js 299 | ! === ipornia.hdzog.com 300 | @@||static.ipornia.com^$image,domain=ipornia.hdzog.com 301 | hdzog.com##.msg-adblock.msg 302 | ! === webcheats.com.br 303 | webcheats.com.br##+js(abort-on-property-read.js, can_run_ads) 304 | webcheats.com.br###bg_trasp 305 | ! === totomi.co 306 | totomi.co##+js(setInterval-defuser.js, /display/.test) 307 | ! === naisho.asia 308 | naisho.asia##+js(abort-on-property-write.js, adBlock) 309 | ! === westeros.org 310 | ||sovrnlabs.net^$domain=westeros.org 311 | ! === NSFW! sankakucomplex.com 312 | sankakucomplex.com##+js(abort-on-property-read.js, BetterJsPop) 313 | ! === short.am 314 | @@||short.am^$generichide,badfilter 315 | ! === wdbloog.com 316 | wdbloog.com###unblocker 317 | ! === dingit.tv, jan-magazine.nl, glamour.nl, quest.nl 318 | dingit.tv,jan-magazine.nl,glamour.nl,quest.nl#@#.adsbox 319 | ||dingit.tv/js/dingit-player/js/html5/videojs.ads.js$script,redirect=noopjs 320 | ! === vz.lt 321 | /countsJS.php$domain=vz.lt 322 | ! === xess.pro 323 | ||xess.pro/js/popup.js 324 | ! === iprima.cz 325 | iprima.cz##.play-wrapper.player-wrapper > .you-shall-not-pass 326 | iprima.cz##.play-wrapper.player-wrapper + .you-shall-not-pass 327 | iprima.cz###AdTrackVideoPlayer 328 | ! === hayan.tv 329 | ||hayan.tv/gibberish-aes.js^ 330 | ! === nbcsports.com 331 | ||hdliveextra-a.akamaihd.net/*/ads.js$script,redirect=noopjs 332 | ! === openculture.com 333 | ||openculture.com/wp-content/uploads/$script 334 | ! === goalsarena.org 335 | @@||config.playwire.com^$domain=goalsarena.org 336 | ! === tecmundo.com.br 337 | tecmundo.com.br##.gallery-ads 338 | ! === der-postillon.com 339 | der-postillon.com###steady-adblock-overlay-container 340 | ! === kinja.com and related domains 341 | ||kinja.com/sp/ 342 | ||deadspin.com/sp/ 343 | ||splinternews.com/sp/ 344 | ||gizmodo.com/sp/ 345 | ||jalopnik.com/sp/ 346 | ||jezebel.com/sp/ 347 | ||kotaku.com/sp/ 348 | ||mms.kotaku.com^$script,xmlhttprequest 349 | ||lifehacker.com/sp/ 350 | ||theroot.com/sp/ 351 | ! === adshorte.com 352 | ||dailymotion.com^$domain=adshorte.com 353 | ! === paksociety.com, f-hd.net 354 | paksociety.com,f-hd.net##.blocked 355 | ! === cleveland.com 356 | ||fastly.net/mms-client.js$domain=cleveland.com 357 | ||fastly.net/messaging.js$domain=cleveland.com 358 | ! === couponcabin.com 359 | couponcabin.com###adblocker-reminder 360 | ! === tubeninja.net 361 | @@||tubeninja.net/ads.js$first-party 362 | ! === tlz.de 363 | tlz.de##.ab-shader 364 | ! === 1tv.ru 365 | ||v.adfox.ru^$xmlhttprequest,redirect=nooptext,domain=1tv.ru 366 | ! === 1tiny.net 367 | 1tiny.net##+js(abort-on-property-read.js, jQuery.ready) 368 | ! === thevideo.me 369 | thevideo.me##.notification-adblock 370 | ! === fas.li 371 | ||fas.li/js/p.js 372 | ! === smashingmagazine.com 373 | smashingmagazine.com###blocked 374 | ! === kustvaartforum.com 375 | ||kustvaartforum.com/block.js 376 | ! === latin.it 377 | @@||latin.it/banner.php$first-party 378 | ! === stocks.cafe 379 | ||stocks.cafe/amazon/google$subdocument 380 | ! === geo.de 381 | ||laterpay.net^$domain=geo.de 382 | ! === techforever.net 383 | techforever.net##+js(setTimeout-defuser.js, canABP) 384 | ! === seekingalpha.com 385 | @@||seekingalpha.com^$script,badfilter 386 | ||seekingalpha.com/ads_data.js$script,redirect=noopjs 387 | ! === btcinbtc.com and related domains 388 | /checkme.js$domain=btcinbtc.com|hamsab.net|20hk.com|my115.net|bitcoball.com|seek-inn.com|at-spot.com 389 | ! === explosm.net 390 | @@||proper.io/embed/$subdocument,domain=explosm.net 391 | ! === mspfa.com 392 | mspfa.com###nopepsi 393 | ! === klisza.org 394 | ||klisza.org/wp-content/plugins/popups/ 395 | klisza.org##.spu-box 396 | ! === womenshealthmag.com 397 | @@||womenshealthmag.com^$script,first-party 398 | ! === mitele.es 399 | ||mitele.es/vendor/adjs.js$xmlhttprequest,redirect=noopjs 400 | ||mitele.es/vendor/fuckadblock.js$xmlhttprequest,redirect=noopjs 401 | ||player.ooyala.com/*/ad-plugin/$important,script,badfilter 402 | ||player.ooyala.com/*/ad-plugin/$important,script,domain=~mitele.es 403 | ||player.ooyala.com/*/ad-plugin/$important,script,domain=mitele.es,redirect=noopjs 404 | ! === virgilio.it 405 | virgilio.it##+js(abort-on-property-read.js, VVIDEO.adBlock) 406 | ! === auroravid.to 407 | ||auroravid.to^$inline-script 408 | ! === amarujala.com 409 | amarujala.com##+js(abort-on-property-read.js, call_adblocker) 410 | ! === oddreaders.com 411 | ||oddreaders.com/wp-content/plugins/sociallocker-next-premium/ 412 | ! === sportspyder.com 413 | sportspyder.com##+js(setTimeout-defuser.js, BlockerChecker) 414 | ||sportspyder.com/assets/application-$script,badfilter 415 | ! === tvnow.de 416 | tvnow.de##.no-flash-box:has-text(Adblocker) 417 | ! === kiss.com.tw 418 | kiss.com.tw#@##ads 419 | ! === igeeksblog.com 420 | igeeksblog.com###quads-ad1_widget 421 | ! === linclik.com 422 | *$script,third-party,domain=linclik.com 423 | ! === espresso.repubblica.it 424 | ||espresso.repubblica.it/pw/pw2-espressosfoglio.js 425 | ! === net.hr 426 | net.hr#@#.reklama 427 | net.hr#@#.reklama1 428 | ! === televisa.com, lasestrellas.tv 429 | /adblock/*$domain=televisa.com|lasestrellas.tv 430 | ! === watson.ch 431 | watson.ch##.adget.frog_block_alert 432 | ! === stol.it 433 | stol.it###block-message 434 | ! === sledujufilmy.cz 435 | sledujufilmy.cz##.bottom-advert 436 | sledujufilmy.cz##.ads-position 437 | sledujufilmy.cz##.riding-banner 438 | ! === mycloud.to 439 | mycloud.to###jwa 440 | ! === mmorpgitalia.it 441 | mmorpgitalia.it##.noticeContainer:has-text(ADBLOCK) 442 | ! === insurancenewsnet.com, advisornews.com 443 | insurancenewsnet.com,advisornews.com##+js(abort-on-property-read.js, adblock_detect) 444 | ! === mmovie.it 445 | mmovie.it###advleft 446 | ! === zeperfs.com 447 | zeperfs.com##+js(noeval-if.js, AdBlock) 448 | ! === userupload.net,firstonetv.net 449 | userupload.net,firstonetv.net##+js(noeval-if.js, Adblock) 450 | ! === mashable.com, niezalezna.pl 451 | mashable.com,niezalezna.pl##+js(noeval-if.js, adblock) 452 | ! === iptvultra.com 453 | iptvultra.com##+js(setTimeout-defuser.js, div.table_download) 454 | ! === pcgames-download.com 455 | ||pcgames-download.com/wp-content/plugins/noadb-leftthenicemessage/ 456 | ! === grazia-magazin.de 457 | grazia-magazin.de##.subNaviNotification:has-text(Adblocker) 458 | ! === dreamfancy.org, trhileci.com 459 | ||metin2bot.net/kontrol/adb.js 460 | ! === afdah.to 461 | @@||afdah.to/show-ad$first-party 462 | ! === vertamedia.com 463 | @@||vertamedia.com/assets/img/adimage.png$first-party 464 | ! === rallye-magazin.de 465 | rallye-magazin.de###billboardattention 466 | ! === schwarzwaelder-bote.de 467 | schwarzwaelder-bote.de###blocker-note 468 | ! === wer-weiss-was.de 469 | wer-weiss-was.de###hint 470 | ! === peugeot-metropolis.de 471 | peugeot-metropolis.de###displaywise 472 | ! === topagrar.com 473 | ||topagrar.com/_themes/topagrar-responsive/_js/ads.js$script,redirect=noopjs 474 | ! === tagesspiegel.de 475 | /tgs.teaser-ad.js$domain=tagesspiegel.de 476 | ! === t3n.de 477 | t3n.de#@##adsbox 478 | ! === yiv.com 479 | yiv.com###LeftAdDiv 480 | yiv.com###RightAdDiv 481 | ! === agar.io 482 | agar.io###advertisement 483 | ! === dolldivine.com 484 | ||dolldivine.com/images/fairy-preview.jpg 485 | ! === peugeot-metropolis.de 486 | peugeot-metropolis.de##+js(abort-current-inline-script.js, $, #gandalfads) 487 | ! === warforum.cz 488 | warforum.cz###popwrapper 489 | ! === kisscartoon.io and related domains 490 | ||ad.kisscartoon.*^$important 491 | ! === randaris-anime.net 492 | randaris-anime.net##.advert1 493 | randaris-anime.net##.adblock-box 494 | ! === androidsage.com 495 | androidsage.com##+js(abort-on-property-read.js, blckad) 496 | ! === bento.de, pcgamer.com 497 | bento.de,pcgamer.com##+js(abort-on-property-read.js, _sp_.mms) 498 | ! === cwseed.com 499 | cwseed.com##+js(abort-on-property-read.js, wc.url) 500 | ! === wasabisyrup.com 501 | ||wasabisyrup.com/template/plugin02.js 502 | ! === prevention.com, avoiderrors.net, gulmeklazim.com 503 | ! === https://github.com/jspenguin2017/uBlockProtector/issues/589 504 | prevention.com,avoiderrors.net,gulmeklazim.com##+js(setTimeout-defuser.js, adblock) 505 | ! === getfree-bitcoin.com 506 | getfree-bitcoin.com##+js(setTimeout-defuser.js, Adblock) 507 | getfree-bitcoin.com##.left-advertisement 508 | getfree-bitcoin.com##a[href^="//mellowads.com/"] 509 | ! === estrenos10.com 510 | estrenos10.com##+js(setTimeout-defuser.js, AdBlock) 511 | ! === programinadresi.com 512 | programinadresi.com##+js(setTimeout-defuser.js, adBlock) 513 | ! === kshowes.net 514 | kshowes.net##+js(abort-current-inline-script.js, setTimeout, Im.offsetHeight<=0) 515 | kshowes.net###hide:style(display: block !important;) 516 | kshowes.net##input.buttonlink#contador 517 | ! === moat.com 518 | moat.com##+js(setTimeout-defuser.js, adbCheckBlocker) 519 | imleagues.com##+js(setTimeout-defuser.js, show_ads.js) 520 | ! === indiatimes.com 521 | indiatimes.com###append_overlay_photo_ads 522 | ! === nontonanime.org 523 | nontonanime.org##nav.navbar + div.banner > a[href^="https://goo.gl/"] 524 | ||eurifsiooyof.bid^$script,third-party 525 | ! === lavozdealmeria.es 526 | ||lavozdealmeria.es/js/addblock.js 527 | ! === all-in.de 528 | all-in.de###a_info 529 | ! === greenocktelegraph.co.uk 530 | greenocktelegraph.co.uk##.dfp-top-ad-container 531 | ! === ouo.press, ouo.io 532 | ||ouo.press/js/pop.t.js 533 | *$script,third-party,domain=ouo.press|ouo.io 534 | ! === linkkawy.com 535 | linkkawy.com###exestylepopupdiv 536 | ! === homebank.free.fr 537 | homebank.free.fr###disablemessage 538 | ! === getrelax.club 539 | getrelax.club##.loaded-popup-wrapper 540 | ! === mycinema.pro 541 | mycinema.pro##.adsbygoogle 542 | ! === okkazeo.com 543 | okkazeo.com###ads 544 | ! === digitalinformationworld.com 545 | digitalinformationworld.com##+js(abort-on-property-read.js, adsbygoogle) 546 | ! === moat.com 547 | @@||moat.com/creatives/advertiser/$first-party 548 | @@||moat.com/api/entity_report/advertiser/$first-party 549 | ! === mangashost.net,mangashost.com 550 | mangashost.net,mangashost.com##+js(setTimeout-defuser.js, ads160left) 551 | ! === cnn.com 552 | ||mms.cnn.com^$script 553 | ! === attorz.com 554 | attorz.com##+js(abort-on-property-write.js, isAdBlocked) 555 | attorz.com###lineage104_pic 556 | ! === resourcepacks24.de 557 | resourcepacks24.de##+js(setTimeout-defuser.js, google_jobrunner) 558 | ! === literaturcafe.de 559 | literaturcafe.de##+js(setTimeout-defuser.js, blockStatus) 560 | ! === deckshop.pro 561 | deckshop.pro###friendlyReminder 562 | ! === citytv.com 563 | citytv.com##.widget_ad-widget 564 | citytv.com##.adv_wrap 565 | citytv.com##.adv_leaderboard 566 | citytv.com##.ad_bigbox 567 | ! === maisgasolina.com 568 | maisgasolina.com##+js(setTimeout-defuser.js, window.google_jobrunner) 569 | ! === vaughnlive.tv 570 | @@||vaughnlive.tv/ad/banner/_adsense_/_adserver/_adview_.ad.json$xmlhttprequest,first-party 571 | ! === insuranceage.co.uk 572 | ||adpass.co.uk^ 573 | ! === strefadb.pl 574 | strefadb.pl###videoad 575 | ! === ultimate-catch.eu 576 | ultimate-catch.eu##.special-message-wrapper 577 | ! === alemdarleech.com 578 | alemdarleech.com##+js(abort-on-property-read.js, koddostu_com_adblock_yok) 579 | ! === communitech.ca 580 | communitech.ca#@#a[href*="/?aff="] 581 | ! === vidfile.net 582 | vidfile.net##.rek 583 | ! === strikeout.co 584 | ||cdn.cdnserv.pw/js/cnads.js$script,redirect=noopjs,domain=strikeout.co 585 | ! === crash-aerien.news 586 | crash-aerien.news##+js(abort-on-property-read.js, noPub) 587 | ! === gratisprogramas.co, gratisjuegos.co, gratispeliculas.xyz 588 | gratisprogramas.co,gratisjuegos.co,gratispeliculas.xyz##div[id^="hide"]:style(display: block !important;) 589 | gratisprogramas.co,gratisjuegos.co,gratispeliculas.xyz##input[id^="contar"] 590 | ! === freestocks.org 591 | freestocks.org##.popup 592 | ! === NSFW! pornhub.com 593 | pornhub.com##+js(abort-on-property-read.js, userABMessage) 594 | ! === rus.delfi.ee 595 | rus.delfi.ee###ab--notification-ribbon 596 | ! === imgur.com 597 | imgur.com##.footerlink-report-ads 598 | ! === simply-debrid.com 599 | simply-debrid.com##.adsbygoogle 600 | simply-debrid.com###google_ads:style(height: 1px !important; visibility: hidden !important;) 601 | ! === slader.com 602 | slader.com##+js(abort-on-property-read.js, sladerAbm) 603 | slader.com##section.solutions-list.loading:style(height: auto !important;) 604 | slader.com##.ads.ads-to-hide 605 | ! === jsfiddle.net 606 | jsfiddle.net###keep-us-running 607 | ! === animeheaven.eu 608 | @@||animeheaven.eu^$script,first-party 609 | ! === gej-porno.pl, animezone.pl, newpct.com 610 | gej-porno.pl#@#.myTestAd 611 | gej-porno.pl,animezone.pl,newpct.com##a[href^="//"] 612 | ! === m.delfi.ee 613 | m.delfi.ee##.md-banner-placement 614 | ! === jacquieetmicheltv.net 615 | jacquieetmicheltv.net##+js(abort-on-property-read.js, is_adblocked) 616 | ! === haberler.com 617 | haberler.com##.playButton 618 | ! === livesport.ws 619 | livesport.ws##+js(abort-on-property-read.js, document.avp_ready) 620 | ! === backin.net 621 | backin.net##+js(setTimeout-defuser.js, /myadz|adblock/) 622 | ! === stealive.club 623 | ||stealive.club/js/ht.js 624 | ! === mejorescanales.com 625 | mejorescanales.com##+js(abort-on-property-read.js, jQuery.adblock) 626 | ! === gr8forte.org 627 | gr8forte.org###alert-block 628 | gr8forte.org##+js(abort-on-property-read.js, clickNS) 629 | ! === diariosur.es 630 | ||static.vocento.com/adbd/ 631 | ! === flashx.tv, flashx.to 632 | flashx.tv,flashx.to##+js(abort-on-property-read.js, open) 633 | ||flashx.tv/checkembed.php 634 | ||static.flashx.tv/js/flashx.js$script 635 | ||static.flashx.tv/img/player.png$image 636 | ! === dailyuploads.net 637 | dailyuploads.net###adblockinfo 638 | ! === programminginsider.com 639 | programminginsider.com##+js(addEventListener-defuser.js, load, ad-blocker) 640 | programminginsider.com##.g1-top:style(display: block !important;) 641 | ! === allnorilsk.ru 642 | ||allnorilsk.ru/js/adb.js 643 | ! === discudemy.com 644 | discudemy.com##.closeAdBlock 645 | ! === okdiario.com 646 | ||okdiario.com/*/check-blocker.js 647 | ! === radioloyalty.com 648 | radioloyalty.com###bottomDisplayAd 649 | radioloyalty.com###mainDisplayAd 650 | ! === moviesroom.pl 651 | moviesroom.pl###advert-notice 652 | ! === playview.io 653 | playview.io##.ads_player 654 | @@||playview.io/*/showads.js$xmlhttprequest,first-party 655 | ! === dogecatch.website, dashcatch.xyz 656 | dogecatch.website,dashcatch.xyz###fuck-adb-not-enabled 657 | ! === depositfiles.com 658 | depositfiles.com##.adblock_alert 659 | ! === locopelis.com 660 | locopelis.com##.div-banner-popup-event 661 | locopelis.com##+js(abort-on-property-write.js, adbClick) 662 | ! === nba.com 663 | /assets/js/sourcepoint/*$script,domain=nba.com 664 | ! === nbc.com 665 | nbc.com##+js(abort-on-property-read.js, mps._ab) 666 | ! === eurogamer.de 667 | eurogamer.de##+js(abort-on-property-read.js, _sp_.msg.displayMessage) 668 | ! === deportesmax.info 669 | deportesmax.info###wmpu 670 | ! === msfn.org 671 | msfn.org##.displayGlobalMessage:has-text(ad-blocking) 672 | ! === theguardian.com 673 | theguardian.com##div.site-message:has(a[href^="https://membership.theguardian.com/"]) 674 | theguardian.com##.contributions__epic 675 | ! === krassotaa.com 676 | krassotaa.com###haider 677 | ! === onvasortir.com 678 | onvasortir.com##+js(abort-on-property-read.js, adBlockDetected) 679 | ! === kryminalnapolska.pl 680 | kryminalnapolska.pl##+js(abort-on-property-read.js, ai_adb_detected) 681 | ! === doublemesh.com 682 | doublemesh.com##+js(setTimeout-defuser.js, ads) 683 | ! === crockolinks.com 684 | crockolinks.com##+js(addEventListener-defuser.js, mousedown) 685 | ! === NSFW! fakeporn.tv 686 | fakeporn.tv##+js(setTimeout-defuser.js, innerText) 687 | fakeporn.tv##+js(abort-on-property-write.js, prPuShown) 688 | ! === bigbtc.win 689 | bigbtc.win##+js(abort-on-property-read.js, ad_block_test) 690 | ! === github.com 691 | @@/adguard.$domain=github.com 692 | ! === askleo.com 693 | askleo.com##[class^="askleo_adblock1"] 694 | ! === mope.io 695 | ||mope.io/img/blocked.png$image,first-party 696 | ! === geektyper.com 697 | geektyper.com###itemz 698 | ! === demotywatory.pl 699 | ||demotywatory.pl/res/js/advertisement.js$script,important 700 | ! === twinsagadb.com 701 | twinsagadb.com##.top-content 702 | ! === redtube.com 703 | redtube.com###video_right_col > .clearfix 704 | redtube.com##div[class][style]:has(> a.removeAdLink) 705 | redtube.com##div[class][style]:has(> div[class][style] > a.removeAdLink) 706 | @@||rdtcdn.com^$script,domain=redtube.com 707 | ! === bild.de 708 | ||acdn.adnxs.com/*/adplayer.css$stylesheet,redirect=noopcss,domain=bild.de 709 | ! === blockads.fivefilters.org 710 | ||blockads.fivefilters.org$inline-script 711 | blockads.fivefilters.org###no-blocking:style(display: block !important;) 712 | 713 | # ------------------------------------------------------------------------------------------------------------------- # 714 | -------------------------------------------------------------------------------- /list/4-generichide.txt: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------------------------------------------- # 2 | 3 | @@||20min.ch^$generichide 4 | @@||24opole.pl^$generichide 5 | @@||7sim.net^$generichide 6 | @@||aftonbladet.se^$generichide 7 | @@||al.ly^$generichide 8 | @@||ally.sh^$generichide 9 | @@||ani.gamer.com.tw^$generichide 10 | @@||atresplayer.com^$generichide 11 | @@||behindwoods.com^$generichide 12 | @@||cbs.com^$generichide 13 | @@||citytv.com^$generichide 14 | @@||comicallyincorrect.com^$generichide 15 | @@||ff14angler.com^$generichide 16 | @@||flooxer.com^$generichide 17 | @@||freedomoutpost.com^$generichide 18 | @@||gala.de^$generichide 19 | @@||gamestar.de^$generichide 20 | @@||getrelax.club^$generichide 21 | @@||globalbesthosting.com^$generichide 22 | @@||greenocktelegraph.co.uk^$generichide 23 | @@||hells-hack.com^$generichide 24 | @@||imleagues.com^$generichide 25 | @@||leech.ae^$generichide 26 | @@||libertyunyielding.com^$generichide 27 | @@||linksh.top^$generichide 28 | @@||lolstat.gg^$generichide 29 | @@||main-echo.de^$generichide 30 | @@||mitele.es^$generichide 31 | @@||mycinema.pro^$generichide 32 | @@||playstation.com^$generichide 33 | @@||randaris-anime.net^$generichide 34 | @@||simply-debrid.com^$generichide 35 | @@||stream.nbcsports.com^$generichide 36 | @@||streamplay.gdn^$generichide 37 | @@||symbolab.com^$generichide 38 | @@||tv.yahoo.com^$generichide 39 | @@||tvsportslive.stream^$generichide 40 | @@||viz.com^$generichide 41 | @@||wp.pl^$generichide 42 | @@||yiv.com^$generichide 43 | 44 | # ------------------------------------------------------------------------------------------------------------------- # 45 | -------------------------------------------------------------------------------- /list/5-whitelist.txt: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------------------------------------------- # 2 | 3 | # These exceptions will not allow ads to show 4 | 5 | # ------------------------------------------------------------------------------------------------------------------- # 6 | 7 | # https://github.com/jspenguin2017/uBlockProtector/issues/155 8 | @@||imasdk.googleapis.com/js/sdkloader/outstream.js$script,domain=ovar.io 9 | 10 | # https://github.com/jspenguin2017/uBlockProtector/issues/338 11 | @@||edgedatg.com^$script,domain=abc.go.com 12 | 13 | # ------------------------------------------------------------------------------------------------------------------- # 14 | 15 | @@||flashx1.tv/js/showad*.js$script 16 | @@||flashx1.tv/sidead.js$script 17 | @@||flashx1.tv/jquery2.js$script 18 | @@||flashx.tv/counter.cgi$script 19 | @@||flashx.to/counter.cgi$script 20 | @@||zencdn.net^$script,domain=flashx.tv 21 | @@/showad_.js$script,domain=flashx.to 22 | 23 | @@/crossdomain.xml$domain=channel4.com 24 | @@||ak.http.anno.channel4.com^$domain=channel4.com 25 | @@||cf.http.anno.channel4.com^$domain=channel4.com 26 | 27 | @@||playapi.mtgx.tv/v3/adinfo?$xmlhttprequest,domain=tvplay.skaties.lv|play.tv3.lt|tv3play.tv3.ee|play.nova.bg 28 | 29 | @@||acortar.net/rollups/aes.js$domain=dclinks.info 30 | 31 | @@||akamaihd.net^$xmlhttprequest,script,domain=mitele.es 32 | 33 | @@||fwmrm.net^$domain=viasatsport.se 34 | ||freewheel-mtgx-tv.akamaized.net^$media,domain=viasatsport.se 35 | ||fwmrm.net^$image,important,domain=viasatsport.se 36 | ||fwmrm.net/ad/*$xmlhttprequest,important,redirect=nooptext,domain=viasatsport.se 37 | 38 | @@||moatads.com/*/moatwrapper.js$script,domain=viz.com 39 | 40 | # ------------------------------------------------------------------------------------------------------------------- # 41 | -------------------------------------------------------------------------------- /notes/extension-development.md: -------------------------------------------------------------------------------- 1 | # Notes for Chromium extension development 2 | 3 | ## Generic notes 4 | 5 | Official manifest documentation page: 6 | https://developer.chrome.com/extensions/manifest 7 | 8 | Official API documentation page: 9 | https://developer.chrome.com/extensions/api_index 10 | 11 | Chromium documentation is generated, which means it sometimes includes weird 12 | things. Here are some extra notes that might be helpful. 13 | 14 | ### Notes for manifest fields 15 | 16 | * `automation`: Experimental, https://developer.chrome.com/extensions/automation 17 | * `background_page`: This field is probably here for legacy reasons, use 18 | `background` with field `page` instead 19 | * `content_capabilities`: Internal use for Chromium developers only, 20 | https://bugs.chromium.org/p/chromium/issues/detail?id=573504 21 | * `converted_from_user_script`: Internally used by Chromium, used to mark an 22 | extension as Userscript, I think it is legacy now 23 | * `current_locale`: Internally used by Chromium, used to detect locale changes 24 | so it can update extension UI 25 | * `input_components`: Used by extensions that acts as Input Method Editor, I 26 | think it only works on Chromium OS, 27 | https://bugs.chromium.org/p/chromium/issues/detail?id=340961#c12 28 | * `oauth2`: OAuth2 related, I think it is legacy now, `chrome.identity` is 29 | probably better, https://developer.chrome.com/extensions/identity 30 | https://stackoverflow.com/questions/35199571/chrome-extension-with-oauth2 31 | * `platforms`: Used by Native Clients to separate download packages, 32 | https://stackoverflow.com/questions/30397450/what-is-platforms-for-in-manifest-json 33 | * `signature`: After 1 hour of research, I found precisely 0 documenation on 34 | it, I guess it has something to do with extension packaging, probably filled 35 | internally by Chromium packaging tool, 36 | https://developer.chrome.com/extensions/packaging 37 | * `spellcheck`: Add spellcheck dictionary, not sure if it is still experimental, 38 | https://stackoverflow.com/questions/21270403/custom-spelling-in-google-chrome 39 | * `system_indicator`: Add tray icons, it is being removed, 40 | https://bugs.chromium.org/p/chromium/issues/detail?id=142450 41 | 42 | ### Notes for permissions 43 | 44 | * `displaySource`: Experimental, documentation page returns 404 not found, 45 | https://bugs.chromium.org/p/chromium/issues/detail?id=702686 46 | * `idltest`: Internal use for Chromium developers only, documentation page 47 | returns 404 not found, 48 | https://bugs.chromium.org/p/chromium/issues/detail?id=644010 49 | 50 | ## Specific notes for Nano Defender 51 | 52 | ### Requested permissions 53 | 54 | * `tabs`: To enforce UserCSS rules 55 | * `webNavigation`: To know the URL of each tab and frame in order to properly 56 | enforce redirection rules 57 | * `webRequest`: To enforce redirection rules 58 | * `webRequestBlocking`: Some `webRequest` handling need to be synchronous 59 | * `http://*/*`, `https://*/*`: To enforce generic content script rules (along 60 | with other rules) 61 | 62 | ### Permissions that might be useful 63 | 64 | * `cookies`: Could be useful when monitoring changes to a cookie is needed, but 65 | this is asynchronous, could be hard to use 66 | -------------------------------------------------------------------------------- /notes/issue-reporter.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy for Quick Issue Reporter 2 | 3 | This Privacy Policy (the "Policy") applies to the Quick Issue Reporter 4 | (the "Tool") published and distributed by @jspenguin2017 (the "Author"). 5 | The Author has little control over forks of the Tool so the Policy may 6 | not apply to them. Furthermore, the Policy only applies to latest unmodified 7 | production builds of the Tool. 8 | 9 | The Tool allows you to quickly report issues related to Nano Adblocker and Nano 10 | Defender (the "Projects") you encounter when browsing the Internet. 11 | 12 | The Tool will only collect your data when you actively use it, and will not 13 | connect to remote servers before the "Send" button is clicked. 14 | 15 | By using the Tool, you consent to: 16 | - The most recent version of the Policy, 17 | - The [privacy policy of GeoJS](https://www.geojs.io/privacy/), 18 | - The [privacy policy of MaxMind](https://www.maxmind.com/en/privacy-policy), 19 | - The 20 | [privacy policy of GitHub](https://help.github.com/en/articles/github-privacy-statement), 21 | and 22 | - The [privacy policy of GitLab](https://about.gitlab.com/privacy/) 23 | 24 | ### Data Collection and Usage 25 | 26 | 1. Your IP address 27 | - We may use GeoJS and/or MaxMind to process your IP address 28 | - You can use a VPN, but make sure that the issue you are reporting can be 29 | reproduced while using your VPN 30 | - The country (if not available, the continent and/or the ISP) that your IP 31 | address belongs to may be shared publicly 32 | 2. User agent string of your browser 33 | - Do not try to mask or change it; if the maintainers are unable to 34 | reproduce the issue, your report will be ignored 35 | 3. Version string of the Projects that you are using 36 | 4. The URL of the page where the Tool is opened 37 | - You are responsible in ensuring that you are not opening the Tool on a 38 | page where the URL is sensitive 39 | 5. The form that you have filled 40 | - If you supplied a test account in the form, that account will not be 41 | shared publicly (it may still be shared with a selected group of 42 | people) 43 | - Please note that although the Author will only select people he trusts 44 | to be part of the group, there is no guarantee of any sort 45 | - The Author takes no responsibility for the actions of other people in 46 | the group 47 | - You are responsible in ensuring information you entered into this form 48 | is not sensitive in nature and test accounts that you supplied contain 49 | only test data 50 | - Please refrain from submitting personally identifiable information 51 | 52 | Collected data will be used to improve the Projects, as well as related 53 | projects such as uAssets. Collected data may be shared with a selected group of 54 | people or publicly unless otherwise indicated above. 55 | 56 | ### Data Deletion 57 | 58 | By using the Tool, you are contributing to open source projects, and you may 59 | not take back your contributions at a later date. 60 | 61 | ### Security Practices 62 | 63 | The server acting as temporary storage is controlled by the Author and has 64 | systems in place to prevent unauthorized access: 65 | - Two Factor Authentication on Amazon Web Services root account 66 | - Public key authentication for Secure Shell access 67 | - Firewall with only necessary ports open 68 | - Automatic HTTPS upgrade for production endpoints 69 | 70 | Moderated reports are stored in GitHub and/or GitLab issues trackers. 71 | 72 | Please note that although the Author is committed in keeping his server secure, 73 | there is no guarantee of any sort. Like many other open source projects, the 74 | Tool is delivered as-is and comes with absolutely no warranty. 75 | 76 | ### Alternative Solutions 77 | 78 | You can report issues to respective issues trackers manually. 79 | 80 | ### Future Versions 81 | 82 | The Policy may be modified at any time, with or without notice. 83 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiCybora/NanoDefenderFirefox/2006d69afdefbbb2dcd1b2dca31bb2a516efc4d1/screenshot.png -------------------------------------------------------------------------------- /src/background/core.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Core library for background rules 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | a.init = () => { 30 | 31 | // ------------------------------------------------------------------------------------------------------------- // 32 | 33 | // Internal messaging 34 | 35 | chrome.runtime.onMessage.addListener((msg, sender, res) => { 36 | if (msg instanceof Object === false || sender instanceof Object === false || typeof res !== "function") 37 | return; 38 | 39 | if (typeof msg.cmd !== "string" || sender.tab instanceof Object === false) 40 | return; 41 | 42 | const tab = sender.tab.id; 43 | const frame = sender.frameId || 0; 44 | 45 | if (typeof tab !== "number" || typeof frame !== "number") 46 | return; 47 | 48 | switch (msg.cmd) { 49 | // Inject UserCSS to caller frame 50 | // 51 | // data - CSS code to inject 52 | case "inject css": 53 | if (typeof msg.data === "string") 54 | a.userCSS(tab, frame, msg.data); 55 | break; 56 | 57 | // Send a highly privileged XMLHttpRequest, it ignores Cross Origin Resource Sharing policies as well as 58 | // adblocker filtering 59 | // Requests must be explicitly whitelisted in a.sanitizeXhr() 60 | // 61 | // details - Details object, see a.xhr() 62 | // 63 | // Returns the response text, or null if the request failed 64 | case "xhr": 65 | if (msg.details instanceof Object) { 66 | const sanitizedDetails = a.sanitizeXhr(sender, msg.details); 67 | if (!sanitizedDetails) 68 | return; 69 | 70 | const onError = () => { 71 | res(null); 72 | }; 73 | 74 | if (a.xhr(sanitizedDetails, res, onError)) { 75 | // Must return true since I need to respond to content script asynchronously 76 | return true; 77 | } else { 78 | onError(); 79 | } 80 | } 81 | break; 82 | 83 | // Forcefully close the caller tab 84 | case "remove tab": 85 | if (tab !== chrome.tabs.TAB_ID_NONE) 86 | chrome.tabs.remove(tab, a.noopErr); 87 | break; 88 | 89 | //@pragma-if-debug 90 | 91 | case "log": 92 | if (a.debugMode) 93 | console.log(msg.data); 94 | break; 95 | 96 | //@pragma-end-if 97 | 98 | default: 99 | break; 100 | } 101 | }); 102 | 103 | // ------------------------------------------------------------------------------------------------------------- // 104 | 105 | // External messaging 106 | 107 | const reporter = chrome.runtime.getURL("/reporter/index.html"); 108 | 109 | chrome.runtime.onMessageExternal.addListener((msg, sender, res) => { 110 | if (msg instanceof Object === false || sender instanceof Object === false || typeof res !== "function") 111 | return; 112 | 113 | if (typeof msg.data !== "string" || sender.id !== a.NanoAdblockerExtensionID) 114 | return; 115 | 116 | switch (msg.data) { 117 | case "Ping": 118 | res({ data: "ok" }); 119 | break; 120 | 121 | case "Open Quick Issue Reporter": 122 | if (typeof msg.tab === "number") { 123 | chrome.tabs.create({ url: reporter + "?" + msg.tab.toString() }); 124 | res({ data: "ok" }); 125 | } 126 | break; 127 | 128 | default: 129 | break; 130 | } 131 | }); 132 | 133 | setTimeout(() => { 134 | chrome.runtime.sendMessage( 135 | a.NanoAdblockerExtensionID, 136 | { 137 | data: "Nano Defender Enabled", 138 | }, 139 | a.noopErr, 140 | ); 141 | }, 15 * 1000); 142 | 143 | // ------------------------------------------------------------------------------------------------------------- // 144 | 145 | // Taken from https://bit.ly/2OJzDAI (GitHub gorhill/uBlock) 146 | 147 | const root = chrome.runtime.getURL("/"); 148 | 149 | chrome.webRequest.onBeforeRequest.addListener( 150 | (details) => { 151 | if (!details.url.endsWith(a.rSecret)) 152 | return { redirectUrl: root }; 153 | }, 154 | { 155 | urls: [ 156 | a.rRoot + "*", 157 | ], 158 | }, 159 | [ 160 | "blocking", 161 | ], 162 | ); 163 | 164 | // ------------------------------------------------------------------------------------------------------------- // 165 | 166 | //@pragma-if-debug 167 | 168 | if (a.debugMode) { 169 | chrome.browserAction.setBadgeText({ text: "DBG" }); 170 | chrome.browserAction.setBadgeBackgroundColor({ color: "#406BD1" }); 171 | } else { 172 | chrome.browserAction.setBadgeText({ text: "DEV" }); 173 | chrome.browserAction.setBadgeBackgroundColor({ color: "#00871D" }); 174 | } 175 | 176 | //@pragma-end-if 177 | 178 | // ------------------------------------------------------------------------------------------------------------- // 179 | 180 | const hasNews = false; 181 | 182 | const newsPage = "https://jspenguin2017.github.io/uBlockProtector/#announcements"; 183 | const newsReadFlag = "news-read"; 184 | 185 | // This handler becomes inactive when there is a popup page set 186 | chrome.browserAction.onClicked.addListener(() => { 187 | chrome.browserAction.setBadgeText({ text: "" }); 188 | 189 | // IMPORTANT: This must match the manifest 190 | chrome.browserAction.setPopup({ popup: "popup/index.html" }); 191 | 192 | localStorage.setItem(newsReadFlag, "true"); 193 | 194 | chrome.tabs.create({ url: newsPage }); 195 | }); 196 | 197 | if (hasNews) { 198 | if (!chrome.extension.inIncognitoContext && !localStorage.getItem(newsReadFlag)) { 199 | chrome.browserAction.setBadgeText({ text: "NEW" }); 200 | chrome.browserAction.setBadgeBackgroundColor({ color: "#FF0000" }); 201 | 202 | chrome.browserAction.setPopup({ popup: "" }); 203 | } 204 | } else { 205 | localStorage.removeItem(newsReadFlag); 206 | } 207 | 208 | // ------------------------------------------------------------------------------------------------------------- // 209 | 210 | }; 211 | 212 | // ----------------------------------------------------------------------------------------------------------------- // 213 | 214 | a.noopErr = () => { 215 | void chrome.runtime.lastError; 216 | }; 217 | 218 | // ----------------------------------------------------------------------------------------------------------------- // 219 | 220 | a.cryptoRandom = () => { 221 | const array = new Uint32Array(4); 222 | crypto.getRandomValues(array); 223 | 224 | let out = ""; 225 | for (const entry of array) 226 | out += entry.toString(16); 227 | 228 | return out; 229 | }; 230 | 231 | // ----------------------------------------------------------------------------------------------------------------- // 232 | 233 | // Redirect helpers 234 | 235 | a.rSecret = a.cryptoRandom(); 236 | 237 | a.rRoot = chrome.runtime.getURL("/resources/"); 238 | 239 | a.rLink = (name) => { 240 | return a.rRoot + name + "?s=" + a.rSecret; 241 | }; 242 | 243 | // ----------------------------------------------------------------------------------------------------------------- // 244 | 245 | // Redirect resources 246 | 247 | // 1 second blank video, taken from https://bit.ly/2JcYAyq (GitHub uBlockOrigin/uAssets). 248 | a.blankMP4 = a.rLink("blank.mp4"); 249 | 250 | // ----------------------------------------------------------------------------------------------------------------- // 251 | 252 | // tab - Id of the tab 253 | // frame - Id of the frame 254 | // 255 | // Returns the Url of the tab, or an empty string if it is not known 256 | a.getTabURL = (() => { 257 | // tabs[tabId][frameId] = url 258 | const tabs = {}; 259 | 260 | //@pragma-if-debug 261 | 262 | if (a.debugMode) 263 | window.getTabURLInternal = tabs; 264 | 265 | //@pragma-end-if 266 | 267 | chrome.tabs.query({discarded: false}, (existingTabs) => { 268 | for (const existingTab of existingTabs) { 269 | const id = existingTab.id; 270 | if (id === chrome.tabs.TAB_ID_NONE) 271 | continue; 272 | 273 | if (!tabs[id]) 274 | tabs[id] = {}; 275 | 276 | // Keep existing Url because that is probably more up to date 277 | tabs[id][0] = tabs[id][0] || existingTab.url; 278 | 279 | chrome.webNavigation.getAllFrames({ tabId: id }, (frames) => { 280 | if (chrome.runtime.lastError) 281 | return; 282 | 283 | if (!tabs[id]) 284 | return; 285 | 286 | for (const frame of frames) { 287 | const frameId = frame.frameId; 288 | 289 | // Keep existing Url like before 290 | tabs[id][frameId] = tabs[id][frameId] || frame.url; 291 | } 292 | }); 293 | } 294 | }); 295 | 296 | chrome.webNavigation.onCommitted.addListener((details) => { 297 | const { tabId, frameId, url } = details; 298 | 299 | // Clear store when the tab has navigated 300 | if (!tabs[tabId] || frameId === 0) 301 | tabs[tabId] = {}; 302 | 303 | tabs[tabId][frameId] = url; 304 | }); 305 | 306 | chrome.tabs.onRemoved.addListener((id) => { 307 | delete tabs[id]; 308 | }); 309 | 310 | return (tab, frame) => { 311 | if (tabs[tab]) 312 | return tabs[tab][frame] || ""; 313 | else 314 | return ""; 315 | }; 316 | })(); 317 | 318 | // Check if the domain of an URL ends with one of the domains in the list 319 | // A list entry "example.com" will match domains that matches /(^|.*\.)example\.com$/ 320 | // 321 | // url - URL to check 322 | // domList - List of domains to compare 323 | // isMatch - Whether the domains list is a match list 324 | // 325 | // Returns true if the domain of the URL is in the list, false otherwise 326 | a.domCmp = (() => { 327 | const domainExtractor = /^https?:\/\/([^/:?#]+)/; 328 | 329 | return (url, domList, isMatch) => { 330 | let dom = domainExtractor.exec(url); 331 | if (!dom) 332 | return false; 333 | 334 | dom = dom[1]; 335 | 336 | for (const entry of domList) { 337 | if ( 338 | dom.endsWith(entry) && 339 | ( 340 | dom.length === entry.length || 341 | dom.charAt(dom.length - entry.length - 1) === "." 342 | ) 343 | ) { 344 | return true === isMatch; 345 | } 346 | } 347 | 348 | return false === isMatch; 349 | }; 350 | })(); 351 | 352 | // ----------------------------------------------------------------------------------------------------------------- // 353 | 354 | // urls - Urls to loopback 355 | // types - Types of request to loopback 356 | // data - Data to loopback to, must be already encoded and ready to serve 357 | // domList - Domains list, omit to match all domains 358 | // isMatch - Whether the domains list is a match list, defaults to true 359 | a.staticServer = (urls, types, data, domList, isMatch = true) => { 360 | chrome.webRequest.onBeforeRequest.addListener( 361 | (details) => { 362 | const url = a.getTabURL(details.tabId, details.frameId); 363 | 364 | if (!domList || a.domCmp(url, domList, isMatch)) { 365 | 366 | //@pragma-if-debug 367 | 368 | if (a.debugMode) 369 | console.log("Redirected " + details.url + " to " + data); 370 | 371 | //@pragma-end-if 372 | 373 | return { redirectUrl: data }; 374 | } 375 | }, 376 | { 377 | urls: urls, 378 | types: types, 379 | }, 380 | [ 381 | "blocking", 382 | ], 383 | ); 384 | }; 385 | 386 | // urls - Urls to loopback 387 | // types - Types of request to loopback 388 | // server - Server function, it will be passed as the event listener, view Chromium API documentations for more 389 | // information: https://developer.chrome.com/extensions/webRequest 390 | // domList - Domains list, omit to match all domains 391 | // isMatch - Whether the domains list is a match list, defaults to true 392 | // onWhat - Triggering condition of webRequest, defaults to "onBeforeRequest" 393 | a.dynamicServer = (urls, types, server, domList, isMatch = true, onWhat="onBeforeRequest") => { 394 | let blockRes = ["blocking"]; 395 | if (onWhat === "onBeforeSendHeaders") blockRes.push("requestHeaders"); 396 | if (onWhat === "onHeadersReceived") blockRes.push("responseHeaders"); 397 | chrome.webRequest[onWhat].addListener( 398 | (details) => { 399 | const url = a.getTabURL(details.tabId, details.frameId); 400 | 401 | if (!domList || a.domCmp(url, domList, isMatch)) { 402 | const response = server(details); 403 | 404 | //@pragma-if-debug 405 | 406 | if (a.debugMode && response) { 407 | if (response.cancel) 408 | console.log("Cancelled " + details.url); 409 | else if (response.redirectUrl) 410 | console.log("Redirected " + details.url + " to " + response.redirectUrl); 411 | } 412 | 413 | //@pragma-end-if 414 | 415 | return response; 416 | } 417 | }, 418 | { 419 | urls: urls, 420 | types: types, 421 | }, 422 | blockRes, 423 | ); 424 | }; 425 | 426 | // ----------------------------------------------------------------------------------------------------------------- // 427 | 428 | // tab - Target tab 429 | // frame - Target frame 430 | // code - CSS code to inject 431 | a.userCSS = (tab, frame, code) => { 432 | if (tab === chrome.tabs.TAB_ID_NONE) 433 | return; 434 | 435 | chrome.tabs.insertCSS(tab, { 436 | code: code, 437 | cssOrigin: "user", 438 | frameId: frame, 439 | }, a.noopErr); 440 | }; 441 | 442 | a.sanitizeXhr = (sener, details) => { 443 | // Nothing is allowed for now 444 | return null; 445 | }; 446 | 447 | // details - Details about this request 448 | // method - Method of the request, can be 'GET' or 'POST' 449 | // url - Url of the request 450 | // headers - Headers of the request, optional 451 | // payload - Payload of the request, optional 452 | // onload - Load handler 453 | // response - Response text 454 | // onerror - Error handler 455 | // 456 | // Returns true if the request is sent, false if details are not valid and the request was not sent 457 | a.xhr = (details, onload, onerror) => { 458 | if (typeof details.method !== "string" || typeof details.url !== "string") 459 | return false; 460 | 461 | if (details.method !== "GET" && details.method !== "POST") 462 | return false; 463 | 464 | console.log("[Nano] Cross Origin Request ::", details.url); 465 | 466 | const req = new XMLHttpRequest(); 467 | 468 | req.onreadystatechange = () => { 469 | if (req.readyState !== XMLHttpRequest.DONE) 470 | return; 471 | 472 | if (req.status === 200) 473 | onload(req.responseText); 474 | else 475 | onerror(); 476 | }; 477 | 478 | req.open(details.method, details.url); 479 | 480 | if (details.headers instanceof Object) { 481 | for (const key in details.headers) { 482 | const header = details.headers[key]; 483 | 484 | if (details.headers.hasOwnProperty(key) && typeof header === "string") 485 | req.setRequestHeader(key, header); 486 | } 487 | } 488 | 489 | if (typeof details.payload === "string") 490 | req.send(payload); 491 | else 492 | req.send(null); 493 | 494 | return true; 495 | }; 496 | 497 | // ----------------------------------------------------------------------------------------------------------------- // 498 | 499 | a.generic = () => { 500 | a.staticServer( 501 | [ 502 | "http://*.medianetworkinternational.com/js/advertisement.js*", 503 | ], 504 | [ 505 | "script", 506 | ], 507 | a.rLink("jquery.js"), 508 | ); 509 | 510 | // Not working correctly 511 | /* 512 | a.staticServer( 513 | [ 514 | "https://imasdk.googleapis.com/js/sdkloader/ima3.js*", 515 | "http://imasdk.googleapis.com/js/sdkloader/ima3.js*", 516 | ], 517 | [ 518 | "script", 519 | ], 520 | a.rLink("ima3.js"), 521 | // List whitelisted domains in the array 522 | //[ 523 | //], 524 | //false, 525 | ); 526 | */ 527 | 528 | a.staticServer( 529 | [ 530 | "https://*.moatads.com/*/MoatFreeWheelJSPEM.js*", 531 | ], 532 | [ 533 | "script", 534 | ], 535 | a.rLink("fw.js"), 536 | ); 537 | }; 538 | 539 | // ----------------------------------------------------------------------------------------------------------------- // 540 | 541 | //@pragma-if-debug 542 | 543 | // Attempt to make the server think the request is from a different IP, rarely works 544 | // Only available in debug mode 545 | // 546 | // urls - Urls to activate on 547 | // ip - Camouflage Ip, keep in mind that the server still have access to your real Ip 548 | // log - Whether details should be logged to console for every matched request, defaults to false 549 | a.proxy = (urls, ip, log) => { 550 | if (!a.debugMode) 551 | return void console.error("a.proxy() is only available in debug mode."); 552 | 553 | chrome.webRequest.onBeforeSendHeaders.addListener( 554 | (details) => { 555 | details.requestHeaders.push({ 556 | name: "X-Forwarded-For", 557 | value: ip, 558 | }); 559 | 560 | details.requestHeaders.push({ 561 | name: "Client-IP", 562 | value: ip, 563 | }); 564 | 565 | if (log) 566 | console.log(details); 567 | 568 | return { requestHeaders: details.requestHeaders }; 569 | }, 570 | { 571 | urls: urls, 572 | }, 573 | [ 574 | "blocking", 575 | "requestHeaders", 576 | ], 577 | ); 578 | }; 579 | 580 | //@pragma-end-if 581 | 582 | // ----------------------------------------------------------------------------------------------------------------- // 583 | -------------------------------------------------------------------------------- /src/background/debug.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Background rules for debugging, only run in debug mode 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | //@pragma-if-debug 30 | 31 | // ----------------------------------------------------------------------------------------------------------------- // 32 | 33 | // Tools 34 | 35 | if (a.debugMode) { 36 | 37 | { 38 | // https://github.com/jspenguin2017/uBlockProtector/issues/338 39 | 40 | a.proxy( 41 | [ 42 | "*://*.go.com/*", 43 | "*://go.com/*", 44 | ], 45 | "107.77.200.10", 46 | ); 47 | } 48 | 49 | { 50 | // https://github.com/jspenguin2017/uBlockProtector/issues/286 51 | 52 | a.proxy( 53 | [ 54 | "*://*.itv.com/*", 55 | "*://itv.com/*", 56 | ], 57 | "88.82.2.10", 58 | ); 59 | } 60 | 61 | { 62 | // https://gitlab.com/xuhaiyang1234/NanoAdblockerSecretIssues/issues/10 63 | 64 | a.proxy( 65 | [ 66 | "*://*.tvnow.de/*", 67 | "*://tvnow.de/*", 68 | ], 69 | "46.101.180.199", 70 | ); 71 | } 72 | 73 | // a.proxy() does not work for: 74 | // topserialy.to 75 | // viasport.fi 76 | 77 | } 78 | 79 | // ----------------------------------------------------------------------------------------------------------------- // 80 | 81 | // Rules 82 | 83 | if (a.debugMode) { 84 | 85 | { 86 | // https://github.com/uBlockOrigin/uAssets/issues/772 87 | 88 | const reBlock = /^https?:\/\/(?:[^.]*?\.)?uplynk\.com\/api\/v3\/preplay\//; 89 | const reStrip = /^https?:\/\/(?:[^.]*?\.)?uplynk\.com\/ext\/[^?]*\.m3u8\?/; 90 | 91 | a.dynamicServer( 92 | [ 93 | "*://*.uplynk.com/*", 94 | "*://uplynk.com/*", 95 | ], 96 | [ 97 | "xmlhttprequest", 98 | ], 99 | (details) => { 100 | if (reBlock.test(details.url)) { 101 | return { cancel: true }; 102 | } else if (reStrip.test(details.url)) { 103 | const i = details.url.indexOf('?'); 104 | return { redirectUrl: details.url.substring(0, i) }; 105 | } 106 | }, 107 | ); 108 | } 109 | 110 | { 111 | // https://github.com/jspenguin2017/uBlockProtector/issues/1015 112 | 113 | chrome.webRequest.onBeforeSendHeaders.addListener( 114 | (details) => { 115 | for (const header of details.requestHeaders) { 116 | if (header.name === "User-Agent") 117 | header.value = "curl/7.47.0"; 118 | } 119 | return { requestHeaders: details.requestHeaders }; 120 | }, 121 | { 122 | urls: [ 123 | "*://5k4i.com/*", 124 | "*://ceesty.com/*", 125 | "*://clkme.me/*", 126 | "*://clkmein.com/*", 127 | "*://cllkme.com/*", 128 | "*://corneey.com/*", 129 | "*://destyy.com/*", 130 | "*://festyy.com/*", 131 | "*://gestyy.com/*", 132 | "*://iklan.master-cyber.com/*", 133 | "*://links.orgasmatrix.com/*", 134 | "*://pj45.com/*", 135 | "*://sh.st/*", 136 | "*://shorte.st/*", 137 | "*://skiip.me/*", 138 | "*://viid.me/*", 139 | "*://wiid.me/*", 140 | "*://wik34.com/*", 141 | "*://xiw34.com/*", 142 | "*://zryydi.com/*", 143 | ], 144 | types: [ 145 | "main_frame", 146 | "sub_frame", 147 | ], 148 | }, 149 | [ 150 | "blocking", 151 | "requestHeaders", 152 | ], 153 | ); 154 | } 155 | 156 | } 157 | 158 | // ----------------------------------------------------------------------------------------------------------------- // 159 | 160 | //@pragma-end-if 161 | 162 | // ----------------------------------------------------------------------------------------------------------------- // 163 | -------------------------------------------------------------------------------- /src/background/rules.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Background rules 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | a.init(); 30 | a.generic(); 31 | 32 | // ----------------------------------------------------------------------------------------------------------------- // 33 | 34 | { 35 | 36 | // No specific rules for now 37 | 38 | } 39 | 40 | // ----------------------------------------------------------------------------------------------------------------- // 41 | -------------------------------------------------------------------------------- /src/common.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Common constants and initializations for background and content script 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | var a = {}; 30 | 31 | // ----------------------------------------------------------------------------------------------------------------- // 32 | 33 | //@pragma-if-debug 34 | 35 | a.debugMode = true; 36 | 37 | //@pragma-end-if 38 | 39 | // ----------------------------------------------------------------------------------------------------------------- // 40 | -------------------------------------------------------------------------------- /src/content/debug.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Content rules for debugging 22 | // Only run in debug mode 23 | 24 | // ----------------------------------------------------------------------------------------------------------------- // 25 | 26 | "use strict"; 27 | 28 | // ----------------------------------------------------------------------------------------------------------------- // 29 | 30 | //@pragma-if-debug 31 | 32 | // ----------------------------------------------------------------------------------------------------------------- // 33 | 34 | // Tools 35 | 36 | if (a.debugMode) { 37 | 38 | // ------------------------------------------------------------------------------------------------------------- // 39 | 40 | // Force Twitch to show debug logs 41 | if (a.domCmp([ 42 | "twitch.tv", 43 | ], true)) { 44 | a.readOnly("log", "window.console.log.bind(window.console)", "window.console"); 45 | a.readOnly("warn", "window.console.warn.bind(window.console)", "window.console"); 46 | a.readOnly("error", "window.console.error.bind(window.console)", "window.console"); 47 | } 48 | 49 | // ------------------------------------------------------------------------------------------------------------- // 50 | 51 | } 52 | 53 | // ----------------------------------------------------------------------------------------------------------------- // 54 | 55 | // Rules 56 | 57 | if (a.debugMode) { 58 | 59 | // ------------------------------------------------------------------------------------------------------------- // 60 | 61 | // https://github.com/NanoAdblocker/NanoFilters/issues/218 62 | if (a.domCmp([ 63 | "di.fm", 64 | "jazzradio.com", 65 | ])) { 66 | a.loopbackXHR((_ignored, url) => { 67 | if (url.startsWith("https://pubads.g.doubleclick.net/")) { 68 | return [ 69 | '', 70 | '', 71 | '', 72 | ].join("\n"); 73 | } 74 | }); 75 | } 76 | 77 | // ------------------------------------------------------------------------------------------------------------- // 78 | 79 | // https://github.com/NanoMeow/QuickReports/issues/352 80 | // https://github.com/uBlockOrigin/uAssets/issues/4290 81 | // https://github.com/jspenguin2017/uBlockProtector/pull/1045 82 | if (a.domCmp([ 83 | "gamer.com.tw", 84 | ])) { 85 | a.inject(() => { 86 | "use strict"; 87 | 88 | const _XMLHttpRequest = window.XMLHttpRequest; 89 | 90 | const patchPlayer = (src) => { 91 | const adsTimerOffset = //; 92 | let adsTimerPrompt = 93 | /\w\.innerHTML='

'\+window\._molSettings\.skipText.*?"<\/p>"/g; 94 | let adsSkipPrompt = /\w\.innerHTML=window\._molSettings\.skipButtonText/g; 95 | const req = new _XMLHttpRequest(); 96 | req.onreadystatechange = () => { 97 | if (req.readyState === 4) { 98 | let payload = req.responseText; 99 | try { 100 | payload = payload.replace(adsTimerOffset, ''); 101 | payload = payload.replace(adsSkipPrompt, [ 102 | "$('.vast-skip-button.enabled')[0].click()", 103 | "$('#ani_video_html5_api').show()", 104 | "$('#ani_video_html5_api').prop('muted', false)", 105 | ].join(",")); 106 | payload = payload.replace(adsTimerPrompt, (match) => { 107 | return "(" + [ 108 | match, 109 | "$('#ani_video_html5_api').hide()", 110 | "$('#ani_video_html5_api').prop('muted', true)", 111 | ].join(",") + ")"; 112 | }); 113 | } catch (err) { } 114 | const script = window.document.createElement("script"); 115 | script.textContent = payload; 116 | window.document.body.append(script); 117 | } 118 | }; 119 | req.open("GET", src); 120 | req.send(); 121 | }; 122 | 123 | const _appendChild = window.Element.prototype.appendChild; 124 | window.Element.prototype.appendChild = function (elem) { 125 | if ( 126 | elem.tagName === "SCRIPT" && 127 | elem.src && 128 | elem.src.startsWith("https://i2.bahamut.com.tw/build/js/animeplayer") 129 | ) { 130 | return void patchPlayer(elem.src); 131 | } 132 | return _appendChild.apply(this, arguments); 133 | }; 134 | }); 135 | } 136 | 137 | // ------------------------------------------------------------------------------------------------------------- // 138 | 139 | } 140 | 141 | // ----------------------------------------------------------------------------------------------------------------- // 142 | 143 | //@pragma-end-if 144 | 145 | // ----------------------------------------------------------------------------------------------------------------- // 146 | -------------------------------------------------------------------------------- /src/content/rules-common.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Handle whitelist and initialize generic content solutions. Then apply common content rules 22 | // 23 | // Solutions from Anti-Adblock Killer (by Reek) are modified to fit the content core library 24 | // 25 | // Anti-Adblock Killer Repository (contains original source code and license): 26 | // https://github.com/reek/anti-adblock-killer 27 | 28 | // ----------------------------------------------------------------------------------------------------------------- // 29 | 30 | "use strict"; 31 | 32 | // ----------------------------------------------------------------------------------------------------------------- // 33 | 34 | { 35 | 36 | // ------------------------------------------------------------------------------------------------------------- // 37 | 38 | a.init(); 39 | 40 | // ------------------------------------------------------------------------------------------------------------- // 41 | 42 | const domCmpWhitelist = [ 43 | 44 | // --------------------------------------------------------------------------------------------------------- // 45 | 46 | // Local network 47 | "127.0.0.1", 48 | "local", 49 | 50 | // Reserved TLDs 51 | "example", 52 | "invalid", 53 | "localhost", 54 | "test", 55 | 56 | // --------------------------------------------------------------------------------------------------------- // 57 | 58 | // Baidu 59 | "baidu.com", 60 | 61 | // Google 62 | "google.it.ao", 63 | "google.ne.jp", 64 | "google.off.ai", 65 | 66 | // PayPal 67 | "paypal.com", 68 | "paypal.me", 69 | 70 | // Twitch 71 | "twitch.tv", 72 | 73 | // Wikipedia 74 | "wikipedia.org", 75 | 76 | // YouTube 77 | "youtu.be", 78 | "youtube.com", 79 | 80 | // --------------------------------------------------------------------------------------------------------- // 81 | 82 | // Advanced tools (for performance) 83 | "lab.wolframcloud.com", 84 | 85 | // Image hosts (for performance) 86 | "flickr.com", 87 | "imgbox.com", 88 | "imgur.com", 89 | 90 | // JavaScript playgrounds (for performance) 91 | "ask.com", 92 | "codepen.io", 93 | "jsbin.com", 94 | "jsfiddle.net", 95 | "plnkr.co", 96 | "preloaders.net", 97 | "stackoverflow.com", 98 | "w3schools.com", 99 | 100 | // Media sites (for performance) 101 | "calm.com", 102 | "vimeo.com", 103 | "xemvtv.net", 104 | "yandex.ru", 105 | 106 | // Social networks (for performance) 107 | "bufferapp.com", 108 | "chatango.com", 109 | "facebook.com", 110 | "instagram.com", 111 | "linkedin.com", 112 | "messenger.com", 113 | "pinterest.com", 114 | "reddit.com", 115 | "twitter.com", 116 | 117 | // --------------------------------------------------------------------------------------------------------- // 118 | 119 | // Custom FuckAdBlock 120 | "atresplayer.com", 121 | "aviationweek.com", 122 | "futbin.com", 123 | "juprimaulana.com", 124 | "paraedu.id", 125 | "rmcmv.us", 126 | "yuukithemes.com", 127 | 128 | // False positives from Adfly skipper 129 | "programme-tv.net", 130 | 131 | // False positives from legacy BlockAdBlock defuser 132 | "alternativeto.net", 133 | 134 | // Other false positives 135 | "anandabazar.com", 136 | "animesync.tv", 137 | "aternos.org", 138 | "automobile-propre.com", 139 | "avgle.com", 140 | "babbel.com", 141 | "bild.de", 142 | "browserleaks.com", 143 | "bungie.net", 144 | "buxfer.com", 145 | "ccbluex.net", 146 | "cfnc.org", 147 | "dallasnews.com", 148 | "derstandard.at", 149 | "di.fm", 150 | "download.ipeenk.com", 151 | "duellinksmeta.com", 152 | "egy.best", 153 | "filmweb.pl", 154 | "finobe.com", 155 | "gamersclub.com.br", 156 | "gaobook.review", 157 | "hackintosh.computer", 158 | "imdb.com", 159 | "infostrow.pl", 160 | "jazzradio.com", 161 | "lcpdfr.com", 162 | "lemonde.fr", 163 | "linetv.tw", 164 | "lolalytics.com", 165 | "myworkday.com", 166 | "o2.pl", 167 | "ostrzeszowinfo.pl", 168 | "pasty.link", 169 | "pokyun.tv", 170 | "pornhub.com", 171 | "privacy-port.de", 172 | "reevown.com", 173 | "shinden.pl", 174 | "socketloop.com", 175 | "sport-tv-guide.live", 176 | "store.playstation.com", 177 | "strefadb.pl", 178 | "techradar.com", 179 | "tv3sport.dk", 180 | "tvserial.it", 181 | "viasatsport.se", 182 | "viasport.fi", 183 | "viasport.no", 184 | "vod.pl", 185 | "wilmaa.com", 186 | "workday.com", 187 | "wp.pl", 188 | "wstream.video", 189 | 190 | // Handled by a special private extension 191 | "boost.ink", 192 | 193 | // --------------------------------------------------------------------------------------------------------- // 194 | 195 | ]; 196 | 197 | const domIncWhitelist = [ 198 | 199 | // --------------------------------------------------------------------------------------------------------- // 200 | 201 | // Local network 202 | "192.168.0", 203 | "192.168.1", 204 | 205 | // --------------------------------------------------------------------------------------------------------- // 206 | 207 | // Google 208 | "google", 209 | "google.co", 210 | "google.com", 211 | 212 | // Yahoo 213 | "yahoo", 214 | 215 | // --------------------------------------------------------------------------------------------------------- // 216 | 217 | // Stores (for performance) 218 | "amazon", 219 | "ebay", 220 | 221 | // --------------------------------------------------------------------------------------------------------- // 222 | 223 | // Other false positives 224 | "9anime", 225 | "egybest", 226 | "italiashare", 227 | "imgdew", 228 | "imgfile", 229 | "imgmaze", 230 | "imgoutlet", 231 | "imgrock", 232 | "imgview", 233 | "kickassanime", 234 | "kiss-anime", 235 | "kissanime", 236 | "kissasian", 237 | "oladblock", 238 | "oload", 239 | "openload", 240 | "viafree", 241 | 242 | // --------------------------------------------------------------------------------------------------------- // 243 | 244 | ]; 245 | 246 | // ------------------------------------------------------------------------------------------------------------- // 247 | 248 | if (a.domCmp(domCmpWhitelist, true) || a.domInc(domIncWhitelist, true)) { 249 | 250 | console.log("[Nano] Excluded :: All Generically Applied Solutions"); 251 | 252 | } else { 253 | 254 | if (false) { 255 | console.log("[Nano] Excluded :: Common Generic Solutions"); 256 | } else { 257 | a.generic(); 258 | } 259 | 260 | if (a.domCmp([ 261 | // https://github.com/NanoMeow/QuickReports/issues/2641 262 | "topadnetworks.net", 263 | "topshort.net", 264 | // https://github.com/NanoMeow/QuickReports/issues/2950 265 | "freealtsgenerator.es", 266 | "uforum.us", 267 | // https://github.com/NanoMeow/QuickReports/issues/3113 268 | "ctrn.cc", 269 | "cutearn.net", 270 | ], true) || a.domInc([ 271 | // https://github.com/uBlockOrigin/uAssets/issues/6553 272 | "cutlinks", 273 | ], true)) { 274 | console.log("[Nano] Excluded :: Adfly Skipper"); 275 | } else { 276 | a.generic.Adfly(); 277 | } 278 | 279 | if (false) { 280 | console.log("[Nano] Excluded :: Adfly Forced Notification Blocker"); 281 | } else { 282 | a.generic.AdflyForcedNotification(); 283 | } 284 | 285 | if (false) { 286 | console.log("[Nano] Excluded :: app_vars Defuser"); 287 | } else { 288 | a.generic.app_vars(); 289 | } 290 | 291 | if (false) { 292 | console.log("[Nano] Excluded :: Cloudflare Apps Defuser"); 293 | } else { 294 | a.generic.CloudflareApps(); 295 | } 296 | 297 | } 298 | 299 | // ------------------------------------------------------------------------------------------------------------- // 300 | 301 | // Deprecated 302 | if (a.domCmp([ 303 | "acquavivalive.it", 304 | "beinsports.com", 305 | "listamais.com.br", 306 | "lolskinlistgenerator.com", 307 | "m.delfi.ee", 308 | "memurlar.net", 309 | "molfettalive.it", 310 | "palemoon.org", 311 | "palolive.it", 312 | "passionea300allora.it", 313 | "sledujserialy.sk", 314 | "stocks.cafe", 315 | "uploadboy.com", 316 | "videohelp.com", 317 | "vidoza.net", 318 | "warforum.cz", 319 | "zeiz.me", 320 | ])) { 321 | a.generic.adsjsV2(); 322 | } 323 | 324 | // ------------------------------------------------------------------------------------------------------------- // 325 | 326 | if (false) { 327 | a.uBOExtraExcluded = true; 328 | console.log("[Nano] Excluded :: uBO-Extra"); 329 | } 330 | 331 | // ------------------------------------------------------------------------------------------------------------- // 332 | 333 | } 334 | 335 | // ----------------------------------------------------------------------------------------------------------------- // 336 | 337 | // a.filter 338 | 339 | if (a.domCmp([ 340 | "darmowe-pornosy.pl", 341 | "exrapidleech.info", 342 | "flashx.to", 343 | "flashx.tv", 344 | "linx.cloud", 345 | "urle.co", 346 | "usapoliticstoday.com", 347 | "vidlox.tv", 348 | ])) { 349 | a.filter("eval"); 350 | } 351 | 352 | if (a.domCmp([ 353 | "cloudwebcopy.com", 354 | "sc2casts.com", 355 | "webqc.org", 356 | ])) { 357 | a.filter("setTimeout"); 358 | } 359 | 360 | if (a.domCmp([ 361 | "1movies.tv", 362 | "adshort.co", 363 | "adshort.im", 364 | "adshorte.com", 365 | "arenavision.in", 366 | "atdhe.al", 367 | "atdhe.bz", 368 | "atdhe.li", 369 | "atdhe.me", 370 | "atdhe.mx", 371 | "atdhe.ru", 372 | "atdhe.se", 373 | "atdhe.to", 374 | "atdhe.top", 375 | "backin.net", 376 | "coinb.ink", 377 | "ddlfr.pw", 378 | "doramasflv.net", 379 | "firstrow.co", 380 | "firstrow1us.eu", 381 | "firstrows.biz", 382 | "firstrows.co", 383 | "firstrows.org", 384 | "firstrows.ru", 385 | "firstrows.tv", 386 | "firstrowsportes.com", 387 | "firstrowsportes.tv", 388 | "firstrowus.eu", 389 | "firstsrowsports.eu", 390 | "hahasport.me", 391 | "iiv.pl", 392 | "justfirstrowsports.com", 393 | "katfile.com", 394 | "l2s.io", 395 | "linclik.com", 396 | "linkkawy.com", 397 | "linksh.top", 398 | "myp2p.biz", 399 | "myp2p.com", 400 | "myp2p.ec", 401 | "myp2p.eu", 402 | "myp2p.la", 403 | "myp2p.sx", 404 | "myp2p.tv", 405 | "myp2p.ws", 406 | "sawlive.tv", 407 | "shink.me", 408 | "u2s.io", 409 | "ur.ly", 410 | "urle.co", 411 | "videowood.tv", 412 | "vidoza.net", 413 | "wiziwig.ru", 414 | "wiziwig.sx", 415 | "wiziwig.to", 416 | "wiziwig.tv", 417 | "zlshorte.net", 418 | ])) { 419 | a.filter("open"); 420 | } 421 | 422 | if (a.domCmp([ 423 | "businesstoday.in", 424 | "dl-protect.com", 425 | "doatoolsita.altervista.org", 426 | "drivearabia.com", 427 | "filecom.net", 428 | "free-movie-home.com", 429 | "generatupremium.biz", 430 | "kooora.com", 431 | "mega-debrid.eu", 432 | "newsinlevels.com", 433 | "pc.online143.com", 434 | "pipocas.tv", 435 | "premiumst0re.blogspot.com", 436 | "putlocker.com", 437 | "sockshare.com", 438 | "str3am.altervista.org", 439 | "str3amtv.altervista.org", 440 | "str3amtv.co.nr", 441 | "str3amtv.co.nr", 442 | "vipracing.biz", 443 | ])) { 444 | a.filter("alert"); 445 | } 446 | 447 | // ----------------------------------------------------------------------------------------------------------------- // 448 | 449 | // a.readOnly 450 | 451 | if (a.domCmp([ 452 | "financialexpress.com", 453 | "indianexpress.com", 454 | "jansatta.com", 455 | "srt.am", 456 | "uskip.me", 457 | ])) { 458 | a.readOnly("RunAds", true); 459 | } 460 | 461 | if (a.domCmp([ 462 | "catcatyfaucet.xyz", 463 | "jagranjunction.com", 464 | "nekopoi.bid", 465 | ])) { 466 | a.readOnly("isAdsDisplayed", true); 467 | } 468 | 469 | if (a.domCmp([ 470 | "stream.nbcsports.com", 471 | "swissadspaysethfaucet.com", 472 | "swissadspaysfaucet.com", 473 | ])) { 474 | a.readOnly("adBlockEnabled", false); 475 | } 476 | 477 | if (a.domCmp([ 478 | "link.tl", 479 | ])) { 480 | a.readOnly("adblocker", false); 481 | } 482 | 483 | if (a.domCmp([ 484 | "megogo.net", 485 | ])) { 486 | a.readOnly("adBlock", false); 487 | } 488 | 489 | if (a.domCmp([ 490 | "4tests.com", 491 | "8bbit.com", 492 | "alcodistillers.ru", 493 | "angrybirdsnest.com", 494 | "freizeitpartnerweb.de", 495 | "nekopoi.bid", 496 | "outdoorpartner.net", 497 | "translatica.pl", 498 | "urlaubspartner.net", 499 | ])) { 500 | a.readOnly("adblock", false); 501 | } 502 | 503 | if (a.domCmp([ 504 | "code.ptcong.com", 505 | "hanime.tv", 506 | "mega-estrenos.com", 507 | "mexashare.com", 508 | "popunderjs.com", 509 | "shortin.ga", 510 | ])) { 511 | a.readOnly("BetterJsPop", "window.Object.freeze({})"); 512 | } 513 | 514 | if (a.domCmp([ 515 | "he2eini7ka.com", 516 | "youwatch.to", 517 | ])) { 518 | a.readOnly("jsPopunder", () => { }); 519 | } 520 | 521 | if (a.domCmp([ 522 | "ahzahg6ohb.com", 523 | "ajihezo.info", 524 | "bojem3a.info", 525 | "chefti.info", 526 | "chouhaa.info", 527 | "exashare.com", 528 | "he2eini7ka.com", 529 | "yahmaib3ai.com", 530 | "youwatch.org", 531 | "youwatch.to", 532 | ])) { 533 | a.readOnly("adsShowPopup1", 1); 534 | } 535 | 536 | if (a.domCmp([ 537 | "game-debate.com", 538 | "naruto-mx.net", 539 | "onepiece-mx.net", 540 | "scan-mx.com", 541 | ])) { 542 | a.readOnly("ad_block_test", () => { }); 543 | } 544 | 545 | if (a.domCmp([ 546 | "freebitcoins.nx.tc", 547 | "getbitcoins.nx.tc", 548 | ])) { 549 | a.readOnly("ad_block_test", () => false); 550 | } 551 | 552 | if (a.domCmp([ 553 | "1movies.tv", 554 | "xmovies8.es", 555 | ])) { 556 | a.readOnly("check_adblock", true); 557 | } 558 | 559 | if (a.domCmp([ 560 | "fourchette-et-bikini.fr", 561 | "meteocity.com", 562 | ])) { 563 | a.readOnly("adProtect", 1); 564 | } 565 | 566 | if (a.domCmp([ 567 | "homerun.re", 568 | "securenetsystems.net", 569 | "strikeout.co", 570 | "strikeout.me", 571 | "vipapp.me", 572 | "vipbox.biz", 573 | "vipbox.co", 574 | "vipbox.eu", 575 | "vipbox.nu", 576 | "vipbox.so", 577 | "vipbox.sx", 578 | "vipbox.tv", 579 | "vipboxsa.co", 580 | "vipboxtv.co", 581 | "vipleague.ch", 582 | "vipleague.co", 583 | "vipleague.is", 584 | "vipleague.me", 585 | "vipleague.mobi", 586 | "vipleague.se", 587 | "vipleague.sx", 588 | "vipleague.tv", 589 | "vipleague.ws", 590 | ])) { 591 | a.readOnly("iExist", true); 592 | } 593 | 594 | // ----------------------------------------------------------------------------------------------------------------- // 595 | 596 | // a.noAccess 597 | 598 | if (a.domCmp([ 599 | "adshort.co", 600 | "adshorte.com", 601 | "animeforce.org", 602 | "coinb.ink", 603 | "debridnet.com", 604 | "imgrock.info", 605 | "linksh.top", 606 | "srt.am", 607 | ])) { 608 | a.noAccess("_pop"); 609 | } 610 | 611 | if (a.domCmp([ 612 | "linx.cloud", 613 | ])) { 614 | a.noAccess("popns"); 615 | } 616 | 617 | if (a.domCmp([ 618 | "adlinkme.com", 619 | "arenabg.ch", 620 | "jzrputtbut.net", 621 | "maango.info", 622 | "psarips.com", 623 | "solidfiles.com", 624 | "streamcloud.eu", 625 | "torrentfunk.com", 626 | "vidfile.net", 627 | ])) { 628 | a.noAccess("open"); 629 | } 630 | 631 | // ----------------------------------------------------------------------------------------------------------------- // 632 | 633 | // a.bait 634 | 635 | if (a.domCmp([ 636 | "leveldown.fr", 637 | "primeshare.tv", 638 | ])) { 639 | a.bait("div", "#adblock"); 640 | } 641 | 642 | if (a.domCmp([ 643 | "720pmkv.com", 644 | "psarips.com", 645 | ])) { 646 | a.bait("div", "#advert"); 647 | } 648 | 649 | if (a.domCmp([ 650 | "bitcoiner.net", 651 | "d3brid4y0u.info", 652 | "dashcatch.xyz", 653 | "dogecatch.website", 654 | "dramapassion.com", 655 | "easybillets.com", 656 | "fileice.net", 657 | "freeallmusic.info", 658 | "litecoiner.net", 659 | "nosteam.ro", 660 | "online.ua", 661 | "openrunner.com", 662 | "osoarcade.com", 663 | "putlocker.com", 664 | "shortify.pw", 665 | "sockshare.com", 666 | "spox.fr", 667 | "tgo-tv.com", 668 | "tv3.co.nz", 669 | "yooclick.com", 670 | "yovoyages.com", 671 | ])) { 672 | a.bait("div", "#tester"); 673 | } 674 | 675 | if (a.domCmp([ 676 | "alein.org", 677 | ])) { 678 | a.bait("div", "#tester", true); 679 | } 680 | 681 | if (a.domCmp([ 682 | "filecom.net", 683 | "globeslot.com", 684 | "mwfiles.net", 685 | "skippyfile.com", 686 | "up-flow.org", 687 | "upshare.org", 688 | ])) { 689 | a.bait("div", "#add"); 690 | } 691 | 692 | if (a.domCmp([ 693 | "bluesatoshi.com", 694 | "oneadfaucet.com", 695 | "razercrypt.com", 696 | "satoshiempire.com", 697 | ])) { 698 | a.bait("div", "#test"); 699 | } 700 | 701 | if (a.domCmp([ 702 | "bitcoinaliens.com", 703 | "door2windows.com", 704 | ])) { 705 | a.bait("ins", ".adsbygoogle"); 706 | } 707 | 708 | if (a.domCmp([ 709 | "hellsmedia.com", 710 | "leaguesecretary.com", 711 | "teknogods.com", 712 | ])) { 713 | a.bait("div", "#adpbtest"); 714 | } 715 | 716 | if (a.domCmp([ 717 | "freesportsbet.com", 718 | "sportsplays.com", 719 | ])) { 720 | a.bait("div", "#ad-tester"); 721 | } 722 | 723 | if (a.domCmp([ 724 | "bitcoiner.net", 725 | "litecoiner.net", 726 | ])) { 727 | a.bait("div", "#ad-top"); 728 | } 729 | 730 | // ----------------------------------------------------------------------------------------------------------------- // 731 | -------------------------------------------------------------------------------- /src/content/rules-sticky.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Content rules for sticky websites. 3 | */ 4 | "use strict"; 5 | 6 | if (a.domCmp(["debridnet.com"])) { 7 | const re = /\.height\(\)/g; 8 | a.beforeScript((script) => { 9 | if (script.textContent) { 10 | script.textContent = script.textContent.replace(re, " && false && 0"); 11 | } 12 | }); 13 | a.timewarp("setTimeout", a.matchMethod.RegExp, /^\d+000$/, 0.2); 14 | for (let i = 0; i < 15; i++) { 15 | const s = document.createElement("script"); 16 | document.documentElement.append(s); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/content/ubo-extra.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | if (a.uBOExtraExcluded) { 3 | return; 4 | } 5 | 6 | 7 | 8 | /******************************************************************************* 9 | 10 | uBO-Extra - A companion extension to uBlock Origin: to gain ability to 11 | foil early hostile anti-user mechanisms working around 12 | content blockers. 13 | Copyright (C) 2016-2018 Raymond Hill 14 | 15 | This program is free software: you can redistribute it and/or modify 16 | it under the terms of the GNU General Public License as published by 17 | the Free Software Foundation, either version 3 of the License, or 18 | (at your option) any later version. 19 | 20 | This program is distributed in the hope that it will be useful, 21 | but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | GNU General Public License for more details. 24 | 25 | You should have received a copy of the GNU General Public License 26 | along with this program. If not, see {http://www.gnu.org/licenses/}. 27 | 28 | Home: https://github.com/gorhill/uBO-WebSocket 29 | */ 30 | 31 | 'use strict'; 32 | 33 | /* global HTMLDocument, XMLDocument */ 34 | 35 | /******************************************************************************* 36 | 37 | All scriptlets to inject: the scriptlets to inject are to foil or work 38 | around hostile anti-user mechanism used by some web sites. 39 | 40 | **/ 41 | 42 | var scriptlets = [], 43 | hostname = window.location.hostname, 44 | contentScriptSecret = 45 | String.fromCharCode(Date.now() % 26 + 97) + 46 | Math.floor(Math.random() * 982451653 + 982451653).toString(36); 47 | 48 | /******************************************************************************* 49 | 50 | Don't run on non-HTML documents. 51 | 52 | **/ 53 | 54 | var abort = (function() { 55 | var doc = document; 56 | if ( doc instanceof HTMLDocument === false ) { 57 | if ( 58 | doc instanceof XMLDocument === false || 59 | doc.createElement('div') instanceof HTMLDivElement === false 60 | ) { 61 | return true; 62 | } 63 | } 64 | if ( (doc.contentType || '').lastIndexOf('image/', 0) === 0 ) { 65 | return true; 66 | } 67 | return false; 68 | })(); 69 | 70 | /******************************************************************************* 71 | 72 | Fetch hostname from ancestors if none available (we could be executed from 73 | inside an anonymous frame). 74 | 75 | **/ 76 | 77 | if ( !abort ) { 78 | if ( hostname === '' ) { 79 | hostname = (function() { 80 | var win = window, hn = '', max = 10; 81 | try { 82 | for (;;) { 83 | hn = win.location.hostname; 84 | if ( hn !== '' ) { return hn; } 85 | if ( win.parent === win ) { break; } 86 | win = win.parent; 87 | if ( !win ) { break; } 88 | if ( (max -= 1) === 0 ) { break; } 89 | } 90 | } catch(ex) { 91 | } 92 | return hn; 93 | })(); 94 | } 95 | // Don't inject if document is from local network. 96 | abort = /^192\.168\.\d+\.\d+$/.test(hostname); 97 | } 98 | 99 | /******************************************************************************* 100 | 101 | Instart Logic defuser 102 | 103 | **/ 104 | 105 | (function() { 106 | if ( abort ) { return; } 107 | 108 | var scriptlet = function() { 109 | var magic = String.fromCharCode(Date.now() % 26 + 97) + 110 | Math.floor(Math.random() * 982451653 + 982451653).toString(36), 111 | targets = [ 112 | 'atob', 113 | 'console.error', 114 | 'INSTART', 115 | 'INSTART_TARGET_NAME', 116 | 'navigator.userAgent', 117 | 'performance', 118 | 'require' 119 | ], 120 | reScriptText = /\b(?:Instart-|I10C|I11C|IXC_|INSTART)/, 121 | reScriptSrc = /\babd.*?\/instart.js|\?i10c\./, 122 | thisScript = document.currentScript; 123 | var validate = function() { 124 | var script = document.currentScript; 125 | if ( script instanceof HTMLScriptElement === false ) { return; } 126 | if ( script === thisScript ) { return; } 127 | if ( script.src === '' ) { 128 | if ( reScriptText.test(script.textContent) ) { 129 | throw new ReferenceError(magic); 130 | } 131 | } else if ( reScriptSrc.test(script.src) ) { 132 | throw new ReferenceError(magic); 133 | } 134 | }; 135 | var makeGetterSetter = function(owner, prop) { 136 | var value = owner[prop]; 137 | return { 138 | get: function() { 139 | validate(); 140 | return value; 141 | }, 142 | set: function(a) { 143 | validate(); 144 | value = a; 145 | } 146 | }; 147 | }; 148 | var i = targets.length, 149 | owner, target, chain, prop; 150 | while ( i-- ) { 151 | owner = window; 152 | target = targets[i]; 153 | chain = target.split('.'); 154 | for (;;) { 155 | prop = chain.shift(); 156 | if ( chain.length === 0 ) { break; } 157 | owner = owner[prop]; 158 | } 159 | Object.defineProperty(owner, prop, makeGetterSetter(owner, prop)); 160 | } 161 | var oe = window.onerror; 162 | window.onerror = function(msg) { 163 | if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) { 164 | return true; 165 | } 166 | if ( oe instanceof Function ) { 167 | return oe.apply(this, arguments); 168 | } 169 | }.bind(); 170 | }; 171 | 172 | scriptlets.push({ 173 | scriptlet: scriptlet, 174 | targets: [ 175 | 'afterellen.com', 176 | 'americanphotomag.com', 177 | 'atvrider.com', 178 | 'baggersmag.com', 179 | 'baltimoresun.com', 180 | 'boatingmag.com', 181 | 'boston.com', 182 | 'cafemom.com', 183 | 'calgaryherald.com', 184 | 'calgarysun.com', 185 | 'capitalgazette.com', 186 | 'carrollcountytimes.com', 187 | 'cattime.com', 188 | 'cbssports.com', 189 | 'chicagotribune.com', 190 | 'chowhound.com', 191 | 'chron.com', 192 | 'chroniclelive.co.uk', 193 | 'citypaper.com', 194 | 'comingsoon.net', 195 | 'computershopper.com', 196 | 'courant.com', 197 | 'craveonline.com', 198 | 'cruisingworld.com', 199 | 'csgoutpost.com', 200 | 'ctnow.com', 201 | 'cycleworld.com', 202 | 'dailydot.com', 203 | 'dailypress.com', 204 | 'dayzdb.com', 205 | 'deathandtaxesmag.com', 206 | 'delmartimes.net', 207 | 'destinationweddingmag.com', 208 | 'dirtrider.com', 209 | 'diversitybestpractices.com', 210 | 'dogtime.com', 211 | 'dotaoutpost.com', 212 | 'download.cnet.com', 213 | 'edmontonjournal.com', 214 | 'edmontonsun.com', 215 | 'edmunds.com', 216 | 'emedicinehealth.com', 217 | 'esohead.com', 218 | 'everquest.allakhazam.com', 219 | 'extremetech.com', 220 | 'fieldandstream.com', 221 | 'financialpost.com', 222 | 'floridatravellife.com', 223 | 'flyingmag.com', 224 | 'focus.de', 225 | 'foxsports.com.au', 226 | 'gamepedia.com', 227 | 'gamerevolution.com', 228 | 'gamespot.com', 229 | 'geek.com', 230 | 'goal.com', 231 | 'gofugyourself.com', 232 | 'growthspotter.com', 233 | 'hearthhead.com', 234 | 'hockeysfuture.com', 235 | 'hotbikeweb.com', 236 | 'hoylosangeles.com', 237 | 'ibtimes.com', 238 | 'infinitiev.com', 239 | 'islands.com', 240 | 'lajollalight.com', 241 | 'laptopmag.com', 242 | 'latintimes.com', 243 | 'leaderpost.com', 244 | 'legacy.com', 245 | 'lifewire.com', 246 | 'livescience.com', 247 | 'lolking.net', 248 | 'mcall.com', 249 | 'mamaslatinas.com', 250 | 'marlinmag.com', 251 | 'medicaldaily.com', 252 | 'medicinenet.com', 253 | 'metacritic.com', 254 | 'metrolyrics.com', 255 | 'mmo-champion.com', 256 | 'momtastic.com', 257 | 'montrealgazette.com', 258 | 'motorcyclecruiser.com', 259 | 'motorcyclistonline.com', 260 | 'motortrend.com', 261 | 'msn.com', 262 | 'musicfeeds.com.au', 263 | 'mustangandfords.com', 264 | 'mysanantonio.com', 265 | 'nasdaq.com', 266 | 'nationalpost.com', 267 | 'newsarama.com', 268 | 'newsweek.com', 269 | 'orlandosentinel.com', 270 | 'ottawacitizen.com', 271 | 'ottawasun.com', 272 | 'outdoorlife.com', 273 | 'pcmag.com', 274 | 'playstationlifestyle.net', 275 | 'popphoto.com', 276 | 'popsci.com', 277 | 'ranchosantafereview.com', 278 | 'range365.com', 279 | 'ranker.com', 280 | 'ratemyprofessors.com', 281 | 'realclearpolitics.com', 282 | 'realitytea.com', 283 | 'redeyechicago.com', 284 | 'salon.com', 285 | 'saltwatersportsman.com', 286 | 'sandiegouniontribune.com', 287 | 'saveur.com', 288 | 'scubadiving.com', 289 | 'scubadivingintro.com', 290 | 'seattlepi.com', 291 | 'sfgate.com', 292 | 'sherdog.com', 293 | 'slate.com', 294 | 'slickdeals.net', 295 | 'southflorida.com', 296 | 'space.com', 297 | 'spin.com', 298 | 'sporcle.com', 299 | 'sportdiver.com', 300 | 'sportfishingmag.com', 301 | 'sportingnews.com', 302 | 'sportrider.com', 303 | 'spox.com', 304 | 'stereogum.com', 305 | 'streetchopperweb.com', 306 | 'sun-sentinel.com', 307 | 'superherohype.com', 308 | 'superstreetbike.com', 309 | 'tenplay.com.au', 310 | 'tf2outpost.com', 311 | 'thebalance.com', 312 | 'thefashionspot.com', 313 | 'theprovince.com', 314 | 'thespruce.com', 315 | 'thestarphoenix.com', 316 | 'thoughtcatalog.com', 317 | 'thoughtco.com', 318 | 'timeanddate.com', 319 | 'timesunion.com', 320 | 'tomsguide.com', 321 | 'tomsguide.fr', 322 | 'tomshardware.co.uk', 323 | 'tomshardware.com', 324 | 'tomshardware.de', 325 | 'tomshardware.fr', 326 | 'torontosun.com', 327 | 'totalbeauty.com', 328 | 'trustedreviews.com', 329 | 'tv.com', 330 | 'tvguide.com', 331 | 'tvtropes.org', 332 | 'twincities.com', 333 | 'utvdriver.com', 334 | 'vancouversun.com', 335 | 'vg.no', 336 | 'vibe.com', 337 | 'wakeboardingmag.com', 338 | 'washingtonpost.com', 339 | 'waterskimag.com', 340 | 'wetteronline.de', 341 | 'wibc.com', 342 | 'wikia.com', 343 | 'windowscentral.com', 344 | 'windsorstar.com', 345 | 'winnipegsun.com', 346 | 'workingmother.com', 347 | 'wowhead.com', 348 | 'wrestlezone.com', 349 | 'xda-developers.com', 350 | 'yachtingmagazine.com', 351 | 'zam.com', 352 | ] 353 | }); 354 | })(); 355 | 356 | /******************************************************************************* 357 | 358 | Instart Logic buster: v2 359 | 360 | https://github.com/uBlockOrigin/uAssets/issues/227#issuecomment-268409666 361 | 362 | **/ 363 | 364 | (function() { 365 | if ( abort ) { return; } 366 | 367 | var scriptlet = function() { 368 | var magic = String.fromCharCode(Date.now() % 26 + 97) + 369 | Math.floor(Math.random() * 982451653 + 982451653).toString(36); 370 | var makeNanovisorProxy = function() { 371 | return new Proxy({}, { 372 | get: function(target, name) { 373 | switch ( name ) { 374 | case 'HtmlStreaming': 375 | return { 376 | InsertTags: function(a, b) { 377 | document.write(b); // jshint ignore:line 378 | }, 379 | InterceptNode: function() { 380 | }, 381 | PatchBegin: function() { 382 | }, 383 | PatchEnd: function() { 384 | }, 385 | PatchInit: function() { 386 | }, 387 | ReloadWithNoHtmlStreaming: function() { 388 | window.location.reload(true); 389 | }, 390 | RemoveTags: function() { 391 | }, 392 | UpdateAttributes: function() { 393 | } 394 | }; 395 | default: 396 | return target[name]; 397 | } 398 | }, 399 | set: function(target, name, value) { 400 | switch ( name ) { 401 | case 'CanRun': 402 | target.CanRun = function() { 403 | return false; 404 | }; 405 | break; 406 | default: 407 | target[name] = value; 408 | } 409 | } 410 | }); 411 | }; 412 | var instartInit; 413 | window.I10C = window.I11C = makeNanovisorProxy(); 414 | window.INSTART = new Proxy({}, { 415 | get: function(target, name) { 416 | switch ( name ) { 417 | case 'Init': 418 | return function(a) { 419 | if ( 420 | a instanceof Object && 421 | typeof a.nanovisorGlobalNameSpace === 'string' && 422 | a.nanovisorGlobalNameSpace !== '' 423 | ) { 424 | window[a.nanovisorGlobalNameSpace] = makeNanovisorProxy(); 425 | } 426 | a.enableHtmlStreaming = false; 427 | a.enableQSCallDiffComputationConfig = false; 428 | a.enableQuerySelectorMonitoring = false; 429 | a.serveNanovisorSameDomain = false; 430 | a.virtualDomains = 0; 431 | a.virtualizeDomains = []; 432 | instartInit(a); 433 | }; 434 | default: 435 | if ( target[name] === undefined ) { 436 | throw new Error(magic); 437 | } 438 | return target[name]; 439 | } 440 | }, 441 | set: function(target, name, value) { 442 | switch ( name ) { 443 | case 'Init': 444 | instartInit = value; 445 | break; 446 | default: 447 | target[name] = value; 448 | } 449 | } 450 | }); 451 | var oe = window.error; 452 | window.onerror = function(msg, src, line, col, error) { 453 | if ( msg.indexOf(magic) !== -1 ) { 454 | return true; 455 | } 456 | if ( oe instanceof Function ) { 457 | return oe(msg, src, line, col, error); 458 | } 459 | }.bind(); 460 | }; 461 | 462 | scriptlets.push({ 463 | scriptlet: scriptlet, 464 | targets: [ 465 | 'calgaryherald.com', 466 | 'edmontonjournal.com', 467 | 'financialpost.com', 468 | 'leaderpost.com', 469 | 'montrealgazette.com', 470 | 'nationalpost.com', 471 | 'ottawacitizen.com', 472 | 'theprovince.com', 473 | 'thestarphoenix.com', 474 | 'windsorstar.com', 475 | ] 476 | }); 477 | })(); 478 | 479 | /******************************************************************************* 480 | 481 | Instart Logic console detection defuser. 482 | 483 | To allow using the dev tools to investigate IL's code: 484 | - Un-comment out the block of code 485 | - Add the site you wish to investigate in the `targets` array. 486 | 487 | **/ 488 | 489 | 490 | (function() { 491 | if ( abort ) { return; } 492 | 493 | var scriptlet = function() { 494 | var realConsole = console, 495 | realLog = console.log; 496 | console.log = function () { 497 | for ( var i = 0; i < arguments.length; i++ ) { 498 | if ( arguments[i] instanceof HTMLElement ) { return; } 499 | } 500 | return realLog.apply(realConsole, arguments); 501 | }.bind(console); 502 | Object.defineProperty(console.log, 'name', { value: 'log' }); 503 | }; 504 | 505 | scriptlets.push({ 506 | scriptlet: scriptlet, 507 | targets: [ 508 | 'laptopmag.com' 509 | ] 510 | }); 511 | })(); 512 | 513 | /******************************************************************************* 514 | 515 | Upmanager 516 | 517 | https://github.com/uBlockOrigin/uAssets/issues/251#issuecomment-276257642 518 | 519 | **/ 520 | 521 | (function() { 522 | if ( abort ) { return; } 523 | 524 | var scriptlet = function() { 525 | var magic = String.fromCharCode(Date.now() % 26 + 97) + 526 | Math.floor(Math.random() * 982451653 + 982451653).toString(36); 527 | var oe = window.error; 528 | window.onerror = function(msg, src, line, col, error) { 529 | if ( msg.indexOf(magic) !== -1 ) { return true; } 530 | if ( oe instanceof Function ) { 531 | return oe(msg, src, line, col, error); 532 | } 533 | }.bind(); 534 | Object.defineProperty(window, 'upManager', { 535 | set: function() { 536 | throw new Error(magic); 537 | } 538 | }); 539 | }; 540 | 541 | scriptlets.push({ 542 | scriptlet: scriptlet, 543 | targets: [ 544 | '101greatgoals.com', 545 | '4chan.org', 546 | 'allthetests.com', 547 | 'biology-online.org', 548 | 'destructoid.com', 549 | 'eurweb.com', 550 | 'fullmatchesandshows.com', 551 | 'grammarist.com', 552 | 'jerusalemonline.com', 553 | 'lucianne.com', 554 | 'phonesreview.co.uk', 555 | 'thefreethoughtproject.com', 556 | 'veteranstoday.com', 557 | 'walla.co.il', 558 | 'yad2.co.il', 559 | ] 560 | }); 561 | })(); 562 | 563 | /******************************************************************************* 564 | 565 | Collate and add scriptlets to document. 566 | 567 | **/ 568 | 569 | (function() { 570 | if ( scriptlets.length === 0 ) { return; } 571 | 572 | var restrFromString = function(s) { 573 | return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 574 | }; 575 | 576 | var reFromArray = function(aa) { 577 | return new RegExp('(^|\\.)(' + aa.map(restrFromString).join('|') + ')$'); 578 | }; 579 | 580 | var scriptText = [], entry, re; 581 | 582 | while ( (entry = scriptlets.shift()) ) { 583 | if ( Array.isArray(entry.targets) ) { 584 | re = reFromArray(entry.targets); 585 | if ( re.test(hostname) === false ) { continue; } 586 | } else if ( Array.isArray(entry.exceptions) ) { 587 | re = reFromArray(entry.exceptions); 588 | if ( re.test(hostname) ) { continue; } 589 | } 590 | scriptText.push('(' + entry.scriptlet.toString() + ')("' + contentScriptSecret + '");'); 591 | } 592 | 593 | if ( scriptText.length === 0 ) { return; } 594 | 595 | var elem = document.createElement('script'); 596 | elem.appendChild(document.createTextNode(scriptText.join('\n'))); 597 | try { 598 | (document.head || document.documentElement).appendChild(elem); 599 | } catch(ex) { 600 | } 601 | // Remove the script tag once executed (leave a clean DOM behind). 602 | elem.textContent = ''; 603 | if ( elem.parentNode ) { 604 | elem.parentNode.removeChild(elem); 605 | } 606 | })(); 607 | 608 | 609 | 610 | })(); 611 | -------------------------------------------------------------------------------- /src/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiCybora/NanoDefenderFirefox/2006d69afdefbbb2dcd1b2dca31bb2a516efc4d1/src/icon128.png -------------------------------------------------------------------------------- /src/libdom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A lightweight DOM manipulation library, will be expanded as needed. 3 | * Behaves quite differently than jQuery. 4 | */ 5 | "use strict"; 6 | 7 | 8 | /** 9 | * Shortcut for new $.Selection(input). 10 | * @function 11 | * @param {string} input - The query selector. 12 | * @return {$.Selection} The selection object. 13 | */ 14 | var $ = input => new $.Selection(input); 15 | 16 | /** 17 | * Selection class. 18 | * Unless otherwise specified, all methods return the keyword this. 19 | * @class 20 | */ 21 | $.Selection = class { 22 | /** 23 | * Constructor. 24 | * @constructor 25 | * @param {string} selector - The query selector. 26 | * @param {Array.} [override=undefined] - If this parameter 27 | * is present, current selection will be set to it and the query selector 28 | * will be ignored. 29 | */ 30 | constructor(selector, override) { 31 | /** 32 | * The selected elements. 33 | * @member {Array.} 34 | */ 35 | this.selection = override ? override : Array.from(document.querySelectorAll(selector)); 36 | /** 37 | * The amount of selected elements. 38 | * @member {integer} 39 | */ 40 | this.length = this.selection.length; 41 | } 42 | 43 | 44 | /** 45 | * Set or update CSS of all selected elements. 46 | * @method 47 | * @param {string} key - The key of the style, use "maxHeight" instead of 48 | * "max-height", similar for other keys with dashes in them. 49 | * @param {string} val - The value to set. 50 | */ 51 | css(key, val) { 52 | for (let s of this.selection) { 53 | s.style[key] = val; 54 | } 55 | return this; 56 | } 57 | /** 58 | * Show all selected elements. 59 | * @method 60 | * @param {string} [state="block"] - The state to apply, defaults to 61 | * "block". 62 | */ 63 | show(state = "block") { 64 | return this.css("display", state); 65 | } 66 | /** 67 | * Hide all selected elements. Current display mode will not be saved. 68 | * Things may break if you try to show them again. 69 | * @method 70 | */ 71 | hide() { 72 | return this.css("display", "none"); 73 | } 74 | /** 75 | * Remove all selected elements from DOM. 76 | * @method 77 | */ 78 | remove() { 79 | for (let s of this.selection) { 80 | s.remove(); 81 | } 82 | return this; 83 | } 84 | /** 85 | * Add classes to all selected elements. 86 | * @method 87 | * @param {string} ...args - Classes to add. 88 | */ 89 | addClass(...args) { 90 | for (let s of this.selection) { 91 | s.classList.add(...args); 92 | } 93 | return this; 94 | } 95 | /** 96 | * Remove classes from all selected elements. 97 | * @method 98 | * @param {string} [...args=[]] - Classes to remove, omit to remove all. 99 | */ 100 | rmClass(...args) { 101 | if (args.length) { 102 | for (let s of this.selection) { 103 | s.classList.remove(...args); 104 | } 105 | } else { 106 | for (let s of this.selection) { 107 | s.className = ""; 108 | } 109 | } 110 | return this; 111 | } 112 | 113 | 114 | /** 115 | * Copy current selection, this is useful when you do not want selection 116 | * methods to update current selection. 117 | * @method 118 | * @return {$.Selection} The new Selection object. 119 | */ 120 | copy() { 121 | return new $.Selection(null, this.selection.slice()); 122 | } 123 | /** 124 | * Update current selection, only keep the selected element with given 125 | * index. 126 | * Clear current selection if no selected element has that index. 127 | * @method 128 | * @param {integer} i - The index, give a negative number to count from 129 | * end. 130 | */ 131 | eq(i) { 132 | if (this.selection.length) { 133 | if (i < 0) { 134 | i += this.selection.length; 135 | } 136 | if (i >= 0 && i < this.selection.length) { 137 | this.selection = [this.selection[i]]; 138 | this.length = 1; 139 | } else { 140 | this.selection = []; 141 | this.length = 0; 142 | } 143 | } 144 | return this; 145 | } 146 | /** 147 | * Update current selection, only keep the first selected element. 148 | * @method 149 | */ 150 | first() { 151 | return this.eq(0); 152 | } 153 | /** 154 | * Update current selection, only keep the last selected element. 155 | * @method 156 | */ 157 | last() { 158 | return this.eq(-1); 159 | } 160 | /** 161 | * Update current selection, set it to children of each selected elements 162 | * that match the new selector. 163 | * @method 164 | * @param {string} selector - The new query selector. 165 | */ 166 | find(selector) { 167 | let newSelection = []; 168 | for (const s of this.selection) { 169 | const elems = s.querySelectorAll(selector); 170 | // newSelection = newSelection.concat(elems); also works, but this 171 | // creates a new array every time, so it may not be faster 172 | // 173 | // Note that the number of arguments is capped at around 30,000 174 | // depending on the browser, but there should not be that many 175 | // elements in the document 176 | newSelection.push(...elems); 177 | } 178 | this.selection = newSelection; 179 | this.length = newSelection.length; 180 | return this; 181 | } 182 | /** 183 | * Update current selection, set it to immediate children of each selected 184 | * elements that match the new selector. 185 | * @method 186 | * @param {string} selector - The new query selector. 187 | */ 188 | children(selector) { 189 | return this.find(":scope > " + selector); 190 | } 191 | /** 192 | * Update current selection, set it to the parent of each selected 193 | * elements if exist. 194 | * Elements that do not have a parent will not be updated. 195 | * @method 196 | */ 197 | parent() { 198 | for (let i = 0; i < this.selection.length; i++) { 199 | const elem = this.selection[i].parentNode; 200 | if (elem) { 201 | this.selection[i] = elem; 202 | } 203 | } 204 | return this; 205 | } 206 | /** 207 | * Update current selection, only keep elements that have children 208 | * matching a given selector. 209 | * @method 210 | * @param {string} selector - The query selector. 211 | * @param {boolean} [match=true] - Set to false to only keep elements 212 | * that do not have children matching the selector. 213 | */ 214 | filter(selector, match = true) { 215 | let newSelection = []; 216 | for (const s of this.selection) { 217 | if (match === Boolean(s.querySelector(selector))) { 218 | newSelection.push(s); 219 | } 220 | } 221 | this.selection = newSelection; 222 | this.length = newSelection.length; 223 | return this; 224 | } 225 | /** 226 | * Update current selection, only keep elements that have the matcher 227 | * string in their textContent. 228 | * @method 229 | * @param {string} matcher - The matcher string. 230 | */ 231 | includes(matcher) { 232 | let newSelection = []; 233 | for (const s of this.selection) { 234 | if (s.textContent.includes(matcher)) { 235 | newSelection.push(s); 236 | } 237 | } 238 | this.selection = newSelection; 239 | this.length = newSelection.length; 240 | return this; 241 | } 242 | /** 243 | * Update current selection, only keep elements that have the matcher 244 | * string as the beginning of their textContent. 245 | * @method 246 | * @param {string} matcher - The matcher string. 247 | */ 248 | startsWith(matcher) { 249 | let newSelection = []; 250 | for (const s of this.selection) { 251 | if (s.textContent.startsWith(matcher)) { 252 | newSelection.push(s); 253 | } 254 | } 255 | this.selection = newSelection; 256 | this.length = newSelection.length; 257 | return this; 258 | } 259 | /** 260 | * Update current selection, only keep elements that have the matcher 261 | * string as the ending of their textContent. 262 | * @method 263 | * @param {string} matcher - The matcher string. 264 | */ 265 | endsWith(matcher) { 266 | let newSelection = []; 267 | for (const s of this.selection) { 268 | if (s.textContent.endsWith(matcher)) { 269 | newSelection.push(s); 270 | } 271 | } 272 | this.selection = newSelection; 273 | this.length = newSelection.length; 274 | return this; 275 | } 276 | /** 277 | * Update current selection, only keep elements that have the matcher 278 | * string as their textContent. 279 | * @method 280 | * @param {string} matcher - The matcher string. 281 | */ 282 | textIs(matcher) { 283 | let newSelection = []; 284 | for (const s of this.selection) { 285 | if (matcher === s.textContent) { 286 | newSelection.push(s); 287 | } 288 | } 289 | this.selection = newSelection; 290 | this.length = newSelection.length; 291 | return this; 292 | } 293 | 294 | 295 | /** 296 | * Add an event listener to all selected elements. 297 | * @param {string} ...args - Listener details 298 | * @param {Event} e - The appropriate event object. 299 | */ 300 | on(...args) { 301 | for (let s of this.selection) { 302 | s.addEventListener(...args); 303 | } 304 | return this; 305 | } 306 | /** 307 | * Trigger a click event to all selected elements. 308 | * @method 309 | */ 310 | click() { 311 | for (let s of this.selection) { 312 | s.click(); 313 | } 314 | return this; 315 | } 316 | 317 | 318 | /** 319 | * Get or set textContent. Affects only the first element on get mode, 320 | * but affects all selected elements in set mode. 321 | * @method 322 | * @param {string} [text=undefined] - The text to set, omit to get. 323 | * @return {string|this} String in get mode, the keyword this in set mode. 324 | * An empty string will be returned if the textContent cannot be 325 | * retrieved. 326 | */ 327 | text(text) { 328 | if (text === undefined) { 329 | return this.selection.length ? this.selection[0].textContent : ""; 330 | } else { 331 | for (let s of this.selection) { 332 | s.textContent = text; 333 | } 334 | return this; 335 | } 336 | } 337 | /** 338 | * Get or set innerHTML. Affects only the first element on get mode, but 339 | * affects all selected elements in set mode. 340 | * @method 341 | * @param {DOMString} [html=undefined] - The DOM string to set, omit to 342 | * get. 343 | * @return {DOMString|this} DOM string in get mode, the keyword this in 344 | * set mode. An empty string will be returned if the innerHTML cannot 345 | * be retrieved. 346 | */ 347 | html(html) { 348 | if (html === undefined) { 349 | return this.selection.length ? this.selection[0].innerHTML : ""; 350 | } else { 351 | for (let s of this.selection) { 352 | s.innerHTML = html; 353 | } 354 | return this; 355 | } 356 | } 357 | /** 358 | * Get or set data. Affects only the first element on get mode, but 359 | * affects all selected elements in set mode. 360 | * @method 361 | * @param {string} name - The name of the data entry. 362 | * @param {string} [val=undefined] - The value to set, omit to get. 363 | * @return {Any|this} The data in get mode, the keyword this in set mode. 364 | * Undefined will be returned if the data cannot be retrieved. 365 | */ 366 | data(name, val) { 367 | if (val === undefined) { 368 | return this.selection.length ? this.selection[0].dataset[name] : undefined; 369 | } else { 370 | for (let s of this.selection) { 371 | s.dataset[name] = val; 372 | } 373 | return this; 374 | } 375 | } 376 | /** 377 | * Get or set attribute. Affect only the first element on get mode, but 378 | * affect all selected elements in set mode. 379 | * @method 380 | * @param {string} name - The name of the attribute. 381 | * @param {string} [val=undefined] - The value to set, omit to get. 382 | * @return {Any|this} The attribute in get mode, the keyword this in set 383 | * mode. Undefined will be returned if the attribute cannot be retrieved. 384 | */ 385 | attr(name, val) { 386 | if (val === undefined) { 387 | return this.selection.length ? this.selection[0].getAttribute(name) : undefined; 388 | } else { 389 | for (let s of this.selection) { 390 | s.setAttribute(name, val); 391 | } 392 | return this; 393 | } 394 | } 395 | /** 396 | * Delete an attribute. 397 | * @method 398 | * @param {string} name - The name of the attribute. 399 | */ 400 | rmAttr(name) { 401 | for (let s of this.selection) { 402 | s.removeAttribute(name); 403 | } 404 | return this; 405 | } 406 | /** 407 | * Get or set property. Affect only the first element on get mode, but 408 | * affect all selected elements in set mode. 409 | * @method 410 | * @param {string} name - The name of the property. 411 | * @param {string} [val=undefined] - The value to set, omit to get. 412 | * @return {Any|this} The property in get mode, the keyword this in set 413 | * mode. Undefined will be returned if the property cannot be retrieved. 414 | */ 415 | prop(name, val) { 416 | if (val === undefined) { 417 | return this.selection.length ? this.selection[0][name] : undefined; 418 | } else { 419 | for (let s of this.selection) { 420 | s[name] = val; 421 | } 422 | return this; 423 | } 424 | } 425 | 426 | 427 | /** 428 | * Insert HTML before the beginning of each selected elements if possible. 429 | * @method 430 | * @param {DOMString} input - The DOM string to insert. 431 | */ 432 | before(input) { 433 | for (let s of this.selection) { 434 | // Must have parent node in this insert mode 435 | if (s.parentNode) { 436 | s.insertAdjacentHTML("beforebegin", input); 437 | } 438 | } 439 | return this; 440 | } 441 | /** 442 | * Insert HTML after the beginning of each selected elements. 443 | * @method 444 | * @param {DOMString} input - The DOM string to insert. 445 | */ 446 | prepend(input) { 447 | for (let s of this.selection) { 448 | s.insertAdjacentHTML("afterbegin", input); 449 | } 450 | return this; 451 | } 452 | /** 453 | * Insert HTML before the end of each selected elements. 454 | * @method 455 | * @param {DOMString} input - The DOM string to insert. 456 | */ 457 | append(input) { 458 | for (let s of this.selection) { 459 | s.insertAdjacentHTML("beforeend", input); 460 | } 461 | return this; 462 | } 463 | /** 464 | * Insert HTML after the end of each selected elements if possible. 465 | * @method 466 | * @param {DOMString} input - The DOM string to insert. 467 | */ 468 | after(input) { 469 | for (let s of this.selection) { 470 | // Must have parent node in this insert mode 471 | if (s.parentNode) { 472 | s.insertAdjacentHTML("afterend", input); 473 | } 474 | } 475 | return this; 476 | } 477 | 478 | 479 | /** 480 | * Get offsetWidth of the first selected element. 481 | * @method 482 | * @return {integer} The offsetWidth, or -1 if the offsetWidth cannot be 483 | * retrieved. 484 | */ 485 | width() { 486 | return this.selection.length ? this.selection[0].offsetWidth : -1; 487 | } 488 | /** 489 | * Get offsetHeight of the first selected element. 490 | * @method 491 | * @return {integer} The offsetHeight, or -1 if the offsetHeight cannot be 492 | * retrieved. 493 | */ 494 | height() { 495 | return this.selection.length ? this.selection[0].offsetHeight : -1; 496 | } 497 | /** 498 | * Loop though each selected element. 499 | * @method 500 | * @param {Function} func - The handler. 501 | * @param {DOMElement} elem - The current DOM element. 502 | */ 503 | each(func) { 504 | for (let s of this.selection) { 505 | func(s); 506 | } 507 | return this; 508 | } 509 | }; 510 | 511 | 512 | /** 513 | * Send a XMLHttpRequest. 514 | * @function 515 | * @param {Object} details - Details about this request. 516 | * @param {string} method - The method of the request, usually "GET" or 517 | * "POST". 518 | * @param {string} url - The URL of the request. 519 | * @param {Object|undefined} [headers=undefined] - The headers of the 520 | * request. 521 | * @param {string|null} [payload=null] - The payload of the request. 522 | * @param {Function} onload - The load event handler. 523 | * @param {string} response - The response text. 524 | * @param {Function} onerror - The error event handler. 525 | */ 526 | $.request = (details, onload, onerror) => { 527 | let req = new XMLHttpRequest(); 528 | 529 | req.onreadystatechange = () => { 530 | if (req.readyState === XMLHttpRequest.DONE) { 531 | if (req.status === 200) { 532 | onload(req.responseText); 533 | } else { 534 | onerror(); 535 | } 536 | } 537 | }; 538 | 539 | req.open(details.method, details.url); 540 | 541 | if (details.headers) { 542 | for (const key in details.headers) { 543 | if (details.headers.hasOwnProperty(key)) { 544 | req.setRequestHeader(key, details.headers[key]); 545 | } 546 | } 547 | } 548 | 549 | req.send(details.payload || null); 550 | }; 551 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Nano Defender Contributors", 3 | "background": { 4 | "scripts": [ 5 | "common.js", 6 | "platform/chromium-vars.js", 7 | "background/core.js", 8 | "background/rules.js", 9 | "background/debug.js" 10 | ] 11 | }, 12 | "browser_action": { 13 | "default_icon": { 14 | "128": "icon128.png" 15 | }, 16 | "default_popup": "popup/index.html", 17 | "default_title": "Nano Defender Debug" 18 | }, 19 | "content_scripts": [ 20 | { 21 | "all_frames": true, 22 | "js": [ 23 | "common.js", 24 | "libdom.js", 25 | "content/core.js", 26 | "content/rules-common.js", 27 | "content/rules-specific.js", 28 | "content/rules-sticky.js", 29 | "content/debug.js", 30 | "content/ubo-extra.js" 31 | ], 32 | "match_about_blank": true, 33 | "matches": [ 34 | "http://*/*", 35 | "https://*/*" 36 | ], 37 | "run_at": "document_start" 38 | } 39 | ], 40 | "description": "Companion extension for Nano Adblocker", 41 | "homepage_url": "https://jspenguin2017.github.io/uBlockProtector/", 42 | "icons": { 43 | "128": "icon128.png" 44 | }, 45 | "incognito": "split", 46 | "manifest_version": 2, 47 | "minimum_chrome_version": "69.0", 48 | "name": "Nano Defender Debug", 49 | "permissions": [ 50 | "http://*/*", 51 | "https://*/*", 52 | "tabs", 53 | "webNavigation", 54 | "webRequest", 55 | "webRequestBlocking" 56 | ], 57 | "version": "15.0.0.206", 58 | "web_accessible_resources": [ 59 | "resources/*" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /src/platform/chromium-vars.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Platform constants for Chromium 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | a.NanoAdblockerExtensionID = "gabbbocakeomblphkmmnoamkioajlkfo"; 30 | 31 | if (navigator.userAgent.includes(" Edg/")) 32 | a.NanoAdblockerExtensionID = "epbkapkgcmdmfpogenoebpdeibmfinpf"; 33 | 34 | // ----------------------------------------------------------------------------------------------------------------- // 35 | -------------------------------------------------------------------------------- /src/platform/edge-content.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Special content script for legacy Edge 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | if (a.domCmp(["windowscentral.com"])) { 30 | a.noAccess("adonisHash"); 31 | a.beforeScript((script) => { 32 | if (script.textContent && script.textContent.includes("adBlocker")) { 33 | script.remove(); 34 | } 35 | }); 36 | } 37 | 38 | // ----------------------------------------------------------------------------------------------------------------- // 39 | -------------------------------------------------------------------------------- /src/platform/edge-vars.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Platform constants for legacy Edge 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | a.NanoAdblockerExtensionID = "EdgeExtension_23837jspenguin2017NanoAdblocker_aegazecm1370c"; 30 | 31 | // ----------------------------------------------------------------------------------------------------------------- // 32 | -------------------------------------------------------------------------------- /src/platform/firefox-background.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Special background script for Firefox 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | //@pragma-if-debug 30 | 31 | // Debug rules 32 | 33 | if (a.debugMode) { 34 | 35 | { 36 | // https://github.com/uBlockOrigin/uAssets/issues/772 37 | 38 | a.dynamicServer( 39 | [ 40 | "*://*.uplynk.com/preplay/*", 41 | ], 42 | [ 43 | "xmlhttprequest", 44 | ], 45 | (details) => { 46 | let payload = ""; 47 | 48 | const filter = browser.webRequest.filterResponseData(details.requestId); 49 | const decoder = new TextDecoder("utf-8"); 50 | const encoder = new TextEncoder(); 51 | 52 | filter.ondata = (e) => { 53 | payload += decoder.decode(e.data, { stream: true }); 54 | }; 55 | filter.onstop = () => { 56 | try { 57 | payload = JSON.parse(payload); 58 | } catch (err) { 59 | filter.write(encoder.encode(payload)); 60 | filter.disconnect(); 61 | return; 62 | } 63 | 64 | // Debug log 65 | console.log(payload.ads); 66 | 67 | payload.ads = { 68 | breakOffsets: [], 69 | breaks: [], 70 | placeholderOffsets: [], 71 | }; 72 | 73 | filter.write(encoder.encode(JSON.stringify(payload))); 74 | filter.disconnect(); 75 | }; 76 | }, 77 | [ 78 | "fox.com", 79 | ], 80 | true, 81 | ); 82 | } 83 | 84 | } 85 | 86 | //@pragma-end-if 87 | 88 | // ----------------------------------------------------------------------------------------------------------------- // 89 | -------------------------------------------------------------------------------- /src/platform/firefox-content.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Special content script for Firefox 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | // ----------------------------------------------------------------------------------------------------------------- // 28 | 29 | // Simply removing the node does not prevent execution of the script 30 | 31 | { 32 | const _remove = Element.prototype.remove; 33 | const remove = function () { 34 | if (this.tagName === "SCRIPT") { 35 | this.textContent = ""; 36 | } 37 | _remove.call(this); 38 | }; 39 | Element.prototype.remove = remove; 40 | } 41 | 42 | // ----------------------------------------------------------------------------------------------------------------- // 43 | -------------------------------------------------------------------------------- /src/platform/firefox-vars.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------------------- // 2 | 3 | // Nano Defender - An anti-adblock defuser 4 | // Copyright (C) 2016-2019 Nano Defender contributors 5 | // 6 | // This program is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published by 8 | // the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // ----------------------------------------------------------------------------------------------------------------- // 20 | 21 | // Platform constants for Firefox 22 | 23 | // ----------------------------------------------------------------------------------------------------------------- // 24 | 25 | "use strict"; 26 | 27 | /** 28 | * The extension ID of Nano Adblocker. 29 | * @const {string} 30 | */ 31 | a.NanoAdblockerExtensionID = "{0f929014-5ed2-4527-8b8d-86a9c889b129}"; 32 | -------------------------------------------------------------------------------- /src/popup/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0px; 3 | min-width: 250px; 4 | width: auto; 5 | font-family: sans-serif; 6 | background-color: #FFFFFF; 7 | user-select: none; 8 | } 9 | 10 | .title { 11 | background-color: #444444; 12 | color: #FFFFFF; 13 | font-size: 12px; 14 | text-align: center; 15 | padding: 5px; 16 | } 17 | 18 | .title > p { 19 | margin: 0px; 20 | } 21 | 22 | .wrapper { 23 | padding: 6px; 24 | } 25 | 26 | .wrapper:hover { 27 | background-color: #EEEEEE; 28 | } 29 | 30 | .wrapper > svg { 31 | margin-right: 3px; 32 | position: relative; 33 | top: 1px; 34 | width: 16px; 35 | } 36 | 37 | .wrapper > span { 38 | font-size: 14px; 39 | position: relative; 40 | top: -2px; 41 | } 42 | 43 | .separator.dashed { 44 | border-bottom: 1px dashed #CCCCCC; 45 | } 46 | 47 | .separator.solid { 48 | border-bottom: 1px solid #444444; 49 | } 50 | -------------------------------------------------------------------------------- /src/popup/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Nano Defender Popup Panel 11 | 12 | 13 | 14 | 15 | 16 | 17 |

18 |

Nano Defender

19 |
20 | 21 |
22 | 23 | 24 | 25 | Home Page 26 |
27 | 28 |
29 | 30 |
31 | 32 | 33 | 34 | Announcements 35 |
36 | 37 |
38 | 39 |
40 | 41 | 42 | 43 | Troubleshooting 44 |
45 | 46 |
47 | 48 |
49 | 50 | 51 | 52 | FAQ 53 |
54 | 55 |
56 | 57 |
58 | 59 | 60 | 61 | Known Issues 62 |
63 | 64 |
65 | 66 |
67 | 68 | 69 | 70 | Report an Issue 71 |
72 | 73 |
74 | 75 |
76 | 77 | 78 | 79 | Source Code 80 |
81 | 82 |
83 | 84 |
85 | 86 | 87 | 88 | License 89 |
90 | 91 |
92 | 93 |
94 | 95 | 96 | 97 | Credits 98 |
99 | 100 | 101 | -------------------------------------------------------------------------------- /src/popup/index.js: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | 3 | Nano Defender - An anti-adblock defuser 4 | Copyright (C) 2016-2018 Nano Defender contributors 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | ******************************************************************************* 20 | 21 | Popup panel script. 22 | 23 | ******************************************************************************/ 24 | 25 | "use strict"; 26 | 27 | /*****************************************************************************/ 28 | 29 | /** 30 | * Homepage links. 31 | * @const {Map} 32 | */ 33 | const home = [ 34 | "", 35 | "https://jspenguin2017.github.io/uBlockProtector/", 36 | "https://github.com/jspenguin2017/uBlockProtector", 37 | chrome.runtime.getURL("/reporter/index.html"), 38 | ]; 39 | 40 | /*****************************************************************************/ 41 | 42 | { 43 | const manifest = chrome.runtime.getManifest(); 44 | $(".title > p").text(manifest.name + " " + manifest.version); 45 | } 46 | 47 | /*****************************************************************************/ 48 | 49 | chrome.tabs.query({ 50 | active: true, 51 | currentWindow: true, 52 | }, (tabs) => { 53 | if (chrome.runtime.lastError || tabs.length === 0) 54 | return; 55 | 56 | home[3] = home[3] + "?" + tabs[0].id; 57 | }); 58 | 59 | /*****************************************************************************/ 60 | 61 | $(".wrapper").on("click", function () { 62 | const url = home[this.dataset.home] + this.dataset.href; 63 | chrome.tabs.create({ url: url }); 64 | }); 65 | 66 | /*****************************************************************************/ 67 | -------------------------------------------------------------------------------- /src/resources/blank.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiCybora/NanoDefenderFirefox/2006d69afdefbbb2dcd1b2dca31bb2a516efc4d1/src/resources/blank.mp4 -------------------------------------------------------------------------------- /src/resources/fw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Moat FreeWheel JSPEM surrogate. 3 | */ 4 | ; (() => { 5 | "use strict"; 6 | 7 | try { 8 | window.console.error("[Nano] Surrogate Injected :: FreeWheel SDK"); 9 | } catch (err) { } 10 | 11 | window.MoatFreeWheelJSPEM = class { 12 | init() { } 13 | dispose() { } 14 | }; 15 | })(); 16 | -------------------------------------------------------------------------------- /src/resources/ima3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Interactive Media Ads Software Development Kit surrogate. 3 | * https://developers.google.com/interactive-media-ads/docs/sdks/html5/v3/apis 4 | */ 5 | ; (() => { 6 | "use strict"; 7 | 8 | try { 9 | window.console.error("[Nano] Surrogate Injected :: IMA SDK"); 10 | } catch (err) { } 11 | 12 | let warnCount = 0; 13 | 14 | window.google = window.google || {}; 15 | 16 | // Interfaces are not implemented 17 | window.google.ima = { 18 | AdDisplayContainer: class { 19 | // constructor(container, video, click) { } 20 | initialize() { } 21 | destroy() { } 22 | }, 23 | 24 | AdError: class { 25 | constructor(message, code, type) { 26 | this._message = message; 27 | this._code = code; 28 | this._type = type; 29 | } 30 | getErrorCode() { 31 | return this._code; 32 | } 33 | getInnerError() { 34 | return null; 35 | } 36 | getMessage() { 37 | return this._message; 38 | } 39 | getType() { 40 | return this._type; 41 | } 42 | getVastErrorCode() { 43 | return window.google.ima.AdError.ErrorCode.UNKNOWN_ERROR; 44 | } 45 | toString() { 46 | return "AdError " + this._code + ": " + this._message + "."; 47 | } 48 | }, 49 | 50 | AdErrorEvent: class extends ErrorEvent { 51 | constructor(error, context) { 52 | super(error); 53 | this._errObj = error; 54 | this._context = context; 55 | } 56 | getError() { 57 | return this._errObj; 58 | } 59 | getUserRequestContext() { 60 | return this._context; 61 | } 62 | }, 63 | 64 | AdEvent: class extends Event { 65 | constructor(type, ad, adData) { 66 | super(type); 67 | this._ad = ad; 68 | this._adData = adData; 69 | } 70 | getAd() { 71 | return this._ad; 72 | } 73 | getAdData() { 74 | return this._adData; 75 | } 76 | }, 77 | 78 | AdsLoader: class { 79 | constructor() { 80 | this._onError = []; 81 | this._onErrorScope = []; 82 | this._error = new window.google.ima.AdErrorEvent( 83 | new window.google.ima.AdError( 84 | "No ads available", 85 | window.google.ima.AdError.ErrorCode.VAST_NO_ADS_AFTER_WRAPPER, 86 | window.google.ima.AdError.Type.AD_LOAD, 87 | ), 88 | {}, 89 | ); 90 | } 91 | addEventListener(event, handler, capture, scope) { 92 | // The real SDK should also always return error 93 | if (event === window.google.ima.AdErrorEvent.Type.AD_ERROR) { 94 | this._onError.push(handler); 95 | this._onErrorScope.push(scope); 96 | } else if (warnCount < 10) { 97 | warnCount++; 98 | try { 99 | window.console.warn("[Nano] IMA Event Ignored :: " + event); 100 | } catch (err) { } 101 | } 102 | } 103 | removeEventListener(event, handler) { 104 | // Capture and scope are not checked 105 | if (event === window.google.ima.AdErrorEvent.Type.AD_ERROR) { 106 | for (let i = 0; i < this._onError.length; i++) { 107 | // This should be good enough 108 | if (this._onError[i] === handler) { 109 | this._onError.splice(i, 1); 110 | this._onErrorScope.splice(i, 1); 111 | i--; 112 | } 113 | } 114 | } 115 | // Ignore otherwise 116 | } 117 | _dispatchError() { 118 | for (let i = 0; i < this._onError.length; i++) { 119 | if (this._onErrorScope[i]) { 120 | this._onError[i].call(this._onErrorScope[i], this._error); 121 | } else { 122 | this._onError[i](this._error); 123 | } 124 | } 125 | } 126 | 127 | contentComplete() { } 128 | destroy() { } 129 | getSettings() { 130 | return window.google.ima.settings; 131 | } 132 | requestAds() { 133 | window.setTimeout(this._dispatchError.bind(this), 10); 134 | } 135 | }, 136 | 137 | AdsManagerLoadedEvent: class extends Event { 138 | constructor() { 139 | // Not implemented 140 | throw new window.Error("[Nano] Not Implemented :: Neutralized AdsManager"); 141 | } 142 | }, 143 | 144 | AdsRenderingSettings: class { 145 | // Not implemented 146 | // constructor() { } 147 | }, 148 | 149 | AdsRequest: class { 150 | // Partially implemented 151 | // constructor() { } 152 | setAdWillAutoPlay() { } 153 | setAdWillPlayMuted() { } 154 | }, 155 | 156 | CompanionAdSelectionSettings: class { 157 | // Not implemented 158 | // constructor() { } 159 | }, 160 | 161 | ImaSdkSettings: class { 162 | // Partially implemented 163 | // constructor() { } 164 | getCompanionBackfill() { 165 | return window.google.ima.ImaSdkSettings.CompanionBackfillMode.ALWAYS; 166 | } 167 | getDisableCustomPlaybackForIOS10Plus() { 168 | return false; 169 | } 170 | getDisableFlashAds() { 171 | return true; 172 | } 173 | getLocale() { 174 | return "en-CA"; 175 | } 176 | getNumRedirects() { 177 | return 1; 178 | } 179 | getPlayerType() { 180 | return "Unknown"; 181 | } 182 | getPlayerVersion() { 183 | return "1.0.0"; 184 | } 185 | getPpid() { 186 | return "2GjCgoECAP0IbU"; 187 | } 188 | 189 | setAutoPlayAdBreaks() { } 190 | setCompanionBackfill() { } 191 | setDisableCustomPlaybackForIOS10Plus() { } 192 | setDisableFlashAds() { } 193 | setLocale() { } 194 | setNumRedirects() { } 195 | setPlayerType() { } 196 | setPlayerVersion() { } 197 | setPpid() { } 198 | setVpaidAllowed() { } 199 | setVpaidMode() { } 200 | }, 201 | 202 | UiElements: { 203 | COUNTDOWN: "countdown", 204 | }, 205 | 206 | ViewMode: { 207 | FULLSCREEN: "fullscreen", 208 | NORMAL: "normal", 209 | }, 210 | 211 | VERSION: "3.173.4", 212 | }; 213 | 214 | window.google.ima.AdError.ErrorCode = { 215 | VIDEO_PLAY_ERROR: 400, 216 | FAILED_TO_REQUEST_ADS: 1005, 217 | REQUIRED_LISTENERS_NOT_ADDED: 900, 218 | VAST_LOAD_TIMEOUT: 301, 219 | VAST_NO_ADS_AFTER_WRAPPER: 303, 220 | VAST_MEDIA_LOAD_TIMEOUT: 402, 221 | VAST_TOO_MANY_REDIRECTS: 302, 222 | VAST_ASSET_MISMATCH: 403, 223 | VAST_LINEAR_ASSET_MISMATCH: 403, 224 | VAST_NONLINEAR_ASSET_MISMATCH: 503, 225 | VAST_ASSET_NOT_FOUND: 1007, 226 | VAST_UNSUPPORTED_VERSION: 102, 227 | VAST_SCHEMA_VALIDATION_ERROR: 101, 228 | VAST_TRAFFICKING_ERROR: 200, 229 | VAST_UNEXPECTED_LINEARITY: 201, 230 | VAST_UNEXPECTED_DURATION_ERROR: 202, 231 | VAST_WRAPPER_ERROR: 300, 232 | NONLINEAR_DIMENSIONS_ERROR: 501, 233 | COMPANION_REQUIRED_ERROR: 602, 234 | VAST_EMPTY_RESPONSE: 1009, 235 | UNSUPPORTED_LOCALE: 1011, 236 | INVALID_ADX_EXTENSION: 1105, 237 | INVALID_ARGUMENTS: 1101, 238 | UNKNOWN_AD_RESPONSE: 1010, 239 | UNKNOWN_ERROR: 900, 240 | OVERLAY_AD_PLAYING_FAILED: 500, 241 | VIDEO_ELEMENT_USED: -1, 242 | VIDEO_ELEMENT_REQUIRED: -1, 243 | VAST_MEDIA_ERROR: -1, 244 | ADSLOT_NOT_VISIBLE: -1, 245 | OVERLAY_AD_LOADING_FAILED: -1, 246 | VAST_MALFORMED_RESPONSE: -1, 247 | COMPANION_AD_LOADING_FAILED: -1, 248 | }; 249 | 250 | window.google.ima.AdError.Type = { 251 | AD_LOAD: "adLoadError", 252 | AD_PLAY: "adPlayError", 253 | }; 254 | 255 | window.google.ima.AdErrorEvent.Type = { 256 | AD_ERROR: "adError", 257 | }; 258 | 259 | window.google.ima.AdEvent.Type = { 260 | CONTENT_RESUME_REQUESTED: "contentResumeRequested", 261 | CONTENT_PAUSE_REQUESTED: "contentPauseRequested", 262 | CLICK: "click", 263 | DURATION_CHANGE: "durationChange", 264 | EXPANDED_CHANGED: "expandedChanged", 265 | STARTED: "start", 266 | IMPRESSION: "impression", 267 | PAUSED: "pause", 268 | RESUMED: "resume", 269 | FIRST_QUARTILE: "firstquartile", 270 | MIDPOINT: "midpoint", 271 | THIRD_QUARTILE: "thirdquartile", 272 | COMPLETE: "complete", 273 | USER_CLOSE: "userClose", 274 | LINEAR_CHANGED: "linearChanged", 275 | LOADED: "loaded", 276 | AD_CAN_PLAY: "adCanPlay", 277 | AD_METADATA: "adMetadata", 278 | AD_BREAK_READY: "adBreakReady", 279 | INTERACTION: "interaction", 280 | ALL_ADS_COMPLETED: "allAdsCompleted", 281 | SKIPPED: "skip", 282 | SKIPPABLE_STATE_CHANGED: "skippableStateChanged", 283 | LOG: "log", 284 | VIEWABLE_IMPRESSION: "viewable_impression", 285 | VOLUME_CHANGED: "volumeChange", 286 | VOLUME_MUTED: "mute", 287 | }; 288 | 289 | window.google.ima.AdsManagerLoadedEvent.Type = { 290 | ADS_MANAGER_LOADED: "adsManagerLoaded", 291 | }; 292 | 293 | window.google.ima.CompanionAdSelectionSettings.CreativeType = { 294 | ALL: "All", 295 | FLASH: "Flash", 296 | IMAGE: "Image", 297 | }; 298 | 299 | window.google.ima.CompanionAdSelectionSettings.ResourceType = { 300 | ALL: "All", 301 | HTML: "Html", 302 | IFRAME: "IFrame", 303 | STATIC: "Static", 304 | }; 305 | 306 | window.google.ima.CompanionAdSelectionSettings.SizeCriteria = { 307 | IGNORE: "IgnoreSize", 308 | SELECT_EXACT_MATCH: "SelectExactMatch", 309 | SELECT_NEAR_MATCH: "SelectNearMatch", 310 | }; 311 | 312 | window.google.ima.ImaSdkSettings.CompanionBackfillMode = { 313 | ALWAYS: "always", 314 | ON_MASTER_AD: "on_master_ad", 315 | }; 316 | 317 | window.google.ima.ImaSdkSettings.VpaidMode = { 318 | DISABLED: 0, 319 | ENABLED: 1, 320 | INSECURE: 2, 321 | }; 322 | 323 | window.google.ima.settings = new window.google.ima.ImaSdkSettings(); 324 | })(); 325 | -------------------------------------------------------------------------------- /src/resources/jquery.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery Anti-adblock plugin defuser. 3 | */ 4 | ; (() => { 5 | "use strict"; 6 | 7 | try { 8 | window.console.error("[Nano] Generic Solution Triggered :: jQuery Plugin"); 9 | } catch (err) { } 10 | 11 | try { 12 | window.$.adblock = false; 13 | } catch (err) { } 14 | try { 15 | window.jQuery.adblock = false; 16 | } catch (err) { } 17 | })(); 18 | -------------------------------------------------------------------------------- /tests/check-syntax.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check for syntax error. 3 | */ 4 | "use strict"; 5 | 6 | /** 7 | * Load modules. 8 | * @const {Module} 9 | */ 10 | const assert = require("assert"); 11 | const esprima = require("esprima"); 12 | const fs = require("./promise-fs.js"); 13 | 14 | /** 15 | * Validate syntax of a JavaScript file. 16 | * @async @function 17 | * @param {string} file - The path to the file to check. 18 | */ 19 | const validateJS = async (file) => { 20 | const data = await fs.readFile(file, "utf8"); 21 | esprima.parse(data); 22 | }; 23 | /** 24 | * Validate syntax of a JSON file. 25 | * @async @function 26 | * @param {string} file - The path to the file to check. 27 | */ 28 | const validateJSON = async (file) => { 29 | const data = await fs.readFile(file, "utf8"); 30 | JSON.parse(data); 31 | }; 32 | 33 | /** 34 | * Check syntax recursively for one directory. 35 | * @async @function 36 | * @param {string} directory - The path to the directory to check. 37 | */ 38 | exports.validateDirectory = async (directory) => { 39 | const files = await fs.readdir(directory); 40 | 41 | let tasks = []; 42 | for (const file of files) { 43 | tasks.push(fs.lstat(directory + "/" + file)); 44 | } 45 | tasks = await Promise.all(tasks); 46 | assert(files.length === tasks.length); 47 | 48 | let validateTasks = []; 49 | for (let i = 0; i < files.length; i++) { 50 | assert(!tasks[i].isSymbolicLink()); 51 | 52 | if (tasks[i].isDirectory()) { 53 | // One directory at a time to make sure things will not get 54 | // overloaded 55 | await exports.validateDirectory(directory + "/" + files[i]); 56 | continue; 57 | } 58 | 59 | assert(tasks[i].isFile()); 60 | if (files[i].endsWith(".js")) { 61 | validateTasks.push(validateJS(directory + "/" + files[i])); 62 | } else if (files[i].endsWith(".json")) { 63 | validateTasks.push(validateJSON(directory + "/" + files[i])); 64 | } 65 | } 66 | await Promise.all(validateTasks); 67 | }; 68 | -------------------------------------------------------------------------------- /tests/promise-fs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Promisified file system module. 3 | * 4 | * Watches for "--trace-fs" command line argument, if exists 5 | * file system calls are logged. 6 | */ 7 | "use strict"; 8 | 9 | 10 | /** 11 | * Load modules. 12 | * @const {Module} 13 | */ 14 | const fs = require("fs"); 15 | const util = require("util"); 16 | 17 | /** 18 | * The new file system namespace, functions are added as needed. 19 | * @const {Namespace} 20 | */ 21 | const newfs = { 22 | appendFile: util.promisify(fs.appendFile), 23 | copyFile: util.promisify(fs.copyFile), 24 | createReadStream: fs.createReadStream, 25 | createWriteStream: fs.createWriteStream, 26 | lstat: util.promisify(fs.lstat), 27 | mkdir: util.promisify(fs.mkdir), 28 | readdir: util.promisify(fs.readdir), 29 | readFile: util.promisify(fs.readFile), 30 | writeFile: util.promisify(fs.writeFile), 31 | }; 32 | 33 | /** 34 | * Print variables, truncate long strings. 35 | * @function 36 | * @param {Any} ...args - Variables to print. 37 | */ 38 | const varDump = (...args) => { 39 | let out = []; 40 | for (const arg of args) { 41 | if (typeof arg === "string" && arg.length > 200) { 42 | out.push(""); 43 | } else { 44 | out.push(arg); 45 | } 46 | } 47 | console.log(...out); 48 | }; 49 | /** 50 | * Make a file system access tracer. 51 | * @function 52 | * @param {string} name - The function to intercept. 53 | * @return {Function} The tracer. 54 | */ 55 | const makeTracer = (name) => { 56 | return (...args) => { 57 | varDump("fs." + name, ...args); 58 | return newfs[name](...args); 59 | }; 60 | }; 61 | 62 | 63 | if (process.argv.includes("--trace-fs")) { 64 | module.exports = {}; 65 | for (const key in newfs) { 66 | if (newfs.hasOwnProperty(key)) { 67 | module.exports[key] = makeTracer(key); 68 | } 69 | } 70 | } else { 71 | module.exports = newfs; 72 | } 73 | -------------------------------------------------------------------------------- /tests/tests-main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Tests entry point. 3 | */ 4 | "use strict"; 5 | 6 | 7 | /** 8 | * Load modules. 9 | * @const {Module} 10 | */ 11 | const assert = require("assert"); 12 | const checkSyntax = require("./check-syntax.js"); 13 | 14 | 15 | process.on("unhandledRejection", (e) => { 16 | throw e; 17 | }); 18 | 19 | assert(/[\\/]uBlockProtector$/.test(process.cwd())); 20 | 21 | (async () => { 22 | await checkSyntax.validateDirectory("./src"); 23 | })(); 24 | --------------------------------------------------------------------------------