329 lines
10 KiB
JavaScript
329 lines
10 KiB
JavaScript
/**
|
|
* 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);
|