Bug 1535582 - nuke now unused bindings xbl-menulist, menulist-popuponly, menulist-editable, panellist, datetextpicker, datetimepicker-base, and fix menulist.css inclusion. r=darktrojan
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Sat, 16 Mar 2019 23:38:10 +0200
changeset 26110 34babfc74629
parent 26109 86cdbc8a3cef
child 26111 439caa176db6
push id15674
push usermozilla@jorgk.com
push dateSat, 16 Mar 2019 22:12:32 +0000
treeherdercomm-central@34babfc74629 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdarktrojan
bugs1535582
Bug 1535582 - nuke now unused bindings xbl-menulist, menulist-popuponly, menulist-editable, panellist, datetextpicker, datetimepicker-base, and fix menulist.css inclusion. r=darktrojan
calendar/base/content/dialogs/calendar-event-dialog-attendees.xul
calendar/base/content/dialogs/calendar-event-dialog-recurrence.xul
calendar/base/content/dialogs/calendar-event-dialog-reminder.xul
calendar/base/content/dialogs/calendar-event-dialog-timezone.xul
calendar/base/content/dialogs/calendar-event-dialog.xul
calendar/base/content/dialogs/calendar-print-dialog.xul
calendar/base/content/dialogs/calendar-summary-dialog.xul
calendar/lightning/content/lightning-item-iframe.xul
calendar/lightning/content/messenger-overlay-sidebar.xul
calendar/lightning/jar.mn
calendar/resources/content/datetimepickers/datetimepickers.css
calendar/resources/content/datetimepickers/datetimepickers.xml
calendar/resources/skin/datetimepickers.css
common/bindings/menulist.css
common/bindings/menulist.xml
editor/ui/dialogs/content/EdAdvancedEdit.xul
editor/ui/dialogs/content/EdFormProps.xul
editor/ui/dialogs/content/EditorPublish.xul
mail/base/content/bindings.css
mail/base/content/menulist.css
mail/base/jar.mn
mail/base/test/browser/files/menulist.xul
mail/components/accountcreation/content/emailWizard.xul
mail/components/compose/content/messengercompose.xul
mail/themes/linux/mail/menulist.css
mail/themes/osx/mail/menulist.css
mail/themes/windows/mail/menulist.css
--- a/calendar/base/content/dialogs/calendar-event-dialog-attendees.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog-attendees.xul
@@ -2,17 +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/. -->
 
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-attendees.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/widgets/minimonth.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://calendar/content/datetimepickers/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/widgets/calendar-widget-bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://lightning-common/skin/datetimepickers.css"?>
 
 <!DOCTYPE dialog [
   <!ENTITY % dtd1 SYSTEM "chrome://calendar/locale/calendar.dtd" > %dtd1;
   <!ENTITY % dtd2 SYSTEM "chrome://calendar/locale/calendar-event-dialog.dtd" > %dtd2;
 ]>
 
--- a/calendar/base/content/dialogs/calendar-event-dialog-recurrence.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog-recurrence.xul
@@ -6,19 +6,17 @@
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/content/bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/skin/messenger.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/skin/calendar-daypicker.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/widgets/minimonth.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/skin/calendar-event-dialog.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/widgets/calendar-widget-bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://calendar/content/datetimepickers/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://lightning-common/skin/datetimepickers.css"?>
-<?xml-stylesheet type="text/css" href="chrome://messenger/content/menulist.css"?>
 
 <!DOCTYPE dialog [
   <!ENTITY % dialogDTD SYSTEM "chrome://calendar/locale/calendar-event-dialog.dtd">
   %dialogDTD;
 ]>
 
 <dialog id="calendar-event-dialog-recurrence"
         title="&recurrence.title.label;"
--- a/calendar/base/content/dialogs/calendar-event-dialog-reminder.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog-reminder.xul
@@ -3,17 +3,16 @@
    - 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/. -->
 
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/content/bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-alarms.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/widgets/minimonth.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/skin/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://calendar/content/datetimepickers/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/widgets/calendar-widget-bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://lightning-common/skin/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/calendar-bindings.css"?>
 
 <!DOCTYPE dialog SYSTEM "chrome://calendar/locale/dialogs/calendar-event-dialog-reminder.dtd" >
 
 <dialog id="calendar-event-dialog-reminder"
         title="&reminderdialog.title;"
--- a/calendar/base/content/dialogs/calendar-event-dialog-timezone.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog-timezone.xul
@@ -1,16 +1,15 @@
 <?xml version="1.0"?>
 <!-- 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/. -->
 
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/skin/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://calendar/content/datetimepickers/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-timezone-highlighter.css"?>
 
 <!DOCTYPE dialog [
   <!ENTITY % dtd1 SYSTEM "chrome://calendar/locale/global.dtd" > %dtd1;
   <!ENTITY % dtd2 SYSTEM "chrome://calendar/locale/calendar.dtd" > %dtd2;
   <!ENTITY % dtd3 SYSTEM "chrome://calendar/locale/calendar-event-dialog.dtd" > %dtd3;
   <!ENTITY % dtd4 SYSTEM "chrome://calendar/locale/preferences/timezones.dtd" > %dtd4;
 ]>
