Bug 1573678 - Implement the Preferences Search Field. r=aleca a=wsmwk
authorKhushil Mistry <khushil324@gmail.com>
Mon, 29 Jun 2020 20:14:38 -0400
changeset 38892 2649b703cb39d297cdf9f160d02bc8de06f6aa31
parent 38891 e5261df827117563d5dfdd8c34b31691f67ae819
child 38893 b7163d202c82417d08460f47ca3f8edd6c7e8567
push id2649
push userthunderbird@calypsoblue.org
push dateTue, 30 Jun 2020 00:27:57 +0000
treeherdercomm-beta@b7163d202c82 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaleca, wsmwk
bugs1573678
Bug 1573678 - Implement the Preferences Search Field. r=aleca a=wsmwk
calendar/base/content/preferences/alarms.inc.xhtml
calendar/base/content/preferences/categories.inc.xhtml
calendar/base/content/preferences/general.inc.xhtml
calendar/base/content/preferences/views.inc.xhtml
calendar/lightning/content/messenger-overlay-preferences.inc.xhtml
calendar/lightning/content/messenger-overlay-preferences.js
calendar/test/browser/preferences/browser_alarmDefaultValue.js
calendar/test/browser/preferences/browser_categoryColors.js
calendar/test/browser/preferences/head.js
calendar/test/modules/CalendarUtils.jsm
mail/app/profile/all-thunderbird.js
mail/components/enterprisepolicies/tests/browser/browser_policy_app_auto_update.js
mail/components/enterprisepolicies/tests/browser/browser_policy_downloads.js
mail/components/enterprisepolicies/tests/browser/disable_app_update/browser_policy_disable_app_update.js
mail/components/preferences/attachmentReminder.xhtml
mail/components/preferences/chat.inc.xhtml
mail/components/preferences/chat.js
mail/components/preferences/colors.xhtml
mail/components/preferences/compose.inc.xhtml
mail/components/preferences/dockoptions.xhtml
mail/components/preferences/findInPage.js
mail/components/preferences/general.inc.xhtml
mail/components/preferences/general.js
mail/components/preferences/jar.mn
mail/components/preferences/notifications.xhtml
mail/components/preferences/offline.xhtml
mail/components/preferences/preferences.js
mail/components/preferences/preferences.xhtml
mail/components/preferences/privacy.inc.xhtml
mail/components/preferences/receipts.xhtml
mail/components/preferences/searchResults.inc.xhtml
mail/components/preferences/sendoptions.xhtml
mail/components/preferences/test/browser/head.js
mail/test/browser/pref-window/browser_fontChooser.js
mail/themes/linux/mail/preferences/preferences.css
mail/themes/osx/mail/preferences/preferences.css
mail/themes/shared/mail/preferences/dialog.css
mail/themes/shared/mail/preferences/preferences.css
mail/themes/windows/mail/preferences/preferences.css
--- a/calendar/base/content/preferences/alarms.inc.xhtml
+++ b/calendar/base/content/preferences/alarms.inc.xhtml
@@ -1,21 +1,21 @@
 # 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/.
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset data-category="paneCalendar">
         <html:legend data-l10n-id="reminder-legend"></html:legend>
         <vbox id="alarm-sound-box">
             <hbox align="center">
                 <checkbox id="alarmSoundCheckbox"
                           preference="calendar.alarms.playsound"
                           data-l10n-id="reminder-play-checkbox"/>
                 <spacer flex="1"/>
-                <button id="calendar.prefs.alarm.sound.play"
+                <button is="highlightable-button" id="calendar.prefs.alarm.sound.play"
                         data-l10n-id="reminder-play-alarm-button"
                         oncommand="gAlarmsPane.previewAlarm()"/>
             </hbox>
             <radiogroup id="alarmSoundType"
                         class="indent"
                         orient="vertical"
                         preference="calendar.alarms.soundType"
                         aria-labelledby="alarmSoundCheckbox">
@@ -33,17 +33,17 @@
             <hbox align="center" class="input-container">
                 <html:input id="alarmSoundFileField"
                             type="text"
                             class="input-filefield indent"
                             readonly="readonly"
                             preference="calendar.alarms.soundURL"
                             preference-editable="true"
                             aria-labelledby="alarmSoundCustom"/>
-                <button id="calendar.prefs.alarm.sound.browse"
+                <button is="highlightable-button" id="calendar.prefs.alarm.sound.browse"
                         data-l10n-id="reminder-browse-sound-label"
                         oncommand="gAlarmsPane.browseAlarm()"/>
             </hbox>
         </vbox>
         <hbox align="center" flex="1">
             <checkbox id="alarmshow"
                       preference="calendar.alarms.show"
                       data-l10n-id="reminder-dialog-label"/>
@@ -51,17 +51,17 @@
         <hbox align="center" flex="1">
             <checkbox id="missedalarms"
                       preference="calendar.alarms.showmissed"
                       data-l10n-id="missed-reminder-label"/>
         </hbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset data-category="paneCalendar">
         <html:legend data-l10n-id="reminder-default-legend"></html:legend>
         <hbox align="center">
             <label data-l10n-id="default-snooze-label"
                    control="defaultsnoozelength"/>
             <html:input id="defaultsnoozelength" type="number" class="size3"
                         min="0"
                         preference="calendar.alarms.defaultsnoozelength"
@@ -72,109 +72,117 @@
         <hbox>
             <html:table id="alarm-defaults-table">
                 <html:tr>
                     <html:td>
                         <label data-l10n-id="event-alarm-label"
                                control="eventdefalarm"/>
                     </html:td>
                     <html:td>
-                        <menulist id="eventdefalarm"
-                                  crop="none"
-                                  preference="calendar.alarms.onforevents">
-                            <menupopup id="eventdefalarmpopup">
-                                <menuitem id="eventdefalarmon"
-                                          data-l10n-id="alarm-on-label"
-                                          value="1"/>
-                                <menuitem id="eventdefalarmoff"
-                                          data-l10n-id="alarm-off-label"
-                                          value="0"
-                                          selected="true"/>
-                            </menupopup>
-                        </menulist>
+                        <hbox>
+                            <menulist id="eventdefalarm"
+                                      crop="none"
+                                      preference="calendar.alarms.onforevents">
+                                <menupopup id="eventdefalarmpopup">
+                                    <menuitem id="eventdefalarmon"
+                                              data-l10n-id="alarm-on-label"
+                                              value="1"/>
+                                    <menuitem id="eventdefalarmoff"
+                                              data-l10n-id="alarm-off-label"
+                                              value="0"
+                                              selected="true"/>
+                                </menupopup>
+                            </menulist>
+                        </hbox>
                     </html:td>
                 </html:tr>
                 <html:tr>
                     <html:td>
                         <label data-l10n-id="task-alarm-label"
                                control="tododefalarm"/>
                     </html:td>
                     <html:td>
-                        <menulist id="tododefalarm"
-                                  crop="none"
-                                  preference="calendar.alarms.onfortodos">
-                            <menupopup id="tododefalarmpopup">
-                                <menuitem id="tododefalarmon"
-                                          data-l10n-id="alarm-on-label"
-                                          value="1"/>
-                                <menuitem id="tododefalarmoff"
-                                          data-l10n-id="alarm-off-label"
-                                          value="0"
-                                          selected="true"/>
-                            </menupopup>
-                        </menulist>
+                        <hbox>
+                            <menulist id="tododefalarm"
+                                      crop="none"
+                                      preference="calendar.alarms.onfortodos">
+                                <menupopup id="tododefalarmpopup">
+                                    <menuitem id="tododefalarmon"
+                                              data-l10n-id="alarm-on-label"
+                                              value="1"/>
+                                    <menuitem id="tododefalarmoff"
+                                              data-l10n-id="alarm-off-label"
+                                              value="0"
+                                              selected="true"/>
+                                </menupopup>
+                            </menulist>
+                        </hbox>
                     </html:td>
                 </html:tr>
                 <html:tr>
                     <html:td>
                         <label data-l10n-id="event-alarm-time-label"
                                control="eventdefalarmlen"/>
                     </html:td>
                     <html:td>
                         <hbox class="defaultTimeBox"
                               align="center"
                               flex="1">
                             <html:input id="eventdefalarmlen" type="number" class="size3" min="0"
                                         preference="calendar.alarms.eventalarmlen"
                                         onselect="updateMenuLabelsPlural('eventdefalarmlen', 'eventdefalarmunit')"
                                         oninput="updateMenuLabelsPlural('eventdefalarmlen', 'eventdefalarmunit')"/>
-                            <menulist id="eventdefalarmunit"
-                                      flex="1"
-                                      crop="none"
-                                      preference="calendar.alarms.eventalarmunit">
-                                <menupopup id="eventdefalarmunitpopup">
-                                    <menuitem id="eventdefalarmunitmin"
-                                              value="minutes"
-                                              selected="true"/>
-                                    <menuitem id="eventdefalarmunithour"
-                                              value="hours"/>
-                                    <menuitem id="eventdefalarmunitday"
-                                              value="days"/>
-                                </menupopup>
-                            </menulist>
+                            <hbox>
+                                <menulist id="eventdefalarmunit"
+                                          flex="1"
+                                          crop="none"
+                                          preference="calendar.alarms.eventalarmunit">
+                                    <menupopup id="eventdefalarmunitpopup">
+                                        <menuitem id="eventdefalarmunitmin"
+                                                  value="minutes"
+                                                  selected="true"/>
+                                        <menuitem id="eventdefalarmunithour"
+                                                  value="hours"/>
+                                        <menuitem id="eventdefalarmunitday"
+                                                  value="days"/>
+                                    </menupopup>
+                                </menulist>
+                            </hbox>
                         </hbox>
                     </html:td>
                 </html:tr>
                 <html:tr>
                     <html:td>
                         <label data-l10n-id="task-alarm-time-label"
                                control="tododefalarmlen"/>
                     </html:td>
                     <html:td>
                         <hbox class="defaultTimeBox"
                               align="center"
                               flex="1">
                             <html:input id="tododefalarmlen" type="number" class="size3" min="0"
                                         preference="calendar.alarms.todoalarmlen"
                                         onselect="updateMenuLabelsPlural('tododefalarmlen', 'tododefalarmunit')"
                                         oninput="updateMenuLabelsPlural('tododefalarmlen', 'tododefalarmunit')"/>
-                            <menulist id="tododefalarmunit"
-                                      flex="1"
-                                      crop="none"
-                                      preference="calendar.alarms.todoalarmunit">
-                                <menupopup id="tododefalarmunitpopup">
-                                    <menuitem id="tododefalarmunitmin"
-                                              value="minutes"
-                                              selected="true"/>
-                                    <menuitem id="tododefalarmunithour"
-                                              value="hours"/>
-                                    <menuitem id="tododefalarmunitday"
-                                              value="days"/>
-                                </menupopup>
-                            </menulist>
+                            <hbox>
+                                <menulist id="tododefalarmunit"
+                                          flex="1"
+                                          crop="none"
+                                          preference="calendar.alarms.todoalarmunit">
+                                    <menupopup id="tododefalarmunitpopup">
+                                        <menuitem id="tododefalarmunitmin"
+                                                  value="minutes"
+                                                  selected="true"/>
+                                        <menuitem id="tododefalarmunithour"
+                                                  value="hours"/>
+                                        <menuitem id="tododefalarmunitday"
+                                                  value="days"/>
+                                    </menupopup>
+                                </menulist>
+                            </hbox>
                         </hbox>
                     </html:td>
                 </html:tr>
             </html:table>
             <spacer flex="1"/>
         </hbox>
     </html:fieldset>
     </html:div>
--- a/calendar/base/content/preferences/categories.inc.xhtml
+++ b/calendar/base/content/preferences/categories.inc.xhtml
@@ -1,26 +1,36 @@
 # 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/.
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset data-category="paneCalendar">
         <separator class="thin"/>
         <hbox>
           <richlistbox id="categorieslist"
                        flex="1"
                        seltype="multiple"
                        onselect="gCategoriesPane.updateButtons()"
                        ondblclick="gCategoriesPane.listOnDblClick(event)"/>
-          <vbox ic="categoriesButtons">
-              <button id="newCButton"
-                      data-l10n-id="new-tag-button"
-                      oncommand="gCategoriesPane.addCategory()"/>
-              <button id="editCButton"
-                      data-l10n-id="edit-tag-button"
-                      oncommand="gCategoriesPane.editCategory()"/>
-              <button id="deleteCButton"
+          <vbox id="categoriesButtons">
+              <hbox>
+                  <button is="highlightable-button" id="newCButton"
+                          data-l10n-id="new-tag-button"
+                          oncommand="gCategoriesPane.addCategory()"
+                          search-l10n-ids="
+                            category-name-label,
+                            category-color-label.label"/>
+              </hbox>
+              <hbox>
+                  <button is="highlightable-button" id="editCButton"
+                          data-l10n-id="edit-tag-button"
+                          oncommand="gCategoriesPane.editCategory()"
+                          search-l10n-ids="
+                            category-name-label,
+                            category-color-label.label"/>
+              </hbox>
+              <button is="highlightable-button" id="deleteCButton"
                       data-l10n-id="delete-tag-button"
                       oncommand="gCategoriesPane.deleteCategory()"/>
           </vbox>
         </hbox>
     </html:fieldset>
     </html:div>
--- a/calendar/base/content/preferences/general.inc.xhtml
+++ b/calendar/base/content/preferences/general.inc.xhtml
@@ -1,37 +1,39 @@
 # 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/.
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset data-category="paneCalendar">
         <html:legend data-l10n-id="todaypane-legend"></html:legend>
         <hbox align="center">
             <label data-l10n-id="soon-label"
                    control="soondays-menulist"/>
-            <menulist id="soondays-menulist"
-                      preference="calendar.agendaListbox.soondays">
-                <menupopup id="soondaysdurationpopup">
-                    <menuitem value="1"/>
-                    <menuitem value="2"/>
-                    <menuitem value="3"/>
-                    <menuitem value="4"/>
-                    <menuitem value="5"/>
-                    <menuitem value="6"/>
-                    <menuitem value="7"/>
-                    <menuitem value="14"/>
-                    <menuitem value="21"/>
-                    <menuitem value="28"/>
-                </menupopup>
-            </menulist>
+            <hbox>
+                <menulist id="soondays-menulist"
+                          preference="calendar.agendaListbox.soondays">
+                    <menupopup id="soondaysdurationpopup">
+                        <menuitem value="1"/>
+                        <menuitem value="2"/>
+                        <menuitem value="3"/>
+                        <menuitem value="4"/>
+                        <menuitem value="5"/>
+                        <menuitem value="6"/>
+                        <menuitem value="7"/>
+                        <menuitem value="14"/>
+                        <menuitem value="21"/>
+                        <menuitem value="28"/>
+                    </menupopup>
+                </menulist>
+            </hbox>
         </hbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset id="defaults-itemtype-groupbox" data-category="paneCalendar">
         <html:legend data-l10n-id="event-task-legend"></html:legend>
         <vbox id="defaults-itemtype-box">
             <hbox id="defaults-event-grid-box" align="center">
                 <label id="default-event-length-label"
                        data-l10n-id="default-length-label"
                        control="defaultlength"/>
                 <html:input id="defaultlength" type="number"
@@ -45,136 +47,144 @@
             <html:table id="defaults-task-table">
                 <html:tr id="defaults-task-start-row">
                     <html:td>
                         <label id="default-task-start-label"
                                data-l10n-id="task-start-label"
                                control="default_task_start"/>
                     </html:td>
                     <html:td>
-                        <menulist id="default_task_start"
-                                  crop="none"
-                                  oncommand="gCalendarGeneralPane.updateDefaultTodoDates()"
-                                  preference="calendar.task.defaultstart">
-                            <menupopup id="default_task_start_popup">
-                                <menuitem id="default_task_start_none"
-                                          data-l10n-id="task-start-1-label"
-                                          value="none"
-                                          selected="true"/>
-                                <menuitem id="default_task_start_start_of_day"
-                                          data-l10n-id="task-start-2-label"
-                                          value="startofday"/>
-                                <menuitem id="default_task_start_tomorrow"
-                                          data-l10n-id="task-start-4-label"
-                                          value="tomorrow"/>
-                                <menuitem id="default_task_start_next_week"
-                                          data-l10n-id="task-start-5-label"
-                                          value="nextweek"/>
-                                <menuitem id="default_task_start_offset_current"
-                                          data-l10n-id="task-start-6-label"
-                                          value="offsetcurrent"/>
-                                <menuitem id="default_task_start_offset_next_hour"
-                                          data-l10n-id="task-start-8-label"
-                                          value="offsetnexthour"/>
-                            </menupopup>
-                        </menulist>
+                        <hbox>
+                            <menulist id="default_task_start"
+                                      crop="none"
+                                      oncommand="gCalendarGeneralPane.updateDefaultTodoDates()"
+                                      preference="calendar.task.defaultstart">
+                                <menupopup id="default_task_start_popup">
+                                    <menuitem id="default_task_start_none"
+                                              data-l10n-id="task-start-1-label"
+                                              value="none"
+                                              selected="true"/>
+                                    <menuitem id="default_task_start_start_of_day"
+                                              data-l10n-id="task-start-2-label"
+                                              value="startofday"/>
+                                    <menuitem id="default_task_start_tomorrow"
+                                              data-l10n-id="task-start-4-label"
+                                              value="tomorrow"/>
+                                    <menuitem id="default_task_start_next_week"
+                                              data-l10n-id="task-start-5-label"
+                                              value="nextweek"/>
+                                    <menuitem id="default_task_start_offset_current"
+                                              data-l10n-id="task-start-6-label"
+                                              value="offsetcurrent"/>
+                                    <menuitem id="default_task_start_offset_next_hour"
+                                              data-l10n-id="task-start-8-label"
+                                              value="offsetnexthour"/>
+                                </menupopup>
+                            </menulist>
+                        </hbox>
                     </html:td>
                     <html:td>
                         <hbox id="default_task_start_offset" align="center">
                             <html:input id="default_task_start_offset_text" type="number"
                                         class="size3"
                                         min="0"
                                         preference="calendar.task.defaultstartoffset"
                                         onselect="updateMenuLabelsPlural('default_task_start_offset_text', 'default_task_start_offset_units')"
                                         oninput="updateMenuLabelsPlural('default_task_start_offset_text', 'default_task_start_offset_units')"/>
-                            <menulist id="default_task_start_offset_units"
-                                      crop="none"
-                                      preference="calendar.task.defaultstartoffsetunits">
-                                <menupopup id="default_task_start_offset_units_popup">
-                                    <menuitem id="default_task_start_offset_units_minutes"
-                                              value="minutes"
-                                              selected="true"/>
-                                    <menuitem id="default_task_start_offset_units_hours"
-                                              value="hours"/>
-                                    <menuitem id="default_task_start_offset_units_days"
-                                              value="days"/>
-                                </menupopup>
-                            </menulist>
+                            <hbox>
+                                <menulist id="default_task_start_offset_units"
+                                          crop="none"
+                                          preference="calendar.task.defaultstartoffsetunits">
+                                    <menupopup id="default_task_start_offset_units_popup">
+                                        <menuitem id="default_task_start_offset_units_minutes"
+                                                  value="minutes"
+                                                  selected="true"/>
+                                        <menuitem id="default_task_start_offset_units_hours"
+                                                  value="hours"/>
+                                        <menuitem id="default_task_start_offset_units_days"
+                                                  value="days"/>
+                                    </menupopup>
+                                </menulist>
+                            </hbox>
                         </hbox>
                     </html:td>
                 </html:tr>
                 <html:tr id="defaults-task-due-row">
                     <html:td>
                         <label id="default-task-due-label"
                                data-l10n-id="task-due-label"
                                control="default_task_due"/>
                     </html:td>
                     <html:td>
-                        <menulist id="default_task_due"
-                                  crop="none"
-                                  oncommand="gCalendarGeneralPane.updateDefaultTodoDates()"
-                                  preference="calendar.task.defaultdue">
-                            <menupopup id="default_task_due_popup">
-                                <menuitem id="default_task_due_none"
-                                          data-l10n-id="task-start-1-label"
-                                          value="none"
-                                          selected="true"/>
-                                <menuitem id="default_task_due_end_of_day"
-                                          data-l10n-id="task-start-3-label"
-                                          value="endofday"/>
-                                <menuitem id="default_task_due_tomorrow"
-                                          data-l10n-id="task-start-4-label"
-                                          value="tomorrow"/>
-                                <menuitem id="default_task_due_next_week"
-                                          data-l10n-id="task-start-5-label"
-                                          value="nextweek"/>
-                                <menuitem id="default_task_due_offset_current"
-                                          data-l10n-id="task-start-7-label"
-                                          value="offsetcurrent"/>
-                                <menuitem id="default_task_due_offset_next_hour"
-                                          data-l10n-id="task-start-8-label"
-                                          value="offsetnexthour"/>
-                            </menupopup>
-                        </menulist>
+                        <hbox>
+                            <menulist id="default_task_due"
+                                      crop="none"
+                                      oncommand="gCalendarGeneralPane.updateDefaultTodoDates()"
+                                      preference="calendar.task.defaultdue">
+                                <menupopup id="default_task_due_popup">
+                                    <menuitem id="default_task_due_none"
+                                              data-l10n-id="task-start-1-label"
+                                              value="none"
+                                              selected="true"/>
+                                    <menuitem id="default_task_due_end_of_day"
+                                              data-l10n-id="task-start-3-label"
+                                              value="endofday"/>
+                                    <menuitem id="default_task_due_tomorrow"
+                                              data-l10n-id="task-start-4-label"
+                                              value="tomorrow"/>
+                                    <menuitem id="default_task_due_next_week"
+                                              data-l10n-id="task-start-5-label"
+                                              value="nextweek"/>
+                                    <menuitem id="default_task_due_offset_current"
+                                              data-l10n-id="task-start-7-label"
+                                              value="offsetcurrent"/>
+                                    <menuitem id="default_task_due_offset_next_hour"
+                                              data-l10n-id="task-start-8-label"
+                                              value="offsetnexthour"/>
+                                </menupopup>
+                            </menulist>
+                        </hbox>
                     </html:td>
                     <html:td>
                         <hbox id="default_task_due_offset" align="center">
                             <html:input id="default_task_due_offset_text" type="number"
                                         class="size3"
                                         min="0"
                                         preference="calendar.task.defaultdueoffset"
                                         onselect="updateMenuLabelsPlural('default_task_due_offset_text', 'default_task_due_offset_units')"
                                         oninput="updateMenuLabelsPlural('default_task_due_offset_text', 'default_task_due_offset_units')"/>
-                            <menulist id="default_task_due_offset_units"
-                                      crop="none"
-                                      preference="calendar.task.defaultdueoffsetunits">
-                                <menupopup id="default_task_due_offset_units_popup">
-                                    <menuitem id="default_task_due_offset_units_minutes"
-                                              value="minutes"
-                                              selected="true"/>
-                                    <menuitem id="default_task_due_offset_units_hours"
-                                              value="hours"/>
-                                    <menuitem id="default_task_due_offset_units_days"
-                                              value="days"/>
-                                </menupopup>
-                            </menulist>
+                            <hbox>
+                                <menulist id="default_task_due_offset_units"
+                                          crop="none"
+                                          preference="calendar.task.defaultdueoffsetunits">
+                                    <menupopup id="default_task_due_offset_units_popup">
+                                        <menuitem id="default_task_due_offset_units_minutes"
+                                                  value="minutes"
+                                                  selected="true"/>
+                                        <menuitem id="default_task_due_offset_units_hours"
+                                                  value="hours"/>
+                                        <menuitem id="default_task_due_offset_units_days"
+                                                  value="days"/>
+                                    </menupopup>
+                                </menulist>
+                            </hbox>
                         </hbox>
                     </html:td>
                 </html:tr>
             </html:table>
         </vbox>
         <hbox align="center">
             <checkbox id="tabedit" pack="end"
                       data-l10n-id="edit-intab-label"
                       preference="calendar.item.editInTab"/>
         </hbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset id="systemColorsGroupbox" data-category="paneCalendar">
         <html:legend data-l10n-id="accessibility-legend"></html:legend>
         <hbox align="center">
             <checkbox id="systemColors" pack="end"
                       data-l10n-id="accessibility-colors-label"
                       preference="calendar.view.useSystemColors"/>
         </hbox>
     </html:fieldset>
--- a/calendar/base/content/preferences/views.inc.xhtml
+++ b/calendar/base/content/preferences/views.inc.xhtml
@@ -1,13 +1,12 @@
 # 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/.
-
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset data-category="paneCalendar">
         <separator/>
         <box id="datePrefsBox">
             <hbox align="center">
                 <label data-l10n-id="dateformat-label"
                        control="dateformat"/>
             </hbox>
             <hbox align="center">
@@ -106,168 +105,178 @@
                               orient="vertical"
                               preference="calendar.week.d6saturdaysoff"/>
                 </hbox>
             </vbox>
         </hbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset data-category="paneCalendar">
         <html:legend data-l10n-id="dayweek-legend"></html:legend>
         <html:table id="dayAndWeekViewsTable">
             <html:tr>
                 <html:th>
                    <label data-l10n-id="visible-hours-label"
                           control="visiblehours"/>
                 </html:th>
                 <html:td>
                     <hbox align="center">
