Bug 1542717 - [de-xbl] convert map-list binding to <menupopup is='map-list'>. r=mkmelin
authorKhushil Mistry <khushil324@gmail.com>
Sun, 14 Apr 2019 00:02:55 +0200
changeset 26335 bddc7eeb6720ddcaf31bdafc85d47166d0414a5a
parent 26334 f57c1c1b7400d272bfd2cd6015cd1942e193e9bf
child 26336 0696198c7fa8d9b6157113e1ddabd6162fc444e2
push id15790
push usermozilla@jorgk.com
push dateSat, 13 Apr 2019 22:04:23 +0000
treeherdercomm-central@bddc7eeb6720 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1542717
Bug 1542717 - [de-xbl] convert map-list binding to <menupopup is='map-list'>. r=mkmelin
mail/base/content/messenger.css
mail/components/addrbook/content/addressbook.xul
mailnews/addrbook/content/addrbookWidgets.xml
mailnews/addrbook/content/map-list.js
mailnews/jar.mn
--- a/mail/base/content/messenger.css
+++ b/mail/base/content/messenger.css
@@ -74,20 +74,16 @@ tabmail {
 menupopup[type="folder"] {
   -moz-binding: url("chrome://messenger/content/folderWidgets.xml#folder-menupopup");
 }
 
 .addrbooksPopup {
   -moz-binding: url("chrome://messenger/content/addressbook/addrbookWidgets.xml#addrbooks-menupopup");
 }
 
-.map-list {
-  -moz-binding: url("chrome://messenger/content/addressbook/addrbookWidgets.xml#map-list");
-}
-
 .chromeclass-toolbar {
   overflow-x: hidden;
 }
 
 /* Lightweight themes support */
 
 :root:-moz-lwtheme {
   --toolbar-color: var(--lwt-text-color, inherit);
--- a/mail/components/addrbook/content/addressbook.xul
+++ b/mail/components/addrbook/content/addressbook.xul
@@ -41,16 +41,17 @@
   </stringbundleset>
 
 <script type="application/javascript" src="chrome://messenger/content/jsTreeView.js"/>
 <script type="application/javascript" src="chrome://messenger/content/addressbook/abTrees.js"/>
 <script type="application/javascript" src="chrome://messenger/content/accountUtils.js"/>
 <script type="application/javascript" src="chrome://messenger/content/mailCore.js"/>
 <script type="application/javascript" src="chrome://messenger/content/mail-compacttheme.js"/>
 <script type="application/javascript" src="chrome://messenger/content/addressbook/addressbook.js"/>
+<script type="application/javascript" src="chrome://messenger/content/addressbook/map-list.js"/>
 <script type="application/javascript" src="chrome://messenger/content/addressbook/abCommon.js"/>
 <script type="application/javascript" src="chrome://communicator/content/contentAreaClick.js"/>
 <script type="application/javascript" src="chrome://global/content/printUtils.js"/>
 <script type="application/javascript" src="chrome://messenger/content/msgPrintEngine.js"/>
 
 <!-- move needed functions into a single js file -->
 <script type="application/javascript" src="chrome://communicator/content/utilityOverlay.js"/>
 <script type="application/javascript" src="chrome://global/content/nsDragAndDrop.js"/>
@@ -812,17 +813,17 @@
                         <description class="CardViewText" id="cvHomeCountry"/>
                       </vbox>
                       <vbox id="cvbHomeMapItBox" pack="end">
                         <button id="cvHomeMapIt"
                                 label="&mapItButton.label;"
                                 type="menu-button"
                                 oncommand="openLinkWithUrl(this.firstChild.mapURL);"
                                 tooltiptext="&mapIt.tooltip;">
-                          <menupopup class="map-list"/>
+                          <menupopup is="map-list"/>
                         </button>
                       </vbox>
                     </hbox>
                     <description class="CardViewLink" id="cvHomeWebPageBox">
                       <html:a onclick="return openLink('cvHomeWebPage');" href="" id="cvHomeWebPage"/>
                     </description>
                   </vbox>
                   <vbox id="cvbOther" class="cardViewGroup">
@@ -881,17 +882,17 @@
                         <description class="CardViewText" id="cvWorkCountry"/>
                       </vbox>
                       <vbox id="cvbWorkMapItBox" pack="end">
                         <button id="cvWorkMapIt"
                                 label="&mapItButton.label;"
                                 type="menu-button"
                                 oncommand="openLinkWithUrl(this.firstChild.mapURL);"
                                 tooltiptext="&mapIt.tooltip;">
-                          <menupopup class="map-list"/>
+                          <menupopup is="map-list"/>
                         </button>
                       </vbox>
                     </hbox>
                     <description class="CardViewLink" id="cvWorkWebPageBox">
                       <html:a onclick="return openLink('cvWorkWebPage');" href="" id="cvWorkWebPage"/>
                     </description>
                   </vbox>
                 </vbox>
--- a/mailnews/addrbook/content/addrbookWidgets.xml
+++ b/mailnews/addrbook/content/addrbookWidgets.xml
@@ -290,247 +290,9 @@
             return 1;
 
           // Sort anything else by the dir type.
           return a.dirType - b.dirType;
         ]]></body>
       </method>
     </implementation>
   </binding>