--- a/calendar/base/content/dialogs/calendar-event-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog.xul
@@ -6,17 +6,16 @@
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/content/bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-alarms.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/widgets/minimonth.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-attendees.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/widgets/calendar-widget-bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/skin/calendar-event-dialog.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://calendar/content/datetimepickers/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/skin/primaryToolbar.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/skin/messenger.css"?>
 
 <!DOCTYPE dialog [
     <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
     <!ENTITY % globalDTD SYSTEM "chrome://calendar/locale/global.dtd">
     <!ENTITY % calendarDTD SYSTEM "chrome://calendar/locale/calendar.dtd">
     <!ENTITY % eventDialogDTD SYSTEM "chrome://calendar/locale/calendar-event-dialog.dtd">
--- a/calendar/base/content/dialogs/calendar-print-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-print-dialog.xul
@@ -1,17 +1,16 @@
 <?xml version="1.0"?>
 <!-- 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/. -->
 
 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 <?xml-stylesheet href="chrome://calendar-common/skin/widgets/minimonth.css"? type="text/css" >
 <?xml-stylesheet href="chrome://messenger/skin/messenger.css" type="text/css"?>
-<?xml-stylesheet href="chrome://calendar/content/datetimepickers/datetimepickers.css" type="text/css"?>
 <?xml-stylesheet href="chrome://calendar/content/widgets/calendar-widget-bindings.css"  type="text/css"?>
 
 <!DOCTYPE dialog [
     <!ENTITY % dtd1 SYSTEM "chrome://calendar/locale/global.dtd" > %dtd1;
     <!ENTITY % dtd2 SYSTEM "chrome://calendar/locale/calendar.dtd" > %dtd2;
 ]>
 
 
--- a/calendar/base/content/dialogs/calendar-summary-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-summary-dialog.xul
@@ -5,17 +5,16 @@
 -->
 
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/content/bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-alarms.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-attendees.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/skin/calendar-event-dialog.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/dialogs/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://calendar/content/datetimepickers/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/calendar-bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/skin/primaryToolbar.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/skin/messenger.css"?>
 
 <!DOCTYPE dialog [
   <!ENTITY % globalDTD SYSTEM "chrome://calendar/locale/global.dtd" >
   <!ENTITY % calendarDTD SYSTEM "chrome://calendar/locale/calendar.dtd" >
   <!ENTITY % dialogDTD SYSTEM "chrome://calendar/locale/calendar-event-dialog.dtd" >
--- a/calendar/lightning/content/lightning-item-iframe.xul
+++ b/calendar/lightning/content/lightning-item-iframe.xul
@@ -8,22 +8,20 @@
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/content/bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-alarms.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/widgets/minimonth.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-attendees.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/widgets/calendar-widget-bindings.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/skin/calendar-event-dialog.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://calendar/content/datetimepickers/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://lightning-common/skin/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/skin/primaryToolbar.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/skin/messenger.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/dialogs/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://messenger/content/menulist.css"?>
 
 <!DOCTYPE window [
     <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
     <!ENTITY % globalDTD SYSTEM "chrome://calendar/locale/global.dtd">
     <!ENTITY % calendarDTD SYSTEM "chrome://calendar/locale/calendar.dtd">
     <!ENTITY % eventDialogDTD SYSTEM "chrome://calendar/locale/calendar-event-dialog.dtd">
     %brandDTD;
     %globalDTD;
--- a/calendar/lightning/content/messenger-overlay-sidebar.xul
+++ b/calendar/lightning/content/messenger-overlay-sidebar.xul
@@ -12,17 +12,16 @@
   <!ENTITY % dtd4 SYSTEM "chrome://lightning/locale/lightning-toolbar.dtd" > %dtd4;
   <!ENTITY % messengerDTD SYSTEM "chrome://messenger/locale/messenger.dtd" > %messengerDTD;
   <!ENTITY % eventDialogDTD SYSTEM "chrome://calendar/locale/calendar-event-dialog.dtd" > %eventDialogDTD;
 ]>
 
 <?xml-stylesheet href="chrome://lightning/skin/lightning.css" type="text/css"?>
 
 <?xml-stylesheet href="chrome://calendar/content/calendar-view-bindings.css" type="text/css"?>
-<?xml-stylesheet href="chrome://calendar/content/datetimepickers/datetimepickers.css" type="text/css"?>
 
 <?xml-stylesheet href="chrome://calendar/skin/calendar-event-dialog.css" type="text/css"?>
 <?xml-stylesheet href="chrome://calendar/content/calendar-event-dialog.css" type="text/css"?>
 <?xml-stylesheet href="chrome://calendar-common/skin/dialogs/calendar-event-dialog.css" type="text/css"?>
 
 <?xul-overlay href="chrome://calendar/content/calendar-calendars-list.xul"?>
 <?xul-overlay href="chrome://calendar/content/calendar-common-sets.xul"?>
 <?xul-overlay href="chrome://calendar/content/calendar-views.xul"?>
--- a/calendar/lightning/jar.mn
+++ b/calendar/lightning/jar.mn
@@ -100,18 +100,16 @@ lightning.jar:
     ../skin/windows/lightning/accountCentral.css              (themes/windows/accountCentral.css)
     ../skin/windows/lightning/imip.css                        (themes/windows/imip.css)
     ../skin/windows/lightning/lightning.css                   (themes/windows/lightning.css)
     ../skin/windows/lightning/lightning-toolbar.css           (themes/windows/lightning-toolbar.css)
 
 calendar.jar:
     content/calendar/calendarCreation.xul                  (../resources/content/calendarCreation.xul)
     content/calendar/calendarCreation.js                   (../resources/content/calendarCreation.js)
-    content/calendar/datetimepickers/datetimepickers.css   (../resources/content/datetimepickers/datetimepickers.css)
-    content/calendar/datetimepickers/datetimepickers.xml   (../resources/content/datetimepickers/datetimepickers.xml)
     content/calendar/datetimepickers/datetimepickers.js    (../resources/content/datetimepickers/datetimepickers.js)
     content/calendar/mouseoverPreviews.js                  (../resources/content/mouseoverPreviews.js)
     content/calendar/publish.js                            (../resources/content/publish.js)
     content/calendar/publishDialog.js                      (../resources/content/publishDialog.js)
     content/calendar/publishDialog.xul                     (../resources/content/publishDialog.xul)
     content/calendar/sound.wav                             (../resources/content/sound.wav)
     ../skin/lightning-common/datetimepickers.css           (../resources/skin/datetimepickers.css)
     ../skin/lightning-common/dialogOverlay.css             (../resources/skin/dialogOverlay.css)
deleted file mode 100644
--- a/calendar/resources/content/datetimepickers/datetimepickers.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/* 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/. */
-
-@import url("chrome://messenger/content/menulist.css");
-
-menulist[type="panel"] {
-  -moz-binding: url("chrome://calendar/content/datetimepickers/datetimepickers.xml#panellist");
-}
-
-datetextpicker {
-  -moz-binding: url("chrome://calendar/content/datetimepickers/datetimepickers.xml#datetextpicker");
-}
-
-timepicker-grids {
-  display: -moz-box;
-}
deleted file mode 100644
--- a/calendar/resources/content/datetimepickers/datetimepickers.xml
+++ /dev/null
@@ -1,665 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<!-- 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/. -->
-
-<!-- globals cal -->
-
-<!--
-    This defines <datepicker/> <timepicker/> and <datetimepicker/>
-    which all descend from datetimepicker-base to get date/time parsing
-    and consistent behavior.
-    It relies on <minimonth/> for the date picker's drop down.
-    You can be notified of change event as follows:
-      <datepicker id="my-date-picker" onchange="myDatePick(this);"/>
-    May get/set value in javascript with
-      document.getElementById("my-date-picker").value = new Date();
-    May disable/enable in javascript with
-      document.getElementById("my-date-picker").disabled = true;
-    May also disable/enable a datetimepicker's component
-      datepicker or timepicker individually with
-      document.getElementById("my-datetimepicker").datepickerdisabled = true;
-      document.getElementById("my-datetimepicker").timepickerdisabled = true;
--->
-<bindings id="xulDatePicker"
-          xmlns="http://www.mozilla.org/xbl"
-          xmlns:html="http://www.w3.org/1999/xhtml"
-          xmlns:xbl="http://www.mozilla.org/xbl"
-          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-  <binding id="panellist" extends="chrome://messenger/content/menulist.xml#menulist-editable">
-    <content sizetopopup="pref">
-      <xul:hbox class="menulist-editable-box textbox-input-box" xbl:inherits="context,disabled,readonly,focused" flex="1">
-        <html:input class="menulist-editable-input" flex="1" anonid="input" allowevents="true"
-                    xbl:inherits="value=label,value,disabled,tabindex,readonly,placeholder"/>
-      </xul:hbox>
-      <xul:dropmarker class="menulist-dropmarker" type="menu"
-                      xbl:inherits="open,disabled,parentfocused=focused"/>
-      <children includes="panel"/>
-    </content>
-  </binding>
-
-  <binding id="datetextpicker"
-           extends="chrome://calendar/content/datetimepickers/datetimepickers.xml#datetimepicker-base">
-    <content>
-      <xul:hbox flex="1">
-        <xul:textbox anonid="date-textbox" flex="1"
-                     onfocus="this.select();"
-                     onkeypress="if (event.key == 'Enter') fireGoEvent();"/>
-        <xul:button anonid="date-go-button" oncommand="fireGoEvent()"/>
-      </xul:hbox>
-    </content>
-
-    <implementation>
-      <field name="mRelativeDates">[]</field>
-      <field name="mDayNames">[]</field>
-      <field name="mRelationWords">[]</field>
-      <field name="mMonthLongNames">[]</field>
-      <field name="mMonthShortNames">[]</field>
-
-      <constructor><![CDATA[
-          const { cal } = ChromeUtils.import("resource://calendar/modules/calUtils.jsm");
-          let goButton = document.getAnonymousElementByAttribute(this, "anonid", "date-go-button");
-          goButton.setAttribute("label", cal.l10n.getCalString("go"));
-          // Load the stuff we're going to use to parse written dates
-          this.mRelativeDates = [
-              { word: cal.l10n.getCalString("today").toLowerCase(), offset: 0 },
-              { word: cal.l10n.getCalString("yesterday").toLowerCase(), offset: -1 },
-              { word: cal.l10n.getCalString("tomorrow").toLowerCase(), offset: 1 }];
-          for (let i = 1; i <= 7; i++) {
-              this.mDayNames.push(cal.l10n.getDateFmtString(`day.${i}.name`).toLowerCase());
-          }
-
-          for (let i = 1; i <= 12; i++) {
-              this.mMonthLongNames.push(cal.l10n.getDateFmtString(`month.${i}.name`).toLowerCase());
-              this.mMonthShortNames.push(cal.l10n.getDateFmtString(`month.${i}.Mmm`).toLowerCase());
-          }
-
-          // note that some languages have different conjugations of
-          // next/last depending on the day
-          this.mRelationWords = [
-              { word: cal.l10n.getCalString("last1"), offset: -1 },
-              { word: cal.l10n.getCalString("last2"), offset: -1 },
-              { word: cal.l10n.getCalString("next1"), offset: 0 },
-              { word: cal.l10n.getCalString("next2"), offset: 0 }];
-
-          // Set the value to today
-          let text = document.getAnonymousElementByAttribute(this, "anonid", "date-textbox");
-          text.value = cal.l10n.getCalString("today");
-      ]]></constructor>
-
-      <property name="value">
-        <getter><![CDATA[
-            return this.mValue;
-        ]]></getter>
-        <setter><![CDATA[
-            let text = document.getAnonymousElementByAttribute(this, "anonid", "date-textbox");
-            try {
-                text.value = this.formatDate(val);
-            } catch (ex) {
-                // Don't fail if date formatting fails.
-            }
-            return val;
-        ]]></setter>
-      </property>
-
-      <method name="fireGoEvent">
-        <body><![CDATA[
-            let text = document.getAnonymousElementByAttribute(this, "anonid", "date-textbox");
-            let date = this.parseLanguageDate(text.value);
-            if (!date) {
-                date = this.parseDateTime(text.value);
-            }
-            let prettyDate;
-            if (date) {
-                // format fails if year <= 1600 on win2k, so try format first.
-                try {
-                    prettyDate = this.formatDate(date);
-                } catch (ex) {
-                    // Don't fail if date formatting fails.
-                }
-            }
-            if (date && prettyDate) {
-                this.mValue = date;
-                text.value = prettyDate;
-                this.fireEvent("command", date);
-            }
-        ]]></body>
-      </method>
-
-      <!-- This function will take written (with words) dates and, if
-         - possible, return a Date() object described by the words.  Note
-         - that this function will not parse explicit dates, like 1/1/06,
-         - you should use parseDateTime for that.
-        -->
-      <method name="parseLanguageDate">
-        <parameter name="aValue"/>
-        <body><![CDATA[
-            if (!aValue) {
-                return null;
-            }
-            let val = aValue.toLowerCase();
-            // Look for the easy ones like today, tomorrow, etc
-            for (let rel of this.mRelativeDates) {
-                if (val == rel.word) {
-                    let now = new Date();
-                    now.setDate(now.getDate() + rel.offset);
-                    return now;
-                }
-            }
-
-            let self = this;
-
-            // Takes a written day of the week and returns a js-date
-            // corresponding to the nearest day in the future that is
-            // that day of the week
-            function getDateForDay(aWord) {
-                for (let i in self.mDayNames) {
-                    if (aWord != self.mDayNames[i]) {
-                        continue;
-                    }
-                    // Figure out what day of the week today is.
-                    let today = cal.dtz.now();
-
-                    // i-weekday gets the offset. Add 7 to ensure that the %
-                    // operation stays positive.
-                    let offset = (i - today.weekday + 7) % 7;
-                    today.day = today.day + offset;
-                    return cal.dtz.dateTimeToJsDate(today);
-                }
-                return null;
-            }
-
-            // Remove commas
-            val = val.replace(",", "");
-
-            if (!val.includes(" ")) {
-                // Just a single word, or a single date.
-                return getDateForDay(val);
-            }
-
-            // Replace month names with numbers
-            for (let i in this.mMonthLongNames) {
-                if (val.includes(this.mMonthLongNames[i])) {
-                    let newVal = val.replace(this.mMonthLongNames[i], Number(i) + 1);
-                    newVal = newVal.replace(" ", "/");
-                    return this.parseDateTime(newVal);
-                }
-            }
-
-            // Same for short month names
-            for (let i in this.mMonthShortNames) {
-                if (val.includes(this.mMonthShortNames[i])) {
-                    let newVal = val.replace(this.mMonthShortNames[i], Number(i) + 1);
-                    newVal = newVal.replace(" ", "/");
-                    return this.parseDateTime(newVal);
-                }
-            }
-
-            // Now for the cool 'next' and 'last'
-            let words = val.split(" ");
-            let offset, day;
-            for (let word of words) {
-                for (let rel of this.mRelationWords) {
-                    if (word == rel.word) {
-                        offset = rel.offset;
-                        break;
-                    }
-                }
-                for (let i in this.mDayNames) {
-                    if (word == this.mDayNames[i]) {
-                        day = getDateForDay(word);
-                        break;
-                    }
-                }
-            }
-
-            if (day && offset != undefined) {
-                day.setDate(day.getDate() + (7 * offset));
-                return day;
-            }
-            return null;
-        ]]></body>
-      </method>
-    </implementation>
-  </binding>
-
-  <binding id="datetimepicker-base" extends="chrome://global/content/bindings/general.xml#basecontrol"
-           inherits="value,onchange">
-    <implementation>
-      <constructor><![CDATA[
-          this.kTimeFormatObject = { timeStyle: "short" };
-          this.initDateFormat();
-          this.initTimeFormat();
-      ]]></constructor>
-
-      <property name="value"
-                onget="return this.mValue"
-                onset="this.update(val, false)"/>
-
-      <property name="lastDateParseIncludedTime"
-                onget="return this.mLastDateParseIncludedTime;"
-                onset="this.mLastDateParseIncludedTime = val;" />
-
-      <method name="update">
-        <parameter name="aValue"/>
-        <parameter name="aRefresh"/>
-        <body><![CDATA[
-            if (aValue != null) {
-                this.mValue = aValue;
-            }
-        ]]></body>
-      </method>
-
-      <method name="fireEvent">
-        <parameter name="aEventName"/>
-        <parameter name="aDetail"/>
-        <body><![CDATA[
-            let event = document.createEvent("Events");
-            event.initEvent(aEventName, true, true);
-            event.detail = aDetail;
-            this.dispatchEvent(event);
-        ]]></body>
-      </method>
-
-      <!-- Parameter aValue may be a date or a date time. Dates are
-           read according to locale/OS setting (d-m-y or m-d-y or ...).
-           (see initDateFormat). Uses parseTime() for times.
-      -->
-      <method name="parseDateTime">
-        <parameter name="aValue"/>
-        <body><![CDATA[
-            this.mLastDateParseIncludedTime = false;
-            let tempDate = null;
-            if (!this.probeSucceeded) {
-                return null; // avoid errors accessing uninitialized data.
-            }
-
-            let year = Number.MIN_VALUE;
-            let month = -1;
-            let day = -1;
-            let timeString = null;
-
-            if (this.alphaMonths == null) {
-                // SHORT NUMERIC DATE, such as 2002-03-04, 4/3/2002, or CE2002Y03M04D.
-                // Made of digits & nonDigits.  (Nondigits may be unicode letters
-                // which do not match \w, esp. in CJK locales.)
-                // (.*)? binds to null if no suffix.
-                let parseNumShortDateRegex = /^\D*(\d+)\D+(\d+)\D+(\d+)(.*)?$/;
-                let dateNumbersArray = parseNumShortDateRegex.exec(aValue);
-                if (dateNumbersArray != null) {
-                    year = Number(dateNumbersArray[this.yearIndex]);
-                    month = Number(dateNumbersArray[this.monthIndex]) - 1; // 0-based
-                    day = Number(dateNumbersArray[this.dayIndex]);
-                    timeString = dateNumbersArray[4];
-                }
-            } else {
-                // SHORT DATE WITH ALPHABETIC MONTH, such as "dd MMM yy" or "MMMM dd, yyyy"
-                // (\d+|[^\d\W]) is digits or letters, not both together.
-                // Allows 31dec1999 (no delimiters between parts) if OS does (w2k does not).
-                // Allows Dec 31, 1999 (comma and space between parts)
-                // (Only accepts ASCII month names; JavaScript RegExp does not have an
-                // easy way to describe unicode letters short of a HUGE character range
-                // regexp derived from the Alphabetic ranges in
-                // http://www.unicode.org/Public/UNIDATA/DerivedCoreProperties.txt)
-                // (.*)? binds to null if no suffix.
-                let parseAlphShortDateRegex = /^\s*(\d+|[^\d\W]+)\W{0,2}(\d+|[^\d\W]+)\W{0,2}(\d+|[^\d\W]+)(.*)?$/;
-                let datePartsArray = parseAlphShortDateRegex.exec(aValue);
-                if (datePartsArray != null) {
-                    year = Number(datePartsArray[this.yearIndex]);
-                    let monthString = datePartsArray[this.monthIndex].toUpperCase();
-                    for (let monthIdx = 0; monthIdx < this.alphaMonths.length; monthIdx++) {
-                        if (monthString == this.alphaMonths[monthIdx]) {
-                            month = monthIdx;
-                            break;
-                        }
-                    }
-                    day = Number(datePartsArray[this.dayIndex]);
-                    timeString = datePartsArray[4];
-                }
-            }
-            if (year != Number.MIN_VALUE && month != -1 && day != -1) {
-                // year, month, day successfully parsed
-                if (year >= 0 && year < 100) {
-                    // If 0 <= year < 100, treat as 2-digit year (like formatDate):
-                    //   parse year as up to 30 years in future or 69 years in past.
-                    //   (Covers 30-year mortgage and most working people's birthdate.)
-                    // otherwise will be treated as four digit year.
-                    let currentYear = new Date().getFullYear();
-                    let currentCentury = currentYear - currentYear % 100;
-                    year = currentCentury + year;
-                    if (year < currentYear - 69) {
-                        year += 100;
-                    }
-                    if (year > currentYear + 30) {
-                        year -= 100;
-                    }
-                }
-                // if time is also present, parse it
-                let hours = 0;
-                let minutes = 0;
-                let seconds = 0;
-                if (timeString != null) {
-                    let time = this.parseTime(timeString);
-                    if (time != null) {
-                        hours = time.getHours();
-                        minutes = time.getMinutes();
-                        seconds = time.getSeconds();
-                        this.mLastDateParseIncludedTime = true;
-                    }
-                }
-                tempDate = new Date(year, month, day, hours, minutes, seconds, 0);
-            } // else did not match regex, not a valid date
-            return tempDate;
-        ]]></body>
-      </method>
-
-      <!-- Parse a variety of time formats so that cut and paste is likely to work.
-           separator:            ':'         '.'        ' '        symbol        none
-                                 "12:34:56"  "12.34.56" "12 34 56" "12h34m56s"   "123456"
-           seconds optional:     "02:34"     "02.34"    "02 34"    "02h34m"      "0234"
-           minutes optional:     "12"        "12"       "12"       "12h"         "12"
-           1st hr digit optional:"9:34"      " 9.34"     "9 34"     "9H34M"       "934am"
-           skip nondigit prefix  " 12:34"    "t12.34"   " 12 34"   "T12H34M"     "T0234"
-           am/pm optional        "02:34 a.m.""02.34pm"  "02 34 A M" "02H34M P.M." "0234pm"
-           am/pm prefix          "a.m. 02:34""pm02.34"  "A M 02 34" "P.M. 02H34M" "pm0234"
-           am/pm cyrillic        "02:34\u0430.\u043c."  "02 34 \u0420 \u041c"
-           am/pm arabic          "\u063502:34" (RTL 02:34a) "\u0645 02.34" (RTL 02.34 p)
-           above/below noon      "\u4e0a\u534802:34"    "\u4e0b\u5348 02 34"
-           noon before/after     "\u5348\u524d02:34"    "\u5348\u5f8c 02 34"
-      -->
-      <method name="parseTime">
-        <parameter name="aValue"/>
-        <body><![CDATA[
-            let now = new Date();
-
-            let noon = cal.l10n.getDateFmtString("noon");
-            if (aValue.toLowerCase() == noon.toLowerCase()) {
-                return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 12, 0, 0, 0);
-            }
-
-            let midnight = cal.l10n.getDateFmtString("midnight");
-            if (aValue.toLowerCase() == midnight.toLowerCase()) {
-                return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
-            }
-
-            let time = null;
-            let timePartsArray = this.parseTimeRegExp.exec(aValue);
-            const PRE_INDEX = 1, HR_INDEX = 2, MIN_INDEX = 4, SEC_INDEX = 6, POST_INDEX = 8;
-
-            if (timePartsArray != null) {
-                let hoursString = timePartsArray[HR_INDEX];
-                let hours = Number(hoursString);
-                if (!(hours >= 0 && hours < 24)) {
-                    return null;
-                }
-
-                let minutesString = timePartsArray[MIN_INDEX];
-                let minutes = (minutesString == null ? 0 : Number(minutesString));
-                if (!(minutes >= 0 && minutes < 60)) {
-                    return null;
-                }
-
-                let secondsString = timePartsArray[SEC_INDEX];
-                let seconds = (secondsString == null ? 0 : Number(secondsString));
-                if (!(seconds >= 0 && seconds < 60)) {
-                    return null;
-                }
-
-                let ampmCode = null;
-                if (timePartsArray[PRE_INDEX] || timePartsArray[POST_INDEX]) {
-                    if (this.ampmIndex && timePartsArray[this.ampmIndex]) {
-                        // try current format order first
-                        let ampmString = timePartsArray[this.ampmIndex];
-                        if (this.amRegExp.test(ampmString)) {
-                            ampmCode = "AM";
-                        } else if (this.pmRegExp.test(ampmString)) {
-                            ampmCode = "PM";
-                        }
-                    }
-                    if (ampmCode == null) { // not yet found
-                        // try any format order
-                        let preString = timePartsArray[PRE_INDEX];
-                        let postString = timePartsArray[POST_INDEX];
-                        if ((preString && this.amRegExp.test(preString)) ||
-                            (postString && this.amRegExp.test(postString))) {
-                            ampmCode = "AM";
-                        } else if ((preString && this.pmRegExp.test(preString)) ||
-                                   (postString && this.pmRegExp.test(postString))) {
-                            ampmCode = "PM";
-                        } // else no match, ignore and treat as 24hour time.
-                    }
-                }
-                if (ampmCode == "AM") {
-                    if (hours == 12) {
-                        hours = 0;
-                    }
-                } else if (ampmCode == "PM") {
-                    if (hours < 12) {
-                        hours += 12;
-                    }
-                }
-                time = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes, seconds, 0);
-            }  // else did not match regex, not valid time
-            return time;
-        ]]></body>
-      </method>
-
-      <method name="initDateFormat">
-        <body><![CDATA[
-            // probe the dateformat
-            this.yearIndex = -1;
-            this.monthIndex = -1;
-            this.dayIndex = -1;
-            this.twoDigitYear = false;
-            this.alphaMonths = null;
-            this.probeSucceeded = false;
-            this.mLastDateParseIncludedTime = false;
-
-            // SHORT NUMERIC DATE, such as 2002-03-04, 4/3/2002, or CE2002Y03M04D.
-            // Made of digits & nonDigits.  (Nondigits may be unicode letters
-            // which do not match \w, esp. in CJK locales.)
-            this.parseShortDateRegex = /^\D*(\d+)\D+(\d+)\D+(\d+)\D?$/;
-            // Make sure to use UTC date and timezone here to avoid the pattern
-            // detection to fail if the probe date output would have an timezone
-            // offset due to our lack of support of historic timezone definitions.
-            let probeDate = new Date(Date.UTC(2002, 3, 6)); // month is 0-based
-            let probeString = this.formatDate(probeDate, cal.dtz.UTC);
-            let probeArray = this.parseShortDateRegex.exec(probeString);
-            if (probeArray) {
-                // Numeric month format
-                for (let i = 1; i <= 3; i++) {
-                    switch (Number(probeArray[i])) {
-                        case 2: this.twoDigitYear = true; // falls through
-                        case 2002: this.yearIndex = i; break;
-                        case 4: this.monthIndex = i; break;
-                        case 5: // falls through for OS timezones western to GMT
-                        case 6: this.dayIndex = i; break;
-                    }
-                }
-                // All three indexes are set (not -1) at this point.
-                this.probeSucceeded = true;
-            } else {
-                // SHORT DATE WITH ALPHABETIC MONTH, such as "dd MMM yy" or "MMMM dd, yyyy"
-                // (\d+|[^\d\W]) is digits or letters, not both together.
-                // Allows 31dec1999 (no delimiters between parts) if OS does (w2k does not).
-                // Allows Dec 31, 1999 (comma and space between parts)
-                // (Only accepts ASCII month names; JavaScript RegExp does not have an
-                // easy way to describe unicode letters short of a HUGE character range
-                // regexp derived from the Alphabetic ranges in
-                // http://www.unicode.org/Public/UNIDATA/DerivedCoreProperties.txt)
-                this.parseShortDateRegex = /^\s*(\d+|[^\d\W]+)\W{0,2}(\d+|[^\d\W]+)\W{0,2}(\d+|[^\d\W]+)\s*$/;
-                probeArray = this.parseShortDateRegex.exec(probeString);
-                if (probeArray != null) {
-                    for (let j = 1; j <= 3; j++) {
-                        switch (Number(probeArray[j])) {
-                            case 2: this.twoDigitYear = true; // falls through
-                            case 2002: this.yearIndex = j; break;
-                            case 5: // falls through for OS timezones western to GMT
-                            case 6: this.dayIndex = j; break;
-                            default: this.monthIndex = j; break;
-                        }
-                    }
-                    if (this.yearIndex != -1 && this.dayIndex != -1 && this.monthIndex != -1) {
-                        this.probeSucceeded = true;
-                        // Fill this.alphaMonths with month names.
-                        this.alphaMonths = new Array(12);
-                        for (let monthIdx = 0; monthIdx < 12; monthIdx++) {
-                            probeDate.setMonth(monthIdx);
-                            probeString = this.formatDate(probeDate);
-                            probeArray = this.parseShortDateRegex.exec(probeString);
-                            if (probeArray) {
-                                this.alphaMonths[monthIdx] = probeArray[this.monthIndex].toUpperCase();
-                            } else {
-                                this.probeSucceeded = false;
-                            }
-                        }
-                    }
-                }
-            }
-            if (!this.probeSucceeded) {
-                dump("\nOperating system short date format is not recognized: " + probeString + "\n");
-            }
-        ]]></body>
-      </method>
-
-      <!-- Time format in 24-hour format or 12-hour format with am/pm string.
-           Should match formats
-                HH:mm,       H:mm,       HH:mm:ss,       H:mm:ss
-                hh:mm tt,    h:mm tt,    hh:mm:ss tt,    h:mm:ss tt
-             tt hh:mm,    tt h:mm,    tt hh:mm:ss,    tt h:mm:ss
-           where
-           HH is 24 hour digits, with leading 0.  H is 24 hour digits, no leading 0.
-           hh is 12 hour digits, with leading 0.  h is 12 hour digits, no leading 0.
-           mm and ss are is minutes and seconds digits, with leading 0.
-           tt is localized AM or PM string.
-           ':' may be ':' or a units marker such as 'h', 'm', or 's' in  15h12m00s
-           or may be omitted as in 151200.
-      -->
-      <method name="initTimeFormat">
-        <body><![CDATA[
-            const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-            // probe the Time format
-            this.ampmIndex = null;
-            // Digits         HR       sep      MIN     sep      SEC     sep
-            //   Index:       2        3        4       5        6       7
-            let digitsExpr = "(\\d?\\d)(\\D)?(?:(\\d\\d)(\\D)?(?:(\\d\\d)(\\D)?)?)?";
-            // any letters or '.': non-digit alphanumeric, period (a.m.), or space (P M)
-            let anyAmPmExpr = "(?:[^\\d\\W]|[. ])+";
-            // digitsExpr has 6 captures, so index of first ampmExpr is 1, of last is 8.
-            let probeTimeRegExp =
-                new RegExp("^(" + anyAmPmExpr + ")?\\s?" + digitsExpr + "(" + anyAmPmExpr + ")?\\s*$");
-            const PRE_INDEX = 1, HR_INDEX = 2, MIN_INDEX = 4, SEC_INDEX = 6, POST_INDEX = 8; // eslint-disable-line no-unused-vars
-            let amProbeTime = new Date(2000, 0, 1, 6, 12, 34);
-            let pmProbeTime = new Date(2000, 0, 1, 18, 12, 34);
-            let formatter = new Services.intl.DateTimeFormat(undefined, this.kTimeFormatObject);
-            let amProbeString = formatter.format(amProbeTime);
-            let pmProbeString = formatter.format(pmProbeTime);
-            let amFormatExpr = null, pmFormatExpr = null;
-            if (amProbeString != pmProbeString) {
-                let amProbeArray = probeTimeRegExp.exec(amProbeString);
-                let pmProbeArray = probeTimeRegExp.exec(pmProbeString);
-                if (amProbeArray != null && pmProbeArray != null) {
-                    if (amProbeArray[PRE_INDEX] && pmProbeArray[PRE_INDEX] &&
-                        amProbeArray[PRE_INDEX] != pmProbeArray[PRE_INDEX]) {
-                        this.ampmIndex = PRE_INDEX;
-                    } else if (amProbeArray[POST_INDEX] && pmProbeArray[POST_INDEX]) {
-                        if (amProbeArray[POST_INDEX] == pmProbeArray[POST_INDEX]) {
-                            // check if need to append previous character,
-                            // captured by the optional separator pattern after seconds digits,
-                            // or after minutes if no seconds, or after hours if no minutes.
-                            for (let k = SEC_INDEX; k >= HR_INDEX; k -= 2) {
-                                let nextSepI = k + 1;
-                                let nextDigitsI = k + 2;
-                                if ((k == SEC_INDEX ||
-                                     (!amProbeArray[nextDigitsI] && !pmProbeArray[nextDigitsI])) &&
-                                    amProbeArray[nextSepI] && pmProbeArray[nextSepI] &&
-                                    amProbeArray[nextSepI] != pmProbeArray[nextSepI]) {
-                                    amProbeArray[POST_INDEX] =
-                                      amProbeArray[nextSepI] + amProbeArray[POST_INDEX];
-                                    pmProbeArray[POST_INDEX] =
-                                      pmProbeArray[nextSepI] + pmProbeArray[POST_INDEX];
-                                    this.ampmIndex = POST_INDEX;
-                                    break;
-                                }
-                            }
-                        } else {
-                            this.ampmIndex = POST_INDEX;
-                        }
-                    }
-                    if (this.ampmIndex) {
-                        let makeFormatRegExp = function(string) {
-                            // make expr to accept either as provided, lowercased, or uppercased
-                            let regExp = string.replace(/(\W)/g, "[$1]"); // escape punctuation
-                            let lowercased = string.toLowerCase();
-                            if (string != lowercased) {
-                                regExp += "|" + lowercased;
-                            }
-                            let uppercased = string.toUpperCase();
-                            if (string != uppercased) {
-                                regExp += "|" + uppercased;
-                            }
-                            return regExp;
-                        };
-                        amFormatExpr = makeFormatRegExp(amProbeArray[this.ampmIndex]);
-                        pmFormatExpr = makeFormatRegExp(pmProbeArray[this.ampmIndex]);
-                    }
-                }
-            }
-            // International formats ([roman, cyrillic]|arabic|chinese/kanji characters)
-            // covering languages of U.N. (en,fr,sp,ru,ar,zh) and G8 (en,fr,de,it,ru,ja).
-            // See examples at parseTimeOfDay.
-            let amExpr =
-                "[Aa\u0410\u0430][. ]?[Mm\u041c\u043c][. ]?|\u0635|\u4e0a\u5348|\u5348\u524d";
-            let pmExpr =
-                "[Pp\u0420\u0440][. ]?[Mm\u041c\u043c][. ]?|\u0645|\u4e0b\u5348|\u5348\u5f8c";
-            if (this.ampmIndex) {
-                amExpr = amFormatExpr + "|" + amExpr;
-                pmExpr = pmFormatExpr + "|" + pmExpr;
-            }
-            let ampmExpr = amExpr + "|" + pmExpr;
-            // Must build am/pm formats into parse time regexp so that it can
-            // match them without mistaking the initial char for an optional divider.
-            // (For example, want to be able to parse both "12:34pm" and
-            // "12H34M56Spm" for any characters H,M,S and any language's "pm".
-            // The character between the last digit and the "pm" is optional.
-            // Must recogize "pm" directly, otherwise in "12:34pm" the "S" pattern
-            // matches the "p" character so only "m" is matched as ampm suffix.)
-            //
-            // digitsExpr has 6 captures, so index of first ampmExpr is 1, of last is 8.
-            this.parseTimeRegExp =
-                new RegExp("(" + ampmExpr + ")?\\s?" + digitsExpr + "(" + ampmExpr + ")?\\s*$");
-            this.amRegExp = new RegExp("^(?:" + amExpr + ")$");
-            this.pmRegExp = new RegExp("^(?:" + pmExpr + ")$");
-        ]]></body>
-      </method>
-
-      <method name="formatDate">
-        <parameter name="aDate"/>
-        <parameter name="aTimezone"/>
-        <body><![CDATA[
-            // Usually, floating is ok here, so no need to pass aTimezone - we just need to pass
-            // it in if we need to make sure formatting happens without a timezone conversion.
-            let timezone = aTimezone || cal.dtz.floating;
-            return cal.getDateFormatter().formatDateShort(
-                cal.dtz.jsDateToDateTime(aDate, timezone)
-            );
-        ]]></body>
-      </method>
-
-      <method name="formatTime">
-        <parameter name="aValue"/>
-        <body><![CDATA[
-            const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-            let formatter = new Services.intl.DateTimeFormat(undefined, this.kTimeFormatObject);
-            return formatter.format(aValue);
-        ]]></body>
-      </method>
-    </implementation>
-  </binding>
-</bindings>
--- a/calendar/resources/skin/datetimepickers.css
+++ b/calendar/resources/skin/datetimepickers.css
@@ -1,16 +1,18 @@
 /* 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/. */
 
 /*--------------------------------------------------------------------
  *   Datepicker (text field with minimonth popup)
  *-------------------------------------------------------------------*/