-                    <menulist id="visiblehours"
-                              preference="calendar.view.visiblehours">
-                        <menupopup id="visiblehourspopup">
-                            <menuitem label="1" value="1"/>
-                            <menuitem label="2" value="2"/>
-                            <menuitem label="3" value="3"/>
-                            <menuitem label="4" value="4"/>
-                            <menuitem label="5" value="5"/>
-                            <menuitem label="6" value="6"/>
-                            <menuitem label="7" value="7"/>
-                            <menuitem label="8" value="8"/>
-                            <menuitem label="9" value="9"/>
-                            <menuitem label="10" value="10"/>
-                            <menuitem label="11" value="11"/>
-                            <menuitem label="12" value="12"/>
-                            <menuitem label="13" value="13"/>
-                            <menuitem label="14" value="14"/>
-                            <menuitem label="15" value="15"/>
-                            <menuitem label="16" value="16"/>
-                            <menuitem label="17" value="17"/>
-                            <menuitem label="18" value="18"/>
-                            <menuitem label="19" value="19"/>
-                            <menuitem label="20" value="20"/>
-                            <menuitem label="21" value="21"/>
-                            <menuitem label="22" value="22"/>
-                            <menuitem label="23" value="23"/>
-                            <menuitem label="24" value="24"/>
-                        </menupopup>
-                    </menulist>
+                    <hbox>
+                        <menulist id="visiblehours"
+                                  preference="calendar.view.visiblehours">
+                            <menupopup id="visiblehourspopup">
+                                <menuitem label="1" value="1"/>
+                                <menuitem label="2" value="2"/>
+                                <menuitem label="3" value="3"/>
+                                <menuitem label="4" value="4"/>
+                                <menuitem label="5" value="5"/>
+                                <menuitem label="6" value="6"/>
+                                <menuitem label="7" value="7"/>
+                                <menuitem label="8" value="8"/>
+                                <menuitem label="9" value="9"/>
+                                <menuitem label="10" value="10"/>
+                                <menuitem label="11" value="11"/>
+                                <menuitem label="12" value="12"/>
+                                <menuitem label="13" value="13"/>
+                                <menuitem label="14" value="14"/>
+                                <menuitem label="15" value="15"/>
+                                <menuitem label="16" value="16"/>
+                                <menuitem label="17" value="17"/>
+                                <menuitem label="18" value="18"/>
+                                <menuitem label="19" value="19"/>
+                                <menuitem label="20" value="20"/>
+                                <menuitem label="21" value="21"/>
+                                <menuitem label="22" value="22"/>
+                                <menuitem label="23" value="23"/>
+                                <menuitem label="24" value="24"/>
+                            </menupopup>
+                        </menulist>
+                    </hbox>
                     <label data-l10n-id="visible-hours-end-label"/>
                     </hbox>
                 </html:td>
             </html:tr>
             <html:tr>
                 <html:th>
                     <label data-l10n-id="day-start-label"
                            control="daystarthour"/>
                 </html:th>
                 <html:td>
-                    <menulist id="daystarthour"
-                              oncommand="gViewsPane.updateViewEndMenu(this.value);"
-                              preference="calendar.view.daystarthour">
-                        <menupopup id="daystarthourpopup">
-                            <menuitem id="timeStart0" value="0" data-l10n-id="midnight-label"/>
-                            <menuitem id="timeStart1" value="1"/>
-                            <menuitem id="timeStart2" value="2"/>
-                            <menuitem id="timeStart3" value="3"/>
-                            <menuitem id="timeStart4" value="4"/>
-                            <menuitem id="timeStart5" value="5"/>
-                            <menuitem id="timeStart6" value="6"/>
-                            <menuitem id="timeStart7" value="7"/>
-                            <menuitem id="timeStart8" value="8"/>
-                            <menuitem id="timeStart9" value="9"/>
-                            <menuitem id="timeStart10" value="10"/>
-                            <menuitem id="timeStart11" value="11"/>
-                            <menuitem id="timeStart12" value="12" data-l10n-id="noon-label"/>
-                            <menuitem id="timeStart13" value="13"/>
-                            <menuitem id="timeStart14" value="14"/>
-                            <menuitem id="timeStart15" value="15"/>
-                            <menuitem id="timeStart16" value="16"/>
-                            <menuitem id="timeStart17" value="17"/>
-                            <menuitem id="timeStart18" value="18"/>
-                            <menuitem id="timeStart19" value="19"/>
-                            <menuitem id="timeStart20" value="20"/>
-                            <menuitem id="timeStart21" value="21"/>
-                            <menuitem id="timeStart22" value="22"/>
-                            <menuitem id="timeStart23" value="23"/>
-                        </menupopup>
-                    </menulist>
+                    <hbox>
+                        <menulist id="daystarthour"
+                                  oncommand="gViewsPane.updateViewEndMenu(this.value);"
+                                  preference="calendar.view.daystarthour">
+                            <menupopup id="daystarthourpopup">
+                                <menuitem id="timeStart0" value="0" data-l10n-id="midnight-label"/>
+                                <menuitem id="timeStart1" value="1"/>
+                                <menuitem id="timeStart2" value="2"/>
+                                <menuitem id="timeStart3" value="3"/>
+                                <menuitem id="timeStart4" value="4"/>
+                                <menuitem id="timeStart5" value="5"/>
+                                <menuitem id="timeStart6" value="6"/>
+                                <menuitem id="timeStart7" value="7"/>
+                                <menuitem id="timeStart8" value="8"/>
+                                <menuitem id="timeStart9" value="9"/>
+                                <menuitem id="timeStart10" value="10"/>
+                                <menuitem id="timeStart11" value="11"/>
+                                <menuitem id="timeStart12" value="12" data-l10n-id="noon-label"/>
+                                <menuitem id="timeStart13" value="13"/>
+                                <menuitem id="timeStart14" value="14"/>
+                                <menuitem id="timeStart15" value="15"/>
+                                <menuitem id="timeStart16" value="16"/>
+                                <menuitem id="timeStart17" value="17"/>
+                                <menuitem id="timeStart18" value="18"/>
+                                <menuitem id="timeStart19" value="19"/>
+                                <menuitem id="timeStart20" value="20"/>
+                                <menuitem id="timeStart21" value="21"/>
+                                <menuitem id="timeStart22" value="22"/>
+                                <menuitem id="timeStart23" value="23"/>
+                            </menupopup>
+                        </menulist>
+                    </hbox>
                 </html:td>
             </html:tr>
             <html:tr>
                 <html:th>
                     <label data-l10n-id="day-end-label"
                            control="dayendhour"/>
                 </html:th>
                 <html:td>
-                    <menulist id="dayendhour"
-                              oncommand="gViewsPane.updateViewStartMenu(this.value);"
-                              preference="calendar.view.dayendhour">
-                        <menupopup id="dayendhourpopup">
-                            <menuitem id="timeEnd1" value="1"/>
-                            <menuitem id="timeEnd2" value="2"/>
-                            <menuitem id="timeEnd3" value="3"/>
-                            <menuitem id="timeEnd4" value="4"/>
-                            <menuitem id="timeEnd5" value="5"/>
-                            <menuitem id="timeEnd6" value="6"/>
-                            <menuitem id="timeEnd7" value="7"/>
-                            <menuitem id="timeEnd8" value="8"/>
-                            <menuitem id="timeEnd9" value="9"/>
-                            <menuitem id="timeEnd10" value="10"/>
-                            <menuitem id="timeEnd11" value="11"/>
-                            <menuitem id="timeEnd12" value="12" data-l10n-id="noon-label"/>
-                            <menuitem id="timeEnd13" value="13"/>
-                            <menuitem id="timeEnd14" value="14"/>
-                            <menuitem id="timeEnd15" value="15"/>
-                            <menuitem id="timeEnd16" value="16"/>
-                            <menuitem id="timeEnd17" value="17"/>
-                            <menuitem id="timeEnd18" value="18"/>
-                            <menuitem id="timeEnd19" value="19"/>
-                            <menuitem id="timeEnd20" value="20"/>
-                            <menuitem id="timeEnd21" value="21"/>
-                            <menuitem id="timeEnd22" value="22"/>
-                            <menuitem id="timeEnd23" value="23"/>
-                            <menuitem id="timeEnd24" value="24" data-l10n-id="midnight-label"/>
-                        </menupopup>
-                    </menulist>
+                    <hbox>
+                        <menulist id="dayendhour"
+                                  oncommand="gViewsPane.updateViewStartMenu(this.value);"
+                                  preference="calendar.view.dayendhour">
+                            <menupopup id="dayendhourpopup">
+                                <menuitem id="timeEnd1" value="1"/>
+                                <menuitem id="timeEnd2" value="2"/>
+                                <menuitem id="timeEnd3" value="3"/>
+                                <menuitem id="timeEnd4" value="4"/>
+                                <menuitem id="timeEnd5" value="5"/>
+                                <menuitem id="timeEnd6" value="6"/>
+                                <menuitem id="timeEnd7" value="7"/>
+                                <menuitem id="timeEnd8" value="8"/>
+                                <menuitem id="timeEnd9" value="9"/>
+                                <menuitem id="timeEnd10" value="10"/>
+                                <menuitem id="timeEnd11" value="11"/>
+                                <menuitem id="timeEnd12" value="12" data-l10n-id="noon-label"/>
+                                <menuitem id="timeEnd13" value="13"/>
+                                <menuitem id="timeEnd14" value="14"/>
+                                <menuitem id="timeEnd15" value="15"/>
+                                <menuitem id="timeEnd16" value="16"/>
+                                <menuitem id="timeEnd17" value="17"/>
+                                <menuitem id="timeEnd18" value="18"/>
+                                <menuitem id="timeEnd19" value="19"/>
+                                <menuitem id="timeEnd20" value="20"/>
+                                <menuitem id="timeEnd21" value="21"/>
+                                <menuitem id="timeEnd22" value="22"/>
+                                <menuitem id="timeEnd23" value="23"/>
+                                <menuitem id="timeEnd24" value="24" data-l10n-id="midnight-label"/>
+                            </menupopup>
+                        </menulist>
+                    </hbox>
                 </html:td>
             </html:tr>
         </html:table>
         <checkbox id="showLocation" pack="end"
                   data-l10n-id="location-checkbox"
                   preference="calendar.view.showLocation"/>
         <spacer/>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneCalendar">
     <html:fieldset id="viewsMultiweekGroupbox" data-category="paneCalendar">
         <html:legend data-l10n-id="multiweek-legend"></html:legend>
         <hbox align="center">
             <label data-l10n-id="number-of-weeks-label"
                    control="viewsMultiweekTotalWeeks"/>
-            <menulist id="viewsMultiweekTotalWeeks"
-                      preference="calendar.weeks.inview">
-                <menupopup>
-                    <menuitem data-l10n-id="week-1-label" value="1"/>
-                    <menuitem data-l10n-id="week-2-label" value="2"/>
-                    <menuitem data-l10n-id="week-3-label" value="3"/>
-                    <menuitem data-l10n-id="week-4-label" value="4"/>
-                    <menuitem data-l10n-id="week-5-label" value="5"/>
-                    <menuitem data-l10n-id="week-6-label" value="6"/>
-                </menupopup>
-            </menulist>
+            <hbox>
+                <menulist id="viewsMultiweekTotalWeeks"
+                          preference="calendar.weeks.inview">
+                    <menupopup>
+                        <menuitem data-l10n-id="week-1-label" value="1"/>
+                        <menuitem data-l10n-id="week-2-label" value="2"/>
+                        <menuitem data-l10n-id="week-3-label" value="3"/>
+                        <menuitem data-l10n-id="week-4-label" value="4"/>
+                        <menuitem data-l10n-id="week-5-label" value="5"/>
+                        <menuitem data-l10n-id="week-6-label" value="6"/>
+                    </menupopup>
+                </menulist>
+            </hbox>
         </hbox>
         <hbox align="center" id="previousWeeksBox">
             <label data-l10n-id="previous-weeks-label"
                    control="viewsMultiweekPreviousWeeks"/>
-            <menulist id="viewsMultiweekPreviousWeeks"
-                      preference="calendar.previousweeks.inview">
-                <menupopup>
-                    <menuitem data-l10n-id="week-0-label" value="0"/>
-                    <menuitem data-l10n-id="week-1-label" value="1"/>
-                    <menuitem data-l10n-id="week-2-label" value="2"/>
-                </menupopup>
-            </menulist>
+            <hbox>
+                <menulist id="viewsMultiweekPreviousWeeks"
+                          preference="calendar.previousweeks.inview">
+                    <menupopup>
+                        <menuitem data-l10n-id="week-0-label" value="0"/>
+                        <menuitem data-l10n-id="week-1-label" value="1"/>
+                        <menuitem data-l10n-id="week-2-label" value="2"/>
+                    </menupopup>
+                </menulist>
+            </hbox>
         </hbox>
     </html:fieldset>
     </html:div>
--- a/calendar/lightning/content/messenger-overlay-preferences.inc.xhtml
+++ b/calendar/lightning/content/messenger-overlay-preferences.inc.xhtml
@@ -1,24 +1,23 @@
 # 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/.
 
 # This file requires the following localization files:
 # chrome://lightning/locale/lightning.dtd
 # chrome://calendar/locale/global.dtd
 # chrome://calendar/locale/calendar-event-dialog.dtd
-
-  <prefpane id="paneLightning"
-            flex="1"
-            insertbefore="paneAdvanced">
-
-    <linkset>
-      <html:link rel="localization" href="calendar/preferences.ftl"/>
-    </linkset>
+  <linkset>
+    <html:link rel="localization" href="calendar/preferences.ftl"/>
+    <html:link rel="localization" href="calendar/category-dialog.ftl"/>
+  </linkset>
+  <html:template id="paneCalendar"
+                 flex="1"
+                 insertbefore="paneChat">
 
     <hbox id="calendarPaneCategory"
           class="subcategory"
           data-category="paneCalendar">
       <html:h1 data-l10n-id="calendar-title"></html:h1>
     </hbox>
 
 #include ../../base/content/preferences/views.inc.xhtml
@@ -34,9 +33,9 @@
 
     <hbox id="calendarCategoriesCategory"
           class="subcategory"
           data-category="paneCalendar">
       <html:h1 data-l10n-id="calendar-title-category"></html:h1>
     </hbox>
 
 #include ../../base/content/preferences/categories.inc.xhtml
-  </prefpane>
+  </html:template>
--- a/calendar/lightning/content/messenger-overlay-preferences.js
+++ b/calendar/lightning/content/messenger-overlay-preferences.js
@@ -11,20 +11,18 @@
 /* import-globals-from ../../base/content/preferences/categories.js */
 /* import-globals-from ../../base/content/preferences/general.js */
 /* import-globals-from ../../base/content/preferences/views.js */
 
 Preferences.add({ id: "calendar.preferences.lightning.selectedTabIndex", type: "int" });
 
 var gLightningPane = {
   init() {
-    let elements = document.querySelectorAll("#paneLightning preference");
+    let elements = document.querySelectorAll("#paneCalendar preference");
     for (let element of elements) {
       element.updateElements();
     }
+    gCalendarGeneralPane.init();
+    gAlarmsPane.init();
+    gCategoriesPane.init();
+    gViewsPane.init();
   },
 };
