├── .gitignore ├── LICENSE ├── README.md ├── content.js ├── icon_128.png ├── icon_16.png ├── icon_32.png ├── icon_48.png ├── manifest.json ├── popup.css ├── popup.html └── popup.js /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | 3 | #Misc assets 4 | media 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Andreas Winkler 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Linux Scroll Speed Fix 2 | 3 | #### Download: [Chrome web store package](https://chrome.google.com/webstore/detail/linux-scroll-speed-fix/mlboohjioameadaedfjcpemcaangkkbp) 4 | 5 | ## DESCRIPTION 6 | Fixes the slow scroll speed in Chrome for Linux by emulating the Windows scroll speed when the extension detects Linux. When it detects Windows it will disable itself. 7 | 8 | The extension also allows for custom scroll speed values in both Windows and Linux. 9 | 10 | All settings are saved locally in the browser to not mess with syncing between different systems. 11 | 12 | ## FEATURES 13 | - Automatic "similar-to-Windows" scroll speed in Linux. 14 | - Custom scroll speed settings 15 | - Settings are saved locally in the browser 16 | 17 | ## CHANGELOG 18 | 19 | #### Version 1.7.2 20 | - Fixed Outlook scrolling 21 | 22 | #### Version 1.7.1 23 | - Added Outlook 365 to exception list 24 | 25 | #### Version 1.7.0 26 | - Fixed Youtube fullscreen scroll problems 27 | - Fixed images on Instagram not loading correctly when scrolling 28 | - Disabled scrolling plugin on Outlook until fix is found 29 | 30 | #### Version 1.6.9 31 | - Made overflow fix compatible with fullscreen 32 | 33 | #### Version 1.6.8 34 | - Made overflow fix apply more reliably 35 | 36 | #### Version 1.6.7 37 | - Fixed overflow issue - again 38 | 39 | #### Version 1.6.6 40 | - Fixed overflow issue 41 | 42 | #### Version 1.6.5 43 | - Clarified some text 44 | - Removed some debug stuff 45 | 46 | #### Version 1.6.4 47 | - Reworked icon and background color 48 | - Reworked change in 1.6.3 to no cause issues with certain sites. 49 | 50 | #### Version 1.6.3 51 | - Forces OverflowX to be visible. Some sites hides this and this disables scrolling. 52 | 53 | #### Version 1.6.2 54 | - Reworked protection against banners that change behaviour. 55 | 56 | #### Version 1.6.1 57 | - Tab or tabs are now prompted to be refreshed if the plugin is disabled or enabled. 58 | - Updated icons to match the color theme. 59 | 60 | #### Version 1.6.0 61 | - Refactored most of the code. 62 | - CSS Scroll smoothing toggling no longer needs refresh of window. 63 | - Minor bug fixes. 64 | 65 | #### Version 1.5.3 66 | - Added indicator for if the extension is enabled or not 67 | - Changed so that the default behaviour in Windows (not custom) disables the extension. 68 | - Added tooltip for smooth scrolling. 69 | 70 | #### Version 1.5.2 71 | - Reduced Chrome permissions needed 72 | - Minor bug fix 73 | 74 | #### Version 1.5.1 75 | - iFrame security workaround 76 | 77 | #### Version 1.5 78 | - Fixed banners messing with smooth scroll disable behavior 79 | 80 | ## NOTES 81 | iFrames from other domains will use default scroll speed due to security (same-origin-policy). There is to my knowledge nothing to be done about this without some clever rewrite that is currently above my head. 82 | 83 | CSS smooth scroll behavior is disabled by default. To my knowledge, the true smooth scrolling seen in Windows and MacOS will only be available with real hardware acceleration. Google stated that this won't be avaible in Chrome for Linux. The future will tell. 84 | 85 | Please report bugs with description and address to the site where you encountered it. 86 | 87 | Send bug report here: 88 | https://github.com/Dedas/linux-scroll-speed-fix/issues 89 | 90 | #### Settings 91 | 92 | Default scroll speed values: 93 | 94 | Linux = 1.9 95 | 96 | Windows = 1.0 (extension is disabled by default) 97 | 98 | MacOS = 1.0 (This needs testing!) 99 | 100 | #### Thanks to 101 | 102 | Based on gblazex/smoothscroll. 103 | 104 | Fork of DemonTPx/chrome-scroll-speed. 105 | -------------------------------------------------------------------------------- /content.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let scrollFactor = 1.0; 4 | 5 | // *** SETTINGS FETCHERS *** 6 | 7 | // Get setting key variable 8 | async function getSetting(key) { 9 | return new Promise((resolve, reject) => { 10 | try { 11 | chrome.storage.local.get(key, function(items){ 12 | resolve(items); 13 | }) 14 | } 15 | catch (ex) { 16 | reject(ex); 17 | } 18 | }); 19 | } 20 | 21 | async function getScrollFactor() { 22 | let result = await getSetting('scrollFactor'); 23 | 24 | return result.scrollFactor; 25 | } 26 | 27 | async function getDisableExtension() { 28 | let result = await getSetting('disableExtension'); 29 | 30 | return result.disableExtension; 31 | } 32 | 33 | async function getSmoothScroll() { 34 | let result = await getSetting('smoothScroll'); 35 | 36 | return result.smoothScroll; 37 | } 38 | 39 | // *** INIT *** 40 | 41 | init(); 42 | 43 | async function init() { 44 | let disableExtension = await getDisableExtension(); 45 | let smoothScroll = await getSmoothScroll(); 46 | 47 | // Check if extension is disabled. If not run main function. 48 | if(disableExtension == 'false') { 49 | 50 | // Disable smooth scroll if needed 51 | if(smoothScroll == 'false') { 52 | try { 53 | window.onload = () => { 54 | document.querySelectorAll("html")[0].style.scrollBehavior = "auto"; 55 | document.querySelector("body").style.scrollBehavior = "auto" 56 | } 57 | } 58 | catch(err) { 59 | console.log(err); 60 | } 61 | } 62 | 63 | // Run main function 64 | main(); 65 | } 66 | } 67 | 68 | // Main function 69 | async function main() { 70 | 71 | let smoothScroll = await getSmoothScroll(); 72 | 73 | //Check for changes in html element to deal with banners changing smooth scrolling behavior 74 | let mutationObserver = new MutationObserver(function(mutations) { 75 | mutations.forEach(async function() { 76 | 77 | smoothScroll = await getSmoothScroll(); 78 | 79 | if(smoothScroll == 'false') { 80 | window.onload = () => { 81 | document.querySelectorAll("html")[0].style.scrollBehavior = "auto"; 82 | document.querySelector("body").style.scrollBehavior = "auto" 83 | } 84 | 85 | } 86 | }); 87 | }); 88 | 89 | try { 90 | mutationObserver.observe(document.querySelectorAll("html")[0], { 91 | attributes: true, 92 | }); 93 | } catch (err) { 94 | console.log(err) 95 | } 96 | 97 | 98 | if (scrollFactor !== undefined) { 99 | scrollFactor = await getScrollFactor(); 100 | } 101 | 102 | // This function runs every time a scroll is made 103 | function wheel(event) { 104 | const target = event.target; 105 | 106 | if (event.defaultPrevented || event.ctrlKey) { 107 | return true; 108 | } 109 | 110 | let deltaX = event.deltaX; 111 | let deltaY = event.deltaY; 112 | 113 | if (event.shiftKey && !(event.ctrlKey || event.altKey || event.metaKey)) { 114 | deltaX = deltaX || deltaY; 115 | deltaY = 0; 116 | } 117 | 118 | const xOnly = (deltaX && !deltaY); 119 | 120 | let element = overflowingAncestor(target, xOnly); 121 | 122 | if (element === getScrollRoot()) { 123 | element = window; 124 | } 125 | 126 | const isFrame = window.top !== window.self; 127 | 128 | if ( ! element) { 129 | if (isFrame) { 130 | 131 | if (event.preventDefault) { 132 | // TODO 133 | // Is there a better solution for the iFrames? 134 | // Disabled due to cross site security blocking on some sites 135 | // Will hopefully not cause issues 136 | } 137 | } 138 | 139 | return true; 140 | } 141 | 142 | /* SPECIAL SOLUTIONS */ 143 | 144 | // Youtube fullscreen 145 | 146 | if (window.location.hostname === 'youtube.com') { 147 | youtubeFullScreen = element.getElementsByTagName('ytd-app')[0] 148 | 149 | if (youtubeFullScreen && window.document.fullscreenElement) { 150 | youtubeFullScreen.scrollBy({left: deltaX * scrollFactor, top: deltaY * scrollFactor, behavior:'auto'}); 151 | } 152 | } 153 | 154 | else if (window.location.hostname === 'www.nexusmods.com') { 155 | getRealRoot().scrollBy({left: deltaX * scrollFactor, top: deltaY * scrollFactor, behavior:'auto'}); 156 | } 157 | 158 | // Apply scrolling 159 | else { 160 | element.scrollBy({left: deltaX * scrollFactor, top: deltaY * scrollFactor, behavior:'auto'}); 161 | 162 | } 163 | 164 | event.preventDefault(); 165 | } 166 | 167 | function overflowingAncestor(element, horizontal) { 168 | const body = document.body; 169 | const root = window.document.documentElement 170 | const rootScrollHeight = root.scrollHeight; 171 | const rootScrollWidth = root.scrollWidth; 172 | const isFrame = window.top !== window.self; 173 | 174 | do { 175 | if (horizontal && rootScrollWidth === element.scrollWidth || 176 | !horizontal && rootScrollHeight === element.scrollHeight) { 177 | const topOverflowsNotHidden = overflowNotHidden(root, horizontal) && overflowNotHidden(body, horizontal); 178 | const isOverflowCSS = topOverflowsNotHidden || overflowAutoOrScroll(root, horizontal); 179 | 180 | if (isFrame && isContentOverflowing(root, horizontal) || !isFrame && isOverflowCSS) { 181 | 182 | return getScrollRoot() 183 | } 184 | } else if (isContentOverflowing(element, horizontal) && overflowAutoOrScroll(element, horizontal)) { 185 | return element; 186 | } 187 | } while ((element = element.parentElement)); 188 | } 189 | 190 | function isContentOverflowing(element, horizontal) { 191 | const client = horizontal ? element.clientWidth : element.clientHeight; 192 | const scroll = horizontal ? element.scrollWidth : element.scrollHeight; 193 | 194 | return (client + 10 < scroll); 195 | } 196 | 197 | function computedOverflow(element, horizontal) { 198 | return getComputedStyle(element, '').getPropertyValue(horizontal ? 'overflow-x' : 'overflow-y'); 199 | } 200 | 201 | function overflowNotHidden(element, horizontal) { 202 | return computedOverflow(element, horizontal) !== 'hidden'; 203 | } 204 | 205 | function overflowAutoOrScroll(element, horizontal) { 206 | return /^(scroll|auto)$/.test(computedOverflow(element, horizontal)); 207 | } 208 | 209 | function getScrollRoot() { 210 | return (document.scrollingElement || document.body); 211 | } 212 | 213 | function getRealRoot() { 214 | return document.scrollingElement; 215 | } 216 | 217 | function message(message) { 218 | if (message.data.CSS !== 'ChangeScrollSpeed') { 219 | return; 220 | } 221 | 222 | let event = message.data; 223 | event.target = getFrameByEvent(message.source); 224 | wheel(event) 225 | } 226 | 227 | function getFrameByEvent(source) { 228 | const iframes = document.getElementsByTagName('iframe'); 229 | 230 | return [].filter.call(iframes, function (iframe) { 231 | return iframe.contentWindow === source; 232 | })[0]; 233 | } 234 | 235 | function chromeMessage(message) { 236 | if (message.scrollFactor) { 237 | scrollFactor = message.scrollFactor 238 | } 239 | } 240 | 241 | const wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel'; 242 | 243 | const el = (window.document || window.document.body || window) 244 | 245 | el.addEventListener(wheelEvent, wheel, {passive: false}) 246 | 247 | function getIFrame(frame) { 248 | if((frame !== null) && (frame !== 'undefined') && (frame.width > 0)) { 249 | let el = frame; 250 | el.addEventListener(wheelEvent, wheel, {passive: false}) 251 | } 252 | } 253 | 254 | getIFrame(window.document.querySelector('iframe')); 255 | 256 | window.addEventListener('message', message); 257 | 258 | chrome.runtime.onMessage.addListener(chromeMessage); 259 | } -------------------------------------------------------------------------------- /icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dedas/linux-scroll-speed-fix/c48bc19f2c28d99c72cc5740eafbef62c1c48290/icon_128.png -------------------------------------------------------------------------------- /icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dedas/linux-scroll-speed-fix/c48bc19f2c28d99c72cc5740eafbef62c1c48290/icon_16.png -------------------------------------------------------------------------------- /icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dedas/linux-scroll-speed-fix/c48bc19f2c28d99c72cc5740eafbef62c1c48290/icon_32.png -------------------------------------------------------------------------------- /icon_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dedas/linux-scroll-speed-fix/c48bc19f2c28d99c72cc5740eafbef62c1c48290/icon_48.png -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Linux Scroll Speed Fix", 3 | "version": "1.7.2", 4 | "description": "Fix the slow scroll speed in Linux Chrome by setting it to the Windows value", 5 | "permissions": ["storage", "http://*/*", "https://*/*"], 6 | "background": { 7 | "page": "content.js" 8 | }, 9 | "browser_action": { 10 | "default_popup": "popup.html" 11 | }, 12 | "content_scripts": [ 13 | { 14 | "all_frames": true, 15 | "js": [ 16 | "content.js" 17 | ], 18 | "matches": [ 19 | "http://*/*", 20 | "https://*/*", 21 | "ftp://*/*" 22 | ], 23 | "exclude_globs": [ 24 | "*.pdf" 25 | ], 26 | "run_at": "document_start" 27 | } 28 | ], 29 | "icons": { 30 | "16": "icon_16.png", 31 | "32": "icon_32.png", 32 | "48": "icon_48.png", 33 | "128": "icon_128.png" 34 | }, 35 | "manifest_version": 2 36 | } -------------------------------------------------------------------------------- /popup.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0em; 3 | min-width: 26em; 4 | } 5 | 6 | a { 7 | text-decoration: none; 8 | } 9 | 10 | a:visited { 11 | color: blue; 12 | } 13 | 14 | #osDetected { 15 | font-weight: bold; 16 | } 17 | 18 | #scrollFactor { 19 | font-weight: bold; 20 | margin-right: auto; 21 | } 22 | 23 | #recommended { 24 | font-size: 0.7em; 25 | margin: 0em; 26 | } 27 | 28 | #statusText { 29 | font-weight: bold; 30 | } 31 | 32 | .tooltip { 33 | position: relative; 34 | border-bottom: 1px dashed #000; 35 | } 36 | 37 | .tooltip:before { 38 | content: attr(data-text); 39 | position:absolute; 40 | 41 | top:10%; 42 | transform:translateY(-110%); 43 | 44 | left:-150%; 45 | margin-left:15px; 46 | 47 | width:175px; 48 | height:auto; 49 | padding:5px; 50 | border-radius:10px; 51 | background:#000; 52 | color: white; 53 | font-size: 0.7rem; 54 | 55 | display: none; 56 | } 57 | 58 | .tooltip:hover:before { 59 | display: block; 60 | } 61 | 62 | input { 63 | display: flex; 64 | align-items: center; 65 | text-align: center; 66 | max-width: 3.5em; 67 | } 68 | 69 | input[type=checkbox] { 70 | margin: 0em; 71 | margin-left: 0.5em; 72 | } 73 | 74 | input:disabled { 75 | background-color: white; 76 | color: black; 77 | border: none; 78 | } 79 | 80 | input:enabled { 81 | border: none; 82 | background: lightgray; 83 | } 84 | 85 | label { 86 | display: flex; 87 | align-items: center; 88 | margin-right: 0.5em; 89 | font-size: 1.2em; 90 | } 91 | 92 | .title { 93 | margin: 0; 94 | padding: 0.5em; 95 | margin-bottom: 0.5em; 96 | font-size: 1.4em; 97 | color: white; 98 | background-color: #4C86CD; 99 | } 100 | 101 | .os-wrapper { 102 | display: flex; 103 | justify-content: space-between; 104 | padding: 0.5em; 105 | } 106 | 107 | .osDetected { 108 | display: flex; 109 | } 110 | 111 | .statusText { 112 | display: flex; 113 | 114 | } 115 | 116 | .scroll-wrapper { 117 | display: flex; 118 | justify-content: space-between; 119 | padding: 0.5em; 120 | } 121 | 122 | .smooth-wrapper { 123 | display: flex; 124 | justify-content: start; 125 | padding: 0.5em; 126 | } 127 | 128 | .version { 129 | display: flex; 130 | flex-direction: column; 131 | justify-content: flex-end; 132 | align-items: flex-end; 133 | font-size: 0.7em; 134 | color: grey; 135 | padding: 1em 0.5em; 136 | } -------------------------------------------------------------------------------- /popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Linux Scroll Speed Fix 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 | 15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 | 23 |
24 | 25 | 26 | 29 |
30 | 31 |
32 | 35 | 40 | 41 |
42 |
43 | 44 | 45 |
46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /popup.js: -------------------------------------------------------------------------------- 1 | // User information elements 2 | const osText = document.getElementById('osDetected'); 3 | const statusText = document.getElementById('statusText'); 4 | 5 | // User input elements 6 | const scrollFactorInput = document.getElementById('scrollFactorInput'); 7 | const customSettingButton = document.getElementById('customSettingButton'); 8 | const smoothScrollButton = document.getElementById('smoothScrollButton'); 9 | 10 | // Default scroll speed variables 11 | const linuxSpeed = 1.9; 12 | const windowsSpeed = 1.0; 13 | const macSpeed = 1.0; 14 | 15 | // *** INIT *** 16 | 17 | init(); 18 | 19 | // Detects OS and set scroll speed 20 | async function init() { 21 | let smoothScroll = await getSmoothScroll(); 22 | let customSetting = await getCustomSetting(); 23 | let disableExtension = await getDisableExtension(); 24 | let os = await getOS(); 25 | 26 | // Do not initiate if custom settings is checked 27 | if(customSetting !== 'true') { 28 | if(os == 'linux') { 29 | // Set Linux values 30 | osText.innerHTML = 'Linux'; 31 | statusText.innerHTML = 'Enabled'; 32 | 33 | scrollFactorInput.value = linuxSpeed; 34 | scrollFactorInput.disabled = true; 35 | 36 | smoothScrollButton.disabled = true; 37 | smoothScrollButton.checked = false; 38 | 39 | customSettingButton.checked = false; 40 | 41 | setScrollFactor(linuxSpeed); 42 | } else if(os == 'win') { 43 | // TODO Some buginess here with smoothscroll toggle 44 | // Set Windows values 45 | osText.innerHTML = 'Windows'; 46 | statusText.innerHTML = 'Disabled'; 47 | 48 | scrollFactorInput.value = windowsSpeed 49 | scrollFactorInput.disabled = true; 50 | 51 | smoothScrollButton.disabled = true; 52 | smoothScrollButton.checked = true; 53 | 54 | customSettingButton.checked = false; 55 | 56 | setScrollFactor(windowsSpeed); 57 | } else if(os == 'mac') { 58 | osText.innerHTML = 'MacOS'; 59 | statusText.innerHTML = 'Disabled' 60 | 61 | scrollFactorInput.value = macSpeed 62 | scrollFactorInput.disabled = true; 63 | 64 | smoothScrollButton.disabled = true; 65 | smoothScrollButton.checked = true; 66 | 67 | customSettingButton.checked = false; 68 | 69 | setScrollFactor(macSpeed); 70 | } 71 | } else { 72 | // Custom settings 73 | let scrollFactor = await getScrollFactor(); 74 | 75 | osText.innerHTML = 'Custom'; 76 | statusText.innerHTML = 'Enabled'; 77 | 78 | scrollFactorInput.value = scrollFactor; 79 | scrollFactorInput.disabled = false; 80 | 81 | smoothScrollButton.disabled = false; 82 | 83 | customSettingButton.checked = true; 84 | 85 | if(smoothScroll == 'true') { 86 | smoothScrollButton.checked = true; 87 | } else { 88 | smoothScrollButton.checked = false; 89 | } 90 | } 91 | 92 | updateSmoothScroll(); 93 | updateDisableExtension(disableExtension); 94 | } 95 | 96 | // Detect OS 97 | async function getOS() { 98 | return new Promise((resolve, reject) => { 99 | try { 100 | chrome.runtime.getPlatformInfo(function (info) { 101 | resolve(info.os); 102 | }) 103 | } 104 | catch (ex) { 105 | reject(ex) 106 | } 107 | }); 108 | } 109 | 110 | // *** SETTINGS *** 111 | 112 | // Get setting key variable 113 | async function getSetting(key) { 114 | return new Promise((resolve, reject) => { 115 | try { 116 | chrome.storage.local.get(key, function(items){ 117 | resolve(items); 118 | }) 119 | } 120 | catch (ex) { 121 | reject(ex); 122 | } 123 | }); 124 | } 125 | 126 | // SCROLL FACTOR 127 | 128 | async function getScrollFactor() { 129 | let result = await getSetting('scrollFactor'); 130 | 131 | return result.scrollFactor; 132 | } 133 | 134 | function setScrollFactor(value) { 135 | 136 | if (value < 0 || value > 1000) { 137 | return; 138 | } else { 139 | chrome.storage.local.set({'scrollFactor': value}); 140 | } 141 | 142 | updateScrollFactor(); 143 | } 144 | 145 | async function updateScrollFactor() { 146 | let value = parseFloat(await getScrollFactor()); 147 | 148 | chrome.tabs.query({windowType: "normal"}, function(tabs) { 149 | for(let i = 0; i < tabs.length; i++) { 150 | chrome.tabs.sendMessage(tabs[i].id, {scrollFactor: value, CSS: 'ChangeScrollSpeed'}); 151 | } 152 | }); 153 | 154 | } 155 | 156 | // SMOOTH SCROLL 157 | 158 | // Get smoothscroll variable 159 | async function getSmoothScroll() { 160 | let result = await getSetting('smoothScroll'); 161 | 162 | return result.smoothScroll; 163 | } 164 | 165 | // Set smoothscroll variable 166 | function setSmoothScroll(value) { 167 | chrome.storage.local.set({'smoothScroll':value}) 168 | } 169 | 170 | // Apply smooth scroll setting when button is pressed in popup.js 171 | function updateSmoothScroll() { 172 | 173 | if(smoothScrollButton.checked == true) { 174 | setSmoothScroll('true'); 175 | disableSmoothCSS(false); 176 | } else { 177 | setSmoothScroll('false'); 178 | disableSmoothCSS(true); 179 | } 180 | } 181 | 182 | // This function disables and enables CSS smooth scrolling 183 | function disableSmoothCSS(value) { 184 | 185 | if(value) { 186 | // Code to insert 187 | let code = `document.querySelectorAll("html")[0].style.scrollBehavior = "auto";`; 188 | 189 | // Loop through all tabs and insert code 190 | executeScriptAllTabs(code); 191 | 192 | } else { 193 | // Code to insert 194 | let code = `document.querySelectorAll("html")[0].style.scrollBehavior = "";`; 195 | 196 | // Loop through all tabs and insert code 197 | executeScriptAllTabs(code); 198 | 199 | } 200 | } 201 | 202 | function executeScriptAllTabs(code) { 203 | 204 | chrome.tabs.query({windowType: "normal"}, function(tabs) { 205 | 206 | for(let i = 0; i < tabs.length; i++) { 207 | try { 208 | if(tabs[i].url) { 209 | chrome.tabs.executeScript(tabs[i].id, { code }, function() { 210 | if(chrome.runtime.lastError) {} // Suppress error 211 | }); 212 | } 213 | } 214 | catch(err) { 215 | console.log(err); 216 | } 217 | } 218 | }); 219 | } 220 | 221 | // REFRESH TABS 222 | function refreshTab(message) { 223 | 224 | if((message) && (confirm(message))) { 225 | chrome.tabs.getAllInWindow(null, function(tabs) { 226 | for(let i = 0; i < tabs.length; i++) { 227 | chrome.tabs.update(tabs[i].id, {url: tabs[i].url}); 228 | } 229 | }); 230 | } else { 231 | chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 232 | chrome.tabs.update(tabs[0].id, {url: tabs[0].url}); 233 | }); 234 | }; 235 | } 236 | 237 | // CUSTOM SETTING 238 | 239 | async function getCustomSetting() { 240 | let result = await getSetting('customSetting'); 241 | 242 | return result.customSetting; 243 | } 244 | 245 | // Set custom setting variable 246 | function setCustomSetting(value) { 247 | chrome.storage.local.set({'customSetting': value}); 248 | } 249 | 250 | // Apply custom setting variable in popup.js 251 | function updateCustomSetting() { 252 | 253 | // Enable custom settings 254 | if(customSettingButton.checked == true) { 255 | setCustomSetting('true'); 256 | } else { 257 | setCustomSetting('false'); 258 | } 259 | 260 | // Redetect settings 261 | init(); 262 | } 263 | 264 | // DISABLE EXTENSION 265 | 266 | async function getDisableExtension() { 267 | let result = await getSetting('disableExtension'); 268 | 269 | return result.disableExtension; 270 | } 271 | 272 | function setDisableExtension(value) { 273 | chrome.storage.local.set({'disableExtension':value}); 274 | } 275 | 276 | function updateDisableExtension(previousValue) { 277 | 278 | if(statusText.innerHTML == 'Enabled') { 279 | setDisableExtension('false'); 280 | 281 | // Previous value - do refresh 282 | if (previousValue == 'true') { 283 | refreshTab('A tab refresh is required to enable the extension. Do you want to refresh all tabs? Press "Cancel" to just refresh current tab.') 284 | } 285 | } else { 286 | setDisableExtension('true'); 287 | 288 | if(previousValue == 'false') { 289 | refreshTab('A tab refresh is required to disable the extension. Do you want to refresh all tabs? Press "Cancel" to just refresh current tab.') 290 | } 291 | } 292 | } 293 | 294 | // *** LISTENERS *** 295 | 296 | // Custom setting button 297 | customSettingButton.addEventListener('change', updateCustomSetting); 298 | 299 | // Smooth Scroll button 300 | smoothScrollButton.addEventListener('change', updateSmoothScroll); 301 | 302 | // Scroll factor input field 303 | scrollFactorInput.addEventListener('change', () => { 304 | setScrollFactor(scrollFactorInput.value); 305 | }); 306 | 307 | scrollFactorInput.addEventListener('keyup', () => { 308 | setScrollFactor(scrollFactorInput.value); 309 | }); --------------------------------------------------------------------------------