-
-  <binding id="map-list"
-           extends="chrome://global/content/bindings/popup.xml#popup">
-    <implementation>
-      <property name="mapURL" readonly="true">
-        <getter><![CDATA[
-          return this._createMapItURL();
-        ]]></getter>
-      </property>
-
-      <constructor>
-        <![CDATA[
-          this._setWidgetDisabled(true);
-        ]]>
-      </constructor>
-
-      <!--
-        Initializes the necessary address data from an addressbook card.
-        @param aCard        A nsIAbCard to get the address data from.
-        @param aAddrPrefix  A prefix of the card properties to use. Use "Home" or "Work".
-        -->
-      <method name="initMapAddressFromCard">
-        <parameter name="aCard"/>
-        <parameter name="aAddrPrefix"/>
-        <body><![CDATA[
-          let mapItURLFormat = this._getMapURLPref(0);
-          let doNotShowMap = !mapItURLFormat || !aAddrPrefix || !aCard;
-          this._setWidgetDisabled(doNotShowMap);
-          if (doNotShowMap)
-            return;
-
-          this.setAttribute("map_address1", aCard.getProperty(aAddrPrefix + "Address"));
-          this.setAttribute("map_address2", aCard.getProperty(aAddrPrefix + "Address2"));
-          this.setAttribute("map_city", aCard.getProperty(aAddrPrefix + "City"));
-          this.setAttribute("map_state", aCard.getProperty(aAddrPrefix + "State"));
-          this.setAttribute("map_zip", aCard.getProperty(aAddrPrefix + "ZipCode"));
-          this.setAttribute("map_country", aCard.getProperty(aAddrPrefix + "Country"));
-        ]]></body>
-      </method>
-
-      <!--
-        Initializes the necessary address data from passed in values.
-        -->
-      <method name="initMapAddress">
-        <parameter name="aAddr1"/>
-        <parameter name="aAddr2"/>
-        <parameter name="aCity"/>
-        <parameter name="aState"/>
-        <parameter name="aZip"/>
-        <parameter name="aCountry"/>
-        <body><![CDATA[
-          let mapItURLFormat = this._getMapURLPref(0);
-          let doNotShowMap = !mapItURLFormat || !(aAddr1 + aAddr2 + aCity + aState + aZip + aCountry);
-          this._setWidgetDisabled(doNotShowMap);
-          if (doNotShowMap)
-            return;
-
-          this.setAttribute("map_address1", aAddr1);
-          this.setAttribute("map_address2", aAddr2);
-          this.setAttribute("map_city", aCity);
-          this.setAttribute("map_state", aState);
-          this.setAttribute("map_zip", aZip);
-          this.setAttribute("map_country", aCountry);
-        ]]></body>
-      </method>
-
-      <!--
-        Sets the disabled/enabled state of the parent widget (e.g. a button).
-        -->
-      <method name="_setWidgetDisabled">
-        <parameter name="aDisabled"/>
-        <body><![CDATA[
-          this.parentNode.disabled = aDisabled;
-        ]]></body>
-      </method>
-
-      <!--
-        Returns the Map service URL from localized pref. Returns null if there
-        is none at the given index.
-        @param aIndex  The index of the service to return. 0 is the default service.
-        -->
-      <method name="_getMapURLPref">
-        <parameter name="aIndex"/>
-        <body><![CDATA[
-          const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-          let url = null;
-          if (!aIndex) {
-            url = Services.prefs.getComplexValue("mail.addr_book.mapit_url.format",
-                                                 Ci.nsIPrefLocalizedString).data;
-          } else {
-            try {
-              url = Services.prefs.getComplexValue("mail.addr_book.mapit_url." + aIndex + ".format",
-                                                   Ci.nsIPrefLocalizedString).data;
-            } catch (e) {
-            }
-          }
-
-          return url;
-        ]]></body>
-      </method>
-
-      <!--
-        Builds menuitem elements representing map services defined in prefs
-        and attaches them to the specified button.
-        -->
-      <method name="_listMapServices">
-        <body><![CDATA[
-          const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-          let index = 1;
-          let itemFound = true;
-          let defaultFound = false;
-          const kUserIndex = 100;
-          let aMapList = this;
-          while (aMapList.hasChildNodes()) {
-            aMapList.lastChild.remove();
-          }
-
-          let defaultUrl = this._getMapURLPref(0);
-
-          // Creates the menuitem with supplied data.
-          function addMapService(aUrl, aName) {
-            let item = document.createElement("menuitem");
-            item.setAttribute("url", aUrl);
-            item.setAttribute("label", aName);
-            item.setAttribute("type", "radio");
-            item.setAttribute("name", "mapit_service");
-            if (aUrl == defaultUrl)
-              item.setAttribute("checked", "true");
-            aMapList.appendChild(item);
-          }
-
-          // Generates a useful generic name by cutting out only the host address.
-          function generateName(aUrl) {
-            return new URL(aUrl).hostname;
-          }
-
-          // Add all defined map services as menuitems.
-          while (itemFound) {
-            let urlName;
-            let urlTemplate = this._getMapURLPref(index);
-            if (!urlTemplate) {
-              itemFound = false;
-            } else {
-              // Name is not mandatory, generate one if not found.
-              try {
-                urlName = Services.prefs.getComplexValue("mail.addr_book.mapit_url." + index + ".name",
-                                                         Ci.nsIPrefLocalizedString).data;
-              } catch (e) {
-                urlName = generateName(urlTemplate);
-              }
-            }
-            if (itemFound) {
-              addMapService(urlTemplate, urlName);
-              index++;
-              if (urlTemplate == defaultUrl)
-                defaultFound = true;
-            } else if (index < kUserIndex) {
-              // After iterating the base region provided urls, check for user defined ones.
-              index = kUserIndex;
-              itemFound = true;
-            }
-          }
-          if (!defaultFound) {
-            // If user had put a customized map URL into mail.addr_book.mapit_url.format
-            // preserve it as a new map service named with the URL.
-            // 'index' now points to the first unused entry in prefs.
-            let defaultName = generateName(defaultUrl);
-            addMapService(defaultUrl, defaultName);
-            Services.prefs.setCharPref("mail.addr_book.mapit_url." + index + ".format",
-                                        defaultUrl);
-            Services.prefs.setCharPref("mail.addr_book.mapit_url." + index + ".name",
-                                        defaultName);
-          }
-        ]]></body>
-      </method>
-
-      <!--
-        Save user selected mapping service.
-        @param aItem  The chosen menuitem with map service.
-        -->
-      <method name="_chooseMapService">
-        <parameter name="aItem"/>
-        <body><![CDATA[
-          const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-          // Save selected URL as the default.
-          let defaultUrl = Cc["@mozilla.org/pref-localizedstring;1"]
-                             .createInstance(Ci.nsIPrefLocalizedString);
-          defaultUrl.data = aItem.getAttribute("url");
-          Services.prefs.setComplexValue("mail.addr_book.mapit_url.format",
-                                         Ci.nsIPrefLocalizedString, defaultUrl);
-        ]]></body>
-      </method>
-
-      <!--
-        Generate map URL in the href attribute.
-        -->
-      <method name="_createMapItURL">
-        <body><![CDATA[
-          let urlFormat = this._getMapURLPref(0);
-          if (!urlFormat)
-            return null;
-
-          let address1 = this.getAttribute("map_address1");
-          let address2 = this.getAttribute("map_address2");
-          let city     = this.getAttribute("map_city");
-          let state    = this.getAttribute("map_state");
-          let zip      = this.getAttribute("map_zip");
-          let country  = this.getAttribute("map_country");
-
-          urlFormat = urlFormat.replace("@A1", encodeURIComponent(address1));
-          urlFormat = urlFormat.replace("@A2", encodeURIComponent(address2));
-          urlFormat = urlFormat.replace("@CI", encodeURIComponent(city));
-          urlFormat = urlFormat.replace("@ST", encodeURIComponent(state));
-          urlFormat = urlFormat.replace("@ZI", encodeURIComponent(zip));
-          urlFormat = urlFormat.replace("@CO", encodeURIComponent(country));
-
-          return urlFormat;
-        ]]></body>
-      </method>
-    </implementation>
-
-    <handlers>
-      <handler event="command">
-        <![CDATA[
-          this._chooseMapService(event.target);
-          event.stopPropagation();
-        ]]>
-      </handler>
-      <handler event="popupshowing">
-        <![CDATA[
-          this._listMapServices();
-        ]]>
-      </handler>
-    </handlers>
-  </binding>
 </bindings>