-
-gCalendarGeneralPane.init();
-gAlarmsPane.init();
-gCategoriesPane.init();
-gViewsPane.init();
-gLightningPane.init();
--- a/calendar/test/browser/preferences/browser_alarmDefaultValue.js
+++ b/calendar/test/browser/preferences/browser_alarmDefaultValue.js
@@ -26,20 +26,17 @@ add_task(async function testDefaultAlarm
   let unitString = PluralForm.get(DEFVALUE, localeUnitString).replace("#1", DEFVALUE);
   let alarmString = (...args) => cal.l10n.getString("calendar-alarms", ...args);
   let originStringEvent = alarmString("reminderCustomOriginBeginBeforeEvent");
   let originStringTask = alarmString("reminderCustomOriginBeginBeforeTask");
   let expectedEventReminder = alarmString("reminderCustomTitle", [unitString, originStringEvent]);
   let expectedTaskReminder = alarmString("reminderCustomTitle", [unitString, originStringTask]);
 
   // Configure the lightning preferences.
-  let { prefsWindow, prefsDocument } = await openNewPrefsTab(
-    "paneLightning",
-    "defaultsnoozelength"
-  );
+  let { prefsWindow, prefsDocument } = await openNewPrefsTab("paneCalendar", "defaultsnoozelength");
   await handlePrefTab(prefsWindow, prefsDocument);
 
   // Create New Event.
   let eventDialogPromise = BrowserTestUtils.domWindowOpened(null, async win => {
     await BrowserTestUtils.waitForEvent(win, "load");
     return win.document.documentURI == "chrome://calendar/content/calendar-event-dialog.xhtml";
   });
   EventUtils.synthesizeKey("i", { accelKey: true });
--- a/calendar/test/browser/preferences/browser_categoryColors.js
+++ b/calendar/test/browser/preferences/browser_categoryColors.js
@@ -9,28 +9,27 @@ add_task(async function testCategoryColo
   let calendar = manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
   calendar.name = "Mochitest";
   manager.registerCalendar(calendar);
 
   registerCleanupFunction(async () => {
     manager.unregisterCalendar(calendar);
   });
 
-  let { prefsWindow, prefsDocument } = await openNewPrefsTab("paneLightning", "categorieslist");
+  let { prefsWindow, prefsDocument } = await openNewPrefsTab("paneCalendar", "categorieslist");
 
   let listBox = prefsDocument.getElementById("categorieslist");
   Assert.equal(listBox.itemChildren.length, 22);
 
   for (let item of listBox.itemChildren) {
     info(`${item.firstElementChild.value}: ${item.lastElementChild.style.backgroundColor}`);
     Assert.ok(item.lastElementChild.style.backgroundColor);
   }
 
   // Edit the name and colour of a built-in category.
-
   EventUtils.synthesizeMouse(listBox, 5, 5, {}, prefsWindow);
   Assert.equal(listBox.selectedIndex, 0);
   EventUtils.synthesizeMouseAtCenter(prefsDocument.getElementById("editCButton"), {}, prefsWindow);
 
   let subDialogBrowser = prefsDocument.getElementById("dialogOverlay-0").querySelector("browser");
   await BrowserTestUtils.waitForEvent(subDialogBrowser, "load");
   if (subDialogBrowser.contentWindow.location.href == "about:blank") {
     await BrowserTestUtils.waitForEvent(subDialogBrowser, "load");
--- a/calendar/test/browser/preferences/head.js
+++ b/calendar/test/browser/preferences/head.js
@@ -7,34 +7,29 @@
 async function openNewPrefsTab(paneID, scrollPaneTo, otherArgs) {
   let tabmail = document.getElementById("tabmail");
   let prefsTabMode = tabmail.tabModes.preferencesTab;
 
   Assert.equal(prefsTabMode.tabs.length, 0, "Prefs tab is not open");
 
   let prefsDocument = await new Promise(resolve => {
     Services.obs.addObserver(function documentLoaded(subject) {
-      if (subject.URL == "about:preferences") {
+      if (subject.URL.startsWith("about:preferences")) {
         Services.obs.removeObserver(documentLoaded, "chrome-document-loaded");
         resolve(subject);
       }
     }, "chrome-document-loaded");
     openPreferencesTab(paneID, scrollPaneTo, otherArgs);
   });
-  Assert.ok(prefsDocument.URL == "about:preferences", "Prefs tab is open");
+  Assert.ok(prefsDocument.URL.startsWith("about:preferences"), "Prefs tab is open");
 
+  prefsDocument = prefsTabMode.tabs[0].browser.contentDocument;
   let prefsWindow = prefsDocument.ownerGlobal;
+  prefsWindow.resizeTo(screen.availWidth, screen.availHeight);
   if (paneID) {
-    if (prefsWindow.getCurrentPaneID() != paneID) {
-      let pane = prefsDocument.getElementById(paneID);
-      await new Promise(resolve => {
-        pane.addEventListener("paneSelected", resolve, { once: true });
-      });
-    }
-
     await new Promise(resolve => prefsWindow.setTimeout(resolve));
     Assert.equal(prefsWindow.getCurrentPaneID(), paneID, `Selected pane is ${paneID}`);
   } else {
     // If we don't wait here for other scripts to run, they
     // could be in a bad state if our test closes the tab.
     await new Promise(resolve => prefsWindow.setTimeout(resolve));
   }
 
--- a/calendar/test/modules/CalendarUtils.jsm
+++ b/calendar/test/modules/CalendarUtils.jsm
@@ -621,20 +621,20 @@ function findEventsInNode(node, eventNod
   }
 }
 
 function openLightningPrefs(aCallback, aParentController) {
   // Since the Lightning pane is added after load, asking for it with open_pref_tab won't work.
   // Cheat instead.
   let tab = open_pref_tab("paneGeneral");
   let categoryBox = tab.browser.contentDocument.getElementById("pref-category-box");
-  categoryBox.querySelector('radio[pane="paneLightning"]').click();
+  categoryBox.querySelector('radio[pane="paneCalendar"]').click();
   utils.waitFor(
-    () => tab.browser.contentWindow.getCurrentPaneID() == "paneLightning",
-    "Timed out waiting for prefpane paneLightning to load."
+    () => tab.browser.contentWindow.getCurrentPaneID() == "paneCalendar",
+    "Timed out waiting for paneCalendar to load."
   );
   aCallback(tab);
 }
 
 function closeLightningPrefs(tab) {
   close_pref_tab(tab);
 }
 
--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -223,16 +223,17 @@ pref("mail.last_msg_movecopy_was_move", 
 pref("browser.anchor_color", "#0B6CDA");
 
 pref("browser.preferences.instantApply", true);
 #ifdef XP_MACOSX
 pref("browser.preferences.animateFadeIn", true);
 #else
 pref("browser.preferences.animateFadeIn", false);
 #endif
+pref("browser.preferences.search", true);
 
 pref("accessibility.typeaheadfind", false);
 pref("accessibility.typeaheadfind.timeout", 5000);
 pref("accessibility.typeaheadfind.linksonly", false);
 pref("accessibility.typeaheadfind.flashBar", 1);
 
 pref("mail.close_message_window.on_delete", false);
 
--- a/mail/components/enterprisepolicies/tests/browser/browser_policy_app_auto_update.js
+++ b/mail/components/enterprisepolicies/tests/browser/browser_policy_app_auto_update.js
@@ -45,23 +45,16 @@ async function test_app_update_auto(expe
       if (subject.URL == "about:preferences") {
         Services.obs.removeObserver(documentLoaded, "chrome-document-loaded");
         resolve(subject);
       }
     }, "chrome-document-loaded");
     window.openPreferencesTab("paneGeneral", "updateApp");
   });
 
-  let prefsWindow = prefsDocument.ownerGlobal;
-  if (prefsWindow.getCurrentPaneID() != "paneGeneral") {
-    let pane = prefsDocument.getElementById("paneGeneral");
-    await new Promise(resolve => {
-      pane.addEventListener("paneSelected", resolve, { once: true });
-    });
-  }
   await new Promise(resolve => setTimeout(resolve));
 
   is(
     prefsDocument.getElementById("updateSettingsContainer").hidden,
     expectedLocked,
     `When auto update ${
       expectedLocked ? "is" : "isn't"
     } locked, the corresponding preferences entry ${
--- a/mail/components/enterprisepolicies/tests/browser/browser_policy_downloads.js
+++ b/mail/components/enterprisepolicies/tests/browser/browser_policy_downloads.js
@@ -12,17 +12,17 @@ ChromeUtils.defineModuleGetter(
 add_task(async function test_defaultdownload() {
   await setupPolicyEngineWithJson({
     policies: {
       DefaultDownloadDirectory: "${home}/Downloads",
       PromptForDownloadLocation: false,
     },
   });
 
-  window.openPreferencesTab("panePrivacy");
+  window.openPreferencesTab("paneGeneral");
   await BrowserTestUtils.browserLoaded(window.gPrefTab.browser);
   is(
     window.gPrefTab.browser.contentDocument.getElementById("alwaysAsk")
       .disabled,
     true,
     "alwaysAsk should be disabled."
   );
   is(
@@ -58,17 +58,17 @@ add_task(async function test_defaultdown
 
 add_task(async function test_download() {
   await setupPolicyEngineWithJson({
     policies: {
       DownloadDirectory: "${home}/Documents",
     },
   });
 
-  window.openPreferencesTab("panePrivacy");
+  window.openPreferencesTab("paneGeneral");
   await BrowserTestUtils.browserLoaded(window.gPrefTab.browser);
   await new Promise(resolve =>
     window.gPrefTab.browser.contentWindow.setTimeout(resolve)
   );
   is(
     window.gPrefTab.browser.contentDocument.getElementById("alwaysAsk")
       .disabled,
     true,
--- a/mail/components/enterprisepolicies/tests/browser/disable_app_update/browser_policy_disable_app_update.js
+++ b/mail/components/enterprisepolicies/tests/browser/disable_app_update/browser_policy_disable_app_update.js
@@ -29,23 +29,16 @@ add_task(async function test_update_pref
       if (subject.URL == "about:preferences") {
         Services.obs.removeObserver(documentLoaded, "chrome-document-loaded");
         resolve(subject);
       }
     }, "chrome-document-loaded");
     window.openPreferencesTab("paneGeneral", "updateApp");
   });
 
-  let prefsWindow = prefsDocument.ownerGlobal;
-  if (prefsWindow.getCurrentPaneID() != "paneGeneral") {
-    let pane = prefsDocument.getElementById("paneGeneral");
-    await new Promise(resolve => {
-      pane.addEventListener("paneSelected", resolve, { once: true });
-    });
-  }
   await new Promise(resolve => setTimeout(resolve));
 
   let setting = prefsDocument.getElementById("updateSettingsContainer");
   is(
     setting.hidden,
     true,
     "Update choices should be disabled when app update is locked by policy"
   );
--- a/mail/components/preferences/attachmentReminder.xhtml
+++ b/mail/components/preferences/attachmentReminder.xhtml
@@ -9,21 +9,18 @@
 <!DOCTYPE window>
 
 <window type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         data-l10n-id="attachment-reminder-window"
         onload="gAttachmentReminderOptionsDialog.init();"
         style="width:38em;">
-<dialog id="attachmentReminderOptionsDialog"
-        dlgbuttons="accept,cancel">
-
-  <prefpane id="attachmentReminderOptionsDialogPane">
-
+  <dialog id="attachmentReminderOptionsDialog"
+          dlgbuttons="accept,cancel">
     <script src="chrome://messenger/content/preferences/attachmentReminder.js"/>
 
     <linkset>
       <html:link rel="localization" href="branding/brand.ftl"/>
       <html:link rel="localization" href="messenger/preferences/attachment-reminder.ftl"/>
     </linkset>
 
     <vbox>
@@ -36,11 +33,10 @@
                   oncommand="gAttachmentReminderOptionsDialog.addKeyword();"/>
           <button data-l10n-id="keyword-edit-button"
                   oncommand="gAttachmentReminderOptionsDialog.editKeyword();"/>
           <button data-l10n-id="keyword-remove-button"
                   oncommand="gAttachmentReminderOptionsDialog.removeKeyword();"/>
         </vbox>
       </hbox>
     </vbox>
-  </prefpane>
-</dialog>
+  </dialog>
 </window>
--- a/mail/components/preferences/chat.inc.xhtml
+++ b/mail/components/preferences/chat.inc.xhtml
@@ -1,38 +1,39 @@
 # 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/.
-  <prefpane id="paneChat">
-    <script src="chrome://messenger/content/preferences/chat.js"/>
-    <script src="chrome://messenger/content/preferences/messagestyle.js"/>
+  <script src="chrome://messenger/content/preferences/chat.js"/>
+  <script src="chrome://messenger/content/preferences/messagestyle.js"/>
 
-    <stringbundle id="themesBundle"
-                  src="chrome://messenger/locale/preferences/messagestyle.properties"/>
-
+  <stringbundle id="themesBundle"
+                src="chrome://messenger/locale/preferences/messagestyle.properties"/>
+  <html:template id="paneChat">
     <hbox id="chatPaneCategory"
           class="subcategory"
           data-category="paneChat">
       <html:h1 data-l10n-id="chat-pane-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneChat">
     <html:fieldset data-category="paneChat">
       <html:legend data-l10n-id="chat-status-title"></html:legend>
         <!-- Startup -->
         <hbox align="center">
           <label id="chatStartupAction"
                  data-l10n-id="startup-label"
                  control="messengerStartupAction"/>
-          <menulist id="messengerStartupAction" preference="messenger.startup.action">
-            <menupopup>
-              <menuitem data-l10n-id="offline-label" value="0"/>
-              <menuitem data-l10n-id="auto-connect-label" value="1"/>
-            </menupopup>
-          </menulist>
+          <hbox>
+            <menulist id="messengerStartupAction" preference="messenger.startup.action">
+              <menupopup>
+                <menuitem data-l10n-id="offline-label" value="0"/>
+                <menuitem data-l10n-id="auto-connect-label" value="1"/>
+              </menupopup>
+            </menulist>
+          </hbox>
         </hbox>
         <separator/>
 
         <!-- Status -->
         <hbox align="center">
           <checkbox id="reportIdle" data-l10n-id="idle-label"
                     preference="messenger.status.reportIdle"/>
           <html:input id="timeBeforeAway" type="number"
@@ -52,17 +53,17 @@
           <html:input id="defaultIdleAwayMessage"
                       type="text"
                       class="idle-reporting-enabled indent"
                       preference="messenger.status.defaultIdleAwayMessage"/>
         </vbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneChat">
     <html:fieldset data-category="paneChat">
       <html:legend data-l10n-id="chat-notifications-title"></html:legend>
       <hbox>
         <checkbox id="sendTyping"
                   data-l10n-id="send-typing-label"
                   preference="purple.conversations.im.send_typing"/>
         <spacer flex="1"/>
       </hbox>
@@ -71,33 +72,36 @@
 
       <hbox>
         <label data-l10n-id="notification-label"/>
       </hbox>
       <hbox>
         <checkbox id="desktopChatNotifications"
                   data-l10n-id="show-notification-label"
                   preference="mail.chat.show_desktop_notifications"/>
-        <menulist id="chatNotificationInfo" preference="mail.chat.notification_info">
-          <menupopup>
-            <menuitem data-l10n-id="notification-all" value="0"/>
-            <menuitem data-l10n-id="notification-name" value="1"/>
-            <menuitem data-l10n-id="notification-empty" value="2"/>
-          </menupopup>
-        </menulist>
+        <hbox>
+          <menulist id="chatNotificationInfo" preference="mail.chat.notification_info">
+            <menupopup>
+              <menuitem data-l10n-id="notification-all" value="0"/>
+              <menuitem data-l10n-id="notification-name" value="1"/>
+              <menuitem data-l10n-id="notification-empty" value="2"/>
+            </menupopup>
+          </menulist>
+        </hbox>
       </hbox>
       <checkbox id="getAttention"
                 preference="messenger.options.getAttentionOnNewMessages"
                 data-l10n-id="notification-type-label"/>
       <hbox align="center">
         <checkbox id="chatNotification"
                   data-l10n-id="chat-play-sound-label"
                   preference="mail.chat.play_sound"/>
         <spacer flex="1"/>
-        <button id="playChatSound" data-l10n-id="chat-play-button"
+        <button is="highlightable-button" id="playChatSound"
+                data-l10n-id="chat-play-button"
                 oncommand="gChatPane.previewSound();"/>
       </hbox>
       <radiogroup id="chatSoundType"
                   class="indent"
                   orient="vertical"
                   preference="mail.chat.play_sound.type"
                   aria-labelledby="chatNotification">
         <hbox>
@@ -115,57 +119,59 @@
         <hbox align="center" class="input-container">
           <html:input id="chatSoundUrlLocation"
                       type="text"
                       class="input-filefield indent"
                       readonly="readonly"
                       preference="mail.chat.play_sound.url"
                       preference-editable="true"
                       aria-labelledby="chatSoundCustom"/>
-          <button id="browseForChatSound"
+          <button is="highlightable-button" id="browseForChatSound"
                   data-l10n-id="chat-browse-sound-button"
                   oncommand="gChatPane.browseForSoundFile();"/>
         </hbox>
       </radiogroup>
     </html:fieldset>
     </html:div>
 
     <hbox id="chatPaneStylingCategory"
           class="subcategory"
           data-category="paneChat">
       <html:h1 data-l10n-id="chat-pane-styling-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneChat">
     <html:fieldset data-category="paneChat">
       <separator/>
       <hbox align="center">
         <label data-l10n-id="theme-label" control="messagestyle-themename"/>
-        <menulist id="messagestyle-themename"
-                  flex="1" crop="end"
-                  preference="messenger.options.messagesStyle.theme"
-                  onselect="previewObserver.currentThemeChanged();">
-          <menupopup id="theme-menupopup">
-            <menuitem id="mail-menuitem"
-                      data-l10n-id="style-thunderbird"
-                      value="mail"/>
-            <menuitem id="bubbles-menuitem"
-                      data-l10n-id="style-bubbles"
-                      value="bubbles"/>
-            <menuitem id="dark-menuitem"
-                      data-l10n-id="style-dark"
-                      value="dark"/>
-            <menuitem id="papersheets-menuitem"
-                      data-l10n-id="style-paper"
-                      value="papersheets"/>
-            <menuitem id="simple-menuitem"
-                      data-l10n-id="style-simple"
-                      value="simple"/>
-          </menupopup>
-        </menulist>
+        <hbox flex="1">
+          <menulist id="messagestyle-themename"
+                    flex="1" crop="end"
+                    preference="messenger.options.messagesStyle.theme"
+                    onselect="previewObserver.currentThemeChanged();">
+            <menupopup id="theme-menupopup">
+              <menuitem id="mail-menuitem"
+                        data-l10n-id="style-thunderbird"
+                        value="mail"/>
+              <menuitem id="bubbles-menuitem"
+                        data-l10n-id="style-bubbles"
+                        value="bubbles"/>
+              <menuitem id="dark-menuitem"
+                        data-l10n-id="style-dark"
+                        value="dark"/>
+              <menuitem id="papersheets-menuitem"
+                        data-l10n-id="style-paper"
+                        value="papersheets"/>
+              <menuitem id="simple-menuitem"
+                        data-l10n-id="style-simple"
+                        value="simple"/>
+            </menupopup>
+          </menulist>
+        </hbox>
       </hbox>
       <separator class="thin"/>
       <hbox align="start">
       <label data-l10n-id="preview-label"/>
       <tooltip id="aHTMLTooltip" page="true"/>
       <deck flex="1" id="previewDeck" selectedIndex="1">
         <vbox flex="1" id="noPreviewScreen" align="center" pack="center">
           <hbox id="noPreviewBox" align="start">
@@ -175,18 +181,20 @@
                            data-l10n-id="no-preview-description"/>
             </vbox>
           </hbox>
         </vbox>
       </deck>
       </hbox>
       <hbox align="center">
         <label data-l10n-id="chat-variant-label" control="themevariant"/>
-        <menulist id="themevariant"
-                  preference="messenger.options.messagesStyle.variant"
-                  onselect="previewObserver.currentVariantChanged();"/>
+        <hbox>
+          <menulist id="themevariant"
+                    preference="messenger.options.messagesStyle.variant"
+                    onselect="previewObserver.currentVariantChanged();"/>
+        </hbox>
       </hbox>
       <checkbox id="showHeaderCheckbox" data-l10n-id="chat-header-label"
                 preference="messenger.options.messagesStyle.showHeader"/>
     </html:fieldset>
     </html:div>
 
-  </prefpane>
+  </html:template>
--- a/mail/components/preferences/chat.js
+++ b/mail/components/preferences/chat.js
@@ -31,47 +31,36 @@ Preferences.addAll([
 
 var gChatPane = {
   init() {
     this.updateDisabledState();
     this.updateMessageDisabledState();
     this.updatePlaySound();
     this.initPreview();
 
-    window.addEventListener("paneSelected", this.paneSelectionChanged);
-
     let element = document.getElementById("timeBeforeAway");
     Preferences.addSyncFromPrefListener(
       element,
       () =>
         Preferences.get("messenger.status.timeBeforeIdle")
           .valueFromPreferences / 60
     );
     Preferences.addSyncToPrefListener(element, element => element.value * 60);
     Preferences.addSyncFromPrefListener(
       document.getElementById("chatSoundUrlLocation"),
       () => this.readSoundLocation()
     );
   },
 
-  paneSelectionChanged() {
-    gChatPane.initPreview(); // Can't use "this", as it's probably not gChatPane.
-  },
-
   initPreview() {
     // We add this browser only when really necessary.
     let previewDeck = document.getElementById("previewDeck");
     if (previewDeck.querySelector("browser")) {
       return;
     }
-    if (!("getCurrentPaneID" in window) || getCurrentPaneID() != "paneChat") {
-      return;
-    }
-
-    window.removeEventListener("paneSelected", this.paneSelectionChanged);
 
     let browser = document.createXULElement("browser", {
       is: "conversation-browser",
     });
     browser.setAttribute("id", "previewbrowser");
     browser.setAttribute("type", "content");
     browser.setAttribute("flex", "1");
     browser.setAttribute("tooltip", "aHTMLTooltip");
--- a/mail/components/preferences/colors.xhtml
+++ b/mail/components/preferences/colors.xhtml
@@ -10,24 +10,23 @@
 
 <!DOCTYPE window>
 
 <window type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         data-l10n-id="colors-dialog-window"
         data-l10n-attrs="style">
-<dialog id="ColorsDialog"
-        dlgbuttons="accept,cancel">
+  <dialog id="ColorsDialog"
+          dlgbuttons="accept,cancel">
 
-  <linkset>
-    <html:link rel="localization" href="messenger/preferences/colors.ftl"/>
-  </linkset>
+    <linkset>
+      <html:link rel="localization" href="messenger/preferences/colors.ftl"/>
+    </linkset>
 
-  <prefpane id="ColorsDialogPane">
     <hbox>
       <hbox flex="1">
       <html:div>
       <html:fieldset>
         <html:legend data-l10n-id="colors-dialog-legend"></html:legend>
         <hbox align="center">
           <label data-l10n-id="text-color-label" control="foregroundtextmenu"/>
           <spacer flex="1"/>
@@ -83,14 +82,13 @@
                     value="2" id="documentColorAlways"/>
           <menuitem data-l10n-id="override-color-auto"
                     value="0" id="documentColorAutomatic"/>
           <menuitem data-l10n-id="override-color-never"
                     value="1" id="documentColorNever"/>
         </menupopup>
       </menulist>
     </vbox>
-  </prefpane>
 
-  <script src="chrome://global/content/preferencesBindings.js"/>
-  <script src="chrome://messenger/content/preferences/colors.js"/>
-</dialog>
+    <script src="chrome://global/content/preferencesBindings.js"/>
+    <script src="chrome://messenger/content/preferences/colors.js"/>
+  </dialog>
 </window>
--- a/mail/components/preferences/compose.inc.xhtml
+++ b/mail/components/preferences/compose.inc.xhtml
@@ -1,36 +1,37 @@
 # 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/.
-  <prefpane id="paneCompose">
-    <script src="chrome://messenger/content/preferences/compose.js"/>
-    <script src="chrome://global/content/contentAreaUtils.js"/>
-    <script src="chrome://messenger/content/preferences/downloads.js"/>
-    <script src="chrome://communicator/content/utilityOverlay.js"/>
+  <script src="chrome://messenger/content/preferences/compose.js"/>
+  <script src="chrome://global/content/contentAreaUtils.js"/>
+  <script src="chrome://messenger/content/preferences/downloads.js"/>
+  <script src="chrome://communicator/content/utilityOverlay.js"/>
 
-    <stringbundle id="bundle_addressBook" src="chrome://messenger/locale/addressbook/addressBook.properties"/>
-
+  <stringbundle id="bundle_addressBook" src="chrome://messenger/locale/addressbook/addressBook.properties"/>
+  <html:template id="paneCompose">
     <hbox id="compositionMainCategory"
           class="subcategory"
           data-category="paneCompose">
       <html:h1 data-l10n-id="composition-category-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneCompose">
     <html:fieldset data-category="paneCompose">
       <separator class="thin"/>
       <hbox align="center">
         <label data-l10n-id="forward-label" control="forwardMessageMode"/>
-        <menulist id="forwardMessageMode" preference="mail.forward_message_mode">
-          <menupopup>
-            <menuitem value="2" data-l10n-id="inline-label"/>
-            <menuitem value="0" data-l10n-id="as-attachment-label"/>
-          </menupopup>
-        </menulist>
+        <hbox>
+          <menulist id="forwardMessageMode" preference="mail.forward_message_mode">
+            <menupopup>
+              <menuitem value="2" data-l10n-id="inline-label"/>
+              <menuitem value="0" data-l10n-id="as-attachment-label"/>
+            </menupopup>
+          </menulist>
+        </hbox>
         <separator orient="vertical" class="thin"/>
         <checkbox id="addExtension" preference="mail.forward_add_extension"
                   data-l10n-id="extension-label"/>
       </hbox>
 
       <separator class="thin"/>
 
       <hbox align="center" pack="start">
@@ -45,17 +46,18 @@
       <hbox>
         <checkbox id="mailWarnOnSendAccelKey"
                   data-l10n-id="warn-on-send-accel-key"
                   preference="mail.warn_on_send_accel_key"/>
         <spacer flex="1"/>
       </hbox>
     </html:fieldset>
     </html:div>
-    <html:div>
+
+    <html:div data-category="paneCompose">
     <html:fieldset data-category="paneCompose">
       <html:legend data-l10n-id="composition-spelling-title"></html:legend>
       <hbox>
         <checkbox id="spellCheckBeforeSend"
                   data-l10n-id="spellcheck-label"
                   preference="mail.SpellCheckBeforeSend"/>
         <spacer flex="1"/>
       </hbox>
@@ -65,59 +67,66 @@
                   preference="mail.spellcheck.inline"/>
         <spacer flex="1"/>
       </hbox>
 
       <separator class="thin"/>
 
       <hbox align="center" pack="start">
         <label data-l10n-id="language-popup-label" control="languageMenuList"/>
-        <menulist id="languageMenuList" preference="spellchecker.dictionary" flex="1">
-          <menupopup onpopupshowing="gComposePane.initLanguageMenu();">
-            <!-- dynamic content populated by JS -->
-          </menupopup>
-        </menulist>
+        <hbox flex="1">
+          <menulist id="languageMenuList" preference="spellchecker.dictionary" flex="1">
+            <menupopup onpopupshowing="gComposePane.initLanguageMenu();">
+              <!-- dynamic content populated by JS -->
+            </menupopup>
+          </menulist>
+        </hbox>
         <label id="downloadDictionaries" class="text-link"
                 onclick="if (event.button == 0) { openDictionaryList('tab'); }"
                 data-l10n-id="download-dictionaries-link"/>
         <spacer flex="1"/>
       </hbox>
     </html:fieldset>
     </html:div>
-    <html:div>
+
+    <html:div data-category="paneCompose">
     <html:fieldset data-category="paneCompose">
       <html:legend data-l10n-id="compose-html-style-title"></html:legend>
       <hbox>
         <vbox flex="1">
           <hbox align="center">
             <label control="FontSelect" data-l10n-id="font-label"/>
-            <menulist id="FontSelect" preference="msgcompose.font_face"
-                      sizetopopup="pref" crop="center" flex="1">
-              <menupopup>
-                <menuitem value="" label="&fontVarWidth.label;"/>
-                <menuitem value="tt" label="&fontFixedWidth.label;"/>
-                <menuseparator/>
-                <menuitem value="Helvetica, Arial, sans-serif" label="&fontHelvetica.label;"/>
-                <menuitem value="Times New Roman, Times, serif" label="&fontTimes.label;"/>
-                <menuitem value="Courier New, Courier, monospace" label="&fontCourier.label;"/>
-                <menuseparator/>
-              </menupopup>
-            </menulist>
+            <hbox flex="1">
+              <menulist id="FontSelect" preference="msgcompose.font_face"
+                        sizetopopup="pref" crop="center" flex="1">
+                <menupopup>
+                  <menuitem value="" label="&fontVarWidth.label;"/>
+                  <menuitem value="tt" label="&fontFixedWidth.label;"/>
+                  <menuseparator/>
+                  <menuitem value="Helvetica, Arial, sans-serif" label="&fontHelvetica.label;"/>
+                  <menuitem value="Times New Roman, Times, serif" label="&fontTimes.label;"/>
+                  <menuitem value="Courier New, Courier, monospace" label="&fontCourier.label;"/>
+                  <menuseparator/>
+                </menupopup>
+              </menulist>
+            </hbox>
 
             <label control="fontSizeSelect" data-l10n-id="font-size-label"/>
-            <menulist id="fontSizeSelect" preference="msgcompose.font_size">
-              <menupopup>
-                <menuitem value="x-small" label="&size-tinyCmd.label;"/>
-                <menuitem value="small" label="&size-smallCmd.label;"/>
-                <menuitem value="medium" label="&size-mediumCmd.label;"/>
-                <menuitem value="large" label="&size-largeCmd.label;"/>
-                <menuitem value="x-large" label="&size-extraLargeCmd.label;"/>
-                <menuitem value="xx-large" label="&size-hugeCmd.label;"/>
-              </menupopup>
-            </menulist>
+            <hbox>
+              <menulist id="fontSizeSelect" preference="msgcompose.font_size">
+                <menupopup>
+                  <menuitem value="x-small" label="&size-tinyCmd.label;"/>
+                  <menuitem value="small" label="&size-smallCmd.label;"/>
+                  <menuitem value="medium" label="&size-mediumCmd.label;"/>
+                  <menuitem value="large" label="&size-largeCmd.label;"/>
+                  <menuitem value="x-large" label="&size-extraLargeCmd.label;"/>
+                  <menuitem value="xx-large" label="&size-hugeCmd.label;"/>
+                </menupopup>
+              </menulist>
+            </hbox>
           </hbox>
 
           <separator class="thin"/>
 
           <hbox align="center">
             <checkbox id="useReaderDefaults"
                       data-l10n-id="default-colors-label"
                       preference="msgcompose.default_colors"/>
@@ -131,113 +140,151 @@
             <label id="backgroundColorLabel"
                    control="backgroundColorButton"
                    data-l10n-id="bg-color-label"/>
             <html:input type="color" id="backgroundColorButton" preference="msgcompose.background_color"/>
           </hbox>
         </vbox>
         <vbox>
           <spacer flex="1"/>
-          <button data-l10n-id="restore-html-label"
+          <button is="highlightable-button"
+                  data-l10n-id="restore-html-label"
                   oncommand="gComposePane.restoreHTMLDefaults();"/>
         </vbox>
       </hbox>
 
       <separator class="thin"/>
 
       <hbox align="center">
         <checkbox id="defaultToParagraph"
                   data-l10n-id="default-format-label"
                   preference="mail.compose.default_to_paragraph"/>
       </hbox>
 
       <hbox align="center">
         <description flex="1" data-l10n-id="format-description"/>
-        <button data-l10n-id="send-options-label"
-                oncommand="gComposePane.sendOptionsDialog();"/>
+        <hbox>
+          <button is="highlightable-button"
+                  data-l10n-id="send-options-label"
+                  search-l10n-ids="
+                    sendoptions-dialog-window.title,
+                    send-mail-title,
+                    auto-downgrade-label.label,
+                    default-html-format-label,
+                    html-format-ask.label,
+                    html-format-convert.label,
+                    html-format-send-html.label,
+                    html-format-send-both.label,
+                    default-html-format-info,
+                    html-tab-label.label,
+                    plain-tab-label.label,
+                    send-message-domain-label,
+                    add-domain-button.label,
+                    delete-domain-button.label"
+                  oncommand="gComposePane.sendOptionsDialog();"/>
+        </hbox>
       </hbox>
     </html:fieldset>
     </html:div>
 
     <hbox id="compositionAddressingCategory"
           class="subcategory"
           data-category="paneCompose">
       <html:h1 data-l10n-id="composition-addressing-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneCompose">
     <html:fieldset data-category="paneCompose">
       <!-- Address Autocomplete -->
       <separator class="thin"/>
 
       <description data-l10n-id="autocomplete-description"/>
 
       <hbox align="center">
         <checkbox id="addressingAutocomplete" data-l10n-id="ab-label"
                   preference="mail.enable_autocomplete"/>
       </hbox>
 
       <hbox align="center">
         <checkbox id="autocompleteLDAP" data-l10n-id="directories-label"
                   preference="ldap_2.autoComplete.useDirectory"/>
-        <menulist is="menulist-addrbooks" id="directoriesList"
-                  aria-labelledby="autocompleteLDAP"
-                  preference="ldap_2.autoComplete.directoryServer"
-                  data-l10n-id="directories-none-label"
-                  data-l10n-attrs="none"
-                  remoteonly="true"
-                  flex="1"/>
-        <button id="editButton" data-l10n-id="edit-directories-label"
+        <hbox flex="1">
+          <menulist is="menulist-addrbooks" id="directoriesList"
+                    aria-labelledby="autocompleteLDAP"
+                    preference="ldap_2.autoComplete.directoryServer"
+                    data-l10n-id="directories-none-label"
+                    data-l10n-attrs="none"
+                    remoteonly="true"
+                    flex="1"/>
+        </hbox>
+        <button is="highlightable-button" id="editButton"
+                data-l10n-id="edit-directories-label"
                 oncommand="gComposePane.editDirectories();"
                 preference="pref.ldap.disable_button.edit_directories"/>
       </hbox>
 
       <separator class="thin"/>
 
       <hbox align="center" pack="start">
         <checkbox id="emailCollectionOutgoing" data-l10n-id="email-picker-label"
                   preference="mail.collect_email_address_outgoing"/>
-        <menulist is="menulist-addrbooks" id="localDirectoriesList"
-                  aria-labelledby="emailCollectionOutgoing"
-                  preference="mail.collect_addressbook"
-                  localonly="true"
-                  writable="true"
-                  flex="1"/>
+        <hbox flex="1">
+          <menulist is="menulist-addrbooks" id="localDirectoriesList"
+                    aria-labelledby="emailCollectionOutgoing"
+                    preference="mail.collect_addressbook"
+                    localonly="true"
+                    writable="true"
+                    flex="1"/>
+        </hbox>
       </hbox>
 
       <hbox align="center" pack="start">
         <label data-l10n-id="default-directory-label"
                control="defaultStartupDirList"/>
-        <menulist is="menulist-addrbooks" id="defaultStartupDirList"
-                  oncommand="gComposePane.setDefaultStartupDir(this.value);"
-                  data-l10n-id="default-last-label"
-                  data-l10n-attrs="none"
-                  alladdressbooks="true"
-                  mailinglists="true"
-                  flex="1"/>
+        <hbox flex="1">
+          <menulist is="menulist-addrbooks" id="defaultStartupDirList"
+                    oncommand="gComposePane.setDefaultStartupDir(this.value);"
+                    data-l10n-id="default-last-label"
+                    data-l10n-attrs="none"
+                    alladdressbooks="true"
+                    mailinglists="true"
+                    flex="1"/>
+        </hbox>
       </hbox>
     </html:fieldset>
     </html:div>
 
     <hbox id="compositionAttachmentsCategory"
           class="subcategory"
           data-category="paneCompose">
       <html:h1 data-l10n-id="composition-attachments-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneCompose">
     <html:fieldset data-category="paneCompose">
       <hbox align="center">
         <checkbox id="attachment_reminder_label"
                   data-l10n-id="attachment-label"
                   preference="mail.compose.attachment_reminder"/>
         <spacer flex="1"/>
-        <button id="attachment_reminder_button"
-                data-l10n-id="attachment-options-label"
-                oncommand="gComposePane.attachmentReminderOptionsDialog();"/>
+        <hbox>
+          <button is="highlightable-button" id="attachment_reminder_button"
+                  data-l10n-id="attachment-options-label"
+                  oncommand="gComposePane.attachmentReminderOptionsDialog();"
+                  search-l10n-ids="
+                    attachment-reminder-window.title,
+                    attachment-reminder-label,
+                    keyword-new-button.label,
+                    keyword-edit-button.label,
+                    keyword-remove-button.label,
+                    new-keyword-title,
+                    new-keyword-label,
+                    edit-keyword-title,
+                    edit-keyword-label"/>
+        </hbox>
       </hbox>
       <vbox id="cloudFileBox" flex="1">
         <hbox id="cloudFileToggleAndThreshold" align="center">
           <checkbox id="enableThreshold"
                     data-l10n-id="enable-cloud-share"
                     preference="mail.compose.big_attachments.notify"/>
           <html:input id="cloudFileThreshold" type="number" class="size3"
                       preference="mail.compose.big_attachments.threshold_kb"/>
@@ -247,24 +294,26 @@
           <vbox id="provider-listing">
             <richlistbox id="cloudFileView" orient="vertical" flex="1"
                          seltype="single"
                          onoverflow="gCloudFile.onListOverflow();"
                          onselect="gCloudFile.onSelectionChanged(event);">
             </richlistbox>
             <vbox id="addCloudFileAccountButtons">
             </vbox>
-            <menulist id="addCloudFileAccount"
-                      hidden="true"
-                      data-l10n-id="add-cloud-account"
-                      data-l10n-attrs="defaultlabel"
-                      oncommand="gCloudFile.addCloudFileAccount(this.value);">
-              <menupopup id="addCloudFileAccountListItems"/>
-            </menulist>
-            <button id="removeCloudFileAccount"
+            <hbox>
+              <menulist id="addCloudFileAccount"
+                        hidden="true"
+                        data-l10n-id="add-cloud-account"
+                        data-l10n-attrs="defaultlabel"
+                        oncommand="gCloudFile.addCloudFileAccount(this.value);">
+                <menupopup id="addCloudFileAccountListItems"/>
+              </menulist>
+            </hbox>
+            <button is="highlightable-button" id="removeCloudFileAccount"
                     disabled="true"
                     data-l10n-id="remove-cloud-account"
                     oncommand="gCloudFile.removeCloudFileAccount();"/>
             <label is="text-link"
                    id="moreProvidersLink"
                    href="https://addons.thunderbird.net/thunderbird/tag/filelink"
                    data-l10n-id="find-cloud-providers"/>
           </vbox>
@@ -278,9 +327,9 @@
               </vbox>
             </deck>
           </vbox>
         </hbox>
       </vbox>
     </html:fieldset>
     </html:div>
 
-  </prefpane>
+  </html:template>
--- a/mail/components/preferences/dockoptions.xhtml
+++ b/mail/components/preferences/dockoptions.xhtml
@@ -8,24 +8,22 @@
 
 <!DOCTYPE window>
 
 <window type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         data-l10n-id="dock-options-window-dialog"
         data-l10n-attrs="style">
-<dialog id="DockOptionsDialog"
-        dlgbuttons="accept,cancel">
+  <dialog id="DockOptionsDialog"
+          dlgbuttons="accept,cancel">
 
-  <linkset>
-    <html:link rel="localization" href="messenger/preferences/dock-options.ftl"/>
-  </linkset>
-
-  <prefpane id="DockOptionsDialogPane">
+    <linkset>
+      <html:link rel="localization" href="messenger/preferences/dock-options.ftl"/>
+    </linkset>
     <hbox orient="vertical">
       <checkbox id="newMailNotificationBounce"
                 data-l10n-id="bounce-system-dock-icon"
                 preference="mail.biff.animate_dock_icon"/>
       <separator class="thin"/>
       <html:div>
       <html:fieldset>
         <html:legend data-l10n-id="dock-icon-legend"></html:legend>
@@ -41,14 +39,13 @@
                  data-l10n-id="count-new-messages-radio"/>
         </radiogroup>
         </vbox>
       </html:fieldset>
       </html:div>
       <separator/>
       <description class="bold" data-l10n-id="notification-settings-info"/>
     </hbox>
-  </prefpane>
 
-  <script src="chrome://global/content/preferencesBindings.js"/>
-  <script src="chrome://messenger/content/preferences/dockoptions.js"/>
-</dialog>
+    <script src="chrome://global/content/preferencesBindings.js"/>
+    <script src="chrome://messenger/content/preferences/dockoptions.js"/>
+  </dialog>
 </window>
new file mode 100644
--- /dev/null
+++ b/mail/components/preferences/findInPage.js
@@ -0,0 +1,654 @@
+/* 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-globals-from preferences.js */
+
+// A tweak to the standard <button> CE to use textContent on the <label>
+// inside the button, which allows the text to be highlighted when the user
+// is searching.
+var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+const MozButton = customElements.get("button");
+class HighlightableButton extends MozButton {
+  static get inheritedAttributes() {
+    return Object.assign({}, super.inheritedAttributes, {
+      ".button-text": "text=label,accesskey,crop",
+    });
+  }
+}
+customElements.define("highlightable-button", HighlightableButton, {
+  extends: "button",
+});
+
+var gSearchResultsPane = {
+  listSearchTooltips: new Set(),
+  listSearchMenuitemIndicators: new Set(),
+  searchInput: null,
+  // A map of DOM Elements to a string of keywords used in search.
+  // XXX: We should invalidate this cache on `intl:app-locales-changed`.
+  searchKeywords: new WeakMap(),
+  inited: false,
+
+  init() {
+    if (this.inited) {
+      return;
+    }
+    this.inited = true;
+    this.searchInput = document.getElementById("searchInput");
+    this.searchInput.hidden = !Services.prefs.getBoolPref(
+      "browser.preferences.search"
+    );
+    if (!this.searchInput.hidden) {
+      this.searchInput.addEventListener("input", this);
+      this.searchInput.addEventListener("command", this);
+      window.addEventListener("DOMContentLoaded", () => {
+        this.searchInput.focus();
+      });
+      // Initialize other panes in an idle callback.
+      window.requestIdleCallback(() => this.initializeCategories());
+    }
+    let helpUrl =
+      Services.urlFormatter.formatURLPref("app.support.baseURL") +
+      "preferences";
+    let helpContainer = document.getElementById("need-help");
+    helpContainer.querySelector("a").href = helpUrl;
+  },
+
+  async handleEvent(event) {
+    // Ensure categories are initialized if idle callback didn't run soon enough.
+    await this.initializeCategories();
+    this.searchFunction(event);
+  },
+
+  /**
+   * Check that the text content contains the query string.
+   *
+   * @param {String} content the text content to be searched.
+   * @param {String} query the query string.
+   *
+   * @returns {boolean} true when the text content contains the query string else false.
+   */
+  queryMatchesContent(content, query) {
+    if (!content || !query) {
+      return false;
+    }
+    return content.toLowerCase().includes(query.toLowerCase());
+  },
+
+  categoriesInitialized: false,
+
+  /**
+   * Will attempt to initialize all uninitialized categories.
+   */
+  async initializeCategories() {
+    //  Initializing all the JS for all the tabs.
+    if (!this.categoriesInitialized) {
+      this.categoriesInitialized = true;
+      // Each element of gCategoryInits is a name.
+      for (let [name, category] of gCategoryInits) {
+        if (
+          (name != "paneCalendar" && !category.inited) ||
+          (calendarDeactivator.isCalendarActivated && !category.inited)
+        ) {
+          await category.init();
+        }
+      }
+      let lastSelected = Services.xulStore.getValue(
+        "about:preferences",
+        "MailPreferences",
+        "lastSelected"
+      );
+      search(lastSelected, "data-category");
+    }
+  },
+
+  /**
+   * Finds and returns text nodes within node and all descendants.
+   * Iterates through all the sibilings of the node object and adds the sibilings
+   * to an array if sibiling is a TEXT_NODE else checks the text nodes with in current node.
+   * Source - http://stackoverflow.com/questions/10730309/find-all-text-nodes-in-html-page
+   *
+   * @param {Node} node DOM element.
+   *
+   * @returns {Node[]} array of text nodes.
+   */
+  textNodeDescendants(node) {
+    if (!node) {
+      return [];
+    }
+    let all = [];
+    for (node = node.firstChild; node; node = node.nextSibling) {
+      if (node.nodeType === node.TEXT_NODE) {
+        all.push(node);
+      } else {
+        all = all.concat(this.textNodeDescendants(node));
+      }
+    }
+    return all;
+  },
+
+  /**
+   * This function is used to find words contained within the text nodes.
+   * We pass in the textNodes because they contain the text to be highlighted.
+   * We pass in the nodeSizes to tell exactly where highlighting need be done.
+   * When creating the range for highlighting, if the nodes are section is split
+   * by an access key, it is important to have the size of each of the nodes summed.
+   * @param {Node[]} textNodes List of DOM elements.
+   * @param {Node[]} nodeSizes Running size of text nodes. This will contain the same
+   *   number of elements as textNodes. The first element is the size of first textNode element.
+   *   For any nodes after, they will contain the summation of the nodes thus far in the array.
+   *   Example:
+   *   textNodes = [[This is ], [a], [n example]]
+   *   nodeSizes = [[8], [9], [18]]
+   *   This is used to determine the offset when highlighting.
+   * @param {String} textSearch Concatination of textNodes's text content.
+   *    Example:
+   *    textNodes = [[This is ], [a], [n example]]
+   *    nodeSizes = "This is an example"
+   *    This is used when executing the regular expression.
+   * @param {String} searchPhrase word or words to search for.
+   *
+   * @returns {boolean} Returns true when atleast one instance of search phrase is found, otherwise false.
+   */
+  highlightMatches(textNodes, nodeSizes, textSearch, searchPhrase) {
+    if (!searchPhrase) {
+      return false;
+    }
+
+    let indices = [];
+    let i = -1;
+    while ((i = textSearch.indexOf(searchPhrase, i + 1)) >= 0) {
+      indices.push(i);
+    }
+
+    // Looping through each spot the searchPhrase is found in the concatenated string.dom-mutation-list.
+    for (let startValue of indices) {
+      let endValue = startValue + searchPhrase.length;
+      let startNode = null;
+      let endNode = null;
+      let nodeStartIndex = null;
+
+      // Determining the start and end node to highlight from.
+      for (let index = 0; index < nodeSizes.length; index++) {
+        let lengthNodes = nodeSizes[index];
+        // Determining the start node.
+        if (!startNode && lengthNodes >= startValue) {
+          startNode = textNodes[index];
+          nodeStartIndex = index;
+          // Calculating the offset when found query is not in the first node.
+          if (index > 0) {
+            startValue -= nodeSizes[index - 1];
+          }
+        }
+        // Determining the end node.
+        if (!endNode && lengthNodes >= endValue) {
+          endNode = textNodes[index];
+          // Calculating the offset when endNode is different from startNode
+          // or when endNode is not the first node.
+          if (index != nodeStartIndex || index > 0) {
+            endValue -= nodeSizes[index - 1];
+          }
+        }
+      }
+      let range = document.createRange();
+      range.setStart(startNode, startValue);
+      range.setEnd(endNode, endValue);
+      this.getFindSelection(startNode.ownerGlobal).addRange(range);
+    }
+
+    return !!indices.length;
+  },
+
+  /**
+   * Get the selection instance from given window.
+   *
+   * @param {Object} win The window object points to frame's window.
+   */
+  getFindSelection(win) {
+    // Yuck. See bug 138068.
+    let docShell = win.docShell;
+
+    let controller = docShell
+      .QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsISelectionDisplay)
+      .QueryInterface(Ci.nsISelectionController);
+
+    let selection = controller.getSelection(
+      Ci.nsISelectionController.SELECTION_FIND
+    );
+    selection.setColors("currentColor", "#ffe900", "currentColor", "#003eaa");
+
+    return selection;
+  },
+
+  /**
+   * Shows or hides content according to search input.
+   *
+   * @param {Object} event to search for filted query in.
+   */
+  async searchFunction(event) {
+    let query = event.target.value.trim().toLowerCase();
+    if (this.query == query) {
+      return;
+    }
+
+    let subQuery = this.query && query.includes(this.query);
+    this.query = query;
+
+    this.getFindSelection(window).removeAllRanges();
+    this.removeAllSearchTooltips();
+    this.removeAllSearchMenuitemIndicators();
+
+    let srHeader = document.getElementById("header-searchResults");
+    let noResultsEl = document.getElementById("no-results-message");
+    if (this.query) {
+      // Showing the Search Results Tag.
+      await gotoPref("paneSearchResults");
+      srHeader.hidden = false;
+
+      let resultsFound = false;
+
+      // Building the range for highlighted areas.
+      let rootPreferencesChildren = [
+        ...document.querySelectorAll(
+          "#paneDeck > *:not([data-hidden-from-search]):not(script):not(stringbundle):not(commandset):not(keyset):not(linkset)"
+        ),
+      ];
+
+      if (subQuery) {
+        // Since the previous query is a subset of the current query,
+        // there is no need to check elements that is hidden already.
+        rootPreferencesChildren = rootPreferencesChildren.filter(
+          el => !el.hidden
+        );
+      }
+
+      // Attach the bindings for all children if they were not already visible.
+      for (let child of rootPreferencesChildren) {
+        if (child.hidden) {
+          child.classList.add("visually-hidden");
+          child.hidden = false;
+        }
+      }
+
+      let ts = performance.now();
+      let FRAME_THRESHOLD = 10;
+
+      // Showing or Hiding specific section depending on if words in query are found.
+      for (let child of rootPreferencesChildren) {
+        if (performance.now() - ts > FRAME_THRESHOLD) {
+          // Creating tooltips for all the instances found.
+          for (let anchorNode of this.listSearchTooltips) {
+            this.createSearchTooltip(anchorNode, this.query);
+          }
+          ts = await new Promise(resolve =>
+            window.requestAnimationFrame(resolve)
+          );
+          if (query !== this.query) {
+            return;
+          }
+        }
+
+        if (
+          !child.classList.contains("header") &&
+          !child.classList.contains("subcategory") &&
+          (await this.searchWithinNode(child, this.query))
+        ) {
+          child.classList.remove("visually-hidden");
+
+          // Show the preceding search-header if one exists.
+          let groupbox = child.closest("groupbox");
+          let groupHeader =
+            groupbox && groupbox.querySelector(".search-header");
+          if (groupHeader) {
+            groupHeader.hidden = false;
+          }
+
+          resultsFound = true;
+        } else {
+          child.classList.add("visually-hidden");
+        }
+      }
+
+      noResultsEl.hidden = !!resultsFound;
+      noResultsEl.setAttribute("query", this.query);
+      // XXX: This is potentially racy in case where Fluent retranslates the
+      // message and ereases the query within.
+      // The feature is not yet supported, but we should fix for it before
+      // we enable it. See bug 1446389 for details.
+      let msgQueryElem = document.getElementById("sorry-message-query");
+      msgQueryElem.textContent = this.query;
+      if (resultsFound) {
+        // Creating tooltips for all the instances found.
+        for (let anchorNode of this.listSearchTooltips) {
+          this.createSearchTooltip(anchorNode, this.query);
+        }
+      }
+    } else {
+      noResultsEl.hidden = true;
+      document.getElementById("sorry-message-query").textContent = "";
+      // Going back to General when cleared.
+      await gotoPref("paneGeneral");
+      srHeader.hidden = true;
+
+      // Hide some special second level headers in normal view.
+      for (let element of document.querySelectorAll(".search-header")) {
+        element.hidden = true;
+      }
+    }
+
+    window.dispatchEvent(
+      new CustomEvent("PreferencesSearchCompleted", { detail: query })
+    );
+  },
+
+  /**
+   * Finding leaf nodes and checking their content for words to search,
+   * It is a recursive function.
+   *
+   * @param {Node} nodeObject DOM Element.
+   * @param {String} searchPhrase
+   *
+   * @returns {boolean} Returns true when found in at least one childNode, false otherwise.
+   */
+  async searchWithinNode(nodeObject, searchPhrase) {
+    let matchesFound = false;
+    if (
+      nodeObject.childElementCount == 0 ||
+      nodeObject.tagName == "button" ||
+      nodeObject.tagName == "label" ||
+      nodeObject.tagName == "description" ||
+      nodeObject.tagName == "menulist" ||
+      nodeObject.tagName == "menuitem"
+    ) {
+      let simpleTextNodes = this.textNodeDescendants(nodeObject);
+      for (let node of simpleTextNodes) {
+        let result = this.highlightMatches(
+          [node],
+          [node.length],
+          node.textContent.toLowerCase(),
+          searchPhrase
+        );
+        matchesFound = matchesFound || result;
+      }
+
+      // Collecting data from anonymous content / label / description.
+      let nodeSizes = [];
+      let allNodeText = "";
+      let runningSize = 0;
+
+      let accessKeyTextNodes = [];
+
+      if (
+        nodeObject.tagName == "label" ||
+        nodeObject.tagName == "description"
+      ) {
+        accessKeyTextNodes.push(...simpleTextNodes);
+      }
+
+      for (let node of accessKeyTextNodes) {
+        runningSize += node.textContent.length;
+        allNodeText += node.textContent;
+        nodeSizes.push(runningSize);
+      }
+
+      // Access key are presented.
+      let complexTextNodesResult = this.highlightMatches(
+        accessKeyTextNodes,
+        nodeSizes,
+        allNodeText.toLowerCase(),
+        searchPhrase
+      );
+
+      // Searching some elements, such as xul:button, have a 'label' attribute
+      // that contains the user-visible text.
+      let labelResult = this.queryMatchesContent(
+        nodeObject.getAttribute("label"),
+        searchPhrase
+      );
+
+      // Searching some elements, such as xul:label, store their user-visible
+      // text in a "value" attribute. Value will be skipped for menuitem since
+      // value in menuitem could represent index number to distinct each item.
+      let valueResult =
+        nodeObject.tagName !== "menuitem" && nodeObject.tagName !== "radio"
+          ? this.queryMatchesContent(
+              nodeObject.getAttribute("value"),
+              searchPhrase
+            )
+          : false;
+
+      // Searching some elements, such as xul:button, buttons to open subdialogs
+      // using l10n ids.
+      let keywordsResult =
+        nodeObject.hasAttribute("search-l10n-ids") &&
+        (await this.matchesSearchL10nIDs(nodeObject, searchPhrase));
+
+      if (!keywordsResult) {
+        // Searching some elements, such as xul:button, buttons to open subdialogs
+        // using searchkeywords attribute.
+        keywordsResult =
+          !keywordsResult &&
+          nodeObject.hasAttribute("searchkeywords") &&
+          this.queryMatchesContent(
+            nodeObject.getAttribute("searchkeywords"),
+            searchPhrase
+          );
+      }
+
+      // Creating tooltips for buttons.
+      if (
+        keywordsResult &&
+        (nodeObject.tagName === "button" || nodeObject.tagName == "menulist")
+      ) {
+        this.listSearchTooltips.add(nodeObject);
+      }
+
+      if (keywordsResult && nodeObject.tagName === "menuitem") {
+        nodeObject.setAttribute("indicator", "true");
+        this.listSearchMenuitemIndicators.add(nodeObject);
+        let menulist = nodeObject.closest("menulist");
+
+        menulist.setAttribute("indicator", "true");
+        this.listSearchMenuitemIndicators.add(menulist);
+      }
+
+      if (
+        (nodeObject.tagName == "menulist" ||
+          nodeObject.tagName == "menuitem") &&
+        (labelResult || valueResult || keywordsResult)
+      ) {
+        nodeObject.setAttribute("highlightable", "true");
+      }
+
+      matchesFound =
+        matchesFound ||
+        complexTextNodesResult ||
+        labelResult ||
+        valueResult ||
+        keywordsResult;
+    }
+
+    // Should not search unselected child nodes of a <xul:deck> element
+    // except the "historyPane" <xul:deck> element.
+    if (nodeObject.tagName == "deck" && nodeObject.id != "historyPane") {
+      let index = nodeObject.selectedIndex;
+      if (index != -1) {
+        let result = await this.searchChildNodeIfVisible(
+          nodeObject,
+          index,
+          searchPhrase
+        );
+        matchesFound = matchesFound || result;
+      }
+    } else {
+      for (let i = 0; i < nodeObject.childNodes.length; i++) {
+        let result = await this.searchChildNodeIfVisible(
+          nodeObject,
+          i,
+          searchPhrase
+        );
+        matchesFound = matchesFound || result;
+      }
+    }
+    return matchesFound;
+  },
+
+  /**
+   * Search for a phrase within a child node if it is visible.
+   *
+   * @param {Node} nodeObject The parent DOM Element.
+   * @param {Number} index The index for the childNode.
+   * @param {String} searchPhrase
+   *
+   * @returns {boolean} Returns true when found the specific childNode, false otherwise
+   */
+  async searchChildNodeIfVisible(nodeObject, index, searchPhrase) {
+    let result = false;
+    if (
+      !nodeObject.childNodes[index].hidden &&
+      nodeObject.getAttribute("data-hidden-from-search") !== "true"
+    ) {
+      result = await this.searchWithinNode(
+        nodeObject.childNodes[index],
+        searchPhrase
+      );
+      // Creating tooltips for menulist element.
+      if (result && nodeObject.tagName === "menulist") {
+        this.listSearchTooltips.add(nodeObject);
+      }
+    }
+    return result;
+  },
+
+  /**
+   * Search for a phrase in l10n messages associated with the element.
+   *
+   * @param {Node} nodeObject The parent DOM Element.
+   * @param {String} searchPhrase.
+   * @returns {boolean} true when the text content contains the query string else false.
+   */
+  async matchesSearchL10nIDs(nodeObject, searchPhrase) {
+    if (!this.searchKeywords.has(nodeObject)) {
+      // The `search-l10n-ids` attribute is a comma-separated list of
+      // l10n ids. It may also uses a dot notation to specify an attribute
+      // of the message to be used.
+      //
+      // Example: "containers-add-button.label, user-context-personal".
+      //
+      // The result is an array of arrays of l10n ids and optionally attribute names.
+      //
+      // Example: [["containers-add-button", "label"], ["user-context-personal"]]
+      const refs = nodeObject
+        .getAttribute("search-l10n-ids")
+        .split(",")
+        .map(s => s.trim().split("."))
+        .filter(s => !!s[0].length);
+
+      const messages = await document.l10n.formatMessages(
+        refs.map(ref => ({ id: ref[0] }))
+      );
+
+      // Map the localized messages taking value or a selected attribute and
+      // building a string of concatenated translated strings out of it.
+      let keywords = messages
+        .map((msg, i) => {
+          let [refId, refAttr] = refs[i];
+          if (!msg) {
+            console.error(`Missing search l10n id "${refId}"`);
+            return null;
+          }
+          if (refAttr) {
+            let attr =
+              msg.attributes && msg.attributes.find(a => a.name === refAttr);
+            if (!attr) {
+              console.error(`Missing search l10n id "${refId}.${refAttr}"`);
+              return null;
+            }
+            if (attr.value === "") {
+              console.error(
+                `Empty value added to search-l10n-ids "${refId}.${refAttr}"`
+              );
+            }
+            return attr.value;
+          }
+          if (msg.value === "") {
+            console.error(`Empty value added to search-l10n-ids "${refId}"`);
+          }
+          return msg.value;
+        })
+        .filter(keyword => keyword !== null)
+        .join(" ");
+
+      this.searchKeywords.set(nodeObject, keywords);
+      return this.queryMatchesContent(keywords, searchPhrase);
+    }
+
+    return this.queryMatchesContent(
+      this.searchKeywords.get(nodeObject),
+      searchPhrase
+    );
+  },
+
+  /**
+   * Inserting a div structure infront of the DOM element matched textContent.
+   * Then calculation the offsets to position the tooltip in the correct place.
+   *
+   * @param {Node} anchorNode DOM Element.
+   * @param {String} query Word or words that are being searched for.
+   */
+  createSearchTooltip(anchorNode, query) {
+    if (anchorNode.tooltipNode) {
+      return;
+    }
+    let searchTooltip = anchorNode.ownerDocument.createElement("span");
+    let searchTooltipText = anchorNode.ownerDocument.createElement("span");
+    searchTooltip.className = "search-tooltip";
+    searchTooltipText.textContent = query;
+    searchTooltip.appendChild(searchTooltipText);
+
+    // Set tooltipNode property to track corresponded tooltip node.
+    anchorNode.tooltipNode = searchTooltip;
+    anchorNode.parentElement.classList.add("search-tooltip-parent");
+    anchorNode.parentElement.appendChild(searchTooltip);
+
+    this.calculateTooltipPosition(anchorNode);
+  },
+
+  calculateTooltipPosition(anchorNode) {
+    let searchTooltip = anchorNode.tooltipNode;
+    // In order to get the up-to-date position of each of the nodes that we're
+    // putting tooltips on, we have to flush layout intentionally, and that
+    // this is the result of a XUL limitation (bug 1363730).
+    let tooltipRect = searchTooltip.getBoundingClientRect();
+    searchTooltip.style.setProperty(
+      "left",
+      `calc(50% - ${tooltipRect.width / 2}px)`
+    );
+  },
+
+  /**
+   * Remove all search tooltips.
+   */
+  removeAllSearchTooltips() {
+    for (let anchorNode of this.listSearchTooltips) {
+      anchorNode.parentElement.classList.remove("search-tooltip-parent");
+      if (anchorNode.tooltipNode) {
+        anchorNode.tooltipNode.remove();
+      }
+      anchorNode.tooltipNode = null;
+    }
+    this.listSearchTooltips.clear();
+  },
+
+  /**
+   * Remove all indicators on menuitem.
+   */
+  removeAllSearchMenuitemIndicators() {
+    for (let node of this.listSearchMenuitemIndicators) {
+      node.removeAttribute("indicator");
+    }
+    this.listSearchMenuitemIndicators.clear();
+  },
+};
--- a/mail/components/preferences/general.inc.xhtml
+++ b/mail/components/preferences/general.inc.xhtml
@@ -1,103 +1,118 @@
 # 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/.
-  <prefpane id="paneGeneral">
-    <script src="chrome://communicator/content/utilityOverlay.js"/>
-    <script src="chrome://messenger/content/preferences/general.js"/>
-    <script src="chrome://mozapps/content/preferences/fontbuilder.js"/>
+  <script src="chrome://communicator/content/utilityOverlay.js" />
+  <script src="chrome://messenger/content/preferences/general.js"/>
+  <script src="chrome://mozapps/content/preferences/fontbuilder.js"/>
 
-    <commandset id="appPaneCommandSet">
-      <command id="cmd_delete"
-               oncommand="gGeneralPane.onDelete();"/>
-    </commandset>
+  <commandset id="appPaneCommandSet">
+    <command id="cmd_delete"
+             oncommand="gGeneralPane.onDelete();"/>
+  </commandset>
 
-    <keyset id="appPaneKeyset">
-      <key keycode="VK_BACK" modifiers="any" command="cmd_delete"/>
-      <key keycode="VK_DELETE" modifiers="any" command="cmd_delete"/>
-    </keyset>
+  <keyset id="appPaneKeyset">
+    <key keycode="VK_BACK" modifiers="any" command="cmd_delete"/>
+    <key keycode="VK_DELETE" modifiers="any" command="cmd_delete"/>
+  </keyset>
 
-    <keyset>
-      <key data-l10n-id="focus-search-shortcut" modifiers="accel"
-           oncommand="gGeneralPane.focusFilterBox();"/>
-      <key data-l10n-id="focus-search-shortcut-alt" modifiers="accel"
-           oncommand="gGeneralPane.focusFilterBox();"/>
-    </keyset>
+  <keyset>
+    <key data-l10n-id="focus-search-shortcut" modifiers="accel"
+         oncommand="gGeneralPane.focusFilterBox();"/>
+    <key data-l10n-id="focus-search-shortcut-alt" modifiers="accel"
+         oncommand="gGeneralPane.focusFilterBox();"/>
+  </keyset>
 
-    <linkset>
-      <html:link rel="localization" href="branding/brand.ftl"/>
-      <html:link rel="localization" href="messenger/preferences/preferences.ftl"/>
-    </linkset>
+  <linkset>
+    <html:link rel="localization" href="branding/brand.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/preferences.ftl"/>
+  </linkset>
 
-    <stringbundle id="bundlePreferences" src="chrome://messenger/locale/preferences/preferences.properties"/>
+  <stringbundle id="bundlePreferences" src="chrome://messenger/locale/preferences/preferences.properties"/>
 #ifdef HAVE_SHELL_SERVICE
-    <stringbundle id="bundleBrand" src="chrome://branding/locale/brand.properties"/>
+  <stringbundle id="bundleBrand" src="chrome://branding/locale/brand.properties"/>
 #endif
-
+  <html:template id="paneGeneral">
     <hbox id="generalCategory"
           class="subcategory"
           data-category="paneGeneral">
       <html:h1 data-l10n-id="pane-general-title"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <html:legend data-l10n-id="general-legend"></html:legend>
       <vbox>
         <hbox align="start">
           <checkbox id="mailnewsStartPageEnabled"
                     preference="mailnews.start_page.enabled"
                     data-l10n-id="start-page-label"/>
         </hbox>
         <hbox align="center" class="input-container">
           <label data-l10n-id="location-label" control="mailnewsStartPageUrl"/>
           <html:input id="mailnewsStartPageUrl"
                       type="text"
                       preference="mailnews.start_page.url"/>
-          <button id="browseForStartPageUrl"
+          <button is="highlightable-button" id="browseForStartPageUrl"
                   data-l10n-id="restore-default-label"
                   oncommand="gGeneralPane.restoreDefaultStartPage();">
           </button>
         </hbox>
       </vbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <html:legend data-l10n-id="default-search-engine"></html:legend>
       <hbox align="center">
-        <menulist id="defaultWebSearch">
-          <menupopup id="defaultWebSearchPopup"/>
-        </menulist>
-        <button id="addSearchEngine"
+        <hbox>
+          <menulist id="defaultWebSearch">
+            <menupopup id="defaultWebSearchPopup"/>
+          </menulist>
+        </hbox>
+        <button is="highlightable-button" id="addSearchEngine"
                 data-l10n-id="add-search-engine"
                 oncommand="gGeneralPane.addSearchEngine();"/>
-        <button id="removeSearchEngine"
+        <button is="highlightable-button" id="removeSearchEngine"
                 data-l10n-id="remove-search-engine"
                 oncommand="gGeneralPane.removeSearchEngine();"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
 #ifdef HAVE_SHELL_SERVICE
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset id="systemDefaultsGroup" data-category="paneGeneral">
       <html:legend data-l10n-id="system-integration-legend"></html:legend>
       <vbox>
       <hbox id="checkDefaultBox" align="center">
         <checkbox id="alwaysCheckDefault"
                   preference="mail.shell.checkDefaultClient"
                   data-l10n-id="always-check-default"/>
         <spacer flex="1"/>
-        <button id="checkDefaultButton"
-                data-l10n-id="check-default-button"
-                oncommand="gGeneralPane.checkDefaultNow();"
-                preference="pref.general.disable_button.default_mail"/>
+        <hbox>
+          <button is="highlightable-button" id="checkDefaultButton"
+                  data-l10n-id="check-default-button"
+                  oncommand="gGeneralPane.checkDefaultNow();"
+                  preference="pref.general.disable_button.default_mail"
+                  search-l10n-ids="
+                    system-integration-title.title,
+                    system-integration-dialog.buttonlabelaccept,
+                    system-integration-dialog.buttonlabelcancel,
+                    system-integration-dialog.buttonlabelcancel2,
+                    default-client-intro,
+                    unset-default-tooltip,
+                    checkbox-email-label.label,
+                    checkbox-newsgroups-label.label,
+                    checkbox-feeds-label.label,
+                    system-search-integration-label.label,
+                    check-on-startup-label.label"/>
+        </hbox>
       </hbox>
 #ifdef XP_WIN
       <hbox align="start">
         <checkbox data-l10n-id="minimize-to-tray-label"
                   preference="mail.minimizeToTray"/>
       </hbox>
 #endif
       <hbox id="searchIntegrationContainer">
@@ -112,68 +127,141 @@
 
     <hbox id="languageAndAppearanceCategory"
           class="subcategory"
           data-category="paneGeneral">
       <html:h1 data-l10n-id="general-language-and-appearance-header"/>
     </hbox>
 
     <!-- Fonts and Colors -->
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset id="fontsGroup" data-category="paneGeneral">
       <html:legend data-l10n-id="fonts-legend"></html:legend>
 
       <hbox id="fontSettings" flex="1">
         <vbox id="fontRow" flex="1">
           <hbox align="center">
             <label data-l10n-id="default-font-label" control="defaultFont"/>
-            <menulist id="defaultFont" flex="1" sizetopopup="pref" crop="center">
-              <menupopup crop="center"/>
-            </menulist>
+            <hbox flex="1">
+              <menulist id="defaultFont" flex="1" sizetopopup="pref" crop="center">
+                <menupopup crop="center"/>
+              </menulist>
+            </hbox>
             <label data-l10n-id="default-size-label" control="defaultFontSize"/>
-            <menulist id="defaultFontSize" flex="1">
-              <menupopup crop="center">
-                <menuitem value="9" label="9"/>
-                <menuitem value="10" label="10"/>
-                <menuitem value="11" label="11"/>
-                <menuitem value="12" label="12"/>
-                <menuitem value="13" label="13"/>
-                <menuitem value="14" label="14"/>
-                <menuitem value="15" label="15"/>
-                <menuitem value="16" label="16"/>
-                <menuitem value="17" label="17"/>
-                <menuitem value="18" label="18"/>
-                <menuitem value="20" label="20"/>
-                <menuitem value="22" label="22"/>
-                <menuitem value="24" label="24"/>
-                <menuitem value="26" label="26"/>
-                <menuitem value="28" label="28"/>
-                <menuitem value="30" label="30"/>
-                <menuitem value="32" label="32"/>
-                <menuitem value="34" label="34"/>
-                <menuitem value="36" label="36"/>
-                <menuitem value="40" label="40"/>
-                <menuitem value="44" label="44"/>
-                <menuitem value="48" label="48"/>
-                <menuitem value="56" label="56"/>
-                <menuitem value="64" label="64"/>
-                <menuitem value="72" label="72"/>
-              </menupopup>
-            </menulist>
+            <hbox flex="1">
+              <menulist id="defaultFontSize" flex="1">
+                <menupopup crop="center">
+                  <menuitem value="9" label="9"/>
+                  <menuitem value="10" label="10"/>
+                  <menuitem value="11" label="11"/>
+                  <menuitem value="12" label="12"/>
+                  <menuitem value="13" label="13"/>
+                  <menuitem value="14" label="14"/>
+                  <menuitem value="15" label="15"/>
+                  <menuitem value="16" label="16"/>
+                  <menuitem value="17" label="17"/>
+                  <menuitem value="18" label="18"/>
+                  <menuitem value="20" label="20"/>
+                  <menuitem value="22" label="22"/>
+                  <menuitem value="24" label="24"/>
+                  <menuitem value="26" label="26"/>
+                  <menuitem value="28" label="28"/>
+                  <menuitem value="30" label="30"/>
+                  <menuitem value="32" label="32"/>
+                  <menuitem value="34" label="34"/>
+                  <menuitem value="36" label="36"/>
+                  <menuitem value="40" label="40"/>
+                  <menuitem value="44" label="44"/>
+                  <menuitem value="48" label="48"/>
+                  <menuitem value="56" label="56"/>
+                  <menuitem value="64" label="64"/>
+                  <menuitem value="72" label="72"/>
+                </menupopup>
+              </menulist>
+            </hbox>
           </hbox>
         </vbox>
         <vbox id="colorsRow">
-          <button id="advancedFonts"
-                  data-l10n-id="font-options-button"
-                  oncommand="gGeneralPane.configureFonts();"
-                  flex="1"/>
-          <button id="colors"
-                  data-l10n-id="color-options-button"
-                  oncommand="gGeneralPane.configureColors();"
-                  flex="1"/>
+          <hbox flex="1">
+            <button is="highlightable-button" id="advancedFonts"
+                    data-l10n-id="font-options-button"
+                    oncommand="gGeneralPane.configureFonts();"
+                    flex="1"
+                    search-l10n-ids="
+                      fonts-label-default-unnamed.label,
+                      fonts-encoding-dialog-title.title,
+                      fonts-language-legend.value,
+                      fonts-proportional-label.value,
+                      font-language-group-latin.label,
+                      font-language-group-japanese.label,
+                      font-language-group-trad-chinese.label,
+                      font-language-group-simpl-chinese.label,
+                      font-language-group-trad-chinese-hk.label,
+                      font-language-group-korean.label,
+                      font-language-group-cyrillic.label,
+                      font-language-group-el.label,
+                      font-language-group-other.label,
+                      font-language-group-thai.label,
+                      font-language-group-hebrew.label,
+                      font-language-group-arabic.label,
+                      font-language-group-devanagari.label,
+                      font-language-group-tamil.label,
+                      font-language-group-armenian.label,
+                      font-language-group-bengali.label,
+                      font-language-group-canadian.label,
+                      font-language-group-ethiopic.label,
+                      font-language-group-georgian.label,
+                      font-language-group-gujarati.label,
+                      font-language-group-gurmukhi.label,
+                      font-language-group-khmer.label,
+                      font-language-group-malayalam.label,
+                      font-language-group-math.label,
+                      font-language-group-odia.label,
+                      font-language-group-telugu.label,
+                      font-language-group-kannada.label,
+                      font-language-group-sinhala.label,
+                      font-language-group-tibetan.label,
+                      default-font-serif.label,
+                      default-font-sans-serif.label,
+                      font-size-label.value,
+                      font-size-monospace-label.value,
+                      font-serif-label.value,
+                      font-sans-serif-label.value,
+                      font-monospace-label.value,
+                      font-min-size-label.value,
+                      min-size-none.label,
+                      font-control-legend,
+                      use-document-fonts-checkbox.label,
+                      use-fixed-width-plain-checkbox.label,
+                      text-encoding-legend,
+                      text-encoding-description,
+                      font-outgoing-email-label.value,
+                      font-incoming-email-label.value,
+                      default-font-reply-checkbox.label"/>
+          </hbox>
+          <hbox flex="1">
+            <button is="highlightable-button" id="colors"
+                    data-l10n-id="color-options-button"
+                    oncommand="gGeneralPane.configureColors();"
+                    flex="1"
+                    search-l10n-ids="
+                      colors-dialog-window.title,
+                      colors-dialog-legend,
+                      text-color-label.value,
+                      background-color-label.value,
+                      use-system-colors.label,
+                      colors-link-legend,
+                      link-color-label.value,
+                      visited-link-color-label.value,
+                      underline-link-checkbox.label,
+                      override-color-label.value,
+                      override-color-always.label,
+                      override-color-auto.label,
+                      override-color-never.label"/>
+          </hbox>
         </vbox>
       </hbox>
       <hbox>
         <html:legend data-l10n-id="display-width-legend"></html:legend>
       </hbox>
       <hbox>
         <checkbox id="displayGlyph"
                   preference="mail.display_glyph"
@@ -181,85 +269,108 @@
         <spacer flex="1"/>
       </hbox>
 
       <separator class="thin"/>
 
       <label control="displayText" data-l10n-id="display-text-label"/>
       <hbox id="displayText" class="indent" align="center" role="group">
         <label data-l10n-id="style-label" control="mailQuotedStyle"/>
-        <menulist id="mailQuotedStyle" preference="mail.quoted_style">
-          <menupopup>
-            <menuitem value="0" data-l10n-id="regular-style-item"/>
-            <menuitem value="1" data-l10n-id="bold-style-item"/>
-            <menuitem value="2" data-l10n-id="italic-style-item"/>
-            <menuitem value="3" data-l10n-id="bold-italic-style-item"/>
-          </menupopup>
-        </menulist>
+        <hbox>
+          <menulist id="mailQuotedStyle" preference="mail.quoted_style">
+            <menupopup>
+              <menuitem value="0" data-l10n-id="regular-style-item"/>
+              <menuitem value="1" data-l10n-id="bold-style-item"/>
+              <menuitem value="2" data-l10n-id="italic-style-item"/>
+              <menuitem value="3" data-l10n-id="bold-italic-style-item"/>
+            </menupopup>
+          </menulist>
+        </hbox>
         <label data-l10n-id="size-label" control="mailQuotedSize"/>
-        <menulist id="mailQuotedSize" preference="mail.quoted_size">
-          <menupopup>
-            <menuitem value="0" data-l10n-id="regular-size-item"/>
-            <menuitem value="1" data-l10n-id="bigger-size-item"/>
-            <menuitem value="2" data-l10n-id="smaller-size-item"/>
-          </menupopup>
-        </menulist>
+        <hbox>
+          <menulist id="mailQuotedSize" preference="mail.quoted_size">
+            <menupopup>
+              <menuitem value="0" data-l10n-id="regular-size-item"/>
+              <menuitem value="1" data-l10n-id="bigger-size-item"/>
+              <menuitem value="2" data-l10n-id="smaller-size-item"/>
+            </menupopup>
+          </menulist>
+        </hbox>
         <label data-l10n-id="quoted-text-color" control="citationmenu"/>
         <html:input type="color" id="citationmenu" preference="mail.citation_color"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
     <!-- Date and time formatting -->
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <html:legend data-l10n-id="datetime-formatting-legend"></html:legend>
       <radiogroup id="formatLocale" align="start"
                   preference="intl.regional_prefs.use_os_locales"
                   orient="vertical">
         <radio id="appLocale"
                value="false"/>
                <!-- label and accesskey will be set dynamically -->
         <radio id="rsLocale"
                value="true"/>
                <!-- label and accesskey will be set dynamically -->
       </radiogroup>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset id="messengerLanguagesBox" data-category="paneGeneral" hidden="hidden">
       <html:legend data-l10n-id="language-selector-legend"></html:legend>
         <vbox align="start">
         <description flex="1"
                      controls="chooseMessengerLanguage"
                      data-l10n-id="choose-messenger-language-description"/>
         <hbox>
-          <menulist id="defaultMessengerLanguage"
-                    oncommand="gGeneralPane.onMessengerLanguageChange(event)">
-            <menupopup/>
-          </menulist>
-          <button id="manageMessengerLanguagesButton"
-                  class="accessory-button"
-                  data-l10n-id="manage-messenger-languages-button"
-                  oncommand="gGeneralPane.showMessengerLanguages({search: false})"/>
+          <hbox>
+            <menulist id="defaultMessengerLanguage"
+                      oncommand="gGeneralPane.onMessengerLanguageChange(event)">
+              <menupopup/>
+            </menulist>
+          </hbox>
+          <hbox>
+            <button is="highlightable-button" id="manageMessengerLanguagesButton"
+                    class="accessory-button"
+                    data-l10n-id="manage-messenger-languages-button"
+                    oncommand="gGeneralPane.showMessengerLanguages({search: false})"
+                    search-l10n-ids="
+                      languages-customize-moveup.label,
+                      languages-customize-movedown.label,
+                      languages-customize-remove.label,
+                      languages-customize-select-language.placeholder,
+                      languages-customize-add.label,
+                      messenger-languages-window.title,
+                      messenger-languages-description,
+                      messenger-languages-search,
+                      messenger-languages-searching.label,
+                      messenger-languages-downloading.label,
+                      messenger-languages-select-language.label,
+                      messenger-languages-installed-label,
+                      messenger-languages-available-label,
+                      messenger-languages-error"/>
+          </hbox>
         </hbox>
       </vbox>
       <hbox id="confirmMessengerLanguage"
             class="message-bar"
             align="center"
             hidden="true">
         <image class="message-bar-icon"/>
         <vbox class="message-bar-content-container" align="stretch" flex="1"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
     <!-- Scrolling -->
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset id="scrollingGroup" data-category="paneGeneral">
       <html:legend data-l10n-id="scrolling-legend"></html:legend>
       <hbox>
         <checkbox id="useAutoScroll"
                   data-l10n-id="autoscroll-label"
                   preference="general.autoScroll"/>
         <spacer flex="1"/>
       </hbox>
@@ -267,43 +378,62 @@
         <checkbox id="useSmoothScrolling"
                   data-l10n-id="smooth-scrolling-label"
                   preference="general.smoothScroll"/>
         <spacer flex="1"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
-
     <hbox id="incomingMailCategory"
           class="subcategory"
           data-category="paneGeneral">
       <html:h1 data-l10n-id="general-incoming-mail-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <html:legend data-l10n-id="new-message-arrival"></html:legend>
 #ifdef XP_MACOSX
       <hbox align="center">
         <description flex="1" data-l10n-id="change-dock-icon"/>
-        <button id="dockOptions"
-                oncommand="gGeneralPane.configureDockOptions();"
-                data-l10n-id="app-icon-options"/>
+        <hbox>
+          <button is="highlightable-button" id="dockOptions"
+                  oncommand="gGeneralPane.configureDockOptions();"
+                  data-l10n-id="app-icon-options"
+                  search-l10n-ids="
+                    dock-options-window-dialog.title,
+                    bounce-system-dock-icon.label,
+                    dock-icon-legend,
+                    dock-icon-show-label.value,
+                    count-unread-messages-radio.label,
+                    count-new-messages-radio.label,
+                    notification-settings-info"/>
+        </hbox>
       </hbox>
       <description class="bold" data-l10n-id="notification-settings"/>
 #else
       <hbox align="center">
         <checkbox id="newMailNotificationAlert"
                   data-l10n-id="animated-alert-label"
                   preference="mail.biff.show_alert"/>
         <spacer flex="1"/>
-        <button id="customizeMailAlert"
-                oncommand="gGeneralPane.customizeMailAlert();"
-                data-l10n-id="customize-alert-label"/>
+        <hbox>
+          <button is="highlightable-button" id="customizeMailAlert"
+                  oncommand="gGeneralPane.customizeMailAlert();"
+                  data-l10n-id="customize-alert-label"
+                  search-l10n-ids="
+                    notifications-dialog-window.title,
+                    customize-alert-description,
+                    preview-text-checkbox.label,
+                    subject-checkbox.label,
+                    sender-checkbox.label,
+                    open-time-label-before.value,
+                    open-time-label-after.value"/>
+        </hbox>
       </hbox>
       <hbox>
         <checkbox id="newMailNotificationTrayIcon"
 #ifndef XP_WIN
                   hidden="true"
 #endif
                   preference="mail.biff.show_tray_icon"
                   data-l10n-id="tray-icon-label"/>
@@ -311,17 +441,17 @@
 #endif
 
       <hbox align="center">
         <checkbox id="newMailNotification"
                   preference="mail.biff.play_sound"
                   data-l10n-id="mail-play-sound-label"
                   oncommand="gGeneralPane.updatePlaySound();"/>
         <spacer flex="1"/>
-        <button id="playSound"
+        <button is="highlightable-button" id="playSound"
                 data-l10n-id="mail-play-button"
                 oncommand="gGeneralPane.previewSound();"/>
       </hbox>
 
 #ifndef XP_MACOSX
       <radiogroup id="soundType"
                   class="indent"
                   preference="mail.biff.play_sound.type"
@@ -345,30 +475,30 @@
       <hbox align="center" class="input-container">
         <html:input id="soundUrlLocation"
                     type="text"
                     class="input-filefield indent"
                     readonly="readonly"
                     preference="mail.biff.play_sound.url"
                     preference-editable="true"
                     aria-labelledby="custom"/>
-        <button id="browseForSound"
+        <button is="highlightable-button" id="browseForSound"
                 data-l10n-id="mail-browse-sound-button"
                 oncommand="gGeneralPane.browseForSoundFile();"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
     <hbox id="filesAttachmentCategory"
           class="subcategory"
           data-category="paneGeneral">
       <html:h1 data-l10n-id="general-files-and-attachment-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <hbox>
         <search-textbox id="filter"
                         flex="1"
                         data-l10n-id="search-input"
                         data-l10n-attrs="placeholder"
                         aria-controls="handlersView"
                         oncommand="gGeneralPane._rebuildView();"/>
@@ -401,17 +531,17 @@
             <radio id="saveTo" value="true"
                    data-l10n-id="save-to-label"
                    aria-labelledby="saveTo downloadFolder"/>
             <html:input id="downloadFolder"
                         class="input-filefield"
                         type="text"
                         readonly="readonly"
                         aria-labelledby="saveTo"/>
-            <button id="chooseFolder"
+            <button is="highlightable-button" id="chooseFolder"
                     oncommand="gDownloadDirSection.chooseFolder();"
                     data-l10n-id="choose-folder-label"/>
           </hbox>
           <hbox>
             <radio id="alwaysAsk"
                    value="false"
                    data-l10n-id="always-ask-label"/>
           </hbox>
@@ -421,47 +551,59 @@
     </html:div>
 
     <hbox id="tagsCategory"
           class="subcategory"
           data-category="paneGeneral">
       <html:h1 data-l10n-id="general-tags-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <label control="tagList" data-l10n-id="display-tags-text"/>
       <hbox>
         <richlistbox id="tagList"
                      flex="1"
                      height="180px"
                      ondblclick="gGeneralPane.editTag();"
                      onselect="gGeneralPane.onSelectTag();"/>
         <vbox id="tagButtons">
-          <button data-l10n-id="new-tag-button"
-                  oncommand="gGeneralPane.addTag();"/>
-          <button id="editTagButton" disabled="true"
-                  data-l10n-id="edit-tag-button"
-                  oncommand="gGeneralPane.editTag();"/>
-          <button id="removeTagButton" disabled="true"
+          <hbox>
+            <button is="highlightable-button"
+                    data-l10n-id="new-tag-button"
+                    oncommand="gGeneralPane.addTag();"
+                    search-l10n-ids="
+                      tag-dialog-window.title,
+                      tag-name-label.value"/>
+          </hbox>
+          <hbox>
+            <button is="highlightable-button" id="editTagButton"
+                    disabled="true"
+                    data-l10n-id="edit-tag-button"
+                    oncommand="gGeneralPane.editTag();"
+                    search-l10n-ids="
+                      tag-dialog-window.title,
+                      tag-name-label.value"/>
+          </hbox>
+          <button is="highlightable-button" id="removeTagButton"
+                  disabled="true"
                   data-l10n-id="delete-tag-button"
                   oncommand="gGeneralPane.removeTag();"/>
         </vbox>
       </hbox>
     </html:fieldset>
     </html:div>
 
-
     <hbox id="readingAndDisplayCategory"
           class="subcategory"
           data-category="paneGeneral">
       <html:h1 data-l10n-id="general-reading-and-display-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <vbox>
         <hbox>
           <checkbox id="automaticallyMarkAsRead"
                     preference="mailnews.mark_message_read.auto"
                     data-l10n-id="auto-mark-as-read"/>
         </hbox>
 
@@ -518,116 +660,150 @@
                   data-l10n-id="condensed-addresses-label"
                   preference="mail.showCondensedAddresses"/>
       </hbox>
 
       <separator class="thin"/>
 
       <hbox align="center">
         <description flex="1" data-l10n-id="return-receipts-description"/>
-        <button id="showReturnReceipts"
-                data-l10n-id="return-receipts-button"
-                oncommand="gGeneralPane.showReturnReceipts();"/>
+        <hbox>
+          <button is="highlightable-button" id="showReturnReceipts"
+                  data-l10n-id="return-receipts-button"
+                  oncommand="gGeneralPane.showReturnReceipts();"
+                  search-l10n-ids="
+                    receipts-dialog-window.title,
+                    return-receipt-checkbox.label,
+                    receipt-arrive-label,
+                    receipt-leave-radio.label,
+                    receipt-move-radio.label,
+                    receipt-request-label,
+                    receipt-return-never-radio.label,
+                    receipt-return-some-radio.label,
+                    receipt-not-to-cc.value,
+                    receipt-send-never-label.label,
+                    receipt-send-always-label.label,
+                    receipt-send-ask-label.label,
+                    sender-outside-domain.value,
+                    other-cases-label.value"/>
+        </hbox>
       </hbox>
     </html:fieldset>
     </html:div>
 
 #ifdef MOZ_UPDATER
     <hbox id="updatesCategory"
           class="subcategory"
           data-category="paneGeneral">
       <html:h1 data-l10n-id="general-updates-header"/>
     </hbox>
 
     <!-- Update -->
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset id="updateApp" data-category="paneGeneral">
       <html:legend data-l10n-id="update-app-legend"></html:legend>
       <hbox align="center">
         <vbox>
           <description>
             <label id="version"/>
             <label is="text-link" id="releasenotes" hidden="true">&releaseNotes.link;</label>
           </description>
           <description id="distribution" class="text-blurb" hidden="true"/>
           <description id="distributionId" class="text-blurb" hidden="true"/>
         </vbox>
         <spacer flex="1"/>
         <vbox>
-          <button id="showUpdateHistory"
-                  data-l10n-id="update-history-button"
-                  preference="app.update.disable_button.showUpdateHistory"
-                  oncommand="gGeneralPane.showUpdates();"/>
+          <hbox>
+            <button is="highlightable-button" id="showUpdateHistory"
+                    data-l10n-id="update-history-button"
+                    preference="app.update.disable_button.showUpdateHistory"
+                    oncommand="gGeneralPane.showUpdates();"
+                    search-l10n-ids="
+                      history-title,
+                      history-intro,
+                      close-button-label.buttonlabelcancel,
+                      close-button-label.title,
+                      no-updates-label,
+                      name-header,
+                      date-header,
+                      type-header,
+                      state-header"/>
+          </hbox>
         </vbox>
       </hbox>
       <vbox id="updateBox">
         <deck id="updateDeck" orient="vertical">
           <hbox id="checkForUpdates" align="center">
             <spacer flex="1"/>
-            <button id="checkForUpdatesButton" align="start"
+            <button is="highlightable-button" id="checkForUpdatesButton"
+                    align="start"
                     label="&update.checkForUpdatesButton.label;"
                     accesskey="&update.checkForUpdatesButton.accesskey;"
                     oncommand="gAppUpdater.checkForUpdates();"/>
           </hbox>
           <hbox id="downloadAndInstall" align="center">
             <spacer flex="1"/>
-            <button id="downloadAndInstallButton"
+            <button is="highlightable-button" id="downloadAndInstallButton"
                     oncommand="gAppUpdater.startDownload();"/>
                     <!-- label and accesskey will be filled by JS -->
           </hbox>
           <hbox id="apply" align="center">
             <spacer flex="1"/>
-            <button id="updateButton"
+            <button is="highlightable-button" id="updateButton"
                     label="&update.updateButton.label3;"
                     accesskey="&update.updateButton.accesskey;"
                     oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
           </hbox>
           <hbox id="checkingForUpdates" align="center">
             <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
             <spacer flex="1"/>
-            <button label="&update.checkForUpdatesButton.label;"
+            <button is="highlightable-button"
+                    label="&update.checkForUpdatesButton.label;"
                     accesskey="&update.checkForUpdatesButton.accesskey;"
                     disabled="true"/>
           </hbox>
           <hbox id="downloading" align="center">
             <image class="update-throbber"/><label>&update.downloading.start;</label>
             <label id="downloadStatus"/><label>&update.downloading.end;</label>
           </hbox>
           <hbox id="applying" align="center">
             <image class="update-throbber"/><label>&update.applying;</label>
           </hbox>
          <hbox id="downloadFailed" align="center">
             <label>&update.failed.start;</label>
             <label is="text-link" id="failedLink">&update.failed.linkText;</label>
             <label>&update.failed.end;</label>
             <spacer flex="1"/>
-            <button label="&update.checkForUpdatesButton.label;"
+            <button is="highlightable-button"
+                    label="&update.checkForUpdatesButton.label;"
                     accesskey="&update.checkForUpdatesButton.accesskey;"
                     oncommand="gAppUpdater.checkForUpdates();"/>
           </hbox>
           <hbox id="policyDisabled" align="center">
             <label>&update.adminDisabled;</label>
           </hbox>
           <hbox id="noUpdatesFound" align="center">
             <label>&update.noUpdatesFound;</label>
             <spacer flex="1"/>
-            <button label="&update.checkForUpdatesButton.label;"
+            <button is="highlightable-button"
+                    label="&update.checkForUpdatesButton.label;"
                     accesskey="&update.checkForUpdatesButton.accesskey;"
                     oncommand="gAppUpdater.checkForUpdates();"/>
           </hbox>
           <hbox id="otherInstanceHandlingUpdates" align="center">
             <label>&update.otherInstanceHandlingUpdates;</label>
           </hbox>
           <hbox id="manualUpdate" align="center">
             <label>&update.manual.start;</label><label is="text-link" id="manualLink">
               &update.manual.linkText;
             </label>
             <label>&update.manual.end;</label>
             <spacer flex="1"/>
-            <button label="&update.checkForUpdatesButton.label;"
+            <button is="highlightable-button"
+                    label="&update.checkForUpdatesButton.label;"
                     accesskey="&update.checkForUpdatesButton.accesskey;"
                     disabled="true"/>
           </hbox>
           <hbox id="unsupportedSystem" align="center">
             <label>&update.unsupported.start;</label>
             <label is="text-link" id="unsupportedLink">&update.unsupported.linkText;</label>
             <label>&update.unsupported.end;</label>
           </hbox>
@@ -665,50 +841,96 @@
 
     <hbox id="networkAndDiskspaceCategory"
           class="subcategory"
           data-category="paneGeneral">
       <html:h1 data-l10n-id="general-network-and-diskspace-header"/>
     </hbox>
 
     <!-- Networking & Disk Space -->
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <html:legend data-l10n-id="networking-legend"></html:legend>
       <hbox align="center">
         <description control="catProxiesButton"
                      data-l10n-id="proxy-config-description"
                      flex="1"/>
-        <button id="catProxiesButton"
-                data-l10n-id="network-settings-button"
-                oncommand="gGeneralPane.showConnections();"/>
+        <hbox>
+          <button is="highlightable-button" id="catProxiesButton"
+                  data-l10n-id="network-settings-button"
+                  oncommand="gGeneralPane.showConnections();"
+                  search-l10n-ids="
+                    connection-dns-over-https-url-resolver,
+                    connection-dns-over-https-url-custom.label,
+                    connection-dns-over-https-custom-label,
+                    connection-proxy-legend,
+                    proxy-type-no.label,
+                    proxy-type-wpad.label,
+                    proxy-type-system.label,
+                    proxy-type-manual.label,
+                    proxy-http-label.value,
+                    http-port-label.value,
+                    proxy-http-sharing.label,
+                    proxy-https-label.value,
+                    ssl-port-label.value,
+                    proxy-socks-label.value,
+                    socks-port-label.value,
+                    proxy-socks4-label.label,
+                    proxy-socks5-label.label,
+                    proxy-type-auto.label,
+                    proxy-reload-label.label,
+                    no-proxy-label.value,
+                    no-proxy-example,
+                    no-proxy-localhost-label,
+                    proxy-password-prompt.label,
+                    proxy-remote-dns.label,
+                    proxy-enable-doh.label"/>
+        </hbox>
       </hbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <html:legend data-l10n-id="offline-legend"></html:legend>
       <hbox align="center">
         <description data-l10n-id="offline-settings"
                      control="offlineSettingsButton"
                      flex="1"/>
-        <button id="offlineSettingsButton"
-                data-l10n-id="offline-settings-button"
-                oncommand="gGeneralPane.showOffline();"/>
+        <hbox>
+          <button is="highlightable-button" id="offlineSettingsButton"
+                  data-l10n-id="offline-settings-button"
+                  oncommand="gGeneralPane.showOffline();"
+                  search-l10n-ids="
+                    offline-dialog-window.title,
+                    autodetect-online-label.label,
+                    startup-label,
+                    status-radio-remember.label,
+                    status-radio-ask.label,
+                    status-radio-always-online.label,
+                    status-radio-always-offline.label,
+                    going-online-label,
+                    going-online-auto.label,
+                    going-online-not.label,
+                    going-online-ask.label,
+                    going-offline-label,
+                    going-offline-auto.label,
+                    going-offline-not.label,
+                    going-offline-ask.label"/>
+        </hbox>
       </hbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <html:legend data-l10n-id="diskspace-legend"></html:legend>
       <hbox align="center">
         <label id="actualDiskCacheSize" flex="1"/>
-        <button id="clearCacheButton"
+        <button is="highlightable-button" id="clearCacheButton"
                 data-l10n-id="clear-cache-button"
                 oncommand="gGeneralPane.clearCache();"/>
       </hbox>
       <hbox>
         <checkbox preference="browser.cache.disk.smart_size.enabled"
                   id="allowSmartSize"
                   data-l10n-id="smart-cache-label"/>
       </hbox>
@@ -730,55 +952,79 @@
                       min="1" max="2048" value="200"
                       preference="mail.purge_threshhold_mb"
                       aria-labelledby="offlineCompactFolder offlineCompactFolderMin compactFolderMB"/>
           <label id="compactFolderMB" data-l10n-id="compact-folder-size" value=""/>
       </hbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <html:legend data-l10n-id="general-indexing-label"></html:legend>
       <vbox>
         <hbox>
           <checkbox id="enableGloda"
                     preference="mailnews.database.global.indexer.enabled"
                     data-l10n-id="enable-gloda-search-label"/>
         </hbox>
         <hbox align="center">
           <label control="storeTypeMenulist" data-l10n-id="store-type-label"/>
-          <menulist id="storeTypeMenulist"
-                    oncommand="gGeneralPane.updateDefaultStore(this.selectedItem.value)">
-            <menupopup id="storeTypeMenupopup">
-              <menuitem id="mboxStore"
-                        data-l10n-id="mbox-store-label"
-                        value="@mozilla.org/msgstore/berkeleystore;1"/>
-              <menuitem id="maildirStore"
-                        data-l10n-id="maildir-store-label"
-                        value="@mozilla.org/msgstore/maildirstore;1"/>
-            </menupopup>
-          </menulist>
+          <hbox>
+            <menulist id="storeTypeMenulist"
+                      oncommand="gGeneralPane.updateDefaultStore(this.selectedItem.value)">
+              <menupopup id="storeTypeMenupopup">
+                <menuitem id="mboxStore"
+                          data-l10n-id="mbox-store-label"
+                          value="@mozilla.org/msgstore/berkeleystore;1"/>
+                <menuitem id="maildirStore"
+                          data-l10n-id="maildir-store-label"
+                          value="@mozilla.org/msgstore/maildirstore;1"/>
+              </menupopup>
+            </menulist>
+          </hbox>
         </hbox>
         <hbox>
           <checkbox id="allowHWAccel"
                     preference="layers.acceleration.disabled"
                     data-l10n-id="allow-hw-accel"/>
         </hbox>
       </vbox>
       <vbox>
       </vbox>
     </html:fieldset>
     </html:div>
 
     <separator class="thin" data-category="paneGeneral"/>
 
-    <html:div>
+    <html:div data-category="paneGeneral">
     <html:fieldset data-category="paneGeneral">
       <hbox pack="end">
-        <button id="configEditor"
-                data-l10n-id="config-editor-button"
-                oncommand="gGeneralPane.showConfigEdit();"/>
+        <hbox>
+          <button is="highlightable-button" id="configEditor"
+                  data-l10n-id="config-editor-button"
+                  oncommand="gGeneralPane.showConfigEdit();"
+                  search-l10n-ids="
+                    config-window.title,
+                    config-about-warning-title.value,
+                    config-about-warning-text,
+                    config-about-warning-button.label,
+                    config-about-warning-checkbox.label,
+                    config-search-prefs.value,
+                    config-pref-column.label,
+                    config-lock-column.label,
+                    config-type-column.label,
+                    config-value-column.label,
+                    config-default,
+                    config-modified,
+                    config-locked,
+                    config-property-string,
+                    config-property-int,
+                    config-property-bool,
+                    config-new-prompt,
+                    config-nan-title,
+                    config-nan-text"/>
+        </hbox>
       </hbox>
     </html:fieldset>
     </html:div>
 
-  </prefpane>
+  </html:template>
--- a/mail/components/preferences/general.js
+++ b/mail/components/preferences/general.js
@@ -156,16 +156,21 @@ var gGeneralPane = {
 
   async init() {
     function setEventListener(aId, aEventType, aCallback) {
       document
         .getElementById(aId)
         .addEventListener(aEventType, aCallback.bind(gGeneralPane));
     }
 
+    Preferences.addSyncFromPrefListener(
+      document.getElementById("saveWhere"),
+      () => gDownloadDirSection.onReadUseDownloadDir()
+    );
+
     this.mPane = document.getElementById("paneGeneral");
     this._prefsBundle = document.getElementById("bundlePreferences");
     this._brandShortName = document
       .getElementById("bundleBrand")
       .getString("brandShortName");
     this._list = document.getElementById("handlersView");
     this._filter = document.getElementById("filter");
 
--- a/mail/components/preferences/jar.mn
+++ b/mail/components/preferences/jar.mn
@@ -27,16 +27,17 @@ messenger.jar:
     content/messenger/preferences/connection.xhtml
     content/messenger/preferences/downloads.js
     content/messenger/preferences/attachmentReminder.js
     content/messenger/preferences/attachmentReminder.xhtml
     content/messenger/preferences/applicationManager.xhtml
     content/messenger/preferences/applicationManager.js
     content/messenger/preferences/handlers.css
     content/messenger/preferences/actionsshared.js
+    content/messenger/preferences/findInPage.js
     content/messenger/preferences/fonts.js
     content/messenger/preferences/fonts.xhtml
 #ifndef XP_MACOSX
     content/messenger/preferences/notifications.js
     content/messenger/preferences/notifications.xhtml
 #endif
     content/messenger/preferences/offline.js
     content/messenger/preferences/offline.xhtml
--- a/mail/components/preferences/notifications.xhtml
+++ b/mail/components/preferences/notifications.xhtml
@@ -8,24 +8,22 @@
 <?xml-stylesheet href="chrome://global/skin/global.css"?>
 
 <!DOCTYPE window>
 
 <window type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         data-l10n-id="notifications-dialog-window">
-<dialog id="NotificationsDialog"
-        dlgbuttons="accept,cancel">
+  <dialog id="NotificationsDialog"
+          dlgbuttons="accept,cancel">
 
-  <linkset>
-    <html:link rel="localization" href="messenger/preferences/notifications.ftl"/>
-  </linkset>
-
-  <prefpane id="NotificationsDialogPane">
+    <linkset>
+      <html:link rel="localization" href="messenger/preferences/notifications.ftl"/>
+    </linkset>
     <description data-l10n-id="customize-alert-description"/>
 
     <checkbox id="previewText"
               class="indent"
               data-l10n-id="preview-text-checkbox"
               preference="mail.biff.alert.show_preview"/>
     <checkbox id="subject"
               class="indent"
@@ -43,14 +41,13 @@
              control="totalOpenTime"
              data-l10n-id="open-time-label-before"/>
       <html:input id="totalOpenTime" type="number"
                   class="size3" min="1" max="3600"
                   preference="alerts.totalOpenTime"/>
       <label id="totalOpenTimeEnd" data-l10n-id="open-time-label-after"/>
     </hbox>
     <separator/>
-  </prefpane>
 
-  <script src="chrome://global/content/preferencesBindings.js"/>
-  <script src="chrome://messenger/content/preferences/notifications.js"/>
-</dialog>
+    <script src="chrome://global/content/preferencesBindings.js"/>
+    <script src="chrome://messenger/content/preferences/notifications.js"/>
+  </dialog>
 </window>
--- a/mail/components/preferences/offline.xhtml
+++ b/mail/components/preferences/offline.xhtml
@@ -8,20 +8,18 @@
 
 <!DOCTYPE window>
 
 <window type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         onload="gOfflineDialog.dialogSetup();"
         data-l10n-id="offline-dialog-window">
-<dialog id="OfflineSettingsDialog"
-        dlgbuttons="accept,cancel">
-
-  <prefpane id="OfflineSettingsDialogPane">
+  <dialog id="OfflineSettingsDialog"
+          dlgbuttons="accept,cancel">
     <script src="chrome://global/content/preferencesBindings.js"/>
     <script src="chrome://messenger/content/preferences/offline.js"/>
 
     <linkset>
       <html:link rel="localization" href="messenger/preferences/offline.ftl"/>
     </linkset>
 
     <checkbox data-l10n-id="autodetect-online-label"
@@ -53,11 +51,10 @@
     <label data-l10n-id="going-offline-label" control="whengoingOfflinestate"/>
     <radiogroup id="whengoingOfflinestate" orient="horizontal" class="indent"
                 preference="offline.download.download_messages">
       <radio value="1" data-l10n-id="going-offline-auto"/>
       <radio value="2" data-l10n-id="going-offline-not"/>
       <radio value="0" data-l10n-id="going-offline-ask"/>
     </radiogroup>
     <separator/>
-  </prefpane>
-</dialog>
+  </dialog>
 </window>
--- a/mail/components/preferences/preferences.js
+++ b/mail/components/preferences/preferences.js
@@ -4,16 +4,18 @@
 
 /* import-globals-from ../../../../toolkit/content/preferencesBindings.js */
 /* import-globals-from general.js */
 /* import-globals-from compose.js */
 /* import-globals-from downloads.js */
 /* import-globals-from privacy.js */
 /* import-globals-from chat.js */
 /* import-globals-from subdialogs.js */
+/* import-globals-from findInPage.js */
+/* import-globals-from ../../../calendar/lightning/content/messenger-overlay-preferences.js */
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { AppConstants } = ChromeUtils.import(
   "resource://gre/modules/AppConstants.jsm"
 );
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
@@ -30,132 +32,342 @@ var defaultPane = "paneGeneral";
 ChromeUtils.defineModuleGetter(
   this,
   "AddonManager",
   "resource://gre/modules/AddonManager.jsm"
 );
 
 document.addEventListener("DOMContentLoaded", init, { once: true });
 
+var gCategoryInits = new Map();
+var gLastCategory = { category: undefined, subcategory: undefined };
+
+function init_category_if_required(category) {
+  let categoryInfo = gCategoryInits.get(category);
+  if (!categoryInfo) {
+    throw new Error(
+      "Unknown in-content prefs category! Can't init " + category
+    );
+  }
+  if (categoryInfo.inited) {
+    return null;
+  }
+  return categoryInfo.init();
+}
+
+function register_module(categoryName, categoryObject) {
+  gCategoryInits.set(categoryName, {
+    inited: false,
+    async init() {
+      let template = document.getElementById(categoryName);
+      if (template) {
+        // Replace the template element with the nodes inside of it.
+        let frag = template.content;
+        await document.l10n.translateFragment(frag);
+
+        // Actually insert them into the DOM.
+        document.l10n.pauseObserving();
+        template.replaceWith(frag);
+        document.l10n.resumeObserving();
+
+        // Asks Preferences to update the attribute value of the entire
+        // document again (this can be simplified if we could seperate the
+        // preferences of each pane.)
+        Preferences.updateAllElements();
+      }
+      categoryObject.init();
+      this.inited = true;
+    },
+  });
+}
+
 function init() {
   Preferences.forceEnableInstantApply();
 
   gSubDialog.init();
-  gGeneralPane.init();
-  gComposePane.init();
-  gPrivacyPane.init();
+  register_module("paneGeneral", gGeneralPane);
+  register_module("paneCompose", gComposePane);
+  register_module("panePrivacy", gPrivacyPane);
+  register_module("paneCalendar", gLightningPane);
+  register_module("paneSearchResults", gSearchResultsPane);
   if (Services.prefs.getBoolPref("mail.chat.enabled")) {
-    gChatPane.init();
+    register_module("paneChat", gChatPane);
   } else {
     // Remove the pane from the DOM so it doesn't get incorrectly included in
     // the search results.
     document.getElementById("paneChat").remove();
   }
 
   // If no calendar is currently enabled remove it from the DOM so it doesn't
   // get incorrectly included in the search results.
   if (!calendarDeactivator.isCalendarActivated) {
-    document.getElementById("paneLightning").remove();
+    document.getElementById("paneCalendar").remove();
     document.getElementById("category-calendar").remove();
   }
-
-  Preferences.addSyncFromPrefListener(
-    document.getElementById("saveWhere"),
-    () => gDownloadDirSection.onReadUseDownloadDir()
-  );
+  gSearchResultsPane.init();
 
   let categories = document.getElementById("categories");
-  categories.addEventListener("select", event => {
-    showPane(event.target.value);
-  });
+  categories.addEventListener("select", event => gotoPref(event.target.value));
 
   document.documentElement.addEventListener("keydown", event => {
     if (event.keyCode == KeyEvent.DOM_VK_TAB) {
       categories.setAttribute("keyboard-navigation", "true");
     }
   });
   categories.addEventListener("mousedown", function() {
     this.removeAttribute("keyboard-navigation");
   });
 
-  let lastSelected = document.documentElement.getAttribute("lastSelected");
+  window.addEventListener("hashchange", onHashChange);
+  let lastSelected = Services.xulStore.getValue(
+    "about:preferences",
+    "MailPreferences",
+    "lastSelected"
+  );
+  gotoPref(lastSelected);
+}
+
+function onHashChange() {
+  gotoPref();
+}
+
+async function gotoPref(aCategory) {
+  let categories = document.getElementById("categories");
+  const kDefaultCategoryInternalName = "paneGeneral";
+  const kDefaultCategory = "general";
+  let hash = document.location.hash;
+
+  let category = aCategory || hash.substr(1) || kDefaultCategoryInternalName;
+  let breakIndex = category.indexOf("-");
+  // Subcategories allow for selecting smaller sections of the preferences
+  // until proper search support is enabled (bug 1353954).
+  let subcategory = breakIndex != -1 && category.substring(breakIndex + 1);
+  if (subcategory) {
+    category = category.substring(0, breakIndex);
+  }
+  category = friendlyPrefCategoryNameToInternalName(category);
+  if (category != "paneSearchResults") {
+    gSearchResultsPane.query = null;
+    gSearchResultsPane.searchInput.value = "";
+    gSearchResultsPane.getFindSelection(window).removeAllRanges();
+    gSearchResultsPane.removeAllSearchTooltips();
+    gSearchResultsPane.removeAllSearchMenuitemIndicators();
+  } else if (!gSearchResultsPane.searchInput.value) {
+    // Something tried to send us to the search results pane without
+    // a query string. Default to the General pane instead.
+    category = kDefaultCategoryInternalName;
+    document.location.hash = kDefaultCategory;
+    gSearchResultsPane.query = null;
+  }
+
+  // Updating the hash (below) or changing the selected category
+  // will re-enter gotoPref.
+  if (gLastCategory.category == category && !subcategory) {
+    return;
+  }
+
+  let item;
+  if (category != "paneSearchResults") {
+    // Hide second level headers in normal view
+    for (let element of document.querySelectorAll(".search-header")) {
+      element.hidden = true;
+    }
+
+    item = categories.querySelector(".category[value=" + category + "]");
+    if (!item) {
+      category = kDefaultCategoryInternalName;
+      item = categories.querySelector(".category[value=" + category + "]");
+    }
+  }
+
   if (
-    lastSelected &&
-    lastSelected != defaultPane &&
-    document.getElementById(lastSelected)
+    gLastCategory.category ||
+    category != kDefaultCategoryInternalName ||
+    subcategory
   ) {
-    categories.selectedItem = categories.querySelector(
-      ".category[value=" + lastSelected + "]"
+    let friendlyName = internalPrefCategoryNameToFriendlyName(category);
+    document.location.hash = friendlyName;
+  }
+  // Need to set the gLastCategory before setting categories.selectedItem since
+  // the categories 'select' event will re-enter the gotoPref codepath.
+  gLastCategory.category = category;
+  gLastCategory.subcategory = subcategory;
+  if (item) {
+    categories.selectedItem = item;
+  } else {
+    categories.clearSelection();
+  }
+  window.history.replaceState(category, document.title);
+
+  try {
+    await init_category_if_required(category);
+  } catch (ex) {
+    Cu.reportError(
+      new Error(
+        "Error initializing preference category " + category + ": " + ex
+      )
     );
-  } else {
-    showPane(defaultPane);
+    throw ex;
+  }
+
+  // Bail out of this goToPref if the category
+  // or subcategory changed during async operation.
+  if (
+    gLastCategory.category !== category ||
+    gLastCategory.subcategory !== subcategory
+  ) {
+    return;
+  }
+
+  search(category, "data-category");
+
+  let mainContent = document.querySelector(".main-content");
+  mainContent.scrollTop = 0;
+
+  spotlight(subcategory, category);
+
+  document.dispatchEvent(new CustomEvent("paneSelected", { bubbles: true }));
+  document.getElementById("preferencesContainer").scrollTo(0, 0);
+  document.documentElement.setAttribute("lastSelected", category);
+  Services.xulStore.setValue(
+    "about:preferences",
+    "MailPreferences",
+    "lastSelected",
+    category
+  );
+}
+
+function friendlyPrefCategoryNameToInternalName(aName) {
+  if (aName.startsWith("pane")) {
+    return aName;
   }
+  return "pane" + aName.substring(0, 1).toUpperCase() + aName.substr(1);
+}
+
+// This function is duplicated inside of utilityOverlay.js's openPreferences.
+function internalPrefCategoryNameToFriendlyName(aName) {
+  return (aName || "").replace(/^pane./, function(toReplace) {
+    return toReplace[4].toLowerCase();
+  });
+}
+
+function search(aQuery, aAttribute) {
+  let paneDeck = document.getElementById("paneDeck");
+  let elements = paneDeck.children;
+  for (let element of elements) {
+    // If the "data-hidden-from-search" is "true", the
+    // element will not get considered during search.
+    if (
+      element.getAttribute("data-hidden-from-search") != "true" ||
+      element.getAttribute("data-subpanel") == "true"
+    ) {
+      let attributeValue = element.getAttribute(aAttribute);
+      if (attributeValue == aQuery) {
+        element.hidden = false;
+      } else {
+        element.hidden = true;
+      }
+    } else if (
+      element.getAttribute("data-hidden-from-search") == "true" &&
+      !element.hidden
+    ) {
+      element.hidden = true;
+    }
+    element.classList.remove("visually-hidden");
+  }
+
+  let keysets = paneDeck.getElementsByTagName("keyset");
+  for (let element of keysets) {
+    let attributeValue = element.getAttribute(aAttribute);
+    if (attributeValue == aQuery) {
+      element.removeAttribute("disabled");
+    } else {
+      element.setAttribute("disabled", true);
+    }
+  }
+}
+
+async function spotlight(subcategory, category) {
+  let highlightedElements = document.querySelectorAll(".spotlight");
+  if (highlightedElements.length) {
+    for (let element of highlightedElements) {
+      element.classList.remove("spotlight");
+    }
+  }
+  if (subcategory) {
+    scrollAndHighlight(subcategory, category);
+  }
+}
+
+async function scrollAndHighlight(subcategory, category) {
+  let element = document.querySelector(`[data-subcategory="${subcategory}"]`);
+  if (!element) {
+    return;
+  }
+  let header = getClosestDisplayedHeader(element);
+
+  scrollContentTo(header);
+  element.classList.add("spotlight");
 }
 
 /**
- * Actually switches to the specified pane, fires events, and remembers the pane.
+ * If there is no visible second level header it will return first level header,
+ * otherwise return second level header.
  *
- * @param paneID ID of the prefpane to select
+ * @returns {Element}  The closest displayed header.
  */
-function showPane(paneID) {
-  let pane = document.getElementById(paneID);
-  if (!pane) {
-    return;
+function getClosestDisplayedHeader(element) {
+  let header = element.closest("groupbox");
+  let searchHeader = header.querySelector(".search-header");
+  if (
+    searchHeader &&
+    searchHeader.hidden &&
+    header.previousElementSibling.classList.contains("subcategory")
+  ) {
+    header = header.previousElementSibling;
   }
-
-  let currentlySelected = paneDeck.querySelector(
-    "#paneDeck > prefpane[selected]"
-  );
+  return header;
+}
 
-  if (currentlySelected) {
-    if (currentlySelected == pane) {
-      return;
-    }
-    currentlySelected.removeAttribute("selected");
-  }
-
-  pane.setAttribute("selected", "true");
-  pane.dispatchEvent(new CustomEvent("paneSelected", { bubbles: true }));
-  document.getElementById("preferencesContainer").scrollTo(0, 0);
-
-  document.documentElement.setAttribute("lastSelected", paneID);
-  Services.xulStore.persist(document.documentElement, "lastSelected");
+function scrollContentTo(element) {
+  const STICKY_CONTAINER_HEIGHT = document.querySelector(".sticky-container")
+    .clientHeight;
+  let mainContent = document.querySelector(".main-content");
+  let top = element.getBoundingClientRect().top - STICKY_CONTAINER_HEIGHT;
+  mainContent.scroll({
+    top,
+    behavior: "smooth",
+  });
 }
 
 /**
  * Selects the specified preferences pane
  *
  * @param paneID              ID of prefpane to select
  * @param scrollPaneTo        ID of the element to scroll into view
  * @param otherArgs.subdialog ID of button to activate, opening a subdialog
  */
 function selectPrefPane(paneID, scrollPaneTo, otherArgs) {
   if (paneID) {
-    let prefPane = document.getElementById(paneID);
     if (getCurrentPaneID() != paneID) {
-      showPane(paneID);
+      gotoPref(paneID);
     }
     if (scrollPaneTo) {
-      showTab(
-        prefPane,
-        scrollPaneTo,
-        otherArgs ? otherArgs.subdialog : undefined
-      );
+      showTab(scrollPaneTo, otherArgs ? otherArgs.subdialog : undefined);
     }
   }
 }
 
 /**
  * Select the specified tab
  *
- * @param pane         prefpane to operate on
  * @param scrollPaneTo ID of the element to scroll into view
  * @param subdialogID  ID of button to activate, opening a subdialog
  */
-function showTab(pane, scrollPaneTo, subdialogID) {
+function showTab(scrollPaneTo, subdialogID) {
   setTimeout(function() {
     let scrollTarget = document.getElementById(scrollPaneTo);
     if (scrollTarget.closest("groupbox")) {
       scrollTarget = scrollTarget.closest("groupbox");
     }
     scrollTarget.scrollIntoView();
     if (subdialogID) {
       document.getElementById(subdialogID).click();
@@ -163,20 +375,20 @@ function showTab(pane, scrollPaneTo, sub
   });
 }
 
 /**
  * Get the ID of the current pane.
  */
 function getCurrentPaneID() {
   let currentlySelected = paneDeck.querySelector(
-    "#paneDeck > prefpane[selected]"
+    "#paneDeck > div:not([hidden])"
   );
   if (currentlySelected) {
-    return currentlySelected.id;
+    return currentlySelected.getAttribute("data-category");
   }
   return null;
 }
 
 /**
  * Filter the lastFallbackLocale from availableLocales if it doesn't have all
  * of the needed strings.
  *
--- a/mail/components/preferences/preferences.xhtml
+++ b/mail/components/preferences/preferences.xhtml
@@ -46,16 +46,35 @@
   <script src="chrome://global/content/globalOverlay.js"/>
   <script src="chrome://global/content/editMenuOverlay.js"/>
 
   <linkset>
     <html:link rel="localization" href="branding/brand.ftl"/>
     <html:link rel="localization" href="messenger/preferences/preferences.ftl"/>
     <html:link rel="localization" href="messenger/preferences/fonts.ftl"/>
     <html:link rel="localization" href="messenger/preferences/languages.ftl"/>
+
+    <!-- Links below are only used for search-l10n-ids into subdialogs -->
+    <html:link rel="localization" href="messenger/preferences/sendoptions.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/receipts.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/permissions.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/cookies.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/system-integration.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/colors.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/dock-options.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/notifications.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/new-tag.ftl"/>
+    <html:link rel="localization" href="toolkit/updates/history.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/connection.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/offline.ftl"/>
+    <html:link rel="localization" href="toolkit/about/aboutConfig.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/attachment-reminder.ftl"/>
+    <html:link rel="localization" href="messenger/preferences/passwordManager.ftl"/>
+    <html:link rel="localization" href="security/certificates/certManager.ftl"/>
+    <html:link rel="localization" href="security/certificates/deviceManager.ftl"/>
   </linkset>
 
   <stack id="preferences-stack" flex="1">
     <hbox id="prefBox" class="main-content" flex="1">
 
       <vbox id="pref-category-box">
 
         <!-- category list -->
@@ -93,17 +112,17 @@
                         data-l10n-id="category-chat"
                         align="center">
             <image class="category-icon"/>
             <label class="category-name" flex="1" data-l10n-id="pane-chat-title"/>
           </richlistitem>
 
           <richlistitem id="category-calendar"
                         class="category"
-                        value="paneLightning"
+                        value="paneCalendar"
                         data-l10n-id="category-calendar"
                         align="center">
             <image class="category-icon"/>
             <label class="category-name" flex="1" data-l10n-id="pane-calendar-title"/>
           </richlistitem>
         </richlistbox>
 
         <spacer flex="1"/>
@@ -116,27 +135,34 @@
               <image class="sidebar-footer-icon addons-icon"/>
               <label data-l10n-id="addons-button" class="sidebar-footer-label" flex="1"/>
             </hbox>
           </label>
         </hbox>
 
       </vbox>
 
-      <hbox id="preferencesContainer" flex="1">
-        <hbox class="paneDeckContainer" flex="1">
-          <hbox id="paneDeck" flex="1">
+      <vbox id="preferencesContainer" flex="1" align="start">
+        <vbox class="paneDeckContainer">
+          <hbox class="sticky-container" pack="end" align="top" flex="1">
+            <search-textbox id="searchInput"
+                            data-l10n-id="search-input-box"
+                            data-l10n-attrs="placeholder, style"
+                            hidden="true"/>
+          </hbox>
+          <vbox id="paneDeck">
+#include searchResults.inc.xhtml
 #include general.inc.xhtml
 #include compose.inc.xhtml
 #include privacy.inc.xhtml
 #include chat.inc.xhtml
 #include ../../../calendar/lightning/content/messenger-overlay-preferences.inc.xhtml
-          </hbox>
-        </hbox>
-      </hbox>
+          </vbox>
+        </vbox>
+      </vbox>
     </hbox>
     <stack id="dialogStack" hidden="true"/>
     <vbox id="dialogTemplate"
           class="dialogOverlay"
           align="center"
           pack="center"
           topmost="true"
           hidden="true">
@@ -153,16 +179,17 @@
                  disablehistory="true"/>
       </vbox>
     </vbox>
   </stack>
 
   <script src="chrome://global/content/globalOverlay.js"/>
   <script src="chrome://communicator/content/contentAreaClick.js"/>
   <script src="chrome://messenger/content/preferences/preferences.js"/>
+  <script src="chrome://messenger/content/preferences/findInPage.js"/>
   <script src="chrome://messenger/content/preferences/subdialogs.js"/>
 
   <script src="chrome://calendar/content/calendar-ui-utils.js"/>
   <script src="chrome://calendar/content/calendar-dialog-utils.js"/>
   <script src="chrome://calendar/content/preferences/general.js"/>
   <script src="chrome://calendar/content/preferences/alarms.js"/>
   <script src="chrome://calendar/content/preferences/categories.js"/>
   <script src="chrome://calendar/content/preferences/views.js"/>
--- a/mail/components/preferences/privacy.inc.xhtml
+++ b/mail/components/preferences/privacy.inc.xhtml
@@ -1,91 +1,153 @@
 # 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/.
-  <prefpane id="panePrivacy">
-    <script src="chrome://messenger/content/preferences/privacy.js"/>
+  <script src="chrome://messenger/content/preferences/privacy.js"/>
 
-    <stringbundle id="bundlePreferences" src="chrome://messenger/locale/preferences/preferences.properties"/>
-
+  <stringbundle id="bundlePreferences" src="chrome://messenger/locale/preferences/preferences.properties"/>
+  <html:template id="panePrivacy">
     <hbox id="privacyCategory"
           class="subcategory"
           data-category="panePrivacy">
       <html:h1 data-l10n-id="privacy-main-header"/>
     </hbox>
 
     <!-- Mail Content -->
-    <html:div>
+    <html:div data-category="panePrivacy">
     <html:fieldset id="mailContentGroup" data-category="panePrivacy">
       <html:legend data-l10n-id="mail-content"></html:legend>
       <hbox id="remoteContentBox">
         <checkbox id="acceptRemoteContent"
                   preference="mailnews.message_display.disable_remote_image"
                   data-l10n-id="remote-content-label"/>
         <spacer flex="1"/>
-        <button id="remoteContentExceptions"
-                oncommand="gPrivacyPane.showRemoteContentExceptions();"
-                data-l10n-id="exceptions-button"/>
+        <hbox>
+          <button is="highlightable-button" id="remoteContentExceptions"
+                  oncommand="gPrivacyPane.showRemoteContentExceptions();"
+                  data-l10n-id="exceptions-button"
+                  search-l10n-ids="
+                    permissions-reminder-window.title,
+                    website-address-label.value,
+                    block-button.label,
+                    allow-session-button.label,
+                    allow-button.label,
+                    treehead-sitename-label.label,
+                    treehead-status-label.label,
+                    remove-site-button.label,
+                    remove-all-site-button.label,
+                    cancel-button.label,
+                    save-button.label,
+                    permission-can-label,
+                    permission-can-access-first-party-label,
+                    permission-can-session-label,
+                    permission-cannot-label,
+                    invalid-uri-message,
+                    invalid-uri-title"/>
+        </hbox>
       </hbox>
       <hbox>
         <label is="text-link" id="acceptRemoteContentInfo"
                href="https://support.mozilla.org/kb/remote-content-in-messages"
                data-l10n-id="remote-content-info"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
     <!-- Web Content -->
-    <html:div>
+    <html:div data-category="panePrivacy">
     <html:fieldset id="webContentGroup" data-category="panePrivacy">
       <html:legend data-l10n-id="web-content"></html:legend>
       <checkbox id="keepHistory"
                 preference="places.history.enabled"
                 data-l10n-id="history-label"/>
       <hbox id="cookiesBox">
         <checkbox id="acceptCookies"
                   preference="network.cookie.cookieBehavior"
                   data-l10n-id="cookies-label"/>
         <spacer flex="1"/>
-        <button id="cookieExceptions"
-                oncommand="gPrivacyPane.showCookieExceptions();"
-                data-l10n-id="exceptions-button"
-                preference="pref.privacy.disable_button.cookie_exceptions"/>
+        <hbox>
+          <button is="highlightable-button" id="cookieExceptions"
+                  oncommand="gPrivacyPane.showCookieExceptions();"
+                  data-l10n-id="exceptions-button"
+                  preference="pref.privacy.disable_button.cookie_exceptions"
+                  search-l10n-ids="
+                    permissions-reminder-window.title,
+                    website-address-label.value,
+                    block-button.label,
+                    allow-session-button.label,
+                    allow-button.label,
+                    treehead-sitename-label.label,
+                    treehead-status-label.label,
+                    remove-site-button.label,
+                    remove-all-site-button.label,
+                    cancel-button.label,
+                    save-button.label,
+                    permission-can-label,
+                    permission-can-access-first-party-label,
+                    permission-can-session-label,
+                    permission-cannot-label,
+                    invalid-uri-message,
+                    invalid-uri-title"/>
+        </hbox>
       </hbox>
       <hbox id="acceptThirdPartyRow" class="indent">
         <hbox id="acceptThirdPartyBox" align="center">
           <label id="acceptThirdPartyLabel" control="acceptThirdPartyMenu"
                  data-l10n-id="third-party-label"/>
-          <menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior">
-            <menupopup>
-              <menuitem data-l10n-id="third-party-always" value="always"/>
-              <menuitem data-l10n-id="third-party-visited" value="visited"/>
-              <menuitem data-l10n-id="third-party-never" value="never"/>
-            </menupopup>
-          </menulist>
+          <hbox>
+            <menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior">
+              <menupopup>
+                <menuitem data-l10n-id="third-party-always" value="always"/>
+                <menuitem data-l10n-id="third-party-visited" value="visited"/>
+                <menuitem data-l10n-id="third-party-never" value="never"/>
+              </menupopup>
+            </menulist>
+          </hbox>
         </hbox>
       </hbox>
       <hbox id="keepRow" class="indent">
         <hbox id="keepBox" align="center">
           <label id="keepUntil"
                  control="keepCookiesUntil"
                  data-l10n-id="keep-label"/>
-          <menulist id="keepCookiesUntil"
-                    preference="network.cookie.lifetimePolicy">
-            <menupopup>
-              <menuitem data-l10n-id="keep-expire" value="0"/>
-              <menuitem data-l10n-id="keep-close" value="2"/>
-              <menuitem data-l10n-id="keep-ask" value="1"/>
-            </menupopup>
-          </menulist>
+          <hbox>
+            <menulist id="keepCookiesUntil"
+                      preference="network.cookie.lifetimePolicy">
+              <menupopup>
+                <menuitem data-l10n-id="keep-expire" value="0"/>
+                <menuitem data-l10n-id="keep-close" value="2"/>
+                <menuitem data-l10n-id="keep-ask" value="1"/>
+              </menupopup>
+            </menulist>
+          </hbox>
         </hbox>
         <hbox flex="1"/>
-        <button id="showCookiesButton" data-l10n-id="cookies-button"
-                oncommand="gPrivacyPane.showCookies();"
-                preference="pref.privacy.disable_button.view_cookies"/>
+        <hbox>
+          <button is="highlightable-button" id="showCookiesButton"
+                  data-l10n-id="cookies-button"
+                  oncommand="gPrivacyPane.showCookies();"
+                  preference="pref.privacy.disable_button.view_cookies"
+                  search-l10n-ids="
+                    cookies-window-dialog.title,
+                    filter-search-label.value,
+                    cookies-on-system-label,
+                    treecol-site-header.label,
+                    treecol-name-header.label,
+                    props-name-label.value,
+                    props-value-label.value,
+                    props-domain-label.value,
+                    props-path-label.value,
+                    props-secure-label.value,
+                    props-expires-label.value,
+                    props-container-label.value,
+                    remove-cookie-button.label,
+                    remove-all-cookies-button.label,
+                    cookie-close-button.label"/>
+        </hbox>
       </hbox>
 
       <separator class="thin"/>
 
       <hbox align="center">
         <checkbox id="privacyDoNotTrackCheckbox"
                   class="tail-with-learn-more"
                   data-l10n-id="do-not-track-label"
@@ -100,52 +162,83 @@
     <hbox id="privacyPasswordsCategory"
           class="subcategory"
           data-category="panePrivacy">
       <html:h1 data-l10n-id="privacy-passwords-header"/>
     </hbox>
 
     <separator data-category="panePrivacy"/>
 
-    <html:div>
+    <html:div data-category="panePrivacy">
     <html:fieldset data-category="panePrivacy">
       <hbox align="center">
         <description data-l10n-id="passwords-description"/>
         <spacer flex="1"/>
-        <button id="showPasswords"
-                data-l10n-id="passwords-button"
-                oncommand="gPrivacyPane.showPasswords();"
-                preference="pref.privacy.disable_button.view_passwords"/>
+        <hbox>
+          <button is="highlightable-button" id="showPasswords"
+                  data-l10n-id="passwords-button"
+                  oncommand="gPrivacyPane.showPasswords();"
+                  preference="pref.privacy.disable_button.view_passwords"
+                  search-l10n-ids="
+                    saved-logins.title,
+                    copy-provider-url-cmd.label,
+                    copy-username-cmd.label,
+                    edit-username-cmd.label,
+                    copy-password-cmd.label,
+                    edit-password-cmd.label,
+                    search-filter.placeholder,
+                    column-heading-provider.label,
+                    column-heading-username.label,
+                    column-heading-password.label,
+                    column-heading-time-created.label,
+                    column-heading-time-last-used.label,
+                    column-heading-time-password-changed.label,
+                    column-heading-times-used.label,
+                    remove.label,
+                    import.label,
+                    show-passwords.label,
+                    hide-passwords.label,
+                    logins-description-all,
+                    logins-description-filtered,
+                    remove-all.label,
+                    remove-all-shown.label,
+                    remove-all-passwords-prompt,
+                    remove-all-passwords-title,
+                    no-master-password-prompt,
+                    password-os-auth-dialog-message,
+                    password-os-auth-dialog-message-macosx,
+                    password-os-auth-dialog-caption"/>
+        </hbox>
       </hbox>
       <!-- XXX button to do a showExceptions()? -->
 
       <separator class="thin"/>
 
       <description data-l10n-id="master-password-description"/>
       <hbox>
         <checkbox id="useMasterPassword"
                   data-l10n-id="master-password-label"
                   oncommand="gPrivacyPane.updateMasterPasswordButton();"/>
         <spacer flex="1"/>
-        <button id="changeMasterPassword"
+        <button is="highlightable-button" id="changeMasterPassword"
                 data-l10n-id="master-password-button"
                 oncommand="gPrivacyPane.changeMasterPassword();"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
     <hbox id="privacyJunkCategory"
           class="subcategory"
           data-category="panePrivacy">
       <html:h1 data-l10n-id="privacy-junk-header"/>
     </hbox>
 
     <separator data-category="panePrivacy"/>
 
-    <html:div>
+    <html:div data-category="panePrivacy">
     <html:fieldset data-category="panePrivacy">
       <description data-l10n-id="junk-description"/>
       <separator class="thin"/>
       <hbox>
         <checkbox id="manualMark"
                   data-l10n-id="junk-label"
                   preference="mail.spam.manualMark"
                   oncommand="gPrivacyPane.updateManualMarkMode(this.checked);"/>
@@ -174,35 +267,37 @@
                   preference="mail.spam.markAsReadOnSpam"/>
         <spacer flex="1"/>
       </hbox>
       <hbox align="start">
         <checkbox id="enableJunkLogging" data-l10n-id="junk-log-label"
                   oncommand="gPrivacyPane.updateJunkLogButton(this.checked);"
                   preference="mail.spam.logging.enabled"/>
         <spacer flex="1"/>
-        <button id="openJunkLogButton" data-l10n-id="junk-log-button"
+        <button is="highlightable-button" id="openJunkLogButton"
+                data-l10n-id="junk-log-button"
                 oncommand="gPrivacyPane.openJunkLog();"/>
       </hbox>
       <hbox align="start">
         <spacer flex="1"/>
-        <button data-l10n-id="reset-junk-button"
+        <button is="highlightable-button"
+                data-l10n-id="reset-junk-button"
                 oncommand="gPrivacyPane.resetTrainingData()"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
 #ifdef MOZ_DATA_REPORTING
     <hbox id="privacyDataCollectionCategory"
           class="subcategory"
           data-category="panePrivacy">
       <html:h1 data-l10n-id="collection-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="panePrivacy">
     <html:fieldset data-category="panePrivacy">
       <description>
         <label class="tail-with-learn-more" data-l10n-id="collection-description"/>
         <label id="dataCollectionPrivacyNotice"
                class="learnMore" is="text-link"
                data-l10n-id="collection-privacy-notice"/>
       </description>
       <description>
@@ -210,18 +305,18 @@
           <hbox align="top">
             <image class="info-icon-telemetry" flex="1"></image>
           </hbox>
           <hbox align="center" id="dataDescriptionBox" flex="1">
             <html:span id="telemetryDisabledDescription" class="tail-with-learn-more" data-l10n-id="collection-health-report-telemetry-disabled"/>
           </hbox>
           <hbox>
               <button id="telemetryDataDeletionLearnMore"
-                     class="learnMore" is="text-link"
-                     data-l10n-id="collection-health-report-telemetry-disabled-link"/>
+                      class="learnMore" is="text-link"
+                      data-l10n-id="collection-health-report-telemetry-disabled-link"/>
           </hbox>
         </hbox>
       </description>
       <vbox data-subcategory="reports">
         <hbox align="center">
           <checkbox id="submitHealthReportBox"
                     data-l10n-id="collection-health-report"
                     class="tail-with-learn-more"/>
@@ -251,46 +346,46 @@
 #endif
 
     <hbox id="privacySecurityCategory"
           class="subcategory"
           data-category="panePrivacy">
       <html:h1 data-l10n-id="privacy-security-header"/>
     </hbox>
 
-    <html:div>
+    <html:div data-category="panePrivacy">
     <html:fieldset data-category="panePrivacy">
       <html:legend data-l10n-id="privacy-scam-detection-title"></html:legend>
       <description data-l10n-id="phishing-description"/>
       <separator class="thin"/>
       <hbox>
         <checkbox id="enablePhishingDetector"
                   data-l10n-id="phishing-label"
                   preference="mail.phishing.detection.enabled"/>
         <spacer flex="1"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
     <!-- Anti Virus -->
-    <html:div>
+    <html:div data-category="panePrivacy">
     <html:fieldset data-category="panePrivacy">
       <html:legend data-l10n-id="privacy-anti-virus-title"></html:legend>
       <description data-l10n-id="antivirus-description"/>
       <separator class="thin"/>
       <hbox>
         <checkbox id="enableAntiVirusQuarantine"
                   data-l10n-id="antivirus-label"
                   preference="mailnews.downloadToTempFile"/>
         <spacer flex="1"/>
       </hbox>
     </html:fieldset>
     </html:div>
 
-    <html:div>
+    <html:div data-category="panePrivacy">
     <html:fieldset data-category="panePrivacy">
       <html:legend data-l10n-id="privacy-certificates-title"></html:legend>
       <description id="CertSelectionDesc" control="certSelection"
                    data-l10n-id="certificate-description"/>
 
       <!--
         The values on these radio buttons may look like l12y issues, but
         they're not - this preference uses *those strings* as its values.
@@ -312,22 +407,158 @@
 
       <hbox align="start">
         <checkbox id="enableOCSP"
                   data-l10n-id="ocsp-label"
                   preference="security.OCSP.enabled"
                   flex="1"/>
         <spacer flex="1"/>
         <vbox>
-          <button id="manageCertificatesButton"
-                  data-l10n-id="certificate-button"
-                  oncommand="gPrivacyPane.showCertificates();"
-                  preference="security.disable_button.openCertManager"/>
-          <button id="viewSecurityDevicesButton"
-                  data-l10n-id="security-devices-button"
-                  oncommand="gPrivacyPane.showSecurityDevices();"
-                  preference="security.disable_button.openDeviceManager"/>
+          <hbox flex="1">
+            <button is="highlightable-button" id="manageCertificatesButton"
+                    data-l10n-id="certificate-button"
+                    flex="1"
+                    oncommand="gPrivacyPane.showCertificates();"
+                    preference="security.disable_button.openCertManager"
+                    search-l10n-ids="
+                      certmgr-title.title,
+                      certmgr-tab-mine.label,
+                      certmgr-tab-remembered.label,
+                      certmgr-tab-people.label,
+                      certmgr-tab-servers.label,
+                      certmgr-tab-ca.label,
+                      certmgr-mine,
+                      certmgr-remembered,
+                      certmgr-people,
+                      certmgr-servers,
+                      certmgr-ca,
+                      certmgr-edit-ca-cert.title,
+                      certmgr-edit-cert-edit-trust,
+                      certmgr-edit-cert-trust-ssl.label,
+                      certmgr-edit-cert-trust-email.label,
+                      certmgr-delete-cert.title,
+                      certmgr-cert-host.label,
+                      certmgr-cert-name.label,
+                      certmgr-cert-server.label,
+                      certmgr-override-lifetime.label,
+                      certmgr-token-name.label,
+                      certmgr-begins-label.label,
+                      certmgr-expires-label.label,
+                      certmgr-email.label,
+                      certmgr-serial.label,
+                      certmgr-view.label,
+                      certmgr-edit.label,
+                      certmgr-export.label,
+                      certmgr-delete.label,
+                      certmgr-delete-builtin.label,
+                      certmgr-backup.label,
+                      certmgr-backup-all.label,
+                      certmgr-restore.label,
+                      certmgr-add-exception.label,
+                      exception-mgr.title,
+                      exception-mgr-extra-button.label,
+                      exception-mgr-supplemental-warning,
+                      exception-mgr-cert-location-url.value,
+                      exception-mgr-cert-location-download.label,
+                      exception-mgr-cert-status-view-cert.label,
+                      exception-mgr-permanent.label,
+                      pk11-bad-password,
+                      pkcs12-decode-err,
+                      pkcs12-unknown-err-restore,
+                      pkcs12-unknown-err-backup,
+                      pkcs12-unknown-err,
+                      pkcs12-info-no-smartcard-backup,
+                      pkcs12-dup-data,
+                      choose-p12-backup-file-dialog,
+                      file-browse-pkcs12-spec,
+                      choose-p12-restore-file-dialog,
+                      file-browse-certificate-spec,
+                      import-ca-certs-prompt,
+                      import-email-cert-prompt,
+                      delete-user-cert-title.title,
+                      delete-user-cert-confirm,
+                      delete-user-cert-impact,
+                      delete-ssl-cert-title.title,
+                      delete-ssl-cert-confirm,
+                      delete-ssl-cert-impact,
+                      delete-ca-cert-title.title,
+                      delete-ca-cert-confirm,
+                      delete-ca-cert-impact,
+                      delete-email-cert-title.title,
+                      delete-email-cert-confirm,
+                      delete-email-cert-impact,
+                      add-exception-branded-warning,
+                      add-exception-invalid-header,
+                      add-exception-domain-mismatch-short,
+                      add-exception-domain-mismatch-long,
+                      add-exception-expired-short,
+                      add-exception-expired-long,
+                      add-exception-unverified-or-bad-signature-short,
+                      add-exception-unverified-or-bad-signature-long,
+                      add-exception-valid-short,
+                      add-exception-valid-long,
+                      add-exception-checking-short,
+                      add-exception-checking-long,
+                      add-exception-no-cert-short,
+                      add-exception-no-cert-long,
+                      save-cert-as,
+                      cert-format-base64,
+                      cert-format-base64-chain,
+                      write-file-failure,
+                      cert-format-der,
+                      cert-format-pkcs7,
+                      cert-format-pkcs7-chain"/>
+          </hbox>
+          <hbox flex="1">
+            <button is="highlightable-button" id="viewSecurityDevicesButton"
+                    data-l10n-id="security-devices-button"
+                    flex="1"
+                    oncommand="gPrivacyPane.showSecurityDevices();"
+                    preference="security.disable_button.openDeviceManager"
+                    search-l10n-ids="
+                      devmgr.title,
+                      devmgr-devlist.label,
+                      devmgr-header-details.label,
+                      devmgr-header-value.label,
+                      devmgr-button-login.label,
+                      devmgr-button-logout.label,
+                      devmgr-button-changepw.label,
+                      devmgr-button-load.label,
+                      devmgr-button-unload.label,
+                      devmgr-button-enable-fips.label,
+                      devmgr-button-disable-fips.label,
+                      load-device.title,
+                      load-device-info,
+                      load-device-modname.value,
+                      load-device-modname-default.value,
+                      load-device-filename.value,
+                      load-device-browse.label,
+                      devinfo-status.label,
+                      devinfo-status-disabled.label,
+                      devinfo-status-not-present.label,
+                      devinfo-status-uninitialized.label,
+                      devinfo-status-not-logged-in.label,
+                      devinfo-status-logged-in.label,
+                      devinfo-status-ready.label,
+                      devinfo-desc.label,
+                      fips-nonempty-password-required,
+                      unable-to-toggle-fips,
+                      load-pk11-module-file-picker-title,
+                      load-module-help-root-certs-module-name.value,
+                      add-module-failure,
+                      del-module-warning,
+                      del-module-error,
+                      devinfo-man-id.label,
+                      devinfo-hwversion.label,
+                      load-module-help-empty-module-name.value,
+                      devinfo-fwversion.label,
+                      devinfo-modname.label,
+                      devinfo-modpath.label,
+                      login-failed,
+                      devinfo-label.label,
+                      devinfo-serialnum"/>
+          </hbox>
         </vbox>
       </hbox>
     </html:fieldset>
     </html:div>
 
-  </prefpane>
+  </html:template>
--- a/mail/components/preferences/receipts.xhtml
+++ b/mail/components/preferences/receipts.xhtml
@@ -8,20 +8,18 @@
 
 <!DOCTYPE window>
 
 <window type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         data-l10n-id="receipts-dialog-window"
         onload="enableDisableAllowedReceipts();">
-<dialog id="ReturnReceiptsDialog"
-        dlgbuttons="accept,cancel">
-
-  <prefpane id="ReturnReceiptsDialogPane">
+  <dialog id="ReturnReceiptsDialog"
+          dlgbuttons="accept,cancel">
     <script src="chrome://global/content/preferencesBindings.js"/>
     <script src="chrome://messenger/content/preferences/receipts.js"/>
 
     <linkset>
       <html:link rel="localization" href="messenger/preferences/receipts.ftl"/>
     </linkset>
 
     <vbox id="returnReceiptSettings" align="start">
@@ -90,11 +88,10 @@
               <menuitem value="1" data-l10n-id="receipt-send-always-label"/>
               <menuitem value="2" data-l10n-id="receipt-send-ask-label"/>
             </menupopup>
           </menulist>
         </hbox>
       </vbox>
     </radiogroup>
     <separator/>
-  </prefpane>
-</dialog>
+  </dialog>
 </window>
new file mode 100644
--- /dev/null
+++ b/mail/components/preferences/searchResults.inc.xhtml
@@ -0,0 +1,27 @@
+<!-- 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/. -->
+
+  <hbox id="header-searchResults"
+        class="subcategory"
+        hidden="true"
+        data-hidden-from-search="true"
+        data-category="paneSearchResults">
+     <html:h1 data-l10n-id="search-results-header"/>
+   </hbox>
+   <groupbox id="no-results-message"
+             data-hidden-from-search="true"
+             data-category="paneSearchResults"
+             hidden="true">
+     <vbox class="no-results-container">
+       <label id="sorry-message" data-l10n-id="search-results-empty-message">
+         <html:span data-l10n-name="query" id="sorry-message-query"/>
+       </label>
+       <label id="need-help" data-l10n-id="search-results-help-link">
+         <html:a class="text-link" data-l10n-name="url" target="_blank"></html:a>
+       </label>
+     </vbox>
+     <vbox class="no-results-container no-results-image-container" align="center">
+       <image class="no-results-image"></image>
+     </vbox>
+  </groupbox>
--- a/mail/components/preferences/sendoptions.xhtml
+++ b/mail/components/preferences/sendoptions.xhtml
@@ -10,20 +10,18 @@
 <!DOCTYPE window>
 
 <window type="child"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         style="min-height: 33em;"
         data-l10n-id="sendoptions-dialog-window"
         onload="gSendOptionsDialog.init();">
-<dialog id="SendOptionsDialog"
-        dlgbuttons="accept,cancel">
-
-  <prefpane id="SendOptionsDialogPane">
+  <dialog id="SendOptionsDialog"
+          dlgbuttons="accept,cancel">
     <script src="chrome://global/content/preferencesBindings.js"/>
     <script src="chrome://messenger/content/preferences/sendoptions.js"/>
 
     <stringbundle id="bundlePreferences" src="chrome://messenger/locale/preferences/preferences.properties"/>
 
     <linkset>
       <html:link rel="localization" href="branding/brand.ftl"/>
       <html:link rel="localization" href="messenger/preferences/sendoptions.ftl"/>
@@ -106,11 +104,10 @@
             </vbox>
           </hbox>
         </vbox>
 
       </tabpanels>
     </tabbox>
 
     <separator/>
-  </prefpane>
-</dialog>
+  </dialog>
 </window>
--- a/mail/components/preferences/test/browser/head.js
+++ b/mail/components/preferences/test/browser/head.js
@@ -7,34 +7,30 @@
 async function openNewPrefsTab(paneID, scrollPaneTo, otherArgs) {
   let tabmail = document.getElementById("tabmail");
   let prefsTabMode = tabmail.tabModes.preferencesTab;
 
   is(prefsTabMode.tabs.length, 0, "Prefs tab is not open");
 
   let prefsDocument = await new Promise(resolve => {
     Services.obs.addObserver(function documentLoaded(subject) {
-      if (subject.URL == "about:preferences") {
+      if (subject.URL.startsWith("about:preferences")) {
         Services.obs.removeObserver(documentLoaded, "chrome-document-loaded");
         subject.ownerGlobal.setTimeout(() => resolve(subject));
       }
     }, "chrome-document-loaded");
     openPreferencesTab(paneID, scrollPaneTo, otherArgs);
   });
-  ok(prefsDocument.URL == "about:preferences", "Prefs tab is open");
+  ok(prefsDocument.URL.startsWith("about:preferences"), "Prefs tab is open");
 
+  prefsDocument = prefsTabMode.tabs[0].browser.contentDocument;
   let prefsWindow = prefsDocument.ownerGlobal;
+  prefsWindow.resizeTo(screen.availWidth, screen.availHeight);
+
   if (paneID) {
-    if (prefsWindow.getCurrentPaneID() != paneID) {
-      let pane = prefsDocument.getElementById(paneID);
-      await new Promise(resolve => {
-        pane.addEventListener("paneSelected", resolve, { once: true });
-      });
-    }
-
     await new Promise(resolve => prefsWindow.setTimeout(resolve));
     is(prefsWindow.getCurrentPaneID(), paneID, `Selected pane is ${paneID}`);
   } else {
     // If we don't wait here for other scripts to run, they
     // could be in a bad state if our test closes the tab.
     await new Promise(resolve => prefsWindow.setTimeout(resolve));
   }
 
@@ -54,39 +50,34 @@ async function openNewPrefsTab(paneID, s
 async function openExistingPrefsTab(paneID, scrollPaneTo, otherArgs) {
   let tabmail = document.getElementById("tabmail");
   let prefsTabMode = tabmail.tabModes.preferencesTab;
 
   is(prefsTabMode.tabs.length, 1, "Prefs tab is open");
 
   let prefsDocument = prefsTabMode.tabs[0].browser.contentDocument;
   let prefsWindow = prefsDocument.ownerGlobal;
+  prefsWindow.resizeTo(screen.availWidth, screen.availHeight);
 
   if (paneID && prefsWindow.getCurrentPaneID() != paneID) {
-    await new Promise(resolve => {
-      prefsDocument.addEventListener("paneSelected", resolve, { once: true });
-      openPreferencesTab(paneID, scrollPaneTo, otherArgs);
-    });
-  } else {
     openPreferencesTab(paneID, scrollPaneTo, otherArgs);
   }
 
   await new Promise(resolve => prefsWindow.setTimeout(resolve));
   is(prefsWindow.getCurrentPaneID(), paneID, `Selected pane is ${paneID}`);
 
   if (scrollPaneTo) {
     Assert.greater(
       prefsDocument.getElementById("preferencesContainer").scrollTop,
       0,
       "Prefs page did scroll when it was supposed to"
     );
   }
 
   registerCleanupOnce();
-
   return { prefsDocument, prefsWindow };
 }
 
 function registerCleanupOnce() {
   if (registerCleanupOnce.alreadyRegistered) {
     return;
   }
   registerCleanupFunction(closePrefsTab);
@@ -140,16 +131,17 @@ async function testCheckboxes(paneID, sc
       let wantedValue = checked;
       if (test.prefValues) {
         wantedValue = wantedValue ? test.prefValues[1] : test.prefValues[0];
       }
       let checkbox = prefsDocument.getElementById(test.checkboxID);
       is(
         checkbox.checked,
         checked,
+        wantedValue,
         "Checkbox " + (checked ? "is" : "isn't") + " checked"
       );
       if (typeof wantedValue == "number") {
         is(
           Services.prefs.getIntPref(test.pref, -999),
           wantedValue,
           `Pref is ${wantedValue}`
         );
@@ -182,16 +174,17 @@ async function testCheckboxes(paneID, sc
         }
       }
     };
 
     for (let test of tests) {
       info(`Checking ${test.checkboxID}`);
 
       let checkbox = prefsDocument.getElementById(test.checkboxID);
+      checkbox.scrollIntoView(false);
       testUIState(test, initiallyChecked);
 
       EventUtils.synthesizeMouseAtCenter(checkbox, {}, prefsWindow);
       testUIState(test, !initiallyChecked);
 
       EventUtils.synthesizeMouseAtCenter(checkbox, {}, prefsWindow);
       testUIState(test, initiallyChecked);
     }
@@ -279,20 +272,22 @@ async function testRadioButtons(paneID, 
       // Check the initial setup is correct.
       testUIState(initialState);
       // Cycle through possible values, checking each one.
       for (let state of states) {
         if (state == initialState) {
           continue;
         }
         let radio = prefsDocument.getElementById(state.id);
+        radio.scrollIntoView(false);
         EventUtils.synthesizeMouseAtCenter(radio, {}, prefsWindow);
         testUIState(state);
       }
       // Go back to the initial value.
       let initialRadio = prefsDocument.getElementById(initialState.id);
+      initialRadio.scrollIntoView(false);
       EventUtils.synthesizeMouseAtCenter(initialRadio, {}, prefsWindow);
       testUIState(initialState);
 
       await closePrefsTab();
     }
   }
 }
--- a/mail/test/browser/pref-window/browser_fontChooser.js
+++ b/mail/test/browser/pref-window/browser_fontChooser.js
@@ -150,33 +150,38 @@ function assert_fonts_equal(aDescription
 /**
  * Verify that the given fonts are displayed in the font chooser. This opens the
  * pref window to the display pane and checks that, then opens the font chooser
  * and checks that too.
  */
 function _verify_fonts_displayed(aDefaults, aSerif, aSansSerif, aMonospace) {
   // Bring up the preferences window.
   let prefTab = open_pref_tab("paneGeneral");
+  let contentDoc = prefTab.browser.contentDocument;
+  let prefsWindow = contentDoc.ownerGlobal;
+  prefsWindow.resizeTo(screen.availWidth, screen.availHeight);
 
   let isSansDefault =
     Services.prefs.getCharPref("font.default." + kLanguage) == "sans-serif";
   let displayPaneExpected = isSansDefault ? aSansSerif : aSerif;
   let displayPaneActual = content_tab_e(prefTab, "defaultFont");
   mc.waitFor(
     () => displayPaneActual.itemCount > 0,
     "No font names were populated in the font picker."
   );
   assert_fonts_equal(
     "display pane",
     displayPaneExpected,
     displayPaneActual.value
   );
 
+  let advancedFonts = contentDoc.getElementById("advancedFonts");
+  advancedFonts.scrollIntoView(false);
   // Now open the advanced dialog.
-  mc.click(content_tab_eid(prefTab, "advancedFonts"));
+  EventUtils.synthesizeMouseAtCenter(advancedFonts, {}, prefsWindow);
   let fontc = wait_for_frame_load(
     prefTab.browser.contentDocument
       .getElementById("dialogOverlay-0")
       .querySelector("browser"),
     "chrome://messenger/content/preferences/fonts.xhtml"
   );
 
   // The font pickers are populated async so we need to wait for it.
--- a/mail/themes/linux/mail/preferences/preferences.css
+++ b/mail/themes/linux/mail/preferences/preferences.css
@@ -1,17 +1,17 @@
 /* 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/shared/preferences/preferences.css");
 @namespace html "http://www.w3.org/1999/xhtml";
 
 .dialogBox,
-#MailPreferences prefpane,
+#MailPreferences #paneDeck,
 #categories {
   font-size: 1.11em;
 }
 
 .treecol-sortdirection {
   /* override the Linux only toolkit rule */
   -moz-appearance: none;
 }
--- a/mail/themes/osx/mail/preferences/preferences.css
+++ b/mail/themes/osx/mail/preferences/preferences.css
@@ -1,17 +1,17 @@
 /* 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/shared/preferences/preferences.css");
 @namespace html "http://www.w3.org/1999/xhtml";
 
 .dialogBox,
-#MailPreferences prefpane,
+#MailPreferences #paneDeck,
 #categories {
   font-size: 1.36em;
 }
 
 html|h2 {
   border-bottom-width: 0;
   padding-bottom: 2px !important;
   padding-inline-start: 0;
--- a/mail/themes/shared/mail/preferences/dialog.css
+++ b/mail/themes/shared/mail/preferences/dialog.css
@@ -1,29 +1,24 @@
 /* - 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 html url("http://www.w3.org/1999/xhtml");
 
 dialog,
 window,
-prefpane,
 .windowDialog {
   -moz-appearance: none;
   background-color: var(--in-content-page-background);
   color: var(--in-content-page-color);
   margin: 0;
   padding: 0;
 }
 
-prefpane {
-  -moz-box-orient: vertical;
-}
-
 .contentPane {
   margin: 0;
 }
 
 .contentPane,
 dialog::part(content-box) {
   /* This allows the focus ring to display fully when scrolling is enabled. */
   padding: 4px;
@@ -63,20 +58,16 @@ caption {
 }
 
 groupbox {
   margin-top: 0;
   margin-inline: 4px;
   padding-block: 0 5px;
 }
 
-prefpane .groupbox-body {
-  padding: 0 0 5px;
-}
-
 groupbox description {
   margin-inline: 0;
 }
 
 menulist label {
   font-weight: unset;
 }
 
--- a/mail/themes/shared/mail/preferences/preferences.css
+++ b/mail/themes/shared/mail/preferences/preferences.css
@@ -84,29 +84,90 @@ html|th {
 
 description,
 label {
   line-height: 1.8em;
   margin: 0;
 }
 
 #preferencesContainer {
-  padding: 40px 28px;
+  padding: 0 28px 40px;
   overflow: auto;
 }
 
-#MailPreferences prefpane {
-  max-width: 800px;
-  padding: 0;
-  -moz-box-flex: 1;
-  -moz-box-orient: vertical;
+.paneDeckContainer {
+  display: block;
+  width: 800px;
+}
+
+.sticky-container {
+  width: 100%;
+  position: sticky;
+  background-color: var(--in-content-page-background);
+  top: 0;
+  z-index: 1;
+  padding-inline: 4px;
+}
+
+#searchInput {
+  min-height: 32px;
+  margin: 20px 0 30px;
+}
+
+#paneDeck {
+  width: 100%;
+}
+
+.search-tooltip {
+  max-width: 150px;
+  font-size: 1.25rem;
+  position: absolute;
+  padding: 0 10px;
+  background-color: #ffe900;
+  color: #000;
+  border: 1px solid #d7b600;
+  bottom: 36px;
+  opacity: 0.85;
 }
 
-#MailPreferences prefpane:not([selected]) {
-  display: none;
+.search-tooltip:hover {
+  opacity: 0.1;
+}
+
+.search-tooltip::before {
+  position: absolute;
+  content: "";
+  border: 7px solid transparent;
+  border-top-color: #d7b600;
+  top: 100%;
+  inset-inline-start: calc(50% - 7px);
+}
+
+.search-tooltip::after {
+  position: absolute;
+  content: "";
+  border: 6px solid transparent;
+  border-top-color: #ffe900;
+  top: 100%;
+  inset-inline-start: calc(50% - 6px);
+}
+
+.search-tooltip-parent {
+  position: relative;
+}
+
+.search-tooltip > span {
+  -moz-user-select: none;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.visually-hidden {
+  visibility: collapse;
 }
 
 tabpanel > label,
 tabpanel > description,
 tabpanel > hbox > description {
   margin-inline-start: 0;
 }
 
--- a/mail/themes/windows/mail/preferences/preferences.css
+++ b/mail/themes/windows/mail/preferences/preferences.css
@@ -1,17 +1,17 @@
 /* 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/shared/preferences/preferences.css");
 @namespace html "http://www.w3.org/1999/xhtml";
 
 .dialogBox,
-#MailPreferences prefpane,
+#MailPreferences #paneDeck,
 #categories {
   font-size: 1.25em;
 }
 
 html|fieldset {
   border-style: none;
 }