Bug 1507001 - Remove command controller from outgoing attachments pane. r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Wed, 14 Nov 2018 20:36:53 +1300
changeset 32872 e19bd82baf3c10ea00b1fef5754b3e2021646609
parent 32871 465c90ec3466efeac4e52f3696d889069f23ca2a
child 32873 8ca96cbae03df48764aae6ab431b91164f16fd9b
push id2343
push userclokep@gmail.com
push dateMon, 10 Dec 2018 21:37:21 +0000
treeherdercomm-beta@a0750c375f71 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1507001
Bug 1507001 - Remove command controller from outgoing attachments pane. r=mkmelin
mail/components/preferences/applications.inc.xul
mail/components/preferences/applications.js
--- a/mail/components/preferences/applications.inc.xul
+++ b/mail/components/preferences/applications.inc.xul
@@ -52,30 +52,16 @@
     <script type="application/javascript"
             src="chrome://messenger/content/preferences/applications.js"/>
 
     <commandset id="appPaneCommandSet">
       <command id="cmd_delete"
                oncommand="gApplicationsPane.onDelete();"/>
     </commandset>
 
-    <commandset id="cloudFileCommandSet">
-      <commandset id="cloudFileCommandSetUpdate"
-                  commandupdater="true"
-                  events="focus"
-                  oncommandupdate="CommandUpdate_CloudFile()"/>
-      <command id="cmd_addCloudfileAccount"
-               oncommand="goDoCommand('cmd_addCloudfileAccount');"/>
-      <command id="cmd_removeCloudfileAccount"
-               oncommand="goDoCommand('cmd_removeCloudfileAccount');"/>
-      <command id="cmd_reauthCloudfileAccount"
-               oncommand="goDoCommand('cmd_reauthCloudfileAccount');"/>
-
-    </commandset>
-
     <keyset id="appPaneKeyset">
       <key keycode="VK_BACK" modifiers="any" command="cmd_delete"/>
       <key keycode="VK_DELETE" modifiers="any" command="cmd_delete"/>
     </keyset>
 
     <keyset>
       <key key="&focusSearch1.key;" modifiers="accel"
            oncommand="gApplicationsPane.focusFilterBox();"/>
@@ -171,23 +157,27 @@
             <hbox flex="1">
               <vbox id="provider-listing">
                 <richlistbox id="cloudFileView" orient="vertical" flex="1"
                              seltype="single"
                              onselect="gCloudFileTab.onSelectionChanged();">
                 </richlistbox>
                 <separator class="thin"/>
                 <hbox>
-                  <button id="addCloudFileAccount" flex="1" label="&addCloudFileAccount1.label;"
+                  <button id="addCloudFileAccount"
+                          flex="1"
+                          label="&addCloudFileAccount1.label;"
                           accesskey="&addCloudFileAccount1.accesskey;"
-                          command="cmd_addCloudfileAccount"/>
-                  <button id="removeCloudFileAccount" flex="1"
+                          oncommand="gCloudFileTab.addCloudFileAccount();"/>
+                  <button id="removeCloudFileAccount"
+                          flex="1"
+                          disabled="true"
                           label="&removeCloudFileAccount.label;"
                           accesskey="&removeCloudFileAccount.accesskey;"
-                          command="cmd_removeCloudfileAccount"/>
+                          oncommand="gCloudFileTab.removeCloudFileAccount();"/>
                 </hbox>
               </vbox>
               <vbox flex="1">
                 <deck id="cloudFileSettingsDeck" flex="1">
                   <vbox id="cloudFileDefaultPanel" flex="1">
                     <description>&addCloudFileAccount.description;</description>
                   </vbox>
                   <vbox id="cloudFileSettingsWrapper" flex="1">
@@ -204,17 +194,20 @@
                     <hbox>
                       <spring flex="1"/>
                         <image id="authImage"/>
                       <spring flex="1"/>
                     </hbox>
                     <description id="authMessage">&authRequired.description;</description>
                     <hbox>
                       <spring flex="1"/>