- 
+
+@import url("chrome://messenger/skin/menulist.css");
+
 /* menulist */
 datepicker > menulist {
   width: 11em;
 }
 
 /*--------------------------------------------------------------------
  *   Datepicker-forever (style for the "forever" option)
  *-------------------------------------------------------------------*/
deleted file mode 100644
--- a/common/bindings/menulist.css
+++ /dev/null
@@ -1,26 +0,0 @@
-/* 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/. */
-
-@import url("chrome://messenger/skin/menulist.css");
-
-@namespace html url("http://www.w3.org/1999/xhtml"); /* namespace for HTML elements */
-
-menulist[is="menulist-editable"]:not([editable="true"]) .menulist-input,
-menulist[is="menulist-editable"][editable="true"] .menulist-label-box {
-  display: none;
-}
-
-menulist > textbox {
-  margin: 0;
-}
-
-menulist html|*.textbox-input {
-  -moz-appearance: none !important;
-  background: transparent !important;
-  -moz-box-flex: 1;
-  margin: 0 !important;
-  border: none !important;
-  padding: 0 !important;
-  font: inherit;
-}
deleted file mode 100644
--- a/common/bindings/menulist.xml
+++ /dev/null
@@ -1,541 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- 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/. -->
-
-<bindings id="menulistBindings"
-   xmlns="http://www.mozilla.org/xbl"
-   xmlns:html="http://www.w3.org/1999/xhtml"
-   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-   xmlns:xbl="http://www.mozilla.org/xbl">
-
-  <binding id="xbl-menulist"
-           extends="chrome://global/content/bindings/general.xml#basecontrol">
-    <content>
-      <xul:hbox class="menulist-label-box" flex="1">
-        <xul:image class="menulist-icon" xbl:inherits="src=image"/>
-        <xul:label class="menulist-label" xbl:inherits="value=label,crop,accesskey,highlightable" crop="right" flex="1"/>
-        <xul:label class="menulist-highlightable-label" xbl:inherits="xbl:text=label,crop,accesskey,highlightable" crop="right" flex="1"/>
-      </xul:hbox>
-      <xul:dropmarker class="menulist-dropmarker" type="menu" xbl:inherits="disabled,open"/>
-      <children includes="menupopup"/>
-    </content>
-
-    <handlers>
-      <handler event="command" phase="capturing"
-        action="if (event.target.parentNode.parentNode == this) this.selectedItem = event.target;"/>
-
-      <handler event="popupshowing">
-        <![CDATA[
-          if (event.target.parentNode == this) {
-            this.activeChild = null;
-            if (this.selectedItem)
-              // Not ready for auto-setting the active child in hierarchies yet.
-              // For now, only do this when the outermost menupopup opens.
-              this.activeChild = this.mSelectedInternal;
-          }
-        ]]>
-      </handler>
-
-      <handler event="keypress" modifiers="shift any" group="system">
-        <![CDATA[
-          if (!event.defaultPrevented &&
-              (event.keyCode == KeyEvent.DOM_VK_UP ||
-               event.keyCode == KeyEvent.DOM_VK_DOWN ||
-               event.keyCode == KeyEvent.DOM_VK_PAGE_UP ||
-               event.keyCode == KeyEvent.DOM_VK_PAGE_DOWN ||
-               event.keyCode == KeyEvent.DOM_VK_HOME ||
-               event.keyCode == KeyEvent.DOM_VK_END ||
-               event.keyCode == KeyEvent.DOM_VK_BACK_SPACE ||
-               event.charCode > 0)) {
-            // Moving relative to an item: start from the currently selected item
-            this.activeChild = this.mSelectedInternal;
-            if (this.handleKeyPress(event)) {
-              this.activeChild.doCommand();
-              event.preventDefault();
-            }
-          }
-        ]]>
-      </handler>
-    </handlers>
-
-    <implementation implements="nsIDOMXULMenuListElement">
-      <constructor>
-        this.mSelectedInternal = null;
-        this.mAttributeObserver = null;
-        this.setInitialSelection();
-      </constructor>
-
-      <method name="setInitialSelection">
-        <body>
-          <![CDATA[
-            var popup = this.menupopup;
-            if (popup) {
-              var arr = popup.getElementsByAttribute("selected", "true");
-
-              var editable = this.editable;
-              var value = this.value;
-              if (!arr.item(0) && value)
-                arr = popup.getElementsByAttribute(editable ? "label" : "value", value);
-
-              if (arr.item(0))
-                this.selectedItem = arr[0];
-              else if (!editable)
-                this.selectedIndex = 0;
-            }
-          ]]>
-        </body>
-      </method>
-
-      <property name="value" onget="return this.getAttribute('value');">
-        <setter>
-          <![CDATA[
-            // if the new value is null, we still need to remove the old value
-            if (val == null)
-              return this.selectedItem = val;
-
-            var arr = null;
-            var popup = this.menupopup;
-            if (popup)
-              arr = popup.getElementsByAttribute("value", val);
-
-            if (arr && arr.item(0)) {
-              this.selectedItem = arr[0];
-            } else {
-              this.selectedItem = null;
-              this.setAttribute("value", val);
-            }
-
-            return val;
-          ]]>
-        </setter>
-      </property>
-
-      <property name="crop" onset="this.setAttribute('crop',val); return val;"
-                            onget="return this.getAttribute('crop');"/>
-      <property name="image"  onset="this.setAttribute('image',val); return val;"
-                              onget="return this.getAttribute('image');"/>
-      <property name="label" readonly="true" onget="return this.getAttribute('label');"/>
-      <property name="description" onset="this.setAttribute('description',val); return val;"
-                                   onget="return this.getAttribute('description');"/>
-
-      <property name="open" onset="this.openMenu(val); return val;"
-                            onget="return this.hasAttribute('open');"/>
-
-      <property name="itemCount" readonly="true"
-                onget="return this.menupopup ? this.menupopup.children.length : 0"/>
-
-      <property name="menupopup" readonly="true">
-        <getter>
-          <![CDATA[
-            var popup = this.firstElementChild;
-            while (popup && popup.localName != "menupopup")
-              popup = popup.nextElementSibling;
-            return popup;
-          ]]>
-        </getter>
-      </property>
-
-      <method name="contains">
-        <parameter name="item"/>
-        <body>
-          <![CDATA[
-            if (!item)
-              return false;
-
-            var parent = item.parentNode;
-            return (parent && parent.parentNode == this);
-          ]]>
-        </body>
-      </method>
-
-      <property name="selectedIndex">
-        <getter>
-          <![CDATA[
-            // Quick and dirty. We won't deal with hierarchical menulists yet.
-            if (!this.selectedItem ||
-                !this.mSelectedInternal.parentNode ||
-                this.mSelectedInternal.parentNode.parentNode != this)
-              return -1;
-
-            var children = this.mSelectedInternal.parentNode.children;
-            var i = children.length;
-            while (i--)
-              if (children[i] == this.mSelectedInternal)
-                break;
-
-            return i;
-          ]]>
-        </getter>
-        <setter>
-          <![CDATA[
-            var popup = this.menupopup;
-            if (popup && 0 <= val) {
-              if (val < popup.children.length)
-                this.selectedItem = popup.children[val];
-            } else {
-              this.selectedItem = null;
-            }
-            return val;
-          ]]>
-        </setter>
-      </property>
-
-      <property name="selectedItem">
-        <getter>
-          <![CDATA[
-            return this.mSelectedInternal;
-          ]]>
-        </getter>
-        <setter>
-          <![CDATA[
-            var oldval = this.mSelectedInternal;
-            if (oldval == val)
-              return val;
-
-            if (val && !this.contains(val))
-              return val;
-
-            if (oldval) {
-              oldval.removeAttribute("selected");
-              this.mAttributeObserver.disconnect();
-            }
-
-            this.mSelectedInternal = val;
-            let attributeFilter = ["value", "label", "image", "description"];
-            if (val) {
-              val.setAttribute("selected", "true");
-              for (let attr of attributeFilter) {
-                if (val.hasAttribute(attr)) {
-                  this.setAttribute(attr, val.getAttribute(attr));
-                } else {
-                  this.removeAttribute(attr);
-                }
-              }
-
-              this.mAttributeObserver = new MutationObserver(this.handleMutation.bind(this));
-              this.mAttributeObserver.observe(val, { attributeFilter });
-            } else {
-              for (let attr of attributeFilter) {
-                this.removeAttribute(attr);
-              }
-            }
-
-            var event = document.createEvent("Events");
-            event.initEvent("select", true, true);
-            this.dispatchEvent(event);
-
-            event = document.createEvent("Events");
-            event.initEvent("ValueChange", true, true);
-            this.dispatchEvent(event);
-
-            return val;
-          ]]>
-        </setter>
-      </property>
-
-      <method name="handleMutation">
-        <parameter name="aRecords"/>
-        <body>
-          <![CDATA[
-            for (let record of aRecords) {
-              let t = record.target;
-              if (t == this.mSelectedInternal) {
-                let attrName = record.attributeName;
-                switch (attrName) {
-                  case "value":
-                  case "label":
-                  case "image":
-                  case "description":
-                    if (t.hasAttribute(attrName)) {
-                      this.setAttribute(attrName, t.getAttribute(attrName));
-                    } else {
-                      this.removeAttribute(attrName);
-                    }
-                }
-              }
-            }
-          ]]>
-        </body>
-      </method>
-
-      <method name="getIndexOfItem">
-        <parameter name="item"/>
-        <body>
-        <![CDATA[
-          var popup = this.menupopup;
-          if (popup) {
-            var children = popup.children;
-            var i = children.length;
-            while (i--)
-              if (children[i] == item)
-                return i;
-          }
-          return -1;
-        ]]>
-        </body>
-      </method>
-
-      <method name="getItemAtIndex">
-        <parameter name="index"/>
-        <body>
-        <![CDATA[
-          var popup = this.menupopup;
-          if (popup) {
-            var children = popup.children;
-            if (index >= 0 && index < children.length)
-              return children[index];
-          }
-          return null;
-        ]]>
-        </body>
-      </method>
-
-      <method name="appendItem">
-        <parameter name="label"/>
-        <parameter name="value"/>
-        <parameter name="description"/>
-        <body>
-        <![CDATA[
-          var popup = this.menupopup ||
-                      this.appendChild(document.createXULElement("menupopup"));
-          var item = document.createXULElement("menuitem");
-          item.setAttribute("label", label);
-          item.setAttribute("value", value);
-          if (description)
-            item.setAttribute("description", description);
-
-          popup.appendChild(item);
-          return item;
-        ]]>
-        </body>
-      </method>
-
-      <method name="removeAllItems">
-        <body>
-        <![CDATA[
-          this.selectedItem = null;
-          var popup = this.menupopup;
-          if (popup)
-            this.removeChild(popup);
-        ]]>
-        </body>
-      </method>
-
-      <destructor>
-        <![CDATA[
-          if (this.mAttributeObserver) {
-            this.mAttributeObserver.disconnect();
-          }
-        ]]>
-      </destructor>
-    </implementation>
-  </binding>
-
-  <binding id="menulist-popuponly"
-           extends="chrome://messenger/content/menulist.xml#xbl-menulist">
-    <content>
-      <children includes="menupopup"/>
-    </content>
-  </binding>
-
-  <binding id="menulist-editable" extends="chrome://messenger/content/menulist.xml#xbl-menulist">
-    <content sizetopopup="pref">
-      <xul:moz-input-box class="menulist-editable-box moz-input-box" xbl:inherits="context,disabled,readonly,focused" flex="1">
-        <html:input class="menulist-editable-input" anonid="input" allowevents="true"
-                    xbl:inherits="value=label,value,disabled,tabindex,readonly,placeholder"/>
-      </xul:moz-input-box>
-      <xul:dropmarker class="menulist-dropmarker" type="menu"
-                      xbl:inherits="open,disabled,parentfocused=focused"/>
-      <children/>
-    </content>
-
-    <implementation>
-      <constructor><![CDATA[
-        // This block needs to be kept in sync with the parent constructor in
-        // toolkit/content/widgets/menulist.xml.
-        this.mSelectedInternal = null;
-        this.mAttributeObserver = null;
-        this.setInitialSelection();
-
-        this.dispatchEvent(new CustomEvent("bindingattached", { bubbles: false }));
-      ]]></constructor>
-      <method name="_selectInputFieldValueInList">
-        <body><![CDATA[
-            if (this.hasAttribute("disableautoselect"))
-                return;
-
-            // Find and select the menuitem that matches inputField's "value"
-            var arr = null;
-            var popup = this.menupopup;
-
-            if (popup)
-                arr = popup.getElementsByAttribute("label", this.inputField.value);
-
-            this.setSelectionInternal(arr ? arr.item(0) : null);
-        ]]></body>
-      </method>
-
-      <method name="setSelectionInternal">
-        <parameter name="val"/>
-        <body><![CDATA[
-            // This is called internally to set selected item
-            //  without triggering infinite loop
-            //  when using selectedItem's setter
-            if (this.mSelectedInternal == val)
-                return val;
-
-            if (this.mSelectedInternal)
-                this.mSelectedInternal.removeAttribute("selected");
-
-            this.mSelectedInternal = val;
-
-            if (val)
-                val.setAttribute("selected", "true");
-
-            // Do NOT change the "value", which is owned by inputField
-            return val;
-        ]]></body>
-      </method>
-
-      <property name="editable" readonly="true" onget="return true;"/>
-
-      <property name="inputField" readonly="true">
-        <getter><![CDATA[
-            if (!this.mInputField)
-                this.mInputField = document.getAnonymousElementByAttribute(this, "anonid", "input");
-            return this.mInputField;
-        ]]></getter>
-      </property>
-
-      <property name="label" onget="return this.inputField.value;"
-                             onset="return this.inputField.value = val;"/>
-
-      <property name="value" onget="return this.inputField.value;">
-        <setter><![CDATA[
-            // Override menulist's value setter to refer to the inputField's value
-            // (Allows using "menulist.value" instead of "menulist.inputField.value")
-            this.inputField.value = val;
-            this.setAttribute("value", val);
-            this.setAttribute("label", val);
-            this._selectInputFieldValueInList();
-            return val;
-        ]]></setter>
-      </property>
-
-      <property name="selectedItem">
-        <getter><![CDATA[
-            // Make sure internally-selected item
-            //  is in sync with inputField.value
-            this._selectInputFieldValueInList();
-            return this.mSelectedInternal;
-        ]]></getter>
-        <setter><![CDATA[
-            var oldval = this.mSelectedInternal;
-            if (oldval == val)
-              return val;
-
-            if (val && !this.contains(val))
-              return val;
-
-            // This doesn't touch inputField.value or "value" and "label" attributes
-            this.setSelectionInternal(val);
-            if (val) {
-              // Editable menulist uses "label" as its "value"
-              var label = val.getAttribute("label");
-              this.inputField.value = label;
-              this.setAttribute("value", label);
-              this.setAttribute("label", label);
-            } else {
-              this.inputField.value = "";
-              this.removeAttribute("value");
-              this.removeAttribute("label");
-            }
-
-            var event = document.createEvent("Events");
-            event.initEvent("select", true, true);
-            this.dispatchEvent(event);
-
-            event = document.createEvent("Events");
-            event.initEvent("ValueChange", true, true);
-            this.dispatchEvent(event);
-
-            return val;
-        ]]></setter>
-      </property>
-      <property name="disableautoselect"
-                onget="return this.hasAttribute('disableautoselect');">
-        <setter><![CDATA[
-            if (val) {
-                this.setAttribute("disableautoselect", "true");
-            } else {
-                this.removeAttribute("disableautoselect");
-            }
-            return val;
-        ]]></setter>
-      </property>
-
-      <property name="editor" readonly="true">
-        <getter><![CDATA[
-            return this.inputField.editor;
-        ]]></getter>
-      </property>
-
-      <property name="readOnly" onget="return this.inputField.readOnly;">
-        <setter><![CDATA[
-            this.inputField.readOnly = val;
-            if (val) {
-                this.setAttribute("readonly", "true");
-            } else {
-                this.removeAttribute("readonly");
-            }
-            return val;
-        ]]></setter>
-      </property>
-
-      <method name="select">
-        <body><![CDATA[
-            this.inputField.select();
-        ]]></body>
-      </method>
-    </implementation>
-
-    <handlers>
-      <handler event="focus" phase="capturing"><![CDATA[
-          this.setAttribute("focused", "true");
-      ]]></handler>
-
-      <handler event="blur" phase="capturing"><![CDATA[
-          this.removeAttribute("focused");
-      ]]></handler>
-
-      <handler event="popupshowing"><![CDATA[
-          // editable menulists elements aren't in the focus order,
-          // so when the popup opens we need to force the focus to the inputField
-          if (event.target.parentNode == this) {
-              if (document.commandDispatcher.focusedElement != this.inputField)
-                  this.inputField.focus();
-
-              this.activeChild = null;
-              if (this.selectedItem)
-                  // Not ready for auto-setting the active child in hierarchies yet.
-                  // For now, only do this when the outermost menupopup opens.
-                  this.activeChild = this.mSelectedInternal;
-          }
-      ]]></handler>
-
-      <handler event="keypress"><![CDATA[
-          // open popup if key is up arrow, down arrow, or F4
-          if (!event.ctrlKey && !event.shiftKey) {
-              if (event.keyCode == KeyEvent.DOM_VK_UP ||
-                  event.keyCode == KeyEvent.DOM_VK_DOWN ||
-                  (event.keyCode == KeyEvent.DOM_VK_F4 && !event.altKey)) {
-                  event.preventDefault();
-                  this.open = true;
-              }
-          }
-      ]]></handler>
-    </handlers>
-  </binding>
-</bindings>
--- a/editor/ui/dialogs/content/EdAdvancedEdit.xul
+++ b/editor/ui/dialogs/content/EdAdvancedEdit.xul
@@ -3,17 +3,17 @@
    - 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/. -->
 
 <!-- first checkin of the year 2000!      -->
 <!-- Ben Goodger, 12:50AM, 01/00/00 NZST  -->
 
 <?xml-stylesheet href="chrome://editor/skin/editor.css" type="text/css"?>
 <?xml-stylesheet href="chrome://editor/skin/EditorDialog.css" type="text/css"?>