new file mode 100644
--- /dev/null
+++ b/mailnews/addrbook/content/map-list.js
@@ -0,0 +1,198 @@
+/* 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/. */
+
+"use strict";
+
+/* global MozElements */
+{
+  const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+  /**
+   * The MozMapList widget behaves as a popup menu showing available map options
+   * for an address. It is a part of the card view in the addressbook.
+   *
+   * @extends {MozElements.MozMenuPopup}
+   */
+  class MozMapList extends MozElements.MozMenuPopup {
+    connectedCallback() {
+      if (this.delayConnectedCallback() || this.hasConnected) {
+        return;
+      }
+      this.setAttribute("is", "map-list");
+
+      this.addEventListener("command", (event) => {
+        this._chooseMapService(event.target);
+        event.stopPropagation();
+      });
+
+      this.addEventListener("popupshowing", (event) => {
+        this._listMapServices();
+      });
+
+      this._setWidgetDisabled(true);
+    }
+
+    get mapURL() {
+      return this._createMapItURL();
+    }
+
+    /**
+     * Initializes the necessary address data from an addressbook card.
+     * @param {nsIAbCard} card   - the card to get the addess data from
+     * @param {string} addPrefix - card property prefix: "Home" or "Work",
+     *                             to make the map use either HomeAddress
+     *                             or WorkAddress
+     */
+    initMapAddressFromCard(card, addrPrefix) {
+      let mapItURLFormat = this._getMapURLPref();
+      let doNotShowMap = !mapItURLFormat || !addrPrefix || !card;
+      this._setWidgetDisabled(doNotShowMap);
+      if (doNotShowMap) {
+        return;
+      }
+
+      this.address1 = card.getProperty(addrPrefix + "Address");
+      this.address2 = card.getProperty(addrPrefix + "Address2");
+      this.city = card.getProperty(addrPrefix + "City");
+      this._state = card.getProperty(addrPrefix + "State");
+      this.zip = card.getProperty(addrPrefix + "ZipCode");
+      this.country = card.getProperty(addrPrefix + "Country");
+    }
+
+    /**
+     * Sets the disabled/enabled state of the parent widget (e.g. a button).
+     */
+    _setWidgetDisabled(disabled) {
+      this.parentNode.disabled = disabled;
+    }
+
+    /**
+     * Returns the Map service URL from localized pref. Returns null if there
+     * is none at the given index.
+     * @param integer [index=0] - the index of the service to return. 0 is the default service.
+     */
+    _getMapURLPref(index = 0) {
+      let url = null;
+      if (!index) {
+        url = Services.prefs.getComplexValue("mail.addr_book.mapit_url.format",
+          Ci.nsIPrefLocalizedString).data;
+      } else {
+        try {
+          url = Services.prefs.getComplexValue("mail.addr_book.mapit_url." + index + ".format",
+            Ci.nsIPrefLocalizedString).data;
+        } catch (e) { }
+      }
+
+      return url;
+    }
+
+    /**
+     * Builds menuitem elements representing map services defined in prefs
+     * and attaches them to the specified button.
+     */
+    _listMapServices() {
+      let index = 1;
+      let itemFound = true;
+      let defaultFound = false;
+      const kUserIndex = 100;
+      let mapList = this;
+      while (mapList.hasChildNodes()) {
+        mapList.lastChild.remove();
+      }
+
+      let defaultUrl = this._getMapURLPref();
+
+      // Creates the menuitem with supplied data.
+      function addMapService(url, name) {
+        let item = document.createElement("menuitem");
+        item.setAttribute("url", url);
+        item.setAttribute("label", name);
+        item.setAttribute("type", "radio");
+        item.setAttribute("name", "mapit_service");
+        if (url == defaultUrl) {
+          item.setAttribute("checked", "true");
+        }
+        mapList.appendChild(item);
+      }
+
+      // Generates a useful generic name by cutting out only the host address.
+      function generateName(url) {
+        return new URL(url).hostname;
+      }
+
+      // Add all defined map services as menuitems.
+      while (itemFound) {
+        let urlName;
+        let urlTemplate = this._getMapURLPref(index);
+        if (!urlTemplate) {
+          itemFound = false;
+        } else {
+          // Name is not mandatory, generate one if not found.
+          try {
+            urlName = Services.prefs.getComplexValue("mail.addr_book.mapit_url." + index + ".name",
+              Ci.nsIPrefLocalizedString).data;
+          } catch (e) {
+            urlName = generateName(urlTemplate);
+          }
+        }
+        if (itemFound) {
+          addMapService(urlTemplate, urlName);
+          index++;
+          if (urlTemplate == defaultUrl)
+            defaultFound = true;
+        } else if (index < kUserIndex) {
+          // After iterating the base region provided urls, check for user defined ones.
+          index = kUserIndex;
+          itemFound = true;
+        }
+      }
+      if (!defaultFound) {
+        // If user had put a customized map URL into mail.addr_book.mapit_url.format
+        // preserve it as a new map service named with the URL.
+        // 'index' now points to the first unused entry in prefs.
+        let defaultName = generateName(defaultUrl);
+        addMapService(defaultUrl, defaultName);
+        Services.prefs.setCharPref("mail.addr_book.mapit_url." + index + ".format",
+          defaultUrl);
+        Services.prefs.setCharPref("mail.addr_book.mapit_url." + index + ".name",
+          defaultName);
+      }
+    }
+
+    /**
+     * Save user selected mapping service.
+     * @param item  The chosen menuitem with map service.
+     */
+    _chooseMapService(item) {
+      // Save selected URL as the default.
+      let defaultUrl = Cc["@mozilla.org/pref-localizedstring;1"]
+        .createInstance(Ci.nsIPrefLocalizedString);
+      defaultUrl.data = item.getAttribute("url");
+      Services.prefs.setComplexValue("mail.addr_book.mapit_url.format",
+        Ci.nsIPrefLocalizedString, defaultUrl);
+    }
+
+    /**
+     * Generate the map URL used to open the link on clicking the menulist button.
+     * @returns {urlFormat} - the map url generated from the address.
+     */
+    _createMapItURL() {
+      let urlFormat = this._getMapURLPref();
+      if (!urlFormat) {
+        return null;
+      }
+
+      urlFormat = urlFormat.replace("@A1", encodeURIComponent(this.address1));
+      urlFormat = urlFormat.replace("@A2", encodeURIComponent(this.address2));
+      urlFormat = urlFormat.replace("@CI", encodeURIComponent(this.city));
+      urlFormat = urlFormat.replace("@ST", encodeURIComponent(this._state));
+      urlFormat = urlFormat.replace("@ZI", encodeURIComponent(this.zip));
+      urlFormat = urlFormat.replace("@CO", encodeURIComponent(this.country));
+
+      return urlFormat;
+    }
+  }
+
+  customElements.define("map-list", MozMapList, { "extends": "menupopup" });
+}
--- a/mailnews/jar.mn
+++ b/mailnews/jar.mn
@@ -8,16 +8,17 @@ messenger.jar:
     content/messenger/addressbook/pref-editdirectories.js                      (addrbook/prefs/content/pref-editdirectories.js)
     content/messenger/addressbook/pref-editdirectories.xul                     (addrbook/prefs/content/pref-editdirectories.xul)
     content/messenger/addressbook/abAddressBookNameDialog.js                   (addrbook/content/abAddressBookNameDialog.js)
     content/messenger/addressbook/abAddressBookNameDialog.xul                  (addrbook/content/abAddressBookNameDialog.xul)
     content/messenger/addressbook/abResultsPane.js                             (addrbook/content/abResultsPane.js)
     content/messenger/addressbook/addrbookWidgets.xml                          (addrbook/content/addrbookWidgets.xml)
     content/messenger/addressbook/abDragDrop.js                                (addrbook/content/abDragDrop.js)
     content/messenger/addressbook/abMailListDialog.js                          (addrbook/content/abMailListDialog.js)
+    content/messenger/addressbook/map-list.js                                  (addrbook/content/map-list.js)
     content/messagebody/addressbook/print.css                                  (addrbook/content/print.css)
 *   content/messenger/AccountManager.xul                                       (base/prefs/content/AccountManager.xul)
     content/messenger/AccountManager.js                                        (base/prefs/content/AccountManager.js)
     content/messenger/am-main.xul                                              (base/prefs/content/am-main.xul)
     content/messenger/am-main.js                                               (base/prefs/content/am-main.js)
     content/messenger/am-help.js                                               (base/prefs/content/am-help.js)
     content/messenger/am-server.xul                                            (base/prefs/content/am-server.xul)
     content/messenger/am-serverwithnoidentities.xul                            (base/prefs/content/am-serverwithnoidentities.xul)