Repository: darkreader/darkreader (ts)

Issue:
Option for running extension on restricted URLs
https://github.com/darkreader/darkreader/blob/b9408082d7bec6880119a2086982b11d648ddce0/src/background/utils/extension-api.ts#L15

With Dark Reader, restricted sites like addons.mozilla.org can't be themed with the restriction in about:config turned off in: 'privacy.resistFingerprinting.block_mozAddonManager'. For such sites to be themed please edit the file, 'background/index.js'. Then publish the addon on firefox's addon site.

Change the following in background/index.js from:
```
 function canInjectScript(url) {
        if (isFirefox()) {
            return (url
                && url.indexOf('about:') !== 0
                && url.indexOf('moz') !== 0
                && url.indexOf('view-source:') !== 0
                && url.indexOf('https://addons.mozilla.org') !== 0);
        }
        return (url
            && url.indexOf('chrome') !== 0
            && url.indexOf('https://chrome.google.com/webstore') !== 0);
    }
```

..and change it to:

```
   function canInjectScript(url) {
        if (isFirefox()) {
            return (url
                && url.indexOf('about:') !== 0
                && url.indexOf('moz') !== 0
                && url.indexOf('view-source:') !== 0);
        }
        return (url
            && url.indexOf('chrome') !== 0
            && url.indexOf('https://chrome.google.com/webstore') !== 0);
    }
```


Work on protected pages
There are 2 prefs controlling access of webextensions to protected domains:

* `extensions.webextensions.restrictedDomains`
* `privacy.resistFingerprinting.block_mozAddonManager`

But the addon doesn't work on these tabs even if it is configured not to restrict access to these tabs. For example uMatrix works fine on these tabs.

Pull request description:
Add option to run on protected pages
- Add a option under sitelist to allow people to disable the check if a site is protected
- Let users allow to darken sites that aren't protected in there Environment(Firefox about:config)
- Resolves #912
- Resolves #1254

Possible bug with render of UI that when toggling the option and staying in the same pop-up(so not closing it after toggling) that the Toggle site button is still rendering the `old option` so 

Disabled -> Enabled. Toggle site still shows the protected CSS.
Enabled -> Disabled. Toggle site still let you toggle the site.

