From c59006ae953c93feab1223bd571bc0c0670ad298 Mon Sep 17 00:00:00 2001 From: nobody Date: Sun, 21 Feb 2021 19:28:18 +0100 Subject: [PATCH] Options page restructured --- modules/internal/rule-generator.js | 2 +- pages/options/options-advanced.js | 96 +++++++ pages/options/options-basic.js | 61 ++++ pages/options/options-info.js | 120 ++++++++ pages/options/options-other.js | 198 +++++++++++++ pages/options/options.css | 2 +- pages/options/options.html | 43 +-- pages/options/options.js | 433 +++++------------------------ 8 files changed, 578 insertions(+), 377 deletions(-) create mode 100644 pages/options/options-advanced.js create mode 100644 pages/options/options-basic.js create mode 100644 pages/options/options-info.js create mode 100644 pages/options/options-other.js diff --git a/modules/internal/rule-generator.js b/modules/internal/rule-generator.js index 1d4584ae..fbd19c12 100644 --- a/modules/internal/rule-generator.js +++ b/modules/internal/rule-generator.js @@ -30,7 +30,7 @@ ruleGenerator.openRuleSet = function ({target}) { let urls, key, textArea, btnCopy, content; urls = mappings.cdn; - key = target.getAttribute('data-option'); + key = target.getAttribute('data-ruleset'); textArea = document.getElementById('generated-rules'); btnCopy = document.getElementById('button-copy-rule-set'); content = ''; diff --git a/pages/options/options-advanced.js b/pages/options/options-advanced.js new file mode 100644 index 00000000..cec41362 --- /dev/null +++ b/pages/options/options-advanced.js @@ -0,0 +1,96 @@ +/** + * Options Page (Advanced) + * Belongs to LocalCDN + * + * @author nobody + * @since 2021-02-19 + * + * @license MPL 2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +'use strict'; + + +/** + * Options (Advanced) + */ + +var optionsAdvanced = {}; + + +/** + * Private Methods + */ + +// +optionsAdvanced._renderAdvancedSection = function (optionValue) { + if (optionValue === true) { + document.getElementById('div-domains-allowlist-google-fonts').style.display = 'block'; + } else { + document.getElementById('div-domains-allowlist-google-fonts').style.display = 'none'; + } +}; + +optionsAdvanced._renderHtmlFilterSection = function (optionValue) { + if (optionValue === true) { + document.getElementById('html-filter-domains-title-include').style.display = 'none'; + document.getElementById('html-filter-domains-title-exclude').style.display = 'block'; + } else { + document.getElementById('html-filter-domains-title-include').style.display = 'block'; + document.getElementById('html-filter-domains-title-exclude').style.display = 'none'; + } +}; + +optionsAdvanced.preSelectBlockGoogleFonts = function (value) { + if (value) { + document.getElementById('div-domains-allowlist-google-fonts').style.display = 'block'; + } else { + document.getElementById('div-domains-allowlist-google-fonts').style.display = 'none'; + } +}; + +optionsAdvanced.init = function (opt) { + let blockMissing, blockGoogleFonts, allowedDomainsGoogleFonts, logging, domainsManipulateDOM, negateHtmlFilterList; + + if (BrowserType.CHROMIUM) { + document.getElementById('html-filter-div').style.display = 'none'; + document.getElementById('block-google-fonts').style.display = 'none'; + } + + document.getElementById('last-mapping-update').textContent += ` ${mappings.lastMappingUpdate}`; + + blockMissing = options.getOptionElement(Setting.BLOCK_MISSING); + blockMissing.addEventListener('change', options.onOptionChanged); + blockMissing.checked = opt[Setting.BLOCK_MISSING]; + + blockGoogleFonts = options.getOptionElement(Setting.BLOCK_GOOGLE_FONTS); + blockGoogleFonts.addEventListener('change', options.onOptionChanged); + blockGoogleFonts.checked = opt[Setting.BLOCK_GOOGLE_FONTS]; + + allowedDomainsGoogleFonts = options.getOptionElement(Setting.ALLOWED_DOMAINS_GOOGLE_FONTS); + allowedDomainsGoogleFonts.addEventListener('keyup', options.onOptionChanged); + allowedDomainsGoogleFonts.value = opt[Setting.ALLOWED_DOMAINS_GOOGLE_FONTS]; + + logging = options.getOptionElement(Setting.LOGGING); + logging.addEventListener('change', options.onOptionChanged); + logging.checked = opt[Setting.LOGGING]; + + domainsManipulateDOM = options.getOptionElement(Setting.DOMAINS_MANIPULATE_DOM); + domainsManipulateDOM.addEventListener('keyup', options.onOptionChanged); + domainsManipulateDOM.value = opt[Setting.DOMAINS_MANIPULATE_DOM]; + + negateHtmlFilterList = options.getOptionElement(Setting.NEGATE_HTML_FILTER_LIST); + negateHtmlFilterList.addEventListener('change', options.onOptionChanged); + negateHtmlFilterList.checked = opt[Setting.NEGATE_HTML_FILTER_LIST]; + + document.getElementById('generate-ublock-rules').addEventListener('change', ruleGenerator.openRuleSet); + document.getElementById('generate-umatrix-rules').addEventListener('change', ruleGenerator.openRuleSet); + document.getElementById('generate-adguard-rules').addEventListener('change', ruleGenerator.openRuleSet); + document.getElementById('button-copy-rule-set').addEventListener('click', ruleGenerator.copyRuleSet); + document.getElementById('negate-html-filter-list-warning').addEventListener('click', function () { options._onLinkClick(Links.CODEBERG_HTML_FILTER); }); + document.getElementById('ruleset-help').addEventListener('click', function () { options._onLinkClick(Links.CODEBERG_RULESET); }); +}; diff --git a/pages/options/options-basic.js b/pages/options/options-basic.js new file mode 100644 index 00000000..f18da1b7 --- /dev/null +++ b/pages/options/options-basic.js @@ -0,0 +1,61 @@ +/** + * Options Page (Basic) + * Belongs to LocalCDN + * + * @author nobody + * @since 2021-02-19 + * + * @license MPL 2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +'use strict'; + + +/** + * Options (Basic) + */ + +var optionsBasic = {}; + + +/** + * Private Methods + */ + +optionsBasic.init = function (opt) { + let showIconBadge, updateNotification, disablePrefetch, stripMetadata, internalStatistics, + hideDonationButton, allowlistedDomains; + + showIconBadge = options.getOptionElement(Setting.SHOW_ICON_BADGE); + showIconBadge.addEventListener('change', options.onOptionChanged); + showIconBadge.checked = opt[Setting.SHOW_ICON_BADGE]; + + updateNotification = options.getOptionElement(Setting.UPDATE_NOTIFICATION); + updateNotification.addEventListener('change', options.onOptionChanged); + updateNotification.value = opt[Setting.UPDATE_NOTIFICATION]; + + disablePrefetch = options.getOptionElement(Setting.DISABLE_PREFETCH); + disablePrefetch.addEventListener('change', options.onOptionChanged); + disablePrefetch.checked = opt[Setting.DISABLE_PREFETCH]; + + stripMetadata = options.getOptionElement(Setting.STRIP_METADATA); + stripMetadata.addEventListener('change', options.onOptionChanged); + stripMetadata.checked = opt[Setting.STRIP_METADATA]; + + internalStatistics = options.getOptionElement(Setting.INTERNAL_STATISTICS); + internalStatistics.addEventListener('change', options.onOptionChanged); + internalStatistics.checked = true;// opt[Setting.INTERNAL_STATISTICS]; + + + hideDonationButton = options.getOptionElement(Setting.HIDE_DONATION_BUTTON); + hideDonationButton.addEventListener('change', options.onOptionChanged); + hideDonationButton.checked = opt[Setting.HIDE_DONATION_BUTTON]; + + allowlistedDomains = options.getOptionElement(Setting.ALLOWLISTED_DOMAINS); + allowlistedDomains.addEventListener('keyup', options.onOptionChanged); + allowlistedDomains.value = opt[Setting.ALLOWLISTED_DOMAINS]; +}; diff --git a/pages/options/options-info.js b/pages/options/options-info.js new file mode 100644 index 00000000..82c8308c --- /dev/null +++ b/pages/options/options-info.js @@ -0,0 +1,120 @@ +/** + * Options Page (Info) + * Belongs to LocalCDN + * + * @author nobody + * @since 2021-02-19 + * + * @license MPL 2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +'use strict'; + + +/** + * Options (Info) + */ + +var optionsInfo = {}; + + +/** + * Private Methods + */ + +optionsInfo._renderCdnFrameworkSection = function () { + let unsupportedFrameworks, btnCDNs, btnFrameworks; + + unsupportedFrameworks = 0; + optionsInfo._listOfFrameworks = {}; + + btnCDNs = document.getElementById('cdn'); + btnCDNs.value = 'CDNs: '; + + btnFrameworks = document.getElementById('framework'); + btnFrameworks.value = 'Frameworks: '; + + Object.values(Object.values(resources)).forEach((element) => { + let path = Object.values(element)[0]; + path = path.split('/'); + optionsInfo._listOfFrameworks[path[1]] = true; + }); + + if (BrowserType.CHROMIUM) { + // Chromium based browser does not support Google Material Icons and Font Awesome + document.getElementById('unsupported-frameworks').style.display = 'block'; + unsupportedFrameworks = 2; + } + + optionsInfo._createList('cdn'); + document.getElementById('cdn').classList.add('btns-active'); + + btnFrameworks.addEventListener('click', optionsInfo._btnCreateList); + btnCDNs.addEventListener('click', optionsInfo._btnCreateList); + + // Reduce CDNs by 3, because loli.net includes = cdn.css.net, cdnjs.loli.net, ajax.loli.net, fonts.loli.net + btnCDNs.value += Object.keys(mappings.cdn).length - 3; + btnFrameworks.value += Object.keys(optionsInfo._listOfFrameworks).length - unsupportedFrameworks; +}; + +optionsInfo._renderLinkSection = function () { + /* eslint-disable brace-style*/ + document.getElementById('btn-info-tab').addEventListener('click', options._changeTab); + document.getElementById('link-welcome-page').addEventListener('click', function () { options._onLinkClick(Links.WELCOME); }); + document.getElementById('link-changelog').addEventListener('click', function () { options._onLinkClick(Links.CHANGELOG); }); + document.getElementById('link-donate').addEventListener('click', function () { options._onLinkClick(Links.DONATE); }); + document.getElementById('link-faq').addEventListener('click', function () { options._onLinkClick(Links.FAQ); }); + document.getElementById('link-statistic').addEventListener('click', function () { options._onLinkClick(Links.STATISTICS); }); + /* eslint-enable brace-style*/ +}; + +optionsInfo._btnCreateList = function ({target}) { + if (target.id === 'cdn') { + document.getElementById('cdn').classList.add('btns-active'); + document.getElementById('framework').classList.remove('btns-active'); + } else { + document.getElementById('cdn').classList.remove('btns-active'); + document.getElementById('framework').classList.add('btns-active'); + } + optionsInfo._createList(target.id); +}; + +optionsInfo._createList = function (type) { + let textArea, list; + + textArea = document.getElementById('generated-list'); + textArea.value = ''; + + if (type === 'cdn') { + list = Object.keys(mappings.cdn); + } else if (type === 'framework') { + list = Object.keys(optionsInfo._listOfFrameworks); + } else { + return; + } + + list.forEach((elem) => { + if (!(BrowserType.CHROMIUM && (elem === 'fontawesome' || elem === 'google-material-design-icons'))) { + textArea.value += `${elem}\n`; + } + }); +}; + + +/** + * Initializations + */ + +optionsInfo._listOfFrameworks = {}; +optionsInfo._listOfCDNs = {}; + +optionsInfo.init = function () { + optionsInfo._renderCdnFrameworkSection(); + optionsInfo._renderLinkSection(); + + +}; diff --git a/pages/options/options-other.js b/pages/options/options-other.js new file mode 100644 index 00000000..3b8143df --- /dev/null +++ b/pages/options/options-other.js @@ -0,0 +1,198 @@ +/** + * Options Page (Other) + * Belongs to LocalCDN + * + * @author nobody + * @since 2021-02-19 + * + * @license MPL 2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +'use strict'; + + +/** + * Options (Other) + */ + +var optionsOther = {}; + + +/** + * Private Methods + */ + +optionsOther._renderIconSection = function (opt) { + let url, bgColor, txtColor; + + if (!chrome.browserAction.setIcon) { + document.getElementById('icon-style-div').style.display = 'none'; + } else { + let selectedIcon = opt.selectedIcon; + + if (selectedIcon === 'Default') { + document.getElementById('icon-default').checked = true; + } else if (selectedIcon === 'Grey') { + document.getElementById('icon-grey').checked = true; + } else if (selectedIcon === 'Light') { + document.getElementById('icon-light').checked = true; + } + url = chrome.runtime.getURL(`icons/action/${selectedIcon.toLowerCase()}/icon38-default.png`); + document.getElementById('icon-badge-preview').src = url; + + bgColor = opt.badgeColor || '#4A826C'; + txtColor = opt.badgeTextColor || '#FFFFFF'; + + document.getElementById('counter-preview-badge').style.backgroundColor = bgColor; + document.getElementById('pre-badged-background-color').style.backgroundColor = bgColor; + document.getElementById('badged-background-color').value = bgColor; + + document.getElementById('counter-preview-badge').style.color = txtColor; + document.getElementById('pre-badged-text-color').style.backgroundColor = txtColor; + document.getElementById('badged-text-color').value = txtColor; + + document.getElementById('badged-background-color').addEventListener('keyup', optionsOther._onChangedHexColor); + document.getElementById('badged-text-color').addEventListener('keyup', optionsOther._onChangedHexColor); + document.getElementById('restore-background-color').addEventListener('click', optionsOther._setDefaultColor); + document.getElementById('restore-text-color').addEventListener('click', optionsOther._setDefaultColor); + + optionsOther._colorPicker(); + } +}; + +optionsOther._renderStorageSection = function (opt) { + document.getElementById('sync-help').addEventListener('click', function () { options._onLinkClick(`${Links.FAQ}#sync`); }); + document.getElementById('storage-type-local').addEventListener('change', optionsOther._onStorageOptionChanged); + document.getElementById('storage-type-sync').addEventListener('change', optionsOther._onStorageOptionChanged); + document.getElementById('export-data').addEventListener('click', storageManager.export); + document.getElementById('import-data').addEventListener('click', storageManager.startImportFilePicker); + document.getElementById('import-file-picker').addEventListener('change', storageManager.handleImportFilePicker); + + optionsOther._preSelectStorage(opt.storageType); +}; + +optionsOther._setIcon = function (optionValue) { + wrappers.setIcon({'path': optionValue}, 'Enabled'); + let url = chrome.runtime.getURL(`icons/action/${optionValue.toLowerCase()}/icon38-default.png`); + document.getElementById('icon-badge-preview').src = url; +}; + +optionsOther._preSelectStorage = function (type) { + if (type === 'local') { + document.getElementById('storage-type-local').checked = true; + optionsOther._storageSize(chrome.storage.local); + } else { + document.getElementById('storage-type-sync').checked = true; + optionsOther._storageSize(chrome.storage.sync); + } +}; + +optionsOther._onStorageOptionChanged = function ({target}) { + chrome.storage.local.set({ + [Setting.STORAGE_TYPE]: target.value, + }); + if (target.value === 'local') { + storageManager.migrateData('local'); + optionsOther._storageSize(chrome.storage.local); + } else { + storageManager.migrateData('sync'); + optionsOther._storageSize(chrome.storage.sync); + } +}; + +optionsOther._storageSize = function (type) { + + return new Promise((resolve) => { + type.get(null, function (items) { + let value = new TextEncoder().encode(Object.entries(items) + .map(([key, value]) => key + JSON.stringify(value)) + .join('')).length; + value /= 1000; + // document.getElementById('storage-size').textContent = `${value.toLocaleString()} KB`; + console.log(`${value.toLocaleString()} KB`); + resolve(); + }); + }); +}; + +optionsOther._colorPicker = function () { + /* eslint-disable no-undef, no-invalid-this */ + const badgeBackgroundColor = new CP(document.getElementById('badged-background-color')); + badgeBackgroundColor.on('change', function (r, g, b) { + this.source.value = this.color(r, g, b); + }); + badgeBackgroundColor.on('drag', function (r, g, b) { + options._backgroundColor = this.color(r, g, b); + this.source.value = options._backgroundColor; + wrappers.setBadgeBackgroundColor({'color': options._backgroundColor}); + document.getElementById('counter-preview-badge').style.backgroundColor = options._backgroundColor; + document.getElementById('pre-badged-background-color').style.backgroundColor = options._backgroundColor; + }); + + const badgeTextColor = new CP(document.getElementById('badged-text-color')); + badgeTextColor.on('change', function (r, g, b) { + this.source.value = this.color(r, g, b); + }); + badgeTextColor.on('drag', function (r, g, b) { + options._textColor = this.color(r, g, b); + this.source.value = options._textColor; + wrappers.setBadgeTextColor({'color': options._textColor}); + document.getElementById('counter-preview-badge').style.color = options._textColor; + document.getElementById('pre-badged-text-color').style.backgroundColor = options._textColor; + }); + /* eslint-enable no-undef, no-invalid-this */ +}; + +optionsOther._setDefaultColor = function ({target}) { + if (target.id === 'restore-text-color') { + options._textColor = '#FFFFFF'; + wrappers.setBadgeTextColor({'color': options._textColor}); + document.getElementById('counter-preview-badge').style.color = options._textColor; + document.getElementById('pre-badged-text-color').style.backgroundColor = options._textColor; + document.getElementById('badged-text-color').value = options._textColor; + } else if (target.id === 'restore-background-color') { + options._backgroundColor = '#4A826C'; + wrappers.setBadgeBackgroundColor({'color': options._backgroundColor}); + document.getElementById('counter-preview-badge').style.backgroundColor = options._backgroundColor; + document.getElementById('pre-badged-background-color').style.backgroundColor = options._backgroundColor; + document.getElementById('badged-background-color').value = options._backgroundColor; + } +}; + +optionsOther._onChangedHexColor = function ({target}) { + if (/#([a-f0-9]{3}){1,2}\b/i.test(target.value)) { + target.classList.remove('color-error'); + if (target.id === 'badged-text-color') { + options._textColor = target.value; + wrappers.setBadgeTextColor({'color': options._textColor}); + document.getElementById('counter-preview-badge').style.color = options._textColor; + document.getElementById('pre-badged-text-color').style.backgroundColor = options._textColor; + } else { + options._backgroundColor = target.value; + wrappers.setBadgeBackgroundColor({'color': options._backgroundColor}); + document.getElementById('counter-preview-badge').style.backgroundColor = options._backgroundColor; + document.getElementById('pre-badged-background-color').style.backgroundColor = options._backgroundColor; + } + } else { + target.classList.add('color-error'); + } +}; + +optionsOther.init = function (opt) { + if (BrowserType.CHROMIUM) { + document.getElementById('div-badged-text-color').style.display = 'none'; + } + + document.getElementById('icon-default').addEventListener('change', options.onOptionChanged); + document.getElementById('icon-grey').addEventListener('change', options.onOptionChanged); + document.getElementById('icon-light').addEventListener('change', options.onOptionChanged); + + optionsOther._renderIconSection(opt); + optionsOther._renderStorageSection(opt); +}; + +optionsOther._platformSupportIcons = true; diff --git a/pages/options/options.css b/pages/options/options.css index b45217dc..9c29e040 100644 --- a/pages/options/options.css +++ b/pages/options/options.css @@ -389,7 +389,7 @@ body[dir="rtl"] .input-text { } .option-links { - list-style-type: disclosure-closed; + list-style-type: none; margin-top: 0; padding-top: 2rem; } diff --git a/pages/options/options.html b/pages/options/options.html index 007446fe..8d4d4ce4 100644 --- a/pages/options/options.html +++ b/pages/options/options.html @@ -19,13 +19,19 @@ + + + + + +
- - - - + + + +
@@ -75,22 +81,21 @@
- -
This function is currently in an experimental stage. No data transmission. It's all local on your device.
+
No data transmission. It's all local on your device.
Deactivate LocalCDN for these domains:
- +
Enter domains to disable LocalCDN there. One domain per line.

- domain.com;
sub.domain.com;
*.wildcard-domain.com;
+ domain.com
sub.domain.com
*.wildcard-domain.com
@@ -114,7 +119,7 @@
@@ -125,7 +130,7 @@
@@ -139,7 +144,7 @@
@@ -151,13 +156,13 @@
Do not apply HTML filter to these domains:
Apply HTML filter to these domains:
- +
Enter the domains to be handled or ignored by the HTML filter. One domain per line.
@@ -183,19 +188,19 @@
@@ -255,11 +260,11 @@
Storage type
diff --git a/pages/options/options.js b/pages/options/options.js index ade15f3e..cfa54777 100644 --- a/pages/options/options.js +++ b/pages/options/options.js @@ -42,25 +42,12 @@ options._renderContents = function () { options._renderLocaleNotice(); } - if (BrowserType.CHROMIUM) { - document.getElementById('html-filter-div').style.display = 'none'; - document.getElementById('block-google-fonts').style.display = 'none'; - document.getElementById('div-badged-text-color').style.display = 'none'; - } - - if (!chrome.browserAction.setIcon) { - document.getElementById('icon-style-div').style.display = 'none'; - options._platformSupportIcons = false; - } - options._renderInfoPanel(); document.getElementById('label-version').textContent = chrome.runtime.getManifest().version; }; options._renderOptionsPanel = function () { - let allowlistedDomains, domainAllowlist, elements, htmlFilterDomains, domainHtmlFilter, - googleFontsDomains, domainAllowedGoogleFonts, url, bgColor, txtColor; - - Object.assign(options._optionValues, {[Setting.INTERNAL_STATISTICS]: options._internalStatistics}); + let allowlistedDomains, domainAllowlist, htmlFilterDomains, domainHtmlFilter, + googleFontsDomains, domainAllowedGoogleFonts, basic, advanced, other; allowlistedDomains = options._optionValues.allowlistedDomains; domainAllowlist = options._serializeAllowlistedDomains(allowlistedDomains); @@ -71,26 +58,31 @@ options._renderOptionsPanel = function () { googleFontsDomains = options._optionValues.allowedDomainsGoogleFonts; domainAllowedGoogleFonts = options._serializeAllowlistedDomains(googleFontsDomains); - elements = options._optionElements; - Object.assign(elements, {[Setting.INTERNAL_STATISTICS]: document.getElementById('checkbox-internal-statistics')}); + basic = { + 'showIconBadge': options._optionValues.showIconBadge, + 'updateNotification': options._optionValues.updateNotification, + 'disablePrefetch': options._optionValues.disablePrefetch, + 'stripMetadata': options._optionValues.stripMetadata, + 'internalStatistics': options._internalStatistics, + 'allowlistedDomains': domainAllowlist + }; - Object.assign(elements, {[Setting.SELECTED_ICON]: document.getElementsByName('selected-icon')}); + advanced = { + 'blockMissing': options._optionValues.blockMissing, + 'blockGoogleFonts': options._optionValues.blockGoogleFonts, + 'allowedDomainsGoogleFonts': domainAllowedGoogleFonts, + 'enableLogging': options._optionValues.enableLogging, + 'domainsManipulateDOM': domainHtmlFilter, + 'negateHtmlFilterList': options._optionValues.negateHtmlFilterList + }; - elements.showIconBadge.checked = options._optionValues.showIconBadge; - elements.blockMissing.checked = options._optionValues.blockMissing; - elements.disablePrefetch.checked = options._optionValues.disablePrefetch; - elements.stripMetadata.checked = options._optionValues.stripMetadata; - elements.updateNotification.value = options._optionValues.updateNotification; - elements.enableLogging.checked = options._optionValues.enableLogging; - elements.allowlistedDomains.value = domainAllowlist; - elements.domainsManipulateDOM.value = domainHtmlFilter; - elements.negateHtmlFilterList.checked = options._optionValues.negateHtmlFilterList; - elements.blockGoogleFonts.checked = options._optionValues.blockGoogleFonts; - elements.internalStatistics.checked = options._optionValues.internalStatistics; - elements.allowedDomainsGoogleFonts.value = domainAllowedGoogleFonts; - elements.storageType = options._optionValues.storageType; + other = { + 'selectedIcon': options._optionValues.selectedIcon, + 'badgeColor': options._optionValues.badgeColor, + 'badgeTextColor': options._optionValues.badgeTextColor, + 'storageType': options._optionValues.storageType + }; - options._registerOptionChangedEventListeners(elements); options._registerMiscellaneousEventListeners(); if (options._optionValues.blockMissing === true) { @@ -101,87 +93,14 @@ options._renderOptionsPanel = function () { options._renderLocaleNotice(); } - if (elements.blockGoogleFonts.checked) { - document.getElementById('div-domains-allowlist-google-fonts').style.display = 'block'; - } else { - document.getElementById('div-domains-allowlist-google-fonts').style.display = 'none'; - } - - if (elements.storageType === 'local') { - document.getElementById('storage-type-local').checked = true; - } else { - document.getElementById('storage-type-sync').checked = true; - } - - if (options._platformSupportIcons) { - let selectedIcon = options._optionValues.selectedIcon; - - if (selectedIcon === 'Default') { - document.getElementById('icon-default').checked = true; - } else if (selectedIcon === 'Grey') { - document.getElementById('icon-grey').checked = true; - } else if (selectedIcon === 'Light') { - document.getElementById('icon-light').checked = true; - } - url = chrome.runtime.getURL(`icons/action/${selectedIcon.toLowerCase()}/icon38-default.png`); - document.getElementById('icon-badge-preview').src = url; - - bgColor = options._optionValues.badgeColor || '#4A826C'; - txtColor = options._optionValues.badgeTextColor || '#FFFFFF'; - - document.getElementById('counter-preview-badge').style.backgroundColor = bgColor; - document.getElementById('pre-badged-background-color').style.backgroundColor = bgColor; - document.getElementById('badged-background-color').value = bgColor; - - document.getElementById('counter-preview-badge').style.color = txtColor; - document.getElementById('pre-badged-text-color').style.backgroundColor = txtColor; - document.getElementById('badged-text-color').value = txtColor; - } - - document.getElementById('last-mapping-update').textContent += ` ${mappings.lastMappingUpdate}`; - document.getElementById('negate-html-filter-list-warning').addEventListener('click', function () { - options._onLinkClick(Links.CODEBERG_HTML_FILTER); - }); - document.getElementById('link-welcome-page').addEventListener('click', function () { - options._onLinkClick(Links.WELCOME); - }); - document.getElementById('link-changelog').addEventListener('click', function () { - options._onLinkClick(Links.CHANGELOG); - }); - document.getElementById('link-donate').addEventListener('click', function () { - options._onLinkClick(Links.DONATE); - }); - document.getElementById('link-faq').addEventListener('click', function () { - options._onLinkClick(Links.FAQ); - }); - document.getElementById('ruleset-help').addEventListener('click', function () { - options._onLinkClick(Links.CODEBERG_RULESET); - }); - document.getElementById('sync-help').addEventListener('click', function () { - options._onLinkClick(`${Links.FAQ}#sync`); - }); - document.getElementById('link-statistic').addEventListener('click', function () { - options._onLinkClick(Links.STATISTICS); - }); + optionsBasic.init(basic); + optionsAdvanced.init(advanced); + optionsOther.init(other); + optionsInfo.init(); document.getElementById('btn-general-tab').addEventListener('click', options._changeTab); document.getElementById('btn-advanced-tab').addEventListener('click', options._changeTab); document.getElementById('btn-export-import-tab').addEventListener('click', options._changeTab); - document.getElementById('btn-info-tab').addEventListener('click', options._changeTab); - - document.getElementById('storage-type-local').addEventListener('change', options._onStorageOptionChanged); - document.getElementById('storage-type-sync').addEventListener('change', options._onStorageOptionChanged); - document.getElementById('export-data').addEventListener('click', storageManager.export); - document.getElementById('import-data').addEventListener('click', storageManager.startImportFilePicker); - document.getElementById('import-file-picker').addEventListener('change', storageManager.handleImportFilePicker); - - if (options._platformSupportIcons) { - document.getElementById('badged-background-color').addEventListener('keyup', options._onChangedHexColor); - document.getElementById('badged-text-color').addEventListener('keyup', options._onChangedHexColor); - } - - document.getElementById('restore-background-color').addEventListener('click', options._setDefaultColor); - document.getElementById('restore-text-color').addEventListener('click', options._setDefaultColor); }; options._renderBlockMissingNotice = function () { @@ -199,42 +118,31 @@ options._renderLocaleNotice = function () { localeNoticeElement.setAttribute('class', 'notice notice-default'); }; -options._registerOptionChangedEventListeners = function (elements) { - elements.showIconBadge.addEventListener('change', options._onOptionChanged); - elements.blockMissing.addEventListener('change', options._onOptionChanged); - elements.disablePrefetch.addEventListener('change', options._onOptionChanged); - elements.stripMetadata.addEventListener('change', options._onOptionChanged); - elements.enableLogging.addEventListener('change', options._onOptionChanged); - elements.updateNotification.addEventListener('change', options._onOptionChanged); - elements.allowlistedDomains.addEventListener('keyup', options._onOptionChanged); - elements.domainsManipulateDOM.addEventListener('keyup', options._onOptionChanged); - elements.negateHtmlFilterList.addEventListener('change', options._onOptionChanged); - elements.blockGoogleFonts.addEventListener('change', options._onOptionChanged); - elements.selectedIcon[0].addEventListener('change', options._onOptionChanged); - elements.selectedIcon[1].addEventListener('change', options._onOptionChanged); - elements.selectedIcon[2].addEventListener('change', options._onOptionChanged); - elements.ruleSets[0].addEventListener('change', ruleGenerator.openRuleSet); - elements.ruleSets[1].addEventListener('change', ruleGenerator.openRuleSet); - elements.ruleSets[2].addEventListener('change', ruleGenerator.openRuleSet); - elements.copyRuleSet.addEventListener('click', ruleGenerator.copyRuleSet); - elements.internalStatistics.addEventListener('change', options._onOptionChanged); - elements.allowedDomainsGoogleFonts.addEventListener('keyup', options._onOptionChanged); -}; - options._registerMiscellaneousEventListeners = function () { - let blockMissingButtonElement = document.getElementById('button-block-missing'); + let blockMissingButtonElement, changeEvent, optionBlockMissing; + + blockMissingButtonElement = document.getElementById('button-block-missing'); + changeEvent = new Event('change'); + optionBlockMissing = options.getOptionElement('blockMissing'); blockMissingButtonElement.addEventListener('click', function () { - let changeEvent = new Event('change'); - - options._optionElements.blockMissing.checked = false; - options._optionElements.blockMissing.dispatchEvent(changeEvent); + optionBlockMissing.checked = false; + optionBlockMissing.dispatchEvent(changeEvent); }); }; options._determineOptionValues = function () { return new Promise((resolve) => { - let optionKeys = Object.keys(options._optionElements); + let nodeList, optionList, optionKeys; + + nodeList = document.querySelectorAll('[data-option]'); + optionList = {}; + + for (let element of nodeList) { + optionList[element.getAttribute('data-option')] = true; + } + + optionKeys = Object.keys(optionList); storageManager.type.get(optionKeys, function (items) { options._optionValues = items; @@ -253,33 +161,10 @@ options._determineLocalOptionValues = function () { }); }; -options._getOptionElement = function (optionKey) { +options.getOptionElement = function (optionKey) { return document.querySelector(`[data-option=${optionKey}]`); }; -options._getOptionElements = function () { - let optionElements = { - [Setting.SHOW_ICON_BADGE]: options._getOptionElement(Setting.SHOW_ICON_BADGE), - [Setting.BLOCK_MISSING]: options._getOptionElement(Setting.BLOCK_MISSING), - [Setting.DISABLE_PREFETCH]: options._getOptionElement(Setting.DISABLE_PREFETCH), - [Setting.STRIP_METADATA]: options._getOptionElement(Setting.STRIP_METADATA), - [Setting.ALLOWLISTED_DOMAINS]: options._getOptionElement(Setting.ALLOWLISTED_DOMAINS), - [Setting.UPDATE_NOTIFICATION]: options._getOptionElement(Setting.UPDATE_NOTIFICATION), - [Setting.LOGGING]: options._getOptionElement(Setting.LOGGING), - ['ruleSets']: document.getElementsByName('rule-sets'), - ['copyRuleSet']: document.getElementById('button-copy-rule-set'), - [Setting.NEGATE_HTML_FILTER_LIST]: options._getOptionElement(Setting.NEGATE_HTML_FILTER_LIST), - [Setting.DOMAINS_MANIPULATE_DOM]: options._getOptionElement(Setting.DOMAINS_MANIPULATE_DOM), - [Setting.BLOCK_GOOGLE_FONTS]: options._getOptionElement(Setting.BLOCK_GOOGLE_FONTS), - [Setting.SELECTED_ICON]: options._getOptionElement(Setting.SELECTED_ICON), - [Setting.ALLOWED_DOMAINS_GOOGLE_FONTS]: options._getOptionElement(Setting.ALLOWED_DOMAINS_GOOGLE_FONTS), - [Setting.STORAGE_TYPE]: options._getOptionElement(Setting.STORAGE_TYPE), - [Setting.BADGE_COLOR]: options._getOptionElement(Setting.BADGE_COLOR), - [Setting.BADGE_TEXT_COLOR]: options._getOptionElement(Setting.BADGE_TEXT_COLOR) - }; - return optionElements; -}; - options._configureLinkPrefetching = function (value) { if (value === false) { // Restore default values of related preference values. @@ -321,118 +206,6 @@ options._parseDomainAllowlist = function (domainAllowlist) { return allowlistedDomains; }; -options._renderInfoPanel = function () { - let unsupportedFrameworks, btnCDNs, btnFrameworks; - - unsupportedFrameworks = 0; - options._listOfFrameworks = {}; - - btnCDNs = document.getElementById('cdn'); - btnCDNs.value = 'CDNs: '; - - btnFrameworks = document.getElementById('framework'); - btnFrameworks.value = 'Frameworks: '; - - - Object.values(Object.values(resources)).forEach((element) => { - let path = Object.values(element)[0]; - path = path.split('/'); - options._listOfFrameworks[path[1]] = true; - }); - - if (BrowserType.CHROMIUM) { - // Chromium based browser does not support Google Material Icons and Font Awesome - document.getElementById('unsupported-frameworks').style.display = 'block'; - unsupportedFrameworks = 2; - } - - options._createList('cdn'); - document.getElementById('cdn').classList.add('btns-active'); - - btnFrameworks.addEventListener('click', options._btnCreateList); - btnCDNs.addEventListener('click', options._btnCreateList); - - // Reduce CDNs by 3, because loli.net includes = cdn.css.net, cdnjs.loli.net, ajax.loli.net, fonts.loli.net - btnCDNs.value += Object.keys(mappings.cdn).length - 3; - btnFrameworks.value += Object.keys(options._listOfFrameworks).length - unsupportedFrameworks; -}; - -options._btnCreateList = function ({target}) { - if (target.id === 'cdn') { - document.getElementById('cdn').classList.add('btns-active'); - document.getElementById('framework').classList.remove('btns-active'); - } else { - document.getElementById('cdn').classList.remove('btns-active'); - document.getElementById('framework').classList.add('btns-active'); - } - options._createList(target.id); -}; - -options._createList = function (type) { - let textArea, list; - - textArea = document.getElementById('generated-list'); - textArea.value = ''; - - if (type === 'cdn') { - list = Object.keys(mappings.cdn); - } else if (type === 'framework') { - list = Object.keys(options._listOfFrameworks); - } else { - return; - } - - list.forEach((elem) => { - if (!(BrowserType.CHROMIUM && (elem === 'fontawesome' || elem === 'google-material-design-icons'))) { - textArea.value += `${elem}\n`; - } - }); -}; - -options._colorPicker = function () { - /* eslint-disable no-undef, no-invalid-this */ - const badgeBackgroundColor = new CP(document.getElementById('badged-background-color')); - badgeBackgroundColor.on('change', function (r, g, b) { - this.source.value = this.color(r, g, b); - }); - badgeBackgroundColor.on('drag', function (r, g, b) { - options._backgroundColor = this.color(r, g, b); - this.source.value = options._backgroundColor; - wrappers.setBadgeBackgroundColor({'color': options._backgroundColor}); - document.getElementById('counter-preview-badge').style.backgroundColor = options._backgroundColor; - document.getElementById('pre-badged-background-color').style.backgroundColor = options._backgroundColor; - }); - - const badgeTextColor = new CP(document.getElementById('badged-text-color')); - badgeTextColor.on('change', function (r, g, b) { - this.source.value = this.color(r, g, b); - }); - badgeTextColor.on('drag', function (r, g, b) { - options._textColor = this.color(r, g, b); - this.source.value = options._textColor; - wrappers.setBadgeTextColor({'color': options._textColor}); - document.getElementById('counter-preview-badge').style.color = options._textColor; - document.getElementById('pre-badged-text-color').style.backgroundColor = options._textColor; - }); - /* eslint-enable no-undef, no-invalid-this */ -}; - -options._setDefaultColor = function ({target}) { - if (target.id === 'restore-text-color') { - options._textColor = '#FFFFFF'; - wrappers.setBadgeTextColor({'color': options._textColor}); - document.getElementById('counter-preview-badge').style.color = options._textColor; - document.getElementById('pre-badged-text-color').style.backgroundColor = options._textColor; - document.getElementById('badged-text-color').value = options._textColor; - } else if (target.id === 'restore-background-color') { - options._backgroundColor = '#4A826C'; - wrappers.setBadgeBackgroundColor({'color': options._backgroundColor}); - document.getElementById('counter-preview-badge').style.backgroundColor = options._backgroundColor; - document.getElementById('pre-badged-background-color').style.backgroundColor = options._backgroundColor; - document.getElementById('badged-background-color').value = options._backgroundColor; - } -}; - /** * Event Handlers @@ -441,15 +214,13 @@ options._setDefaultColor = function ({target}) { options._onDocumentLoaded = function () { let language = navigator.language; - options._optionElements = options._getOptionElements(); options._languageSupported = helpers.languageIsFullySupported(language); options._scriptDirection = helpers.determineScriptDirection(language); - options._colorPicker(); options._renderContents(); }; -options._onOptionChanged = function ({target}) { +options.onOptionChanged = function ({target}) { let optionKey, optionType, optionValue; optionKey = target.getAttribute('data-option'); @@ -461,68 +232,41 @@ options._onOptionChanged = function ({target}) { optionValue = target.value; } - if (optionKey === Setting.UPDATE_NOTIFICATION) { - optionValue = parseInt(optionValue); + switch (optionKey) { + case Setting.UPDATE_NOTIFICATION: + optionValue = parseInt(optionValue); + break; + case Setting.BLOCK_MISSING: + if (optionValue === true) { + options._renderBlockMissingNotice(); + } else { + options._hideBlockMissingNotice(); + } + break; + case Setting.DISABLE_PREFETCH: + options._configureLinkPrefetching(optionValue); + break; + case Setting.ALLOWLISTED_DOMAINS: + case Setting.DOMAINS_MANIPULATE_DOM: + case Setting.ALLOWED_DOMAINS_GOOGLE_FONTS: + optionValue = options._parseDomainAllowlist(optionValue); + break; + case Setting.BLOCK_GOOGLE_FONTS: + optionsAdvanced._renderAdvancedSection(optionValue); + break; + case Setting.NEGATE_HTML_FILTER_LIST: + optionsAdvanced._renderHtmlFilterSection(optionValue); + break; + case Setting.SELECTED_ICON: + optionsOther._setIcon(optionValue); + break; } - if (optionKey === Setting.BLOCK_MISSING) { - if (optionValue === true) { - options._renderBlockMissingNotice(); - } else { - options._hideBlockMissingNotice(); - } - } - - if (optionKey === Setting.DISABLE_PREFETCH) { - options._configureLinkPrefetching(optionValue); - } - - if (optionKey === Setting.ALLOWLISTED_DOMAINS || - optionKey === Setting.DOMAINS_MANIPULATE_DOM || - optionKey === Setting.ALLOWED_DOMAINS_GOOGLE_FONTS) { - - optionValue = options._parseDomainAllowlist(optionValue); - } - - if (optionKey === Setting.BLOCK_GOOGLE_FONTS) { - if (optionValue === true) { - document.getElementById('div-domains-allowlist-google-fonts').style.display = 'block'; - } else { - document.getElementById('div-domains-allowlist-google-fonts').style.display = 'none'; - } - } - - if (optionKey === Setting.NEGATE_HTML_FILTER_LIST) { - if (optionValue === true) { - document.getElementById('html-filter-domains-title-include').style.display = 'none'; - document.getElementById('html-filter-domains-title-exclude').style.display = 'block'; - } else { - document.getElementById('html-filter-domains-title-include').style.display = 'block'; - document.getElementById('html-filter-domains-title-exclude').style.display = 'none'; - } - } - - if (optionKey === Setting.SELECTED_ICON) { - wrappers.setIcon({'path': optionValue}, 'Enabled'); - let url = chrome.runtime.getURL(`icons/action/${optionValue.toLowerCase()}/icon38-default.png`); - document.getElementById('icon-badge-preview').src = url; - } storageManager.type.set({ [optionKey]: optionValue, }); }; -options._onStorageOptionChanged = function ({target}) { - chrome.storage.local.set({ - [Setting.STORAGE_TYPE]: target.value, - }); - if (target.value === 'local') { - storageManager.migrateData('local'); - } else { - storageManager.migrateData('sync'); - } -}; - options._onLinkClick = function (url) { chrome.tabs.create({ 'url': url, @@ -533,7 +277,7 @@ options._onLinkClick = function (url) { options._changeTab = function ({target}) { let tabContent, tabButton, optionKey; - optionKey = target.getAttribute('data-option'); + optionKey = target.getAttribute('data-option-tab'); tabContent = document.getElementsByClassName('tab-content'); tabButton = document.getElementsByClassName('option-buttons'); @@ -548,24 +292,6 @@ options._changeTab = function ({target}) { } }; -options._onChangedHexColor = function ({target}) { - if (/#([a-f0-9]{3}){1,2}\b/i.test(target.value)) { - target.classList.remove('color-error'); - if (target.id === 'badged-text-color') { - options._textColor = target.value; - wrappers.setBadgeTextColor({'color': options._textColor}); - document.getElementById('counter-preview-badge').style.color = options._textColor; - document.getElementById('pre-badged-text-color').style.backgroundColor = options._textColor; - } else { - options._backgroundColor = target.value; - wrappers.setBadgeBackgroundColor({'color': options._backgroundColor}); - document.getElementById('counter-preview-badge').style.backgroundColor = options._backgroundColor; - document.getElementById('pre-badged-background-color').style.backgroundColor = options._backgroundColor; - } - } else { - target.classList.add('color-error'); - } -}; /** * Updates the domain lists if the options page has no focus. @@ -580,8 +306,6 @@ options._updatesDomainLists = function (changes) { } else if (changedItems[0] === 'domainsManipulateDOM') { document.getElementById('tf-domains-manipulate-dom').value = options._serializeAllowlistedDomains(changes['domainsManipulateDOM'].newValue); } - } else { - // document has the focus } }; @@ -589,11 +313,8 @@ options._updatesDomainLists = function (changes) { /** * Initializations */ -options._internalStatistics = false; + options._storageType = 'local'; -options._listOfFrameworks = {}; -options._listOfCDNs = {}; -options._platformSupportIcons = true; document.addEventListener('DOMContentLoaded', options._onDocumentLoaded);