summaryrefslogtreecommitdiff
path: root/data/extensions/https-everywhere@eff.org/pages/popup
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/https-everywhere@eff.org/pages/popup')
-rw-r--r--data/extensions/https-everywhere@eff.org/pages/popup/index.html84
-rw-r--r--data/extensions/https-everywhere@eff.org/pages/popup/style.css128
-rw-r--r--data/extensions/https-everywhere@eff.org/pages/popup/ux.js281
3 files changed, 493 insertions, 0 deletions
diff --git a/data/extensions/https-everywhere@eff.org/pages/popup/index.html b/data/extensions/https-everywhere@eff.org/pages/popup/index.html
new file mode 100644
index 0000000..21dac99
--- /dev/null
+++ b/data/extensions/https-everywhere@eff.org/pages/popup/index.html
@@ -0,0 +1,84 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title data-i18n="about_ext_name"></title>
+
+ <link href="style.css" rel="stylesheet">
+ <script src="ux.js"></script>
+ <script src="../translation.js"></script>
+ <script src="../send-message.js"></script>
+ </head>
+ <body>
+ <header>
+ <h1 data-i18n="about_ext_name"></h1>
+ </header>
+
+ <section id="disableButton" class="options" style="visibility: hidden;">
+ <div class="onoffswitch">
+ <input id="onoffswitch" type="checkbox" checked><label data-i18n="menu_globalEnable" for="onoffswitch"></label>
+ </div>
+ </section>
+
+ <section id="HttpNowhere" class="options" style="visibility: hidden;">
+ <input id="http-nowhere-checkbox" type="checkbox"><label data-i18n="menu_blockUnencryptedRequests" for="http-nowhere-checkbox"></label>
+ </section>
+
+ <div id="RuleManagement">
+ <section>
+ <a href="javascript:void 0" id="add-rule-link" data-i18n="chrome_add_rule"></a>
+ <div id="add-new-rule-div" style="display: none">
+ <h3 data-i18n="about_add_new_rule"></h3>
+ <p data-i18n="chrome_always_https_for_host"></p>
+ <label for="new-rule-host" data-i18n="chrome_host"></label><br>
+ <input size="50" id="new-rule-host" type="text" disabled><br>
+ <div id="new-rule-regular-text">
+ <a href="javascript:void 0" id="new-rule-show-advanced-link" data-i18n="chrome_show_advanced"></a><br>
+ </div>
+ <div id="new-rule-advanced" style="display: none">
+ <a href="javascript:void 0" id="new-rule-hide-advanced-link" data-i18n="chrome_hide_advanced"></a><br>
+ <br>
+ <label for="new-rule-name" data-i18n="chrome_rule_name"></label><br>
+ <input size="50" id="new-rule-name" type="text"><br>
+ <label for="new-rule-regex" data-i18n="chrome_regex"></label><br>
+ <input size="50" id="new-rule-regex" type="text"><br>
+ <label for="new-rule-redirect" data-i18n="chrome_redirect_to"></label><br>
+ <input size="50" id="new-rule-redirect" type="text"><br>
+ </div>
+ <button id="add-new-rule-button" data-i18n="chrome_add_new_rule"></button><br>
+ <button id="cancel-new-rule" data-i18n="chrome_status_cancel_button"></button>
+ </div>
+ </section>
+
+ <section id="StableRules" class="rules">
+ <h3 data-i18n="chrome_stable_rules"></h3>
+ <p class="description" data-i18n="chrome_stable_rules_description"></p>
+ </section>
+
+ <section id="UnstableRules" class="rules">
+ <h3 data-i18n="chrome_experimental_rules"></h3>
+ <p class="description" data-i18n="chrome_experimental_rules_description"></p>
+ </section>
+
+ <section id="resetButton" class="options">
+ <a href="javascript:void 0" id="reset-to-defaults" data-i18n="prefs_reset_defaults"></a>
+ </section>
+ </div>
+
+ <footer>
+ <a id="viewAllRules" href="https://www.eff.org/https-everywhere/atlas" target="_blank" data-i18n="menu_viewAllRules"></a><br>
+ <br>
+ <a id="aboutTitle" href="https://www.eff.org/https-everywhere" target="_blank" data-i18n="about_title"></a><br>
+ <br>
+ <a id="donateEFF" href="https://supporters.eff.org/donate/support-https-everywhere" target="_blank" data-i18n="menu_donate_eff_imperative"></a>
+ <p>
+ <small>
+ <span data-i18n="about_version">Version</span>: <span id="current-version"></span>
+ <span id="rulesets-versions">
+ </span>
+ </small>
+ </p>
+ </footer>
+
+ </body>
+</html>
diff --git a/data/extensions/https-everywhere@eff.org/pages/popup/style.css b/data/extensions/https-everywhere@eff.org/pages/popup/style.css
new file mode 100644
index 0000000..a1cc358
--- /dev/null
+++ b/data/extensions/https-everywhere@eff.org/pages/popup/style.css
@@ -0,0 +1,128 @@
+html {
+ background-color: #fff
+}
+
+body {
+ cursor: default;
+ margin-left: 1em;
+ margin-right: 1em;
+ margin-top: 0;
+ margin-bottom: 0;
+ min-width: 20em;
+ font-family: 'Lucida Grande', 'Segoe UI', Tahoma, 'DejaVu Sans', Arial, sans-serif;
+ font-size: 75%;
+ color: #303942;
+}
+
+p {
+ line-height: 1.8em;
+}
+
+h1, h2, h3 {
+ user-select: none;
+ font-weight: normal;
+ line-height: 1;
+}
+
+h1 {
+ font-size: 1.5em;
+}
+
+h2 {
+ font-size: 1.3em;
+ margin-bottom: 0.4em;
+}
+
+h3 {
+ color: black;
+ font-size: 1.2em;
+ margin-bottom: 0.8em;
+}
+
+a {
+ color: #15c;
+ text-decoration: underline;
+}
+
+a:active {
+ color: #052577;
+}
+
+/* Don't wrap text for important stuff. */
+h1, h2, h3, .rule > label {
+ white-space: nowrap;
+}
+
+/* Hide rules & options if the extension is off. */
+.disabled #RuleManagement,.disabled #HttpNowhere {
+ display: none;
+}
+
+/* Initially hide section (until rules get added). */
+section.rules {
+ display: none;
+}
+
+.rule {
+ height: 25px;
+}
+
+.rule label {
+ padding: 0;
+ max-width: 93%;
+ overflow: hidden;
+}
+
+/* Underline rules that have notes. */
+.rule[title] span {
+ border-bottom: 1px dotted;
+ cursor: help;
+}
+
+input[type='checkbox'] {
+ vertical-align: middle;
+}
+
+.rule img.remove {
+ float: right;
+}
+
+header {
+ border-bottom: 1px solid #eee;
+}
+
+header > h1 {
+ margin: 0;
+ padding: 21px 0 13px;
+}
+
+section {
+ padding-left: 18px;
+ padding-top: 9px;
+ padding-bottom: 9px;
+}
+
+section > h3 {
+ margin-left: -18px;
+}
+
+footer {
+ border-top: 1px solid #eee;
+ margin-top: 8px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+
+/* By default the "Add a rule" link is hidden. It's shown on HTTPS sites only. */
+#add-rule-link {
+ display: none;
+}
+
+#rulesets-versions{
+ display: block;
+ clear: both;
+}
+
+.rulesets-version{
+ display: block;
+}
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]));
+}