Patch:
diff --git a/index.d.ts b/index.d.ts
index e7c110a4..5129cb44 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -126,6 +126,16 @@ declare namespace DarkReader {
          * ```
          */
         css: string;
+        /**
+         * List of CSS selectors where it's inline style should not be analyzed
+         * Mostly used for color pickers
+         */
+        ignoreInlineStyle: string[];
+        /**
+         * List of CSS selectors where it's image should not be analyzed
+         * Mostly used for wrongly inverted background-images
+         */
+        ignoreImageAnalysis: string[];
     }
 }
 
diff --git a/package-lock.json b/package-lock.json
index cc20a38c..749db5dc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5477,7 +5477,7 @@
     },
     "path-is-absolute": {
       "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
       "dev": true
     },
diff --git a/src/background/extension.ts b/src/background/extension.ts
index c799971e..db636704 100644
--- a/src/background/extension.ts
+++ b/src/background/extension.ts
@@ -91,7 +91,7 @@ export class Extension {
         this.registerCommands();
 
         this.ready = true;
-        this.tabs.updateContentScript();
+        this.tabs.updateContentScript({runOnProtectedPages: this.user.settings.enableForProtectedPages});
 
         this.awaiting.forEach((ready) => ready());
         this.awaiting = null;
@@ -364,7 +364,7 @@ export class Extension {
     private getURLInfo(url: string): TabInfo {
         const {DARK_SITES} = this.config;
         const isInDarkList = isURLInList(url, DARK_SITES);
-        const isProtected = !canInjectScript(url);
+        const isProtected = !(this.user.settings.enableForProtectedPages || canInjectScript(url));
         return {
             url,
             isInDarkList,
diff --git a/src/background/tab-manager.ts b/src/background/tab-manager.ts
index 036f16e0..a02f7fd1 100644
--- a/src/background/tab-manager.ts
+++ b/src/background/tab-manager.ts
@@ -89,9 +89,9 @@ export default class TabManager {
         });
     }
 
-    async updateContentScript() {
+    async updateContentScript(options: {runOnProtectedPages: boolean}) {
         (await queryTabs({}))
-            .filter((tab) => canInjectScript(tab.url))
+            .filter((tab) => options.runOnProtectedPages || canInjectScript(tab.url))
             .filter((tab) => !this.ports.has(tab.id))
             .forEach((tab) => !tab.discarded && chrome.tabs.executeScript(tab.id, {
                 runAt: 'document_start',
diff --git a/src/background/user-storage.ts b/src/background/user-storage.ts
index 4334dfd7..a7742041 100644
--- a/src/background/user-storage.ts
+++ b/src/background/user-storage.ts
@@ -23,6 +23,7 @@ export default class UserStorage {
     private loadSettingsFromStorage() {
         return new Promise<UserSettings>((resolve) => {
             chrome.storage.local.get(DEFAULT_SETTINGS, (local: UserSettings) => {
+                local.syncSettings = local.syncSettings || DEFAULT_SETTINGS.syncSettings;
                 if (!local.syncSettings) {
                     local.theme = {...DEFAULT_SETTINGS.theme, ...local.theme};
                     local.time = {...DEFAULT_SETTINGS.time, ...local.time};
diff --git a/src/config/dark-sites.config b/src/config/dark-sites.config
index 7f30dd76..835166fd 100644
--- a/src/config/dark-sites.config
+++ b/src/config/dark-sites.config
@@ -35,6 +35,7 @@ asoftmurmur.com
 ast4u.me
 atelier.net/virtual-economy
 atlassurvivalshelters.com
+atresplayer.com
 audiolove.club
 audioz.download
 avengedsevenfold.com
@@ -50,7 +51,6 @@ benleggiero.blog
 benleggiero.me
 bequiet.com
 bestblackhatforum.com
-beta.jdownloader.org
 betterttv.com
 bherila.net
 bin.disroot.org
@@ -353,6 +353,7 @@ metropool.nl
 miaou.drycat.fr
 minehut.com
 miniroyale2.io
+missions.ingress.com
 mixer.com
 mixxx.org
 mkbhd.com
@@ -371,6 +372,7 @@ neal.fun/size-of-space
 neundex.com
 newgrounds.com
 nexusmods.com
+ngplus.net
 nh-server.github.io/switch-guide/
 niebezpiecznik.pl
 nitter.13ad.de
@@ -390,6 +392,7 @@ noisebridge.net
 notebooks.quantumstat.com
 null.media
 nulledbb.com
+obsidian.md
 obsproject.com
 offshorecorptalk.com
 ogusers.com
@@ -512,6 +515,7 @@ slither.io
 snazzah.com
 spacebattles.com
 spacespacespaaace.space
+spacestationgaming.com
 speedtest.net
 sportsurge.net
 spy-cards.lubar.me
@@ -560,7 +564,6 @@ thispersondoesnotexist.com
 throwbacks-music.com
 thunix.net
 tilde.club
-tilde.institute
 tilde.team
 tildeverse.org
 tinyzonetv.to
diff --git a/src/config/dynamic-theme-fixes.config b/src/config/dynamic-theme-fixes.config
index 4cce0068..79a4bebf 100644
--- a/src/config/dynamic-theme-fixes.config
+++ b/src/config/dynamic-theme-fixes.config
@@ -59,7 +59,7 @@ body {
     background-image: repeating-linear-gradient(0deg, transparent, transparent 13px, ${#e4e6e8} -13px, ${#e4e6e8} 21px) !important;
 }
 .c-pointer {
-    color: grey !important;
+    color: grey;
 }
 .js-accepted-answer-indicator.fc-green-500 {
     color: var(--green) !important;
@@ -188,12 +188,25 @@ INVERT
 
 ================================
 
+accounts.google.com
+
+INVERT
+img[src$="signin_tapyes.gif"]
+
+================================
+
 acer.com
 
 INVERT
-div.col.a-offset-2.a-8.c-offset-0.c-6.gutter.logos
-div.tx.banner-remotesolutions-comp.container.max-width-d
-div.tx.banner-workanywhere-comp.container.max-width-d
+.firstHeader .logos
+
+CSS
+.contSectionBen img {
+    filter: brightness(50%) sepia(40%) !important;
+}
+.contSectionBen .textOverBen {
+    position: inherit !important;
+}
 
 ================================
 
@@ -297,6 +310,18 @@ CSS
 
 ================================
 
+amap.com
+
+INVERT
+.amap-info
+.amap-menu
+.logo-img
+#subway-svg
+#themap
+.title01-logo > a > img
+
+================================
+
 amazon.*
 amazon.co.uk
 
@@ -575,6 +600,18 @@ INVERT
 
 ================================
 
+bbs.chinauos.com
+
+INVERT
+.post_tip
+
+CSS
+div[style^="all: initial;"] {
+    all: unset !important;
+}
+
+================================
+
 bbs.thinkpad.com
 club.lenovo.com.cn
 
@@ -585,6 +622,27 @@ body[style] {
 
 ================================
 
+bestbuy.ca
+
+INVERT
+.centerContainer
+[class^="facetName"]
+[class^="title"]
+[class^="sortLabel"]
+[class^="headerText"]
+[class^="subTitle"]
+
+CSS
+div[class*="backgroundContainer"] {
+    z-index: 0 !important;
+}
+
+body {
+    background-image: initial; !important;
+}
+
+================================
+
 bfi.org.uk
 
 INVERT
@@ -777,6 +835,15 @@ INVERT
 
 ================================
 
+caiyunapp.com
+
+INVERT
+#icon_current
+#logo-name[src="/imgs/logo/logo-website.png"]
+#map_canvas
+
+================================
+
 calendar.google.com
 
 CSS
@@ -842,6 +909,18 @@ body {
 
 ================================
 
+chinauos.com
+
+INVERT
+.brand
+
+CSS
+.choose {
+    background-image: none !important;
+}
+
+================================
+
 chtoes.li
 
 INVERT
@@ -964,6 +1043,13 @@ INVERT
 
 ================================
 
+colorhunt.co
+
+IGNORE INLINE STYLE
+.palette > div
+
+================================
+
 community.ntppool.org
 
 INVERT
@@ -971,6 +1057,16 @@ INVERT
 
 ================================
 
+compass.pressekompass.net
+
+INVERT
+.logo-holder .brand-logo
+
+IGNORE INLINE STYLE
+text
+
+================================
+
 confectioneryproduction.com
 
 INVERT
@@ -1100,6 +1196,22 @@ img[src$=".png"] {
 
 ================================
 
+cqksy.cn
+
+INVERT
+td[background="image/Index_QI_CenterBar.gif"]
+
+CSS
+table {
+    background-color: var(--darkreader-neutral-background) !important;
+}
+td[background="image/Index_QI_CenterBar.gif"],
+td[background="image/Index_QI_CenterBar.gif"] a {
+    color: ${white} !important;
+}
+
+================================
+
 daily.afisha.ru
 
 INVERT
@@ -1123,6 +1235,22 @@ svg.main-logo.inline-flex g g[fill="#110133"] {
 
 ================================
 
+dailywritingtips.com
+
+CSS
+blockquote {
+    z-index: 0 !important;
+}
+
+================================
+
+darcs.net
+
+INVERT
+#header > a > img
+
+================================
+
 darksky.net
 
 INVERT
@@ -1230,6 +1358,15 @@ h4, h5, h6, a,
 
 ================================
 
+developer.chrome.com
+
+CSS
+mark, pre b {
+    background-color: ${yellow} !important;
+}
+
+================================
+
 developer.mozilla.org
 
 INVERT
@@ -1288,6 +1425,23 @@ nav[aria-label="Servers sidebar"] foreignObject {
 nav[aria-label="Servers sidebar"] foreignObject:hover {
     border-radius: 30% !important;
 }
+path[class^="wavePath"] {
+    fill: ${rgb(226, 224, 220)} !important;
+}
+
+================================
+
+ditu.baidu.com
+
+INVERT
+.BMap_contextMenu
+.BMap_simple_bubble_pop
+.c-title
+.icon
+#maps
+#mapType-wrapper
+.poidetail-widget-generalInfo
+.toolscontainer
 
 ================================
 
@@ -1523,6 +1677,15 @@ INVERT
 
 ================================
 
+emacswiki.org
+
+CSS
+body {
+    background-color: var(--darkreader-neutral-background) !important;
+}
+
+================================
+
 endomondo.com
 
 INVERT
@@ -1556,6 +1719,13 @@ select.input-small {
 
 ================================
 
+eshop-switch.com
+
+INVERT
+.logo
+
+================================
+
 etsy.com
 
 INVERT
@@ -1578,6 +1748,29 @@ canvas
 
 ================================
 
+explainxkcd.com
+
+INVERT
+.mwe-math-element
+.mw-ext-score
+.main-footer-menuToggle
+img[src*="Loudspeaker.svg"]
+img[alt="The Signpost"]
+
+CSS
+.diff-addedline .diffchange {
+    background-color: ${lightblue} !important;
+}
+.diff-deletedline .diffchange {
+    background-color: ${#feeec8} !important;
+}
+
+IGNORE INLINE STYLE
+.legend-color
+.infobox > tbody > tr > td[style*="background-color"]
+
+================================
+
 expressjs.com
 
 CSS
@@ -1627,6 +1820,10 @@ INVERT
 #homepage_panel_promote_footer_pagelet button .img._3-8_
 #event_tabs #reaction_units span img
 .fbPlaceFlyoutWrap img
+._83aj
+._7xv1
+._83ak
+._8g4q
 
 CSS
 .fbNubButton {
@@ -1933,6 +2130,18 @@ CSS
 
 ================================
 
+flowkey.com
+
+INVERT
+body.front #zone-branding-wrapper
+
+CSS
+body.html #page.page #subslogan {
+    color: ${white} !important;
+}
+
+================================
+
 flyzipline.com
 
 INVERT
@@ -2004,6 +2213,19 @@ INVERT
 
 ================================
 
+fusoya.eludevisibility.org
+
+CSS
+body {
+    background-image: none !important;
+}
+td {
+    color: var(--darkreader-neutral-text) !important;
+    background-image: none !important;
+}
+
+================================
+
 garmin.com
 
 INVERT
@@ -2435,6 +2657,19 @@ img[src$="hootsuite_white_form3.png"]
 
 ================================
 
+howbuy.com
+
+INVERT
+.bottomStar
+.cpBottomWord
+.logo
+.navList dt
+.phCon
+.title
+#valuationChar
+
+================================
+
 hypixel.net
 
 INVERT
@@ -2662,6 +2897,13 @@ h4, h5, h6 {
 
 ================================
 
+itch.io
+
+INVERT
+.header_widget .mobile_nav_btn
+
+================================
+
 jailbreak.fce365.info
 
 CSS
@@ -2704,6 +2946,15 @@ h1.logo
 
 ================================
 
+jobs.github.com
+
+CSS
+#page {
+    background-image: none !important;
+}
+
+================================
+
 journal.tinkoff.ru
 
 INVERT
@@ -2742,6 +2993,13 @@ INVERT
 
 ================================
 
+justhost.ru
+
+INVERT
+.header__logo
+
+================================
+
 kaggle.com
 kaggleusercontent.com
 
@@ -2755,6 +3013,28 @@ div.output_png img
 
 ================================
 
+kaytrip.com
+
+INVERT
+.date
+.jd_ss
+.liuchengt
+.nApp
+.nTel
+.n_app
+.tt_t
+.wmap
+
+CSS
+#imageField {
+    background-color: transparent !important;
+}
+.jd_xl {
+    filter: none !important;
+}
+
+================================
+
 keep.google.com
 
 INVERT
@@ -2978,6 +3258,17 @@ img {
 
 ================================
 
+madshi.net
+
+CSS
+body,
+tr,
+td {
+    background-image: none !important;
+}
+
+================================
+
 magazynbieganie.pl
 
 INVERT
@@ -3069,6 +3360,19 @@ CSS
 
 ================================
 
+map.baidu.com
+
+INVERT
+#MapHolder > canvas
+#map-operate > :nth-child(2)
+
+CSS
+#map-operate > :nth-child(2) > button {
+    background-color: white !important;
+}
+
+================================
+
 mapa-turystyczna.pl
 
 INVERT
@@ -3452,6 +3756,15 @@ CSS
 
 ================================
 
+my.bible.com
+
+CSS
+.nav-title {
+    color: var(--darkreader-neutral-text) !important;
+}
+
+================================
+
 my.nextdns.io
 
 INVERT
@@ -3464,8 +3777,11 @@ a.d-none.d-md-inline
 
 my.nintendo.com
 
-IGNORE IMAGE ANALYSIS
-.Layout-app
+CSS
+.Layout-app,
+.signUpButton {
+    background-image: none !important;
+}
 
 ================================
 
@@ -3873,6 +4189,13 @@ CSS
 
 ================================
 
+openebooks.net
+
+INVERT
+img[src="images/home_banner.png"]
+
+================================
+
 opengeofiction.net
 openstreetmap.org
 
@@ -4499,6 +4822,13 @@ INVERT
 
 ================================
 
+signin.nianticlabs.com
+
+INVERT
+img[alt="Niantic"]
+
+================================
+
 skyscanner.*
 skyscanner.*.*
 backpack.github.io
@@ -4609,6 +4939,14 @@ CSS
 
 ================================
 
+soylent.com
+
+INVERT
+.header-logo__image
+.d-header #site-logo
+
+================================
+
 speed.cloudflare.com
 
 INVERT
@@ -4882,6 +5220,32 @@ h4, h5, h6 {
 
 ================================
 
+taobao.com
+
+INVERT
+#logo > a > span
+#J_SearchIcon
+.J_MyShopCoupon
+.J_BtnEditSKU
+.cart-checkbox
+
+CSS
+#logo > a > span {
+    background-color: transparent !important;
+}
+.J_ItemAmount {
+    color: var(--darkreader-neutral-text) !important;
+    background: var(--darkreader-neutral-background) !important;
+}
+.tbh-member.J_Module {
+    background: none !important;
+}
+#q.search-combobox-input {
+    background: var(--darkreader-neutral-background);
+}
+
+================================
+
 teamtrees.org
 
 CSS
@@ -4982,6 +5346,33 @@ INVERT
 
 ================================
 
+theinformation.com
+
+INVERT
+.logo
+
+CSS
+article.single .sticky-header button.button-share,
+#bookmark-and-share button.button-share {
+    background-color: #21498c;
+    color: #e8e6e3;
+}
+article.single .sticky-header button.button-share:hover,
+#bookmark-and-share button.button-share:hover {
+    background-color: #245098;
+}
+.locked section .insert-container {
+    filter: drop-shadow(20px 20px 20px #26292b);
+}
+.locked section .insert-container#app-screenshot-container {
+    filter: drop-shadow(20px -20px 20px #26292b);
+}
+
+IGNORE IMAGE ANALYSIS
+header.locked .logo
+
+================================
+
 thejakartapost.com
 
 INVERT
@@ -5031,6 +5422,13 @@ div.sc-2d8w30-1.bRnfTk svg g path
 
 ================================
 
+thepaper.cn
+
+INVERT
+.head_logo
+
+================================
+
 theregister.*
 theregister.*.*
 
@@ -5086,6 +5484,13 @@ INVERT
 
 ================================
 
+tianocore.org
+
+INVERT
+.tcLogoArea
+
+================================
+
 tieba.baidu.com
 
 INVERT
@@ -5116,6 +5521,15 @@ mark a {
 
 ================================
 
+tmall.com
+
+CSS
+#mallLogo > .mlogo > a {
+    font-size: 0 !important;
+}
+
+================================
+
 tns-e.ru
 
 INVERT
@@ -5465,6 +5879,20 @@ CSS
 
 ================================
 
+uptimerobot.com
+
+INVERT
+.normal-logo
+.socialWrapper > ul > li
+
+CSS
+.page-head,
+.sidebar {
+    background-image: none !important;
+}
+
+================================
+
 urbandictionary.com
 
 INVERT
@@ -5501,6 +5929,15 @@ CSS
 
 ================================
 
+valgrind.org
+
+CSS
+p {
+   color: var(--darkreader-neutral-text) !important;
+}
+
+================================
+
 vandale.nl
 
 INVERT
@@ -5520,6 +5957,15 @@ CSS
 
 ================================
 
+vcb-s.com
+
+CSS
+html {
+    background-color: transparent !important;
+}
+
+================================
+
 vechevoikolokol.ru
 
 INVERT
@@ -5612,6 +6058,25 @@ INVERT
 
 ================================
 
+weather.com.cn
+
+INVERT
+.w_logo
+#hourHolder
+
+CSS
+.lv1,
+.lv2,
+.weatherBg01,
+.weatherBgAll,
+.weatherBgAll01,
+.weatherBgAll02,
+.weatherBgAll03 {
+    background-image: none !important;
+}
+
+================================
+
 web.archive.org
 
 INVERT
@@ -5973,6 +6438,13 @@ CSS
 
 ================================
 
+www.bromite.org
+
+IGNORE IMAGE ANALYSIS
+body
+
+================================
+
 www.ebay.*
 www.ebay.*.*
 
diff --git a/src/defaults.ts b/src/defaults.ts
index f6d182c7..09bf4855 100644
--- a/src/defaults.ts
+++ b/src/defaults.ts
@@ -55,4 +55,5 @@ export const DEFAULT_SETTINGS: UserSettings = {
     },
     previewNewDesign: false,
     enableForPDF: true,
+    enableForProtectedPages: false,
 };
diff --git a/src/definitions.d.ts b/src/definitions.d.ts
index 2e833b3e..3b20391d 100644
--- a/src/definitions.d.ts
+++ b/src/definitions.d.ts
@@ -87,6 +87,7 @@ export interface UserSettings {
     location: LocationSettings;
     previewNewDesign: boolean;
     enableForPDF: boolean;
+    enableForProtectedPages: boolean;
 }
 
 export interface TimeSettings {
diff --git a/src/inject/dynamic-theme/modify-css.ts b/src/inject/dynamic-theme/modify-css.ts
index 0a32a7df..0e551b50 100644
--- a/src/inject/dynamic-theme/modify-css.ts
+++ b/src/inject/dynamic-theme/modify-css.ts
@@ -93,8 +93,8 @@ export function getSelectionColor(theme: Theme) {
     let backgroundColorSelection: string;
     let foregroundColorSelection: string;
     if (theme.selectionColor === 'auto') {
-        backgroundColorSelection = modifyBackgroundColor({r: 0, g: 96, b: 212}, theme);
-        foregroundColorSelection = modifyForegroundColor({r: 255, g: 255, b: 255}, theme);
+        backgroundColorSelection = modifyBackgroundColor({r: 0, g: 96, b: 212}, {...theme, grayscale: 0});
+        foregroundColorSelection = modifyForegroundColor({r: 255, g: 255, b: 255}, {...theme, grayscale: 0});
     } else {
         const rgb = parse(theme.selectionColor);
         const hsl = rgbToHSL(rgb);
diff --git a/src/ui/connect/mock.ts b/src/ui/connect/mock.ts
index 2a2c1427..14b38ea0 100644
--- a/src/ui/connect/mock.ts
+++ b/src/ui/connect/mock.ts
@@ -27,6 +27,7 @@ export function getMockData(override = {} as Partial<ExtensionData>): ExtensionD
             applyToListedOnly: false,
             changeBrowserTheme: false,
             enableForPDF: true,
+            enableForProtectedPages: false,
             notifyOfNews: false,
             syncSettings: true,
             automation: '',
diff --git a/src/ui/controls/slider/index.tsx b/src/ui/controls/slider/index.tsx
index e6eb3e66..2ea2d88f 100644
--- a/src/ui/controls/slider/index.tsx
+++ b/src/ui/controls/slider/index.tsx
@@ -1,5 +1,7 @@
 import {m} from 'malevic';
 import {getContext} from 'malevic/dom';
+import {throttle} from '../../../inject/utils/throttle';
+import {scale, clamp} from '../../../utils/math';
 
 interface SliderProps {
     value: number;
@@ -10,14 +12,6 @@ interface SliderProps {
     onChange: (value: number) => void;
 }
 
-function clamp(x: number, min: number, max: number) {
-    return Math.min(max, Math.max(min, x));
-}
-
-function scale(x: number, inLow: number, inHigh: number, outLow: number, outHigh: number) {
-    return (x - inLow) / (inHigh - inLow) * (outHigh - outLow) + outLow;
-}
-
 function stickToStep(x: number, step: number) {
     const s = Math.round(x / step) * step;
     const exp = Math.floor(Math.log10(step));
@@ -38,6 +32,8 @@ export default function Slider(props: SliderProps) {
         activeProps: SliderProps;
         trackNode: HTMLElement;
         thumbNode: HTMLElement;
+        wheelTimeoutId: number;
+        wheelValue: number;
     };
 
     store.activeProps = props;
@@ -168,11 +164,40 @@ export default function Slider(props: SliderProps) {
         stickToStep(getValue(), props.step)
     );
 
+    function scaleWheelDelta(delta: number) {
+        return scale(delta, 0, -1000, 0, props.max - props.min);
+    }
+
+    const refreshOnWheel = throttle(() => {
+        store.activeValue = stickToStep(store.wheelValue, props.step);
+        store.wheelTimeoutId = setTimeout(() => {
+            const {onChange} = store.activeProps;
+            onChange(store.activeValue);
+            store.isActive = false;
+            store.activeValue = null;
+            store.wheelValue = null;
+        }, 400);
+        context.refresh();
+    });
+
+    function onWheel(event: WheelEvent) {
+        if (store.wheelValue == null) {
+            store.wheelValue = getValue();
+        }
+        store.isActive = true;
+        clearTimeout(store.wheelTimeoutId);
+        event.preventDefault();
+        const accumulatedValue = store.wheelValue + scaleWheelDelta(event.deltaY);
+        store.wheelValue = clamp(accumulatedValue, props.min, props.max);
+        refreshOnWheel();
+    }
+
     return (
         <span
             class={{'slider': true, 'slider--active': store.isActive}}
             oncreate={onRootCreate}
             onmousedown={onPointerDown}
+            onwheel={onWheel}
         >
             <span
                 class="slider__track"
diff --git a/src/ui/popup/body/style.less b/src/ui/popup/body/style.less
index 79eeeac9..af9fad9f 100644
--- a/src/ui/popup/body/style.less
+++ b/src/ui/popup/body/style.less
@@ -132,6 +132,12 @@
     }
 }
 
+.mobile {
+    .darkreader-version {
+        position: relative;
+    }
+}
+
 .preview .dev-tools-button {
     overflow: visible;
     position: relative;
diff --git a/src/ui/popup/site-list-page/index.tsx b/src/ui/popup/site-list-page/index.tsx
index aee1b287..f45bf3d3 100644
--- a/src/ui/popup/site-list-page/index.tsx
+++ b/src/ui/popup/site-list-page/index.tsx
@@ -1,11 +1,15 @@
 import {m} from 'malevic';
 import {ViewProps} from '../types';
 import SiteList from './site-list';
+import CheckButton from '../check-button';
 
 export default function SiteListPage(props: ViewProps) {
     function onSiteListChange(sites: string[]) {
         props.actions.changeSettings({siteList: sites});
     }
+    function onEnableForProtectedPages(value: boolean) {
+        props.actions.changeSettings({enableForProtectedPages: value});
+    }
 
     const label = props.data.settings.applyToListedOnly ?
         'Enable on these websites' :
@@ -18,6 +22,14 @@ export default function SiteListPage(props: ViewProps) {
                 onChange={onSiteListChange}
             />
             <label class="site-list-page__description">Enter website name and press Enter</label>
+            <CheckButton
+                checked={props.data.settings.enableForProtectedPages}
+                onChange={onEnableForProtectedPages}
+                label={'Enable on protected pages'}
+                description={props.data.settings.enableForProtectedPages ?
+                    'Will try running on protected pages (browser settings etc)' :
+                    'Will not try running on protected pages (browser settings etc)'}
+            />
         </div>
     );
 }
diff --git a/src/utils/math.ts b/src/utils/math.ts
index 71124033..04d88d12 100644
--- a/src/utils/math.ts
+++ b/src/utils/math.ts
@@ -8,11 +8,11 @@ export function clamp(x: number, min: number, max: number) {
 
 export function multiplyMatrices(m1: number[][], m2: number[][]) {
     const result: number[][] = [];
-    for (let i = 0; i < m1.length; i++) {
+    for (let i = 0, len = m1.length; i < len; i++) {
         result[i] = [];
-        for (let j = 0; j < m2[0].length; j++) {
+        for (let j = 0, len2 = m2[0].length; j < len2; j++) {
             let sum = 0;
-            for (let k = 0; k < m1[0].length; k++) {
+            for (let k = 0, len3 = m1[0].length; k < len3; k++) {
                 sum += m1[i][k] * m2[k][j];
             }
             result[i][j] = sum;
diff --git a/src/utils/url.ts b/src/utils/url.ts
index fbae5101..7470ce7d 100644
--- a/src/utils/url.ts
+++ b/src/utils/url.ts
@@ -137,7 +137,7 @@ export function isPDF(url: string) {
 }
 
 export function isURLEnabled(url: string, userSettings: UserSettings, {isProtected, isInDarkList}) {
-    if (isProtected) {
+    if (isProtected && userSettings.enableForProtectedPages) {
         return false;
     }
     if (isPDF(url) && userSettings.enableForPDF) {


Test patch:
diff --git a/tests/utils/url.tests.ts b/tests/utils/url.tests.ts
index a901737f..743b107f 100644
--- a/tests/utils/url.tests.ts
+++ b/tests/utils/url.tests.ts
@@ -59,24 +59,39 @@ test('URL is enabled', () => {
     // Special URLs
     expect(isURLEnabled(
         'https://chrome.google.com/webstore',
-        {siteList: ['chrome.google.com'], siteListEnabled: [], applyToListedOnly: false} as UserSettings,
+        {siteList: ['chrome.google.com'], siteListEnabled: [], applyToListedOnly: false, enableForProtectedPages: true} as UserSettings,
         {isProtected: true, isInDarkList: false},
     )).toBe(false);
     expect(isURLEnabled(
         'https://chrome.google.com/webstore',
-        {siteList: ['chrome.google.com'], siteListEnabled: [], applyToListedOnly: true} as UserSettings,
+        {siteList: ['chrome.google.com'], siteListEnabled: [], applyToListedOnly: true, enableForProtectedPages: true} as UserSettings,
+        {isProtected: true, isInDarkList: false},
+    )).toBe(false);
+    expect(isURLEnabled(
+        'https://chrome.google.com/webstore',
+        {siteList: [], siteListEnabled: [], applyToListedOnly: false, enableForProtectedPages: false} as UserSettings,
+        {isProtected: true, isInDarkList: false},
+    )).toBe(true);
+    expect(isURLEnabled(
+        'https://chrome.google.com/webstore',
+        {siteList: ['chrome.google.com'], siteListEnabled: [], applyToListedOnly: false, enableForProtectedPages: true} as UserSettings,
         {isProtected: true, isInDarkList: false},
     )).toBe(false);
     expect(isURLEnabled(
         'https://microsoftedge.microsoft.com/addons',
-        {siteList: ['microsoftedge.microsoft.com'], siteListEnabled: [], applyToListedOnly: false} as UserSettings,
+        {siteList: ['microsoftedge.microsoft.com'], siteListEnabled: [], applyToListedOnly: false, enableForProtectedPages: true} as UserSettings,
         {isProtected: true, isInDarkList: false},
     )).toBe(false);
     expect(isURLEnabled(
         'https://microsoftedge.microsoft.com/addons',
-        {siteList: ['microsoftedge.microsoft.com'], siteListEnabled: [], applyToListedOnly: true} as UserSettings,
+        {siteList: ['microsoftedge.microsoft.com'], siteListEnabled: [], applyToListedOnly: true, enableForProtectedPages: true} as UserSettings,
         {isProtected: true, isInDarkList: false},
     )).toBe(false);
+    expect(isURLEnabled(
+        'https://duckduckgo.com',
+        {siteList: [], siteListEnabled: [], applyToListedOnly: false, enableForProtectedPages: true} as UserSettings,
+        {isProtected: false, isInDarkList: false},
+    )).toBe(true);
     expect(isURLEnabled(
         'https://darkreader.org/',
         {siteList: [], siteListEnabled: [], applyToListedOnly: false} as UserSettings,