summaryrefslogtreecommitdiff
path: root/data/extensions/https-everywhere@eff.org/pages/popup/ux.js
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/https-everywhere@eff.org/pages/popup/ux.js')
-rw-r--r--data/extensions/https-everywhere@eff.org/pages/popup/ux.js281
1 files changed, 281 insertions, 0 deletions
diff --git a/data/extensions/https-everywhere@eff.org/pages/popup/ux.js b/data/extensions/https-everywhere@eff.org/pages/popup/ux.js
new file mode 100644
index 0000000..a35c00c
--- /dev/null
+++ b/data/extensions/https-everywhere@eff.org/pages/popup/ux.js
@@ -0,0 +1,281 @@
+/* global sendMessage */
+
+"use strict";
+
+function e(id) {
+ return document.getElementById(id);
+}
+
+/**
+ * Handles rule (de)activation in the popup
+ */
+function toggleRuleLine(event) {
+ if (event.target.matches("input[type=checkbox]")) {
+ getTab(activeTab => {
+ const set_ruleset = {
+ active: event.target.checked,
+ name: event.target.nextSibling.innerText,
+ tab_id: activeTab.id,
+ };
+
+ sendMessage("set_ruleset_active_status", set_ruleset, () => {
+ // purge the name from the cache so that this unchecking is persistent.
+ sendMessage("delete_from_ruleset_cache", set_ruleset.name, () => {
+ // Now reload the selected tab of the current window.
+ chrome.tabs.reload(set_ruleset.tab_id);
+ });
+ });
+ });
+ }
+}
+
+
+/**
+ * Creates rule lines (including checkbox and icon) for the popup
+ * @param rulesets
+ * @param list_div
+ * @returns {*}
+ */
+function appendRulesToListDiv(rulesets, list_div) {
+ if (rulesets && rulesets.length) {
+ // template parent block for each ruleset
+ let templateLine = document.createElement("div");
+ templateLine.className = "rule checkbox";
+
+ // label "container"
+ let templateLabel = document.createElement("label");
+
+ // checkbox
+ let templateCheckbox = document.createElement("input");
+ templateCheckbox.type = "checkbox";
+
+ // label text
+ let templateLabelText = document.createElement("span");
+
+ // img "remove" button
+ let templateRemove = document.createElement("img");
+ templateRemove.src = chrome.extension.getURL("images/remove.png");
+ templateRemove.className = "remove";
+
+ templateLabel.appendChild(templateCheckbox);
+ templateLabel.appendChild(templateLabelText);
+ templateLine.appendChild(templateLabel);
+
+ for (const ruleset of rulesets) {
+ let line = templateLine.cloneNode(true);
+ let checkbox = line.querySelector("input[type=checkbox]");
+ let text = line.querySelector("span");
+
+ checkbox.checked = ruleset.active;
+ text.innerText = ruleset.name;
+
+ if (ruleset.note && ruleset.note.length) {
+ line.title = ruleset.note;
+
+ if (ruleset.note === "user rule") {
+ let remove = templateRemove.cloneNode(true);
+ line.appendChild(remove);
+
+ remove.addEventListener("click", () => {
+ sendMessage("remove_rule", ruleset, () => {
+ list_div.removeChild(line);
+ });
+ });
+ }
+ }
+ list_div.appendChild(line);
+ }
+ show(list_div);
+ }
+}
+
+function showHttpNowhereUI() {
+ // Set up checkbox for HTTP nowhere mode
+ getOption_('httpNowhere', false, function(item) {
+ if (item.httpNowhere) {
+ e('http-nowhere-checkbox').checked = true;
+ }
+ e('HttpNowhere').style.visibility = "visible";
+ });
+};
+
+// Change the UI to reflect extension enabled/disabled
+function updateEnabledDisabledUI() {
+ getOption_('globalEnabled', true, function(item) {
+ e('onoffswitch').checked = item.globalEnabled;
+ e('disableButton').style.visibility = "visible";
+ // Hide or show the rules sections
+ if (item.globalEnabled) {
+ document.body.className = ""
+ showHttpNowhereUI()
+ } else {
+ document.body.className = "disabled"
+ }
+ });
+}
+
+// Toggle extension enabled/disabled status
+function toggleEnabledDisabled() {
+ var extension_toggle_effect = function() {
+ updateEnabledDisabledUI();
+ // The extension state changed, so reload this tab.
+ chrome.tabs.reload();
+ window.close();
+ }
+
+ getOption_('globalEnabled', true, function(item) {
+ setOption_('globalEnabled', !item.globalEnabled, extension_toggle_effect);
+ });
+
+}
+
+/**
+ * Create the list of rules for a specific tab
+ * @param activeTab
+ */
+function gotTab(activeTab) {
+ sendMessage("get_active_rulesets", activeTab.id, function(rulesets) {
+ if (rulesets) {
+ const stableRules = rulesets.filter(ruleset => ruleset.default_state);
+ const unstableRules = rulesets.filter(ruleset => !ruleset.default_state);
+
+ appendRulesToListDiv(stableRules, e("StableRules"));
+ appendRulesToListDiv(unstableRules, e("UnstableRules"));
+
+ // Add listener to capture the toggle event
+ e("RuleManagement").addEventListener("click", toggleRuleLine);
+ }
+
+ // Only show the "Add a rule" link if we're on an HTTPS page
+ if (/^https:/.test(activeTab.url)) {
+ show(e("add-rule-link"));
+ }
+ });
+}
+
+/**
+ * Fill in content into the popup on load
+ */
+document.addEventListener("DOMContentLoaded", function () {
+ getTab(gotTab);
+
+ // Set up the enabled/disabled switch & hide/show rules
+ updateEnabledDisabledUI();
+ e('onoffswitch').addEventListener('click', toggleEnabledDisabled);
+ e('http-nowhere-checkbox').addEventListener('click', toggleHttpNowhere, false);
+ e('reset-to-defaults').addEventListener('click', () => {
+ if (confirm(chrome.i18n.getMessage("prefs_reset_defaults_message"))) {
+ sendMessage("reset_to_defaults", null, () => {
+ window.close();
+ });
+ }
+ });
+
+ // Print the extension's current version.
+ var the_manifest = chrome.runtime.getManifest();
+ var version_info = e('current-version');
+ version_info.innerText = the_manifest.version;
+
+ let rulesets_versions = e('rulesets-versions');
+ sendMessage("get_ruleset_timestamps", null, timestamps => {
+ for(let [update_channel, timestamp] of timestamps){
+ if(timestamp > 0){
+ let ruleset_date = new Date(timestamp * 1000);
+ let ruleset_version_string = ruleset_date.getUTCFullYear() + "." + (ruleset_date.getUTCMonth() + 1) + "." + ruleset_date.getUTCDate();
+
+ let timestamp_span = document.createElement("span");
+ timestamp_span.className = "rulesets-version";
+ timestamp_span.innerText = chrome.i18n.getMessage("about_rulesets_version") + " " + update_channel + ": " + ruleset_version_string;
+ rulesets_versions.appendChild(timestamp_span);
+ }
+ }
+ });
+ e("aboutTitle").title = chrome.i18n.getMessage("about_title");
+ e("add-rule-link").addEventListener("click", addManualRule);
+});
+
+
+var escapeForRegex = function( value ) {
+ return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
+};
+
+function hide(elem) {
+ elem.style.display = "none";
+}
+
+function show(elem) {
+ elem.style.display = "block";
+}
+
+/**
+ * Handles the manual addition of rules
+ */
+function addManualRule() {
+ getTab(function(tab) {
+ hide(e("add-rule-link"));
+ show(e("add-new-rule-div"));
+
+ const url = new URL(tab.url);
+
+ e("new-rule-host").value = url.host;
+
+ const escapedHost = escapeForRegex(url.host);
+
+ e("new-rule-regex").value = `^http://${escapedHost}/`;
+ e("new-rule-redirect").value = `https://${url.host}/`;
+ e("new-rule-name").value = "Manual rule for " + url.host;
+
+ e("add-new-rule-button").addEventListener("click", function() {
+ const params = {
+ host : e("new-rule-host").value,
+ redirectTo : e("new-rule-redirect").value,
+ urlMatcher : e("new-rule-regex").value
+ };
+ sendMessage("add_new_rule", params, function() {
+ location.reload();
+ });
+ });
+
+ e("cancel-new-rule").addEventListener("click", function() {
+ show(e("add-rule-link"));
+ hide(e("add-new-rule-div"));
+ });
+
+ e("new-rule-show-advanced-link").addEventListener("click", function() {
+ show(e("new-rule-advanced"));
+ hide(e("new-rule-regular-text"));
+ });
+
+ e("new-rule-hide-advanced-link").addEventListener("click", function() {
+ hide(e("new-rule-advanced"));
+ show(e("new-rule-regular-text"));
+ });
+ });
+}
+
+function toggleHttpNowhere() {
+ getOption_('httpNowhere', false, function(item) {
+ setOption_('httpNowhere', !item.httpNowhere);
+ });
+}
+
+function getOption_(opt, defaultOpt, callback) {
+ var details = {};
+ details[opt] = defaultOpt;
+ sendMessage("get_option", details, callback);
+}
+
+function setOption_(opt, value, callback) {
+ var details = {};
+ details[opt] = value;
+ sendMessage("set_option", details, callback);
+}
+
+function getTab(callback) {
+ let url = new URL(window.location.href);
+ if (url.searchParams.has('tabId')) {
+ let parentId = Number(url.searchParams.get('tabId'));
+ return chrome.tabs.get(parentId, callback);
+ }
+ chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => callback(tabs[0]));
+}