-<?xml-stylesheet href="chrome://messenger/content/menulist.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/menulist.css" type="text/css"?>
 
 <!DOCTYPE dialog SYSTEM "chrome://editor/locale/EdAdvancedEdit.dtd">
 
 <dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml"
     id="advancedEditDlg"
     style="width: 40em;"
     title="&WindowTitle.label;"
     onload="Startup()"
--- a/editor/ui/dialogs/content/EdFormProps.xul
+++ b/editor/ui/dialogs/content/EdFormProps.xul
@@ -1,16 +1,16 @@
 <?xml version="1.0"?>
 <!-- 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/. -->
 
 <?xml-stylesheet href="chrome://editor/skin/editor.css" type="text/css"?>
 <?xml-stylesheet href="chrome://editor/skin/EditorDialog.css" type="text/css"?>
-<?xml-stylesheet href="chrome://messenger/content/menulist.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/menulist.css" type="text/css"?>
 
 <!DOCTYPE dialog [
 <!ENTITY % edFormProperties SYSTEM "chrome://editor/locale/EditorFormProperties.dtd">
 %edFormProperties;
 <!ENTITY % edDialogOverlay SYSTEM "chrome://editor/locale/EdDialogOverlay.dtd">
 %edDialogOverlay;
 ]>
 