-                        <button command="cmd_reauthCloudfileAccount" label="&authRequired.button.label;" accesskey="&authRequired.button.accesskey;"/>
+                        <button id="reauthCloudFileAccount"
+                                label="&authRequired.button.label;"
+                                accesskey="&authRequired.button.accesskey;"
+                                oncommand="gCloudFileTab.authSelected();"/>
                       <spring flex="1"/>
                      </hbox>
                     <spacer flex="1"/>
                   </vbox>
                 </deck>
               </vbox>
             </hbox>
           </vbox>
--- a/mail/components/preferences/applications.js
+++ b/mail/components/preferences/applications.js
@@ -2,18 +2,16 @@
  * 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/. */
 
 // applications.inc.xul
 /* globals ICON_URL_APP */
 // mail/base/content/contentAreaClick.js
 /* globals openLinkExternally */
-// toolkit/content/globalOverlay.js
-/* globals goUpdateCommand */
 
 // ------------------------------
 // Constants & Enumeration Values
 
 var PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types";
 
 // Preferences that affect which entries to show in the list.
 var PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list";
@@ -39,17 +37,16 @@ ChromeUtils.import("resource://gre/modul
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 XPCOMUtils.defineLazyServiceGetters(this, {
   gCategoryManager: ["@mozilla.org/categorymanager;1", "nsICategoryManager"],
   gHandlerService: ["@mozilla.org/uriloader/handler-service;1", "nsIHandlerService"],
   gMIMEService: ["@mozilla.org/mime;1", "nsIMIMEService"],
 });
 
-
 // ---------
 // Utilities
 
 function getDisplayNameForFile(aFile) {
   if (AppConstants.platform == "win") {
     if (aFile instanceof Ci.nsILocalFileWin) {
       try {
         return aFile.getVersionInfoField("FileDescription");
@@ -555,77 +552,16 @@ var gApplicationsTabController = {
     if (this.mInitialized)
       document.getElementById("mail.preferences.applications.selectedTabIndex")
               .valueFromPreferences = document.getElementById("attachmentPrefs")
               .selectedIndex;
   },
 
 };
 
-var gCloudFileController = {
-  commands: {
-    cmd_addCloudfileAccount: {
-      isEnabled() {
-        return true;
-      },
-      doCommand() {
-        gCloudFileTab.addCloudFileAccount();
-      },
-    },
-
-    cmd_removeCloudfileAccount: {
-      isEnabled() {
-        let listbox = document.getElementById("cloudFileView");
-        return listbox.selectedCount > 0;
-      },
-      doCommand() {
-        gCloudFileTab.removeCloudFileAccount();
-      },
-    },
-
-    cmd_reauthCloudfileAccount: {
-      isEnabled() {
-        return true;
-      },
-      doCommand() {
-        gCloudFileTab.authSelected();
-      },
-    },
-
-  },
-
-  supportsCommand(aCommand) {
-    return (aCommand in this.commands);
-  },
-
-  isCommandEnabled(aCommand) {
-    if (!this.supportsCommand(aCommand))
-      return false;
-    return this.commands[aCommand].isEnabled();
-  },
-
-  doCommand(aCommand) {
-    if (!this.supportsCommand(aCommand))
-      return;
-
-    let cmd = this.commands[aCommand];
-
-    if (!cmd.isEnabled())
-      return;
-
-    cmd.doCommand();
-  },
-  onEvent(event) {},
-};
-
-function CommandUpdate_CloudFile() {
-  goUpdateCommand("cmd_removeCloudfileAccount");
-  goUpdateCommand("cmd_addCloudfileAccount");
-}
-
 var gCloudFileTab = {
   _initialized: false,
   _list: null,
   _settings: null,
   _settingsDeck: null,
   _tabpanel: null,
   _accountCache: {},
   _settingsPanelWrap: null,
@@ -638,47 +574,42 @@ var gCloudFileTab = {
                    .createBundle("chrome://messenger/locale/preferences/applications.properties");
   },
 
   init() {
     if (this._initialized)
       return;
 
     this._list = document.getElementById("cloudFileView");
+    this._removeAccountButton = document.getElementById("removeCloudFileAccount");
     this._settingsDeck = document.getElementById("cloudFileSettingsDeck");
     this._defaultPanel = document.getElementById("cloudFileDefaultPanel");
     this._settingsPanelWrap = document.getElementById("cloudFileSettingsWrapper");
     this._loadingPanel = document.getElementById("cloudFileLoadingPanel");
     this._authErrorPanel = document.getElementById("cloudFileAuthErrorPanel");
 
-    top.controllers.appendController(gCloudFileController);
-
     this.rebuildView();
 
-    if (this._list.itemCount > 0)
+    if (this._list.itemCount > 0) {
       this._list.selectedIndex = 0;
+      this._removeAccountButton.disabled = false;
+    }
 
     window.addEventListener("unload", this, {capture: false, once: true});
 
-    // We need to defer the command updating a bit otherwise it will happen too early.
-    window.addEventListener("load", () => {
-      setTimeout(CommandUpdate_CloudFile, 0);
-    }, {capture: false, once: true});
-
     this.updateThreshold();
 
     this._initialized = true;
   },
 
-  destroy: function CFT_destroy() {
+  destroy() {
     // Remove any controllers or observers here.
-    top.controllers.removeController(gCloudFileController);
   },
 
-  makeRichListItemForAccount: function CFT_makeRichListItemForAccount(aAccount) {
+  makeRichListItemForAccount(aAccount) {
     let rli = document.createElement("richlistitem");
     rli.value = aAccount.accountKey;
     rli.setAttribute("value", aAccount.accountKey);
     rli.setAttribute("class", "cloudfileAccount");
     rli.setAttribute("state", "waiting-to-connect");
 
     if (aAccount.iconClass)
       rli.style.listStyleImage = "url('" + aAccount.iconClass + "')";
@@ -698,23 +629,23 @@ var gCloudFileTab = {
       let result = this._accountCache[aAccount.accountKey].result;
       this._mapResultToState(rli, result);
       this._accountCache[aAccount.accountKey].listItem = rli;
     }
 
     return rli;
   },
 
-  clearEntries: function CFT_clearEntries() {
+  clearEntries() {
     // Clear the list of entries.
     while (this._list.hasChildNodes())
       this._list.lastChild.remove();
   },
 
-  rebuildView: function CFT_rebuildView() {
+  rebuildView() {
     this.clearEntries();
     let accounts = cloudFileAccounts.accounts;
 
     // Sort the accounts by displayName.
     function sortAccounts(a, b) {
       let aName = cloudFileAccounts.getDisplayName(a.accountKey)
                                    .toLowerCase();
       let bName = cloudFileAccounts.getDisplayName(b.accountKey)
@@ -732,17 +663,17 @@ var gCloudFileTab = {
     for (let account of accounts) {
       let rli = this.makeRichListItemForAccount(account);
       this._list.appendChild(rli);
       if (!(account.accountKey in this._accountCache))
         this.requestUserInfoForItem(rli, false);
     }
   },
 
-  requestUserInfoForItem: function CFT_requestUserInfoForItem(aItem, aWithUI) {
+  requestUserInfoForItem(aItem, aWithUI) {
     let accountKey = aItem.value;
     let account = cloudFileAccounts.getAccount(accountKey);
 
     let observer = {
       onStopRequest(aRequest, aContext, aStatusCode) {
         gCloudFileTab._accountCache[accountKey].result = aStatusCode;
         gCloudFileTab.onUserInfoRequestDone(accountKey);
       },
@@ -758,143 +689,141 @@ var gCloudFileTab = {
     };
 
     this._accountCache[accountKey] = accountInfo;
 
     this._settingsDeck.selectedPanel = this._loadingPanel;
     account.refreshUserInfo(aWithUI, observer);
   },
 
-  onUserInfoRequestDone: function CFT_onUserInfoRequestDone(aAccountKey) {
+  onUserInfoRequestDone(aAccountKey) {
     this.updateRichListItem(aAccountKey);
 
     if (this._list.selectedItem &&
         this._list.selectedItem.value == aAccountKey)
       this._showAccountInfo(aAccountKey);
   },
 
-  updateRichListItem: function CFT_updateRichListItem(aAccountKey) {
+  updateRichListItem(aAccountKey) {
     let accountInfo = this._accountCache[aAccountKey];
     if (!accountInfo)
       return;
 
     let item = accountInfo.listItem;
     let result = accountInfo.result;
     this._mapResultToState(item, result);
   },
 
-  _mapResultToState: function CFT__mapResultToState(aItem, aResult) {
+  _mapResultToState(aItem, aResult) {
     let itemState = "no-connection";
 
     if (aResult == Cr.NS_OK)
       itemState = "connected";
     else if (aResult == Ci.nsIMsgCloudFileProvider.authErr)
       itemState = "auth-error";
     else if (aResult == Cr.NS_ERROR_NOT_AVAILABLE)
       itemState = "no-connection";
     // TODO: What other states are there?
 
     aItem.setAttribute("state", itemState);
   },
 
-
-  onSelectionChanged: function CFT_onSelectionChanged() {
+  onSelectionChanged() {
     // Get the selected item
     let selection = this._list.selectedItem;
+    this._removeAccountButton.disabled = !selection;
     if (!selection)
       return;
 
     // The selection tells us the key.  We need the actual
     // provider here.
     let accountKey = selection.value;
     this._showAccountInfo(accountKey);
   },
 
-  _showAccountInfo: function CFT__showAccountInfo(aAccountKey) {
+  _showAccountInfo(aAccountKey) {
     let account = this._accountCache[aAccountKey].account;
     let result = this._accountCache[aAccountKey].result;
 
-    if (result == Cr.NS_ERROR_NOT_AVAILABLE)
+    if (result == Cr.NS_ERROR_NOT_AVAILABLE) {
       this._settingsDeck.selectedPanel = this._loadingPanel;
-    else if (result == Cr.NS_OK) {
+    } else if (result == Cr.NS_OK) {
       this._settingsDeck.selectedPanel = this._settingsPanelWrap;
       this._showAccountManagement(account);
     } else if (result == Ci.nsIMsgCloudFileProvider.authErr) {
       this._settingsDeck.selectedPanel = this._authErrorPanel;
     } else {
       Cu.reportError("Unexpected connection error.");
     }
   },
 
-  _showAccountManagement: function CFT__showAccountManagement(aProvider) {
+  _showAccountManagement(aProvider) {
     let iframe = document.createElement("iframe");
 
     iframe.setAttribute("src", aProvider.managementURL);
     iframe.setAttribute("flex", "1");
 
     // If we have a past iframe, we replace it. Else append
     // to the wrapper.
     if (this._settings)
       this._settings.remove();
 
     this._settingsPanelWrap.appendChild(iframe);
     this._settings = iframe;
 
     // When the iframe loads, populate it with the provider.
-    this._settings.contentWindow.addEventListener("load",
-      function loadProvider() {
-        try {
-          iframe.contentWindow
-                .wrappedJSObject
-                .onLoadProvider(aProvider);
-        } catch (e) {
-          Cu.reportError(e);
-        }
-      }, {capture: false, once: true});
+    this._settings.contentWindow.addEventListener("load", function() {
+      try {
+        iframe.contentWindow
+              .wrappedJSObject
+              .onLoadProvider(aProvider);
+      } catch (e) {
+        Cu.reportError(e);
+      }
+    }, {capture: false, once: true});
 
     // When the iframe (or any subcontent) fires the DOMContentLoaded event,
     // attach the _onClickLink handler to any anchor elements that we can find.
-    this._settings.contentWindow.addEventListener("DOMContentLoaded",
-      function addClickListeners(e) {
-        let doc = e.originalTarget;
-        let links = doc.getElementsByTagName("a");
+    this._settings.contentWindow.addEventListener("DOMContentLoaded", function(e) {
+      let doc = e.originalTarget;
+      let links = doc.getElementsByTagName("a");
 
-        for (let link of links)
-          link.addEventListener("click", gCloudFileTab._onClickLink);
-      }, {capture: false, once: true});
-
-    CommandUpdate_CloudFile();
+      for (let link of links) {
+        link.addEventListener("click", gCloudFileTab._onClickLink);
+      }
+    }, {capture: false, once: true});
   },
 
-  _onClickLink: function CFT__onClickLink(aEvent) {
+  _onClickLink(aEvent) {
     aEvent.preventDefault();
     let href = aEvent.target.getAttribute("href");
     openLinkExternally(href);
   },
 
-  authSelected: function CFT_authSelected() {
+  authSelected() {
     let item = this._list.selectedItem;
 
     if (!item)
       return;
 
     this.requestUserInfoForItem(item, true);
   },
 
-  addCloudFileAccount: function CFT_addCloudFileAccount() {
+  addCloudFileAccount() {
     let accountKey = cloudFileAccounts.addAccountDialog();
     if (!accountKey)
       return;
 
     this.rebuildView();
     let newItem = this._list.querySelector("richlistitem[value='" + accountKey + "']");
     this._list.selectItem(newItem);
+    this._removeAccountButton.disabled = false;
   },
 
-  removeCloudFileAccount: function CFT_removeCloudFileAccount() {
+  removeCloudFileAccount() {
     // Get the selected account key
     let selection = this._list.selectedItem;
     if (!selection)
       return;
 
     let accountKey = selection.value;
     let accountName = cloudFileAccounts.getDisplayName(accountKey);
     // Does the user really want to remove this account?
@@ -903,39 +832,38 @@ var gCloudFileTab = {
                                                    [accountName], 1);
 
     if (Services.prompt.confirm(null, "", confirmMessage)) {
       this._list.clearSelection();
       cloudFileAccounts.removeAccount(accountKey);
       this.rebuildView();
       this._settingsDeck.selectedPanel = this._defaultPanel;
       delete this._accountCache[accountKey];
-      // For some reason, the focus event isn't fired, so I think
-      // we have to update the buttons manually...
-      CommandUpdate_CloudFile();
+
+      this._removeAccountButton.disabled = (this._list.selectedCount == 0);
     }
   },
 
-  handleEvent: function CFT_handleEvent(aEvent) {
+  handleEvent(aEvent) {
     if (aEvent.type == "unload")
       this.destroy();
   },
 
-  readThreshold: function CFT_readThreshold() {
+  readThreshold() {
     let pref = document.getElementById("mail.compose.big_attachments.threshold_kb");
     return pref.value / 1024;
   },
 
-  writeThreshold: function CFT_writeThreshold() {
+  writeThreshold() {
     let threshold = document.getElementById("cloudFileThreshold");
     let intValue = parseInt(threshold.value, 10);
     return isNaN(intValue) ? 0 : intValue * 1024;
   },
 
-  updateThreshold: function CFT_updateThreshold() {
+  updateThreshold() {
     document.getElementById("cloudFileThreshold").disabled =
     !document.getElementById("enableThreshold").checked;
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsIObserver",
                                           "nsISupportsWeakReference"]),
 };
 
@@ -957,17 +885,16 @@ var gApplicationsPane = {
   _visibleTypes: [],
 
   // Map whose keys are string descriptions and values are references to the
   // first visible HandlerInfoWrapper that has this description. We use this
   // to determine whether or not to annotate descriptions with their types to
   // distinguish duplicate descriptions from each other.
   _visibleDescriptions: new Map(),
 
-
   // -----------------------------------
   // Convenience & Performance Shortcuts
 
   // These get defined by init().
   _brandShortName: null,
   _prefsBundle: null,
   _list: null,
   _filter: null,
@@ -1681,19 +1608,19 @@ var gApplicationsPane = {
       });
     }
   },
 
   confirmDelete(aEvent) {
     aEvent.stopPropagation();
     if (Services.prompt.confirm(null,
                                 this._prefsBundle.getString("confirmDeleteTitle"),
-                                this._prefsBundle.getString("confirmDeleteText")))
+                                this._prefsBundle.getString("confirmDeleteText"))) {
       this.onDelete(aEvent);
-    else {
+    } else {
       // They hit cancel, so return them to the previously selected item.
       let menu = document.getAnonymousElementByAttribute(this._list.selectedItem,
                                                          "class", "actionsMenu");
       menu.selectedItem = menu.previousSelectedItem;
     }
   },
 
   onDelete(aEvent) {