summaryrefslogtreecommitdiff
path: root/data/extensions/https-everywhere-eff@eff.org/chrome/content/code/AndroidUI.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/https-everywhere-eff@eff.org/chrome/content/code/AndroidUI.jsm')
-rw-r--r--data/extensions/https-everywhere-eff@eff.org/chrome/content/code/AndroidUI.jsm236
1 files changed, 236 insertions, 0 deletions
diff --git a/data/extensions/https-everywhere-eff@eff.org/chrome/content/code/AndroidUI.jsm b/data/extensions/https-everywhere-eff@eff.org/chrome/content/code/AndroidUI.jsm
new file mode 100644
index 0000000..1a4936d
--- /dev/null
+++ b/data/extensions/https-everywhere-eff@eff.org/chrome/content/code/AndroidUI.jsm
@@ -0,0 +1,236 @@
+const CC = Components.classes;
+const CI = Components.interfaces;
+const CU = Components.utils;
+
+var HTTPSEverywhere = CC["@eff.org/https-everywhere;1"]
+ .getService(CI.nsISupports).wrappedJSObject;
+
+CU.import("resource://gre/modules/Prompt.jsm");
+
+var menuId;
+var urlbarId;
+var aWindow = getWindow();
+
+
+/*
+ * Setup/Teardown for the UI
+ */
+
+function loadIntoWindow() {
+ if (!aWindow) {
+ return;
+ }
+ var enabled = HTTPSEverywhere.prefs.getBoolPref("globalEnabled");
+ addToggleItemToMenu(enabled);
+ if (enabled) {
+ urlbarId = aWindow.NativeWindow.pageactions.add(urlbarOptions);
+ } else if (urlbarId) {
+ aWindow.NativeWindow.pageactions.remove(urlbarId);
+ }
+
+ // When navigating away from a page, we want to clear the applicable list for
+ // that page. There are a few different APIs to do this, but this is the one
+ // that work on mobile. We trigger on pagehide rather than pageshow because we
+ // want to capture subresources during load.
+ var BrowserApp = aWindow.BrowserApp;
+ BrowserApp.deck.addEventListener("pagehide", function(evt) {
+ var browser = BrowserApp.getBrowserForDocument(evt.target);
+ HTTPSEverywhere.resetApplicableList(browser);
+ }, true);
+}
+
+function unloadFromWindow() {
+ if (!aWindow) {
+ return;
+ }
+ aWindow.NativeWindow.menu.remove(menuId);
+ aWindow.NativeWindow.pageactions.remove(urlbarId);
+}
+
+
+/*
+ * Add a menu item to toggle HTTPS Everywhere
+ */
+
+function addToggleItemToMenu(enabled) {
+ if (menuId) { aWindow.NativeWindow.menu.remove(menuId); }
+ var menuLabel = enabled ? "HTTPS Everywhere on" : "HTTPS Everywhere off";
+ menuId = aWindow.NativeWindow.menu.add(menuLabel, null, function() {
+ popupToggleMenu(aWindow, enabled);
+ });
+}
+
+function popupToggleMenu(aWindow, enabled) {
+ var buttons = [
+ {
+ label: "Yes",
+ callback: function() {
+ toggleEnabledState();
+ var msg = enabled ? "HTTPS Everywhere disabled!" : "HTTPS Everywhere enabled!";
+ aWindow.NativeWindow.toast.show(msg, "short");
+ return true;
+ }
+ }, {
+ label: "No",
+ callback: function() { return false; }
+ }
+ ];
+ var newState = enabled ? "off?" : "on?";
+ aWindow.NativeWindow.doorhanger.show("Would you like to turn HTTPS Everywhere "+newState,
+ "doorhanger-toggle", buttons);
+}
+
+
+/*
+ * The HTTPS Everywhere icon in the URL bar shows a popup of rules that the
+ * user can activate/deactivate. On long click, reset all rules to defaults.
+ */
+
+var popupInfo = {
+ rules: [],
+ ruleItems: [],
+ ruleStatus: [],
+ alist: null,
+ getApplicableList: function() {
+ var browser = aWindow.BrowserApp.selectedBrowser;
+ return HTTPSEverywhere.getApplicableListForBrowser(browser);
+ },
+ fill: function() {
+ this.clear();
+ this.alist = this.getApplicableList();
+ HTTPSEverywhere.log(4,"applicable list active: "+JSON.stringify(this.alist.active));
+ HTTPSEverywhere.log(4,"applicable list inactive: "+JSON.stringify(this.alist.inactive));
+ for (var rule in this.alist.all) {
+ if (this.alist.active.hasOwnProperty(rule)) {
+ // active rules are checked and toggleable
+ this.ruleItems.push({ label: rule, selected: true });
+ this.ruleStatus.push(true);
+ this.rules.push(this.alist.active[rule]);
+ } else if (this.alist.moot.hasOwnProperty(rule)) {
+ // moot rules are checked and toggleable too
+ this.ruleItems.push({ label: rule, selected: true });
+ this.ruleStatus.push(true);
+ this.rules.push(this.alist.moot[rule]);
+ } else if (this.alist.inactive.hasOwnProperty(rule)) {
+ // inactive rules are unchecked and toggleable
+ this.ruleItems.push({ label: rule });
+ this.ruleStatus.push(false);
+ this.rules.push(this.alist.inactive[rule]);
+ } else if (this.alist.breaking.hasOwnProperty(rule)) {
+ // breaking rules are get a unicode clockwise arrow next to them
+ var ruleLabel = "\u21B7"+rule;
+ var isSelected = this.alist.breaking[rule].active;
+ this.ruleItems.push({ label: ruleLabel, selected: isSelected });
+ this.ruleStatus.push(isSelected);
+ this.rules.push(this.alist.breaking[rule]);
+ }
+ }
+ },
+ clear: function() {
+ this.rules = [];
+ this.ruleItems = [];
+ this.ruleStatus = [];
+ this.alist = {};
+ }
+};
+
+var urlbarOptions = {
+
+ title: "HTTPS Everywhere",
+
+ icon: "chrome://https-everywhere/skin/https-everywhere-128.png",
+
+ clickCallback: function() {
+ popupInfo.fill();
+ rulesPrompt.setMultiChoiceItems(popupInfo.ruleItems);
+ rulesPrompt.show(function(data) {
+ var db = data.button;
+ if (db === -1) { return null; } // user didn't click the accept button
+ if (popupInfo.rules.length !== db.length) {
+ // Why does db sometimes have an extra entry that doesn't correspond
+ // to any of the ruleItems? No idea, but let's log it.
+ HTTPSEverywhere.log(5,"Got length mismatch between popupInfo.ruleItems and data.button");
+ HTTPSEverywhere.log(4,"Applicable rules: "+JSON.stringify(popupInfo.rules));
+ HTTPSEverywhere.log(4, "data.button: "+JSON.stringify(db));
+ }
+ for (var i=0; i<popupInfo.rules.length; i++) {
+ if (popupInfo.ruleStatus[i] !== db[i]) {
+ HTTPSEverywhere.log(4, "toggling: "+JSON.stringify(popupInfo.rules[i]));
+ popupInfo.rules[i].toggle();
+ }
+ }
+ reloadTab();
+ return null;
+ });
+ },
+
+ longClickCallback: function() { popupResetDefaultsMenu(aWindow); }
+};
+
+var rulesPrompt = new Prompt({
+ window: aWindow,
+ title: "Enable/disable rules",
+ buttons: ["Apply changes"]
+});
+
+function popupResetDefaultsMenu(aWindow) {
+ var buttons = [
+ {
+ label: "Yes",
+ callback: function() {
+ resetToDefaults();
+ var msg = "Default rules reset.";
+ aWindow.NativeWindow.toast.show(msg, "short");
+ return true;
+ }
+ }, {
+ label: "No",
+ callback: function() { return false; }
+ }
+ ];
+ aWindow.NativeWindow.doorhanger.show("Reset all HTTPS Everywhere rules to defaults?",
+ "doorhanger-reset", buttons);
+}
+
+
+/*
+ * Some useful utils
+ */
+
+function reloadTab() {
+ // There seems to be no API to do this directly?
+ aWindow.BrowserApp.selectedTab.window.location.reload();
+}
+
+function toggleEnabledState(){
+ HTTPSEverywhere.toggleEnabledState();
+ loadIntoWindow();
+ reloadTab();
+}
+
+function resetToDefaults() {
+ HTTPSEverywhere.https_rules.resetRulesetsToDefaults();
+ reloadTab();
+}
+
+function getWindow() {
+ return CC['@mozilla.org/appshell/window-mediator;1']
+ .getService(CI.nsIWindowMediator)
+ .getMostRecentWindow('navigator:browser');
+}
+
+
+/*
+ * Here's the external API to this UI module
+ */
+
+var AndroidUI = {
+ init: function() {
+ loadIntoWindow();
+ },
+ shutdown: function() {
+ unloadFromWindow();
+ }
+};
+
+var EXPORTED_SYMBOLS = ["AndroidUI"];