--- a/editor/ui/dialogs/content/EditorPublish.xul
+++ b/editor/ui/dialogs/content/EditorPublish.xul
@@ -1,17 +1,17 @@
 <?xml version="1.0"?>
 
 <!-- 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/. -->
 
 <?xml-stylesheet href="chrome://editor/skin/editor.css" type="text/css"?>
 <?xml-stylesheet href="chrome://editor/skin/EditorDialog.css" type="text/css"?>
-<?xml-stylesheet href="chrome://messenger/content/menulist.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/menulist.css" type="text/css"?>
 
 <?xul-overlay href="chrome://editor/content/EditorPublishOverlay.xul"?>
 
 <!DOCTYPE dialog SYSTEM "chrome://editor/locale/EditorPublish.dtd">
 
 <dialog title="&windowTitle.label;"
         id="publishDlg"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml"
--- a/mail/base/content/bindings.css
+++ b/mail/base/content/bindings.css
@@ -1,17 +1,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/. */
 
 @import url("chrome://global/skin/textbox.css");
 @import url("chrome://messenger/skin/numberbox.css");
 @import url("chrome://messenger/skin/xbl-notification.css");
 @import url("chrome://messenger/skin/spinbuttons.css");
-@import url("chrome://messenger/content/menulist.css");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 toolbox {
   -moz-binding: url("chrome://messenger/content/toolbar.xml#toolbox");
 }
 
 toolbar {
new file mode 100644
--- /dev/null
+++ b/mail/base/content/menulist.css
@@ -0,0 +1,25 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+menulist[is="menulist-editable"]:not([editable="true"]) .menulist-input,
+menulist[is="menulist-editable"][editable="true"] .menulist-label-box {
+  display: none;
+}
+
+menulist > textbox {
+  margin: 0;
+}
+
+menulist html|*.textbox-input {
+  -moz-appearance: none !important;
+  background: transparent !important;
+  -moz-box-flex: 1;
+  margin: 0 !important;
+  border: none !important;
+  padding: 0 !important;
+  font: inherit;
+}
--- a/mail/base/jar.mn
+++ b/mail/base/jar.mn
@@ -34,25 +34,24 @@ messenger.jar:
     content/messenger/customizeToolbar.js           (../../common/src/customizeToolbar.js)
 *   content/messenger/customizeToolbar.xul          (../../common/src/customizeToolbar.xul)
     content/messenger/viewSource.css                (../../common/src/viewSource.css)
     content/messenger/viewSource.js                 (../../common/src/viewSource.js)
 *   content/messenger/viewSource.xul                (../../common/src/viewSource.xul)
     content/messenger/generalBindings.xml           (../../common/bindings/generalBindings.xml)
     content/messenger/generalBindings.js            (../../common/bindings/generalBindings.js)
     content/messenger/menubutton.xml                (../../common/bindings/menubutton.xml)
-    content/messenger/menulist.css                  (../../common/bindings/menulist.css)
-    content/messenger/menulist.xml                  (../../common/bindings/menulist.xml)
     content/messenger/notificationbox.xml           (../../common/bindings/notificationbox.xml)
     content/messenger/numberbox.xml                 (../../common/bindings/numberbox.xml)
     content/messenger/richlistbox.xml               (../../common/bindings/richlistbox.xml)
     content/messenger/spinbuttons.xml               (../../common/bindings/spinbuttons.xml)
 *   content/messenger/textbox.xml                   (../../common/bindings/textbox.xml)
 *   content/messenger/toolbar.xml                   (../../common/bindings/toolbar.xml)
     content/messenger/attachmentList.css            (content/attachmentList.css)
+    content/messenger/menulist.css                  (content/menulist.css)
 *   content/messenger/bindings.css                  (content/bindings.css)
     content/messenger/nsDragAndDrop.js              (content/nsDragAndDrop.js)
     content/messenger/editContactPanel.js           (content/editContactPanel.js)
     content/messenger/msgMail3PaneWindow.js         (content/msgMail3PaneWindow.js)
     content/messenger/mail3PaneWindowCommands.js    (content/mail3PaneWindowCommands.js)
     content/messenger/mailCommands.js               (content/mailCommands.js)
     content/messenger/mailCore.js                   (content/mailCore.js)
     content/messenger/mailTabs.js                   (content/mailTabs.js)
--- a/mail/base/test/browser/files/menulist.xul
+++ b/mail/base/test/browser/files/menulist.xul
@@ -1,12 +1,12 @@
 <?xml version="1.0"?>
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://messenger/content/bindings.css"?>
-<?xml-stylesheet type="text/css" href="chrome://messenger/content/menulist.css"?>
+<?xml-stylesheet type="text/css" href="chrome://messenger/skin/menulist.css"?>
 
 <page align="start" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml">
   <script type="application/javascript" src="chrome://messenger/content/customElements.js"/>
 
   <button id="before" label="I'm just a button" onclick="alert('I\'m a button!')"/>
 
   <menulist>
     <menupopup>
--- a/mail/components/accountcreation/content/emailWizard.xul
+++ b/mail/components/accountcreation/content/emailWizard.xul
@@ -1,15 +1,15 @@
 <?xml version="1.0"?>
 <!-- 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/. -->
 
 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://messenger/content/menulist.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/menulist.css" type="text/css"?>
 <?xml-stylesheet href="chrome://messenger/skin/accountCreation.css" type="text/css"?>
 
 <!DOCTYPE window [
   <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
   %brandDTD;
   <!ENTITY % acDTD SYSTEM "chrome://messenger/locale/accountCreation.dtd">
   %acDTD;
 ]>
--- a/mail/components/compose/content/messengercompose.xul
+++ b/mail/components/compose/content/messengercompose.xul
@@ -4,18 +4,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 <?xml-stylesheet href="chrome://messenger/content/bindings.css" type="text/css"?>
 <?xml-stylesheet href="chrome://messenger/skin/messengercompose/messengercompose.css" type="text/css"?>
 <?xml-stylesheet href="chrome://messenger/skin/folderMenus.css" type="text/css"?>
 <?xml-stylesheet href="chrome://messenger/skin/attachmentList.css" type="text/css"?>
 <?xml-stylesheet href="chrome://messenger/skin/smime/smime-compose.css" type="text/css"?>
 <?xml-stylesheet href="chrome://messenger/skin/compacttheme.css" type="text/css" alternate="yes" title="Light/Dark"?>
-
-<?xml-stylesheet href="chrome://messenger/content/menulist.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/menulist.css" type="text/css"?>
 
 <!DOCTYPE window [
   <!ENTITY % messengercomposeDTD SYSTEM "chrome://messenger/locale/messengercompose/messengercompose.dtd" >
   %messengercomposeDTD;
   <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
   %brandDTD;
   <!ENTITY % charsetDTD SYSTEM "chrome://global/locale/charsetMenu.dtd" >
   %charsetDTD;
--- a/mail/themes/linux/mail/menulist.css
+++ b/mail/themes/linux/mail/menulist.css
@@ -1,12 +1,14 @@
 /* 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/. */
 
+@import url("chrome://messenger/content/menulist.css");
+
 menulist[is="menulist-editable"][editable="true"] {
   -moz-appearance: none;
 }
 
 menulist[is="menulist-editable"][editable="true"] .menulist-dropmarker {
   display: -moz-box;
   min-width: 2em;
 }
--- a/mail/themes/osx/mail/menulist.css
+++ b/mail/themes/osx/mail/menulist.css
@@ -1,12 +1,14 @@
 /* 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/. */
 
+@import url("chrome://messenger/content/menulist.css");
+
 menulist[is="menulist-editable"][editable="true"] {
   margin: 4px 2px;
 }
 
 menulist[is="menulist-editable"][editable="true"] > menupopup,
 menulist[is="menulist-editable"][editable="true"] > menupopup > menuitem,
 menulist[is="menulist-editable"][editable="true"] > menupopup > menucaption {
   -moz-appearance: none;
--- a/mail/themes/windows/mail/menulist.css
+++ b/mail/themes/windows/mail/menulist.css
@@ -1,12 +1,14 @@
 /* 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/. */
 
+@import url("chrome://messenger/content/menulist.css");
+
 menulist[is="menulist-editable"][editable="true"] {
   padding: 0;
 }
 
 .menulist-input {
   -moz-appearance: none;
   border-style: none;
   margin-top: -2px;