/** * Main Options Page * Belongs to LocalCDN (since 2020-02-26) * (Origin: Decentraleyes) * * @author Thomas Rientjes * @since 2016-08-09 * * @author nobody * @since 2020-05-04 * * @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 */ var options = {}; /** * Private Methods */ options._renderContents = function () { let translationComplete = true; document.body.setAttribute('dir', options._scriptDirection); translationComplete = helpers.insertI18nContentIntoDocument(document); options._determineOptionValues().then(options._determineLocalOptionValues).then(options._renderOptionsPanel); if (!translationComplete) { options._renderLocaleNotice(); } document.getElementById('label-version').textContent = chrome.runtime.getManifest().version; }; options._renderOptionsPanel = function () { let allowlistedDomains, domainAllowlist, htmlFilterDomains, domainHtmlFilter, googleFontsDomains, domainAllowedGoogleFonts, basic, advanced, other; allowlistedDomains = options._optionValues.allowlistedDomains; domainAllowlist = options._serializeAllowlistedDomains(allowlistedDomains); htmlFilterDomains = options._optionValues.domainsManipulateDOM; domainHtmlFilter = options._serializeAllowlistedDomains(htmlFilterDomains); googleFontsDomains = options._optionValues.allowedDomainsGoogleFonts; domainAllowedGoogleFonts = options._serializeAllowlistedDomains(googleFontsDomains); basic = { 'showIconBadge': options._optionValues.showIconBadge, 'updateNotification': options._optionValues.updateNotification, 'disablePrefetch': options._optionValues.disablePrefetch, 'stripMetadata': options._optionValues.stripMetadata, 'internalStatistics': options._internalStatistics, 'hideDonationButton': options._optionValues.hideDonationButton, 'allowlistedDomains': domainAllowlist }; advanced = { 'blockMissing': options._optionValues.blockMissing, 'blockGoogleFonts': options._optionValues.blockGoogleFonts, 'allowedDomainsGoogleFonts': domainAllowedGoogleFonts, 'enableLogging': options._optionValues.enableLogging, 'domainsManipulateDOM': domainHtmlFilter, 'negateHtmlFilterList': options._optionValues.negateHtmlFilterList, 'changeBadgeColorMissingResources': options._optionValues.changeBadgeColorMissingResources }; other = { 'selectedIcon': options._optionValues.selectedIcon, 'badgeColor': options._optionValues.badgeColor, 'badgeTextColor': options._optionValues.badgeTextColor, 'storageType': options._optionValues.storageType }; options._registerMiscellaneousEventListeners(); if (options._optionValues.blockMissing === true) { options._renderBlockMissingNotice(); } if (options._languageSupported === false) { options._renderLocaleNotice(); } 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); }; options._renderBlockMissingNotice = function () { let blockMissingNoticeElement = document.getElementById('notice-block-missing'); blockMissingNoticeElement.setAttribute('class', 'notice notice-warning'); }; options._hideBlockMissingNotice = function () { let blockMissingNoticeElement = document.getElementById('notice-block-missing'); blockMissingNoticeElement.setAttribute('class', 'notice notice-warning hidden'); }; options._renderLocaleNotice = function () { let localeNoticeElement = document.getElementById('notice-locale'); localeNoticeElement.setAttribute('class', 'notice notice-default'); }; options._registerMiscellaneousEventListeners = function () { let blockMissingButtonElement, changeEvent, optionBlockMissing; blockMissingButtonElement = document.getElementById('button-block-missing'); changeEvent = new Event('change'); optionBlockMissing = options.getOptionElement('blockMissing'); blockMissingButtonElement.addEventListener('click', function () { optionBlockMissing.checked = false; optionBlockMissing.dispatchEvent(changeEvent); }); }; options._determineOptionValues = function () { return new Promise((resolve) => { 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; resolve(); }); }); }; options._determineLocalOptionValues = function () { return new Promise((resolve) => { chrome.storage.local.get([Setting.INTERNAL_STATISTICS, Setting.STORAGE_TYPE], function (items) { options._internalStatistics = items.internalStatistics; options._storageType = items.storageType; resolve(); }); }); }; options.getOptionElement = function (optionKey) { return document.querySelector(`[data-option=${optionKey}]`); }; options._configureLinkPrefetching = function (value) { if (value === false) { // Restore default values of related preference values. chrome.privacy.network.networkPredictionEnabled.clear({}); } else { chrome.privacy.network.networkPredictionEnabled.set({ 'value': false, }); } }; options._serializeAllowlistedDomains = function (allowlistedDomains) { if (allowlistedDomains === undefined) { return ''; } let domainAllowlist, allowlistedDomainKeys; allowlistedDomainKeys = Object.keys(allowlistedDomains); domainAllowlist = ''; allowlistedDomainKeys.forEach(function (domain) { domainAllowlist = `${domainAllowlist}${domain}\n`; }); domainAllowlist = domainAllowlist.slice(0, -1); domainAllowlist = domainAllowlist.replace(Allowlist.TRIM_EXPRESSION, ''); return domainAllowlist; }; options._parseDomainAllowlist = function (domainAllowlist) { let allowlistedDomains = {}; domainAllowlist.split(Allowlist.VALUE_SEPARATOR).forEach(function (domain) { allowlistedDomains[helpers.normalizeDomain(domain)] = true; }); return allowlistedDomains; }; /** * Event Handlers */ options._onDocumentLoaded = function () { let language = navigator.language; options._languageSupported = helpers.languageIsFullySupported(language); options._scriptDirection = helpers.determineScriptDirection(language); options._renderContents(); }; options.onOptionChanged = function ({target}) { let optionKey, optionType, optionValue; optionKey = target.getAttribute('data-option'); optionType = target.getAttribute('type'); if (optionType === 'checkbox') { optionValue = target.checked; } else { optionValue = target.value; } 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; case Setting.LOGGING: if (optionValue === false) { chrome.runtime.sendMessage({'topic': 'logs:delete', 'value': ''}); } break; } storageManager.type.set({ [optionKey]: optionValue, }); }; options._onLinkClick = function (url) { chrome.tabs.create({ 'url': url, 'active': true }); }; options._changeTab = function ({target}) { let tabContent, tabButton, optionKey; optionKey = target.getAttribute('data-option-tab'); tabContent = document.getElementsByClassName('tab-content'); tabButton = document.getElementsByClassName('option-buttons'); for (let i = 0; i < tabContent.length; i++) { if (tabContent[i].id === optionKey) { tabContent[i].style.display = 'block'; tabButton[i].classList.add('option-buttons-active'); } else { tabContent[i].style.display = 'none'; tabButton[i].classList.remove('option-buttons-active'); } } }; /** * Updates the domain lists if the options page has no focus. * document.hasFocus() prevents problems with keyboard input. */ options._updatesDomainLists = function (changes) { let changedItems = Object.keys(changes); if (!document.hasFocus()) { if (changedItems[0] === 'allowlistedDomains') { document.getElementById('tf-domains-allowlist').value = options._serializeAllowlistedDomains(changes['allowlistedDomains'].newValue); } else if (changedItems[0] === 'domainsManipulateDOM') { document.getElementById('tf-domains-manipulate-dom').value = options._serializeAllowlistedDomains(changes['domainsManipulateDOM'].newValue); } } }; /** * Initializations */ options._storageType = 'local'; document.addEventListener('DOMContentLoaded', options._onDocumentLoaded); chrome.storage.onChanged.addListener(options._updatesDomainLists);