/** * Popup Page * Belongs to Decentraleyes. * * @author Thomas Rientjes * @since 2016-08-09 * @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/. */ import Helpers from '../shared/code/helpers.js'; /** * Private Functions */ const _groupResourceInjections = (injections) => { return Object.values(injections).reduce((accumulator, injection) => { accumulator[injection.source] = accumulator[injection.source] ?? []; accumulator[injection.source].push(injection); return accumulator; }, {}); }; const _createInjectionGroupHeaderElement = (source, injections) => { let injectionGroupHeaderElement, badgeElement, badgeTextNode, cdnNameTextNode; injectionGroupHeaderElement = document.createElement('li'); injectionGroupHeaderElement.setAttribute('class', 'list-item'); badgeElement = document.createElement('span'); badgeElement.setAttribute('class', 'badge'); badgeTextNode = document.createTextNode(injections.length); badgeElement.appendChild(badgeTextNode); cdnNameTextNode = document.createTextNode(Helpers.determineCdnName(source)); injectionGroupHeaderElement.appendChild(badgeElement); injectionGroupHeaderElement.appendChild(cdnNameTextNode); return injectionGroupHeaderElement; }; const _createInjectionElement = (injection) => { let injectionElement, filename, name, nameTextNode, noteElement, noteTextNode; injectionElement = document.createElement('li'); injectionElement.setAttribute('class', 'sublist-item'); filename = Helpers.extractFilenameFromPath(injection.path); name = Helpers.determineResourceName(filename); nameTextNode = document.createTextNode(`- ${name}`); injectionElement.appendChild(nameTextNode); noteElement = document.createElement('span'); noteElement.setAttribute('class', 'side-note'); noteTextNode = document.createTextNode(` v${injection.version}`); noteElement.appendChild(noteTextNode); injectionElement.appendChild(noteElement); return injectionElement; }; const _createInjectionGroupElement = (source, injections) => { let injectionGroupElement; injectionGroupElement = document.createElement('ul'); injectionGroupElement.setAttribute('class', 'sublist'); for (const injection of injections) { const injectionElement = _createInjectionElement(injection); injectionGroupElement.appendChild(injectionElement); } return injectionGroupElement; }; const _createInjectionOverviewElement = (groupedInjections) => { const injectionOverviewElement = document.createElement('ul'); injectionOverviewElement.setAttribute('class', 'list'); for (const [source, injections] of Object.entries(groupedInjections)) { let injectionGroupHeaderElement, injectionGroupElement; injectionGroupHeaderElement = _createInjectionGroupHeaderElement(source, injections); injectionGroupElement = _createInjectionGroupElement(source, injections); injectionOverviewElement.appendChild(injectionGroupHeaderElement); injectionOverviewElement.appendChild(injectionGroupElement); } return injectionOverviewElement; }; const _renderInjectionPanel = (groupedInjections) => { let websiteContextElement, injectionOverviewElement; websiteContextElement = document.getElementById('website-context'); injectionOverviewElement = _createInjectionOverviewElement(groupedInjections); websiteContextElement.append(injectionOverviewElement); }; const _close = async () => { const platform = await chrome.runtime.getPlatformInfo(); if (platform.os === chrome.runtime.PlatformOs.ANDROID) { const activeTab = await chrome.tabs.getCurrent(); if (activeTab) { chrome.tabs.remove(activeTab.id); } else { window.close(); } } else { window.close(); } }; /** * Event Handlers */ const _onTestingUtilityLinkClicked = (event) => { if (event.button === 0 || event.button === 1) { chrome.tabs.create({ 'url': 'https://decentraleyes.org/test', 'active': (event.button === 0) }); } if (event.button === 0) { window.close(); } }; const _onOptionsButtonClicked = async () => { const platform = await chrome.runtime.getPlatformInfo(); if (platform.os === chrome.runtime.PlatformOs.ANDROID) { chrome.tabs.create({ 'url': chrome.runtime.getURL('pages/options/options.html'), 'active': true }); return window.close(); } else { chrome.runtime.openOptionsPage(); return window.close(); } }; const _renderNonContextualContents = async () => { let versionLabelElement, counterElement, testingUtilityLinkElement, optionsButtonElement, amountInjected; versionLabelElement = document.getElementById('version-label'); counterElement = document.getElementById('injection-counter'); testingUtilityLinkElement = document.getElementById('testing-utility-link'); optionsButtonElement = document.getElementById('options-button'); versionLabelElement.innerText = Helpers.determineVersion(); amountInjected = await Helpers.delegateAction('statistics:get-amount-injected'); counterElement.innerText = Helpers.formatNumber(amountInjected.value); testingUtilityLinkElement.addEventListener('mouseup', _onTestingUtilityLinkClicked); optionsButtonElement.addEventListener('mouseup', _onOptionsButtonClicked); testingUtilityLinkElement.addEventListener('keydown', (event) => { const enterOrSpaceKeyPressed = Helpers.enterOrSpaceKeyPressed(event); if (enterOrSpaceKeyPressed) { chrome.tabs.create({ 'url': 'https://decentraleyes.org/test' }); window.close(); } }); optionsButtonElement.addEventListener('keydown', (event) => { const enterOrSpaceKeyPressed = Helpers.enterOrSpaceKeyPressed(event); if (enterOrSpaceKeyPressed) { chrome.runtime.openOptionsPage(); return window.close(); } }); }; const _onProtectionToggled = async () => { let bypassCache, activeTab; bypassCache = (typeof browser === 'undefined'); activeTab = await Helpers.determineActiveTab(); chrome.tabs.reload(activeTab.id, {bypassCache}); _close(); }; const _enableProtection = async () => { let activeTab, tabDomain; activeTab = await Helpers.determineActiveTab(); tabDomain = await Helpers.delegateAction('domain:extract-from-url', activeTab.url); await Helpers.delegateAction('domain:remove-from-whitelist', tabDomain); _onProtectionToggled(); }; const _disableProtection = async () => { let activeTab, tabDomain; activeTab = await Helpers.determineActiveTab(); tabDomain = await Helpers.delegateAction('domain:extract-from-url', activeTab.url); await Helpers.delegateAction('domain:add-to-whitelist', tabDomain); _onProtectionToggled(); }; const _renderDomainWhitelistPanel = async (domain) => { let websiteContextElement, protectionToggleElement, domainIndicatorElement, domainIsWhitelisted; websiteContextElement = document.getElementById('website-context'); protectionToggleElement = document.getElementById('protection-toggle-button'); domainIndicatorElement = document.getElementById('domain-indicator'); protectionToggleElement.setAttribute('dir', Helpers.determineScriptDirection()); domainIndicatorElement.innerText = domain; domainIsWhitelisted = await Helpers.delegateAction('domain:is-whitelisted', domain); if (domainIsWhitelisted === true) { const enableProtectionTitle = chrome.i18n.getMessage('enableProtectionTitle'); protectionToggleElement.setAttribute('class', 'button button-toggle'); protectionToggleElement.addEventListener('click', _enableProtection); protectionToggleElement.setAttribute('title', enableProtectionTitle); protectionToggleElement.addEventListener('keydown', (event) => { const enterOrSpaceKeyPressed = Helpers.enterOrSpaceKeyPressed(event); if (enterOrSpaceKeyPressed) { _enableProtection(); } }); } else { const disableProtectionTitle = chrome.i18n.getMessage('disableProtectionTitle'); protectionToggleElement.setAttribute('class', 'button button-toggle active'); protectionToggleElement.addEventListener('click', _disableProtection); protectionToggleElement.setAttribute('title', disableProtectionTitle); protectionToggleElement.addEventListener('keydown', (event) => { const enterOrSpaceKeyPressed = Helpers.enterOrSpaceKeyPressed(event); if (enterOrSpaceKeyPressed) { _disableProtection(); } }); } websiteContextElement.classList.remove('hidden'); }; const _renderContextualContents = async () => { let activeTab, tabDomain, tabContext, groupedInjections; activeTab = await Helpers.determineActiveTab(); tabDomain = await Helpers.delegateAction('domain:extract-from-url', activeTab.url); if (tabDomain !== null) { await _renderDomainWhitelistPanel(tabDomain); } tabContext = await Helpers.delegateAction('tab-context:get', activeTab.id); groupedInjections = _groupResourceInjections(tabContext.injections); if (Object.keys(groupedInjections).length > 0) { _renderInjectionPanel(groupedInjections); } }; const _onDocumentLoaded = async () => { Helpers.applyI18nContentToDocument(document); Helpers.applyI18nTitlesToDocument(document); await _renderNonContextualContents(); await _renderContextualContents(); Helpers.unhideDocumentContents(document); }; /** * Initializations */ document.addEventListener('DOMContentLoaded', _onDocumentLoaded);