Bug 1490366 - Part 2: Convert about:addons to card UI r=aswan,jaws
authorMark Striemer <mstriemer@mozilla.com>
Sun, 14 Oct 2018 19:22:59 +0000
changeset 496916 cb62a8b8a525d7442d53ee6441fe3f60608b0160
parent 496915 a19f3794f0c9b63868f7e4e028bc6a76fb199930
child 496917 0a45a5634cf18f31b1ab848f4c71b34cabe80ec5
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan, jaws
bugs1490366
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1490366 - Part 2: Convert about:addons to card UI r=aswan,jaws Differential Revision: https://phabricator.services.mozilla.com/D8102
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/extensions.xml
toolkit/mozapps/extensions/content/extensions.xul
toolkit/mozapps/extensions/test/browser/browser.ini
toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js
toolkit/mozapps/extensions/test/browser/browser_bug562854.js
toolkit/mozapps/extensions/test/browser/browser_details.js
toolkit/mozapps/extensions/test/browser/browser_legacy_pre57.js
toolkit/mozapps/extensions/test/browser/browser_list.js
toolkit/mozapps/extensions/test/browser/browser_plugin_enabled_state_locked.js
toolkit/mozapps/extensions/test/browser/browser_pluginprefs.js
toolkit/mozapps/extensions/test/browser/browser_uninstalling.js
toolkit/themes/shared/extensions/extensions.inc.css
toolkit/themes/shared/in-content/common.inc.css
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -120,24 +120,16 @@ function initialize(event) {
   let viewCommandSet = document.getElementById("viewCommandSet");
   viewCommandSet.addEventListener("commandupdate", function(event) {
     gViewController.updateCommands();
   });
   viewCommandSet.addEventListener("command", function(event) {
     gViewController.doCommand(event.target.id);
   });
 
-  let detailScreenshot = document.getElementById("detail-screenshot");
-  detailScreenshot.addEventListener("load", function(event) {
-    this.removeAttribute("loading");
-  });
-  detailScreenshot.addEventListener("error", function(event) {
-    this.setAttribute("loading", "error");
-  });
-
   let addonPage = document.getElementById("addons-page");
   addonPage.addEventListener("dragenter", function(event) {
     gDragDrop.onDragOver(event);
   });
   addonPage.addEventListener("dragover", function(event) {
     gDragDrop.onDragOver(event);
   });
   addonPage.addEventListener("drop", function(event) {
@@ -1468,17 +1460,17 @@ function shouldShowVersionNumber(aAddon)
     return !/@personas\.mozilla\.org$/.test(aAddon.id);
 
   return true;
 }
 
 function createItem(aObj, aIsInstall) {
   let item = document.createXULElement("richlistitem");
 
-  item.setAttribute("class", "addon addon-view");
+  item.setAttribute("class", "addon addon-view card");
   item.setAttribute("name", aObj.name);
   item.setAttribute("type", aObj.type);
 
   if (aIsInstall) {
     item.mInstall = aObj;
 
     if (aObj.state != AddonManager.STATE_INSTALLED) {
       item.setAttribute("status", "installing");
@@ -2615,34 +2607,16 @@ var gDetailView = {
     var version = document.getElementById("detail-version");
     if (shouldShowVersionNumber(aAddon)) {
       version.hidden = false;
       version.value = aAddon.version;
     } else {
       version.hidden = true;
     }
 
-    var screenshotbox = document.getElementById("detail-screenshot-box");
-    var screenshot = document.getElementById("detail-screenshot");
-    if (aAddon.screenshots && aAddon.screenshots.length > 0) {
-      if (aAddon.screenshots[0].thumbnailURL) {
-        screenshot.src = aAddon.screenshots[0].thumbnailURL;
-        screenshot.width = aAddon.screenshots[0].thumbnailWidth;
-        screenshot.height = aAddon.screenshots[0].thumbnailHeight;
-      } else {
-        screenshot.src = aAddon.screenshots[0].url;
-        screenshot.width = aAddon.screenshots[0].width;
-        screenshot.height = aAddon.screenshots[0].height;
-      }
-      screenshot.setAttribute("loading", "true");
-      screenshotbox.hidden = false;
-    } else {
-      screenshotbox.hidden = true;
-    }
-
     var desc = document.getElementById("detail-desc");
     desc.textContent = aAddon.description;
 
     var fullDesc = document.getElementById("detail-fulldesc");
     if (aAddon.getFullDescription) {
       fullDesc.textContent = "";
       fullDesc.append(aAddon.getFullDescription(document));
       fullDesc.hidden = false;
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -620,41 +620,33 @@
                 <xul:spacer flex="5000"/> <!-- Necessary to make the name crop -->
               </xul:hbox>
             <xul:label anonid="date-updated" class="date-updated"
                        unknown="&addon.unknownDate;"/>
           </xul:hbox>
 
           <xul:hbox class="advancedinfo-container" flex="1">
             <xul:vbox class="description-outer-container" flex="1">
-              <xul:hbox class="description-container">
-                <xul:label anonid="description" class="description" crop="end" flex="1"/>
-                <xul:button anonid="details-btn" class="details button-link"
-                            label="&addon.details.label;"
-                            tooltiptext="&addon.details.tooltip;"
-                            oncommand="document.getBindingParent(this).showInDetailView();"/>
-                <xul:spacer flex="5000"/> <!-- Necessary to make the description crop -->
-              </xul:hbox>
-              <xul:vbox anonid="relnotes-container" class="relnotes-container">
-                <xul:label class="relnotes-header" value="&addon.releaseNotes.label;"/>
-                <xul:label anonid="relnotes-loading" value="&addon.loadingReleaseNotes.label;"/>
-                <xul:label anonid="relnotes-error" hidden="true"
-                           value="&addon.errorLoadingReleaseNotes.label;"/>
-                <xul:vbox anonid="relnotes" class="relnotes"/>
-              </xul:vbox>
               <xul:hbox class="relnotes-toggle-container">
                 <xul:button anonid="relnotes-toggle-btn" class="relnotes-toggle"
                             hidden="true" label="&cmd.showReleaseNotes.label;"
                             tooltiptext="&cmd.showReleaseNotes.tooltip;"
                             showlabel="&cmd.showReleaseNotes.label;"
                             showtooltip="&cmd.showReleaseNotes.tooltip;"
                             hidelabel="&cmd.hideReleaseNotes.label;"
                             hidetooltip="&cmd.hideReleaseNotes.tooltip;"
                             oncommand="document.getBindingParent(this).toggleReleaseNotes();"/>
               </xul:hbox>
+              <xul:vbox anonid="relnotes-container" class="relnotes-container">
+                <xul:label class="relnotes-header" value="&addon.releaseNotes.label;"/>
+                <xul:label anonid="relnotes-loading" value="&addon.loadingReleaseNotes.label;"/>
+                <xul:label anonid="relnotes-error" hidden="true"
+                           value="&addon.errorLoadingReleaseNotes.label;"/>
+                <xul:vbox anonid="relnotes" class="relnotes"/>
+              </xul:vbox>
             </xul:vbox>
           </xul:hbox>
         </xul:vbox>
         <xul:vbox class="status-control-wrapper">
           <xul:hbox class="status-container">
             <xul:hbox anonid="checking-update" hidden="true">
               <xul:image class="spinner"/>
               <xul:label value="&addon.checkingForUpdates.label;"/>
@@ -789,20 +781,16 @@
       </field>
       <field name="_icon">
         document.getAnonymousElementByAttribute(this, "anonid", "icon");
       </field>
       <field name="_dateUpdated">
         document.getAnonymousElementByAttribute(this, "anonid",
                                                 "date-updated");
       </field>
-      <field name="_description">
-        document.getAnonymousElementByAttribute(this, "anonid",
-                                                "description");
-      </field>
       <field name="_stateMenulist">
         document.getAnonymousElementByAttribute(this, "anonid",
                                                 "state-menulist");
       </field>
       <field name="_askToActivateMenuitem">
         document.getAnonymousElementByAttribute(this, "anonid",
                                                 "ask-to-activate-menuitem");
       </field>
@@ -914,21 +902,16 @@
           this.setAttribute("name", aAddon.name);
 
           var iconURL = AddonManager.getPreferredIconURL(aAddon, 32, window);
           if (iconURL)
             this._icon.src = iconURL;
           else
             this._icon.src = "";
 
-          if (this.mAddon.description)
-            this._description.value = this.mAddon.description;
-          else
-            this._description.hidden = true;
-
           let legacyWarning = legacyExtensionsEnabled && !this.mAddon.install &&
             isLegacyExtension(this.mAddon);
           this.setAttribute("legacy", legacyWarning);
           document.getAnonymousElementByAttribute(this, "anonid", "legacy").href = SUPPORT_URL + "webextensions";
 
           if (!("applyBackgroundUpdates" in this.mAddon) ||
               (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DISABLE ||
                (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
@@ -1500,28 +1483,19 @@
         <body><![CDATA[
             this._updateState();
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="click" button="0"><![CDATA[
-        switch (event.detail) {
-        case 1:
-          // Prevent double-click where the UI changes on the first click
-          this._lastClickTarget = event.originalTarget;
-          break;
-        case 2:
-          if (event.originalTarget.localName != "button" &&
-              !event.originalTarget.classList.contains("text-link") &&
-              event.originalTarget == this._lastClickTarget) {
-            this.showInDetailView();
-          }
-          break;
+        if (!["button", "checkbox"].includes(event.originalTarget.localName) &&
+            !event.originalTarget.classList.contains("text-link")) {
+          this.showInDetailView();
         }
       ]]></handler>
     </handlers>
   </binding>
 
 
   <!-- Addon - uninstalled - An uninstalled addon that can be re-installed. -->
   <binding id="addon-uninstalled"
--- a/toolkit/mozapps/extensions/content/extensions.xul
+++ b/toolkit/mozapps/extensions/content/extensions.xul
@@ -211,80 +211,82 @@
           <browser id="discover-browser" type="content" flex="1"
                    disablehistory="true"/>
         </deck>
 
         <!-- container for views with the search/tools header -->
         <vbox id="headered-views" flex="1">
           <!-- main header -->
           <hbox id="header" align="center">
-            <button id="show-all-extensions" hidden="true"
-                    label="&showAllExtensions.button.label;"
-                    command="cmd_showAllExtensions"/>
-            <spacer flex="1"/>
-            <hbox id="updates-container" align="center">
-              <image class="spinner"/>
-              <label id="updates-noneFound" hidden="true"
-                     value="&updates.noneFound.label;"/>
-              <button id="updates-manualUpdatesFound-btn" class="button-link"
-                      hidden="true" label="&updates.manualUpdatesFound.label;"
-                      command="cmd_goToAvailableUpdates"/>
-              <label id="updates-progress" hidden="true"
-                     value="&updates.updating.label;"/>
-              <label id="updates-installed" hidden="true"
-                     value="&updates.installed.label;"/>
-              <label id="updates-downloaded" hidden="true"
-                     value="&updates.downloaded.label;"/>
-              <button id="updates-restart-btn" class="button-link" hidden="true"
-                      label="&updates.restart.label;"
-                      command="cmd_restartApp"/>
+            <hbox id="header-inner">
+              <button id="show-all-extensions" hidden="true"
+                      label="&showAllExtensions.button.label;"
+                      command="cmd_showAllExtensions"/>
+              <spacer flex="1"/>
+              <hbox id="updates-container" align="center">
+                <image class="spinner"/>
+                <label id="updates-noneFound" hidden="true"
+                       value="&updates.noneFound.label;"/>
+                <button id="updates-manualUpdatesFound-btn" class="button-link"
+                        hidden="true" label="&updates.manualUpdatesFound.label;"
+                        command="cmd_goToAvailableUpdates"/>
+                <label id="updates-progress" hidden="true"
+                       value="&updates.updating.label;"/>
+                <label id="updates-installed" hidden="true"
+                       value="&updates.installed.label;"/>
+                <label id="updates-downloaded" hidden="true"
+                       value="&updates.downloaded.label;"/>
+                <button id="updates-restart-btn" class="button-link" hidden="true"
+                        label="&updates.restart.label;"
+                        command="cmd_restartApp"/>
+              </hbox>
+              <button id="show-disabled-unsigned-extensions" hidden="true"
+                      class="warning"
+                      label="&showUnsignedExtensions.button.label;"
+                      command="cmd_showUnsignedExtensions"/>
+              <toolbarbutton id="header-utils-btn" class="header-button" type="menu"
+                             tooltiptext="&toolsMenu.tooltip;">
+                <menupopup id="utils-menu">
+                  <menuitem id="utils-updateNow"
+                            label="&updates.checkForUpdates.label;"
+                            accesskey="&updates.checkForUpdates.accesskey;"
+                            command="cmd_findAllUpdates"/>
+                  <menuitem id="utils-viewUpdates"
+                            label="&updates.viewUpdates.label;"
+                            accesskey="&updates.viewUpdates.accesskey;"
+                            command="cmd_goToRecentUpdates"/>
+                  <menuseparator id="utils-installFromFile-separator"/>
+                  <menuitem id="utils-installFromFile"
+                            label="&installAddonFromFile.label;"
+                            accesskey="&installAddonFromFile.accesskey;"
+                            command="cmd_installFromFile"/>
+                  <menuitem id="utils-debugAddons"
+                            label="&debugAddons.label;"
+                            accesskey="&debugAddons.accesskey;"
+                            command="cmd_debugAddons"/>
+                  <menuseparator/>
+                  <menuitem id="utils-autoUpdateDefault"
+                            label="&updates.updateAddonsAutomatically.label;"
+                            accesskey="&updates.updateAddonsAutomatically.accesskey;"
+                            type="checkbox" autocheck="false"
+                            command="cmd_toggleAutoUpdateDefault"/>
+                  <menuitem id="utils-resetAddonUpdatesToAutomatic"
+                            label="&updates.resetUpdatesToAutomatic.label;"
+                            accesskey="&updates.resetUpdatesToAutomatic.accesskey;"
+                            command="cmd_resetAddonAutoUpdate"/>
+                  <menuitem id="utils-resetAddonUpdatesToManual"
+                            label="&updates.resetUpdatesToManual.label;"
+                            accesskey="&updates.resetUpdatesToManual.accesskey;"
+                            command="cmd_resetAddonAutoUpdate"/>
+                </menupopup>
+              </toolbarbutton>
+              <textbox id="header-search" type="search" searchbutton="true"
+                       searchbuttonlabel="&search.buttonlabel;"
+                       placeholder="&search.placeholder2;" maxlength="100"/>
             </hbox>
-            <button id="show-disabled-unsigned-extensions" hidden="true"
-                    class="warning"
-                    label="&showUnsignedExtensions.button.label;"
-                    command="cmd_showUnsignedExtensions"/>
-            <toolbarbutton id="header-utils-btn" class="header-button" type="menu"
-                           tooltiptext="&toolsMenu.tooltip;">
-              <menupopup id="utils-menu">
-                <menuitem id="utils-updateNow"
-                          label="&updates.checkForUpdates.label;"
-                          accesskey="&updates.checkForUpdates.accesskey;"
-                          command="cmd_findAllUpdates"/>
-                <menuitem id="utils-viewUpdates"
-                          label="&updates.viewUpdates.label;"
-                          accesskey="&updates.viewUpdates.accesskey;"
-                          command="cmd_goToRecentUpdates"/>
-                <menuseparator id="utils-installFromFile-separator"/>
-                <menuitem id="utils-installFromFile"
-                          label="&installAddonFromFile.label;"
-                          accesskey="&installAddonFromFile.accesskey;"
-                          command="cmd_installFromFile"/>
-                <menuitem id="utils-debugAddons"
-                          label="&debugAddons.label;"
-                          accesskey="&debugAddons.accesskey;"
-                          command="cmd_debugAddons"/>
-                <menuseparator/>
-                <menuitem id="utils-autoUpdateDefault"
-                          label="&updates.updateAddonsAutomatically.label;"
-                          accesskey="&updates.updateAddonsAutomatically.accesskey;"
-                          type="checkbox" autocheck="false"
-                          command="cmd_toggleAutoUpdateDefault"/>
-                <menuitem id="utils-resetAddonUpdatesToAutomatic"
-                          label="&updates.resetUpdatesToAutomatic.label;"
-                          accesskey="&updates.resetUpdatesToAutomatic.accesskey;"
-                          command="cmd_resetAddonAutoUpdate"/>
-                <menuitem id="utils-resetAddonUpdatesToManual"
-                          label="&updates.resetUpdatesToManual.label;"
-                          accesskey="&updates.resetUpdatesToManual.accesskey;"
-                          command="cmd_resetAddonAutoUpdate"/>
-              </menupopup>
-            </toolbarbutton>
-            <textbox id="header-search" type="search" searchbutton="true"
-                     searchbuttonlabel="&search.buttonlabel;"
-                     placeholder="&search.placeholder2;" maxlength="100"/>
           </hbox>
 
           <deck id="headered-views-content" flex="1" selectedIndex="0">
             <!-- list view -->
             <vbox id="list-view" flex="1" class="view-pane" align="stretch" tabindex="0">
               <!-- info UI for add-ons that have been disabled for being unsigned -->
               <vbox id="disabled-unsigned-addons-info" hidden="true">
                 <label id="disabled-unsigned-addons-heading" value="&disabledUnsigned.heading;"/>
@@ -425,17 +427,17 @@
                 <button id="update-selected-btn" hidden="true"
                         label="&updates.updateSelected.label;"
                         tooltiptext="&updates.updateSelected.tooltip;"/>
               </hbox>
               <richlistbox id="updates-list" class="list" flex="1"/>
             </vbox>
 
             <!-- detail view -->
-            <scrollbox id="detail-view" flex="1" class="view-pane addon-view" orient="vertical" tabindex="0"
+            <scrollbox id="detail-view" class="view-pane addon-view" orient="vertical" tabindex="0"
                        role="document">
               <!-- global warnings -->
               <hbox class="global-warning-container global-warning">
                 <hbox class="global-warning-safemode" flex="1" align="center"
                       tooltiptext="&warning.safemode.label;">
                   <image class="warning-icon"/>
                   <label class="global-warning-text" flex="1" crop="end"
                          value="&warning.safemode.label;"/>
@@ -457,29 +459,28 @@
                          value="&warning.updatesecurity.label;"/>
                 </hbox>
                 <button class="button-link global-warning-updatesecurity"
                         label="&warning.updatesecurity.enable.label;"
                         tooltiptext="&warning.updatesecurity.enable.tooltip;"
                         command="cmd_enableUpdateSecurity"/>
                 <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
               </hbox>
-              <hbox flex="1">
-                <spacer flex="1"/>
+              <hbox class="detail-view-wrapper">
                 <!-- "loading" splash screen -->
                 <vbox class="alert-container">
                   <spacer class="alert-spacer-before"/>
                   <hbox class="alert loading">
                     <image/>
                     <label value="&loading.label;"/>
                   </hbox>
                   <spacer class="alert-spacer-after"/>
                 </vbox>
                 <!-- actual detail view -->
-                <vbox class="detail-view-container" flex="3" contextmenu="addonitem-popup">
+                <vbox class="detail-view-container" contextmenu="addonitem-popup">
                   <vbox id="detail-notifications">
                     <hbox id="warning-container" align="center" class="warning">
                       <image class="warning-icon"/>
                       <label id="detail-warning" flex="1"/>
                       <label id="detail-warning-link" class="text-link"/>
                       <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
                     </hbox>
                     <hbox id="error-container" align="center" class="error">
@@ -496,42 +497,39 @@
                               command="cmd_restartApp"/>
                       <button id="detail-undo-btn" class="button-link"
                               label="&addon.undoAction.label;"
                               tooltipText="&addon.undoAction.tooltip;"
                               command="cmd_cancelOperation"/>
                       <spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
                     </hbox>
                   </vbox>
-                  <hbox align="start">
-                    <vbox id="detail-icon-container" align="end">
-                      <image id="detail-icon" class="icon"/>
-                    </vbox>
+                  <hbox class="card addon-detail" align="start">
                     <vbox flex="1">
-                      <vbox id="detail-summary">
-                        <hbox id="detail-name-container" class="name-container"
-                              align="start">
-                          <label id="detail-name" flex="1"/>
-                          <label id="detail-version"/>
-                          <label id="detail-legacy-warning" class="legacy-warning text-link" value="&addon.legacy.label;"/>
-                          <label class="disabled-postfix" value="&addon.disabled.postfix;"/>
-                          <label class="update-postfix" value="&addon.update.postfix;"/>
-                          <spacer flex="5000"/> <!-- Necessary to allow the name to wrap -->
-                        </hbox>
-                        <label id="detail-creator" class="creator"/>
-                      </vbox>
-                      <hbox id="detail-desc-container" align="start">
-                        <vbox id="detail-screenshot-box" pack="center" hidden="true"> <!-- Necessary to work around bug 394738 -->
-                          <image id="detail-screenshot"/>
+                      <hbox align="start">
+                        <vbox id="detail-icon-container" align="end">
+                          <image id="detail-icon" class="icon"/>
                         </vbox>
-                        <vbox flex="1">
-                          <description id="detail-desc"/>
-                          <description id="detail-fulldesc"/>
+                        <vbox id="detail-summary">
+                          <hbox id="detail-name-container" class="name-container"
+                                align="start">
+                            <label id="detail-name" flex="1"/>
+                            <label id="detail-version"/>
+                            <label id="detail-legacy-warning" class="legacy-warning text-link" value="&addon.legacy.label;"/>
+                            <label class="disabled-postfix" value="&addon.disabled.postfix;"/>
+                            <label class="update-postfix" value="&addon.update.postfix;"/>
+                            <spacer flex="5000"/> <!-- Necessary to allow the name to wrap -->
+                          </hbox>
+                          <label id="detail-creator" class="creator"/>
                         </vbox>
                       </hbox>
+                      <vbox id="detail-desc-container" align="start" flex="1">
+                        <description id="detail-desc"/>
+                        <description id="detail-fulldesc"/>
+                      </vbox>
                       <vbox id="detail-contributions">
                         <description id="detail-contrib-description">
                           &detail.contributions.description;
                         </description>
                         <hbox align="center">
                           <spacer flex="1"/>
                           <button id="detail-contrib-btn"
                                   label="&cmd.contribute.label;"
--- a/toolkit/mozapps/extensions/test/browser/browser.ini
+++ b/toolkit/mozapps/extensions/test/browser/browser.ini
@@ -26,17 +26,16 @@ support-files =
   !/toolkit/mozapps/extensions/test/xpinstall/unsigned.xpi
   !/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi
   !/toolkit/mozapps/extensions/test/xpinstall/amosigned-restart-required.xpi
 
 [browser_CTP_plugins.js]
 tags = blocklist
 [browser_bug523784.js]
 [browser_bug562797.js]
-[browser_bug562854.js]
 [browser_bug562890.js]
 skip-if = os == 'win' && !debug # Disabled on Windows opt/PGO builds due to intermittent failures (bug 1135866)
 [browser_bug562899.js]
 [browser_bug562992.js]
 [browser_bug567127.js]
 [browser_bug567137.js]
 [browser_bug570760.js]
 skip-if = verify
--- a/toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js
@@ -103,19 +103,17 @@ add_task(async function() {
     let testPlugin = content.document.getElementById("test");
     ok(testPlugin, "part7: should have a plugin element in the page");
     let objLoadingContent = testPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
     ok(!objLoadingContent.activated, "part7: plugin should not be activated");
   });
 
   BrowserTestUtils.removeTab(pluginTab);
 
-  let details = managerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "details-btn");
-  is_element_visible(details, "part7: details link should be visible");
-  EventUtils.synthesizeMouseAtCenter(details, {}, managerWindow);
+  EventUtils.synthesizeMouseAtCenter(pluginEl, {}, managerWindow);
   await BrowserTestUtils.waitForEvent(managerWindow.document, "ViewChanged");
 
   is_element_hidden(enableButton, "part8: detail enable button should be hidden");
   is_element_hidden(disableButton, "part8: detail disable button should be hidden");
   is_element_visible(menu, "part8: detail state menu should be visible");
   is(menu.selectedItem, neverActivateItem, "part8: state menu should have 'Never Activate' selected");
 
   menu.selectedItem = alwaysActivateItem;
@@ -156,17 +154,16 @@ add_task(async function() {
     );
   });
 
   pluginEl = get_addon_element(managerWindow, testPluginId);
   pluginEl.parentNode.ensureElementIsVisible(pluginEl);
   menu = managerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "state-menulist");
   is(menu.disabled, true, "part12: state menu should be disabled");
 
-  details = managerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "details-btn");
-  EventUtils.synthesizeMouseAtCenter(details, {}, managerWindow);
+  EventUtils.synthesizeMouseAtCenter(pluginEl, {}, managerWindow);
   await BrowserTestUtils.waitForEvent(managerWindow.document, "ViewChanged");
 
   menu = managerWindow.document.getElementById("detail-state-menulist");
   is(menu.disabled, true, "part13: detail state menu should be disabled");
 
   managerWindow.close();
 });
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/browser/browser_bug562854.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-/**
- * Tests that double-click does not go to detail view if the target is a link or button.
- */
-
-function test() {
-  requestLongerTimeout(2);
-
-  waitForExplicitFinish();
-
-  var gProvider = new MockProvider();
-  gProvider.createAddons([{
-    id: "test1@tests.mozilla.org",
-    name: "Test add-on 1",
-    description: "foo",
-    operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_NONE,
-  }]);
-
-  run_next_test();
-}
-
-function end_test() {
-  finish();
-}
-
-function is_in_list(aManager, view) {
-  var doc = aManager.document;
-
-  is(doc.getElementById("categories").selectedItem.value, view, "Should be on the right category");
-  is(get_current_view(aManager).id, "list-view", "Should be on the right view");
-}
-
-function is_in_detail(aManager, view) {
-  var doc = aManager.document;
-
-  is(doc.getElementById("categories").selectedItem.value, view, "Should be on the right category");
-  is(get_current_view(aManager).id, "detail-view", "Should be on the right view");
-}
-
-// Check that double-click does something.
-add_test(async function() {
-  let aManager = await open_manager("addons://list/extension");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension");
-
-  var addon = get_addon_element(aManager, "test1@tests.mozilla.org");
-  addon.parentNode.ensureElementIsVisible(addon);
-  EventUtils.synthesizeMouseAtCenter(addon, { clickCount: 1 }, aManager);
-  EventUtils.synthesizeMouseAtCenter(addon, { clickCount: 2 }, aManager);
-
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_detail(aManager, "addons://list/extension");
-
-  close_manager(aManager, run_next_test);
-});
-
-// Check that double-click does nothing when over the disable button.
-add_test(async function() {
-  let aManager = await open_manager("addons://list/extension");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension");
-
-  var addon = get_addon_element(aManager, "test1@tests.mozilla.org");
-  addon.parentNode.ensureElementIsVisible(addon);
-  EventUtils.synthesizeMouseAtCenter(
-    aManager.document.getAnonymousElementByAttribute(addon, "anonid", "disable-btn"),
-    { clickCount: 1 },
-    aManager
-  );
-  // The disable button is replaced by the enable button when clicked on.
-  EventUtils.synthesizeMouseAtCenter(
-    aManager.document.getAnonymousElementByAttribute(addon, "anonid", "enable-btn"),
-    { clickCount: 2 },
-    aManager
-  );
-
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_list(aManager, "addons://list/extension");
-
-  close_manager(aManager, run_next_test);
-});
-
-// Check that double-click does nothing when over the undo button.
-add_test(async function() {
-  let aManager = await open_manager("addons://list/extension");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension");
-
-  var addon = get_addon_element(aManager, "test1@tests.mozilla.org");
-  addon.parentNode.ensureElementIsVisible(addon);
-  EventUtils.synthesizeMouseAtCenter(
-    aManager.document.getAnonymousElementByAttribute(addon, "anonid", "remove-btn"),
-    { clickCount: 1 },
-    aManager
-  );
-
-  // The undo button is removed when clicked on.
-  // We need to wait for the UI to catch up.
-  setTimeout(async function() {
-    var target = aManager.document.getAnonymousElementByAttribute(addon, "anonid", "undo-btn");
-    var rect = target.getBoundingClientRect();
-    var addonRect = addon.getBoundingClientRect();
-
-    EventUtils.synthesizeMouse(target, rect.width / 2, rect.height / 2, { clickCount: 1 }, aManager);
-    EventUtils.synthesizeMouse(addon,
-      rect.left - addonRect.left + rect.width / 2,
-      rect.top - addonRect.top + rect.height / 2,
-      { clickCount: 2 },
-      aManager
-    );
-
-    aManager = await wait_for_view_load(aManager);
-    info("Part 2");
-    is_in_list(aManager, "addons://list/extension");
-
-    close_manager(aManager, run_next_test);
-  }, 0);
-});
--- a/toolkit/mozapps/extensions/test/browser/browser_details.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_details.js
@@ -71,21 +71,16 @@ async function test() {
     description: "Short description",
     creator: { name: "Mozilla", url: null },
     type: "extension",
     iconURL: "chrome://foo/skin/icon.png",
     contributionURL: "http://foo.com",
     contributionAmount: null,
     updateDate: gDate,
     permissions: 0,
-    screenshots: [{
-      url: "chrome://branding/content/about.png",
-      width: 200,
-      height: 150,
-    }],
   }, {
     id: "addon3@tests.mozilla.org",
     name: "Test add-on 3",
     description: "Short description",
     creator: { name: "Mozilla", url: "http://www.mozilla.org" },
     type: "extension",
     sourceURI: Services.io.newURI("http://example.com/foo"),
     updateDate: gDate,
@@ -93,24 +88,16 @@ async function test() {
     reviewURL: "http://example.com/reviews",
     applyBackgroundUpdates: AddonManager.AUTOUPDATE_DISABLE,
     isActive: false,
     isCompatible: false,
     appDisabled: true,
     permissions: AddonManager.PERM_CAN_ENABLE |
                  AddonManager.PERM_CAN_DISABLE |
                  AddonManager.PERM_CAN_UPGRADE,
-    screenshots: [{
-      url: "http://example.com/screenshot",
-      width: 400,
-      height: 300,
-      thumbnailURL: "chrome://branding/content/icon64.png",
-      thumbnailWidth: 160,
-      thumbnailHeight: 120,
-    }],
   }, {
     id: "addon5@tests.mozilla.org",
     blocklistURL: "http://example.com/addon5@tests.mozilla.org",
     name: "Test add-on 5",
     isActive: false,
     blocklistState: Ci.nsIBlocklistService.STATE_BLOCKED,
     appDisabled: true,
   }, {
@@ -164,21 +151,16 @@ add_test(function() {
     is(get("detail-version").value, "2.2", "Version should be correct");
     is(get("detail-icon").src, "chrome://foo/skin/icon.png", "Icon should be correct");
 
     is_element_visible(get("detail-creator"), "Creator should not be hidden");
     is_element_visible(get("detail-creator")._creatorName, "Creator name should not be hidden");
     is(get("detail-creator")._creatorName.value, "Mozilla", "Creator should be correct");
     is_element_hidden(get("detail-creator")._creatorLink, "Creator link should be hidden");
 
-    is_element_visible(get("detail-screenshot-box"), "Screenshot should be visible");
-    is(get("detail-screenshot").src, "chrome://branding/content/about.png", "Should be showing the full sized screenshot");
-    is(get("detail-screenshot").width, 200, "Screenshot dimensions should be set");
-    is(get("detail-screenshot").height, 150, "Screenshot dimensions should be set");
-    is(get("detail-screenshot").hasAttribute("loading"), true, "Screenshot should have loading attribute");
     is(get("detail-desc").textContent, "Short description", "Description should be correct");
     is_element_hidden(get("detail-fulldesc"), "Full description should be hidden");
 
     is_element_visible(get("detail-contributions"), "Contributions section should be visible");
 
     is_element_visible(get("detail-dateUpdated"), "Update date should not be hidden");
     is(get("detail-dateUpdated").value, formatDate(gDate), "Update date should be correct");
 
@@ -195,42 +177,33 @@ add_test(function() {
     is_element_hidden(get("detail-uninstall-btn"), "Remove button should be hidden");
 
     is_element_hidden(get("detail-warning"), "Warning message should be hidden");
     is_element_hidden(get("detail-warning-link"), "Warning link should be hidden");
     is_element_hidden(get("detail-error"), "Error message should be hidden");
     is_element_hidden(get("detail-error-link"), "Error link should be hidden");
     is_element_hidden(get("detail-pending"), "Pending message should be hidden");
 
-    get("detail-screenshot").addEventListener("load", function() {
-      is(this.hasAttribute("loading"), false, "Screenshot should not have loading attribute");
-      run_next_test();
-    }, {once: true});
+    run_next_test();
   });
 });
 
 // Opens and tests the details view for add-on 3
 add_test(function() {
   open_details("addon3@tests.mozilla.org", "extension", function() {
     is(get("detail-name").textContent, "Test add-on 3", "Name should be correct");
     is_element_hidden(get("detail-version"), "Version should be hidden");
     is(get("detail-icon").src, "", "Icon should be correct");
 
     is_element_visible(get("detail-creator"), "Creator should not be hidden");
     is_element_hidden(get("detail-creator")._creatorName, "Creator name should be hidden");
     is_element_visible(get("detail-creator")._creatorLink, "Creator link should not be hidden");
     is(get("detail-creator")._creatorLink.value, "Mozilla", "Creator link should be correct");
     is(get("detail-creator")._creatorLink.href, "http://www.mozilla.org", "Creator link href should be correct");
 
-    is_element_visible(get("detail-screenshot-box"), "Screenshot should be visible");
-    is(get("detail-screenshot").src, "chrome://branding/content/icon64.png", "Should be showing the thumbnail");
-    is(get("detail-screenshot").width, 160, "Screenshot dimensions should be set");
-    is(get("detail-screenshot").height, 120, "Screenshot dimensions should be set");
-    is(get("detail-screenshot").hasAttribute("loading"), true, "Screenshot should have loading attribute");
-
     is_element_hidden(get("detail-contributions"), "Contributions section should be hidden");
 
     is_element_visible(get("detail-updates-row"), "Updates should not be hidden");
     is_element_visible(get("detail-dateUpdated"), "Update date should not be hidden");
     is(get("detail-dateUpdated").value, formatDate(gDate), "Update date should be correct");
 
     is_element_visible(get("detail-rating-row"), "Rating row should not be hidden");
     is_element_hidden(get("detail-rating"), "Rating should be hidden");
@@ -273,20 +246,17 @@ add_test(function() {
 
     is_element_visible(get("detail-warning"), "Warning message should be visible");
     is(get("detail-warning").textContent, "Test add-on 3 is incompatible with " + gApp + " " + gVersion + ".", "Warning message should be correct");
     is_element_hidden(get("detail-warning-link"), "Warning link should be hidden");
     is_element_hidden(get("detail-error"), "Error message should be hidden");
     is_element_hidden(get("detail-error-link"), "Error link should be hidden");
     is_element_hidden(get("detail-pending"), "Pending message should be hidden");
 
-    get("detail-screenshot").addEventListener("load", function() {
-      is(this.hasAttribute("loading"), false, "Screenshot should not have loading attribute");
-      run_next_test();
-    }, {once: true});
+    run_next_test();
   });
 });
 
 // Opens and tests the details view for add-on 5
 add_test(function() {
   open_details("addon5@tests.mozilla.org", "extension", async function() {
     await TestUtils.waitForCondition(() => !BrowserTestUtils.is_hidden(get("detail-error-link")));
     is(get("detail-name").textContent, "Test add-on 5", "Name should be correct");
@@ -552,17 +522,16 @@ add_test(function() {
       operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_NONE,
     }]);
 
     is(get("detail-name").textContent, "Test add-on replacement", "Name should be correct");
     is_element_visible(get("detail-version"), "Version should not be hidden");
     is(get("detail-version").value, "2.5", "Version should be correct");
     is(get("detail-icon").src, "chrome://foo/skin/icon264.png", "Icon should be correct");
     is_element_hidden(get("detail-creator"), "Creator should be hidden");
-    is_element_hidden(get("detail-screenshot-box"), "Screenshot should be hidden");
     is(get("detail-desc").textContent, "Short description replacement", "Description should be correct");
     is(get("detail-fulldesc").textContent, "Longer description replacement", "Full description should be correct");
 
     is_element_hidden(get("detail-contributions"), "Contributions section should be hidden");
 
     is_element_hidden(get("detail-dateUpdated"), "Update date should be hidden");
 
     is_element_visible(get("detail-rating-row"), "Rating row should not be hidden");
--- a/toolkit/mozapps/extensions/test/browser/browser_legacy_pre57.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_legacy_pre57.js
@@ -58,18 +58,17 @@ add_task(async function() {
     if (isLegacy) {
       is_element_visible(badge, `Legacy badge is visible for ${name}`);
       is(badge.href, INFO_URL, "Legacy badge link is correct");
     } else {
       is_element_hidden(badge, `Legacy badge is hidden for ${name}`);
     }
 
     // Click down to the details page.
-    let detailsButton = document.getAnonymousElementByAttribute(item, "anonid", "details-btn");
-    EventUtils.synthesizeMouseAtCenter(detailsButton, {}, mgrWin);
+    EventUtils.synthesizeMouseAtCenter(item, {}, mgrWin);
     await new Promise(resolve => wait_for_view_load(mgrWin, resolve));
 
     // And check the badge
     let elements = document.getElementsByClassName("legacy-warning");
     is(elements.length, 1, "Found the legacy-warning element");
     badge = elements[0];
 
     if (isLegacy) {
--- a/toolkit/mozapps/extensions/test/browser/browser_list.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_list.js
@@ -380,18 +380,16 @@ add_task(async function() {
   is(Object.keys(items).length, EXPECTED_ADDONS, "Should be the right number of add-ons installed");
 
   let addon = items["Test add-on replacement"];
   addon.parentNode.ensureElementIsVisible(addon);
   let { name, version } = await get_tooltip_info(addon);
   is(get_node(addon, "name").value, "Test add-on replacement", "Name should be correct");
   is(name, "Test add-on replacement", "Tooltip name should be correct");
   is(version, "2.0", "Tooltip version should be correct");
-  is_element_visible(get_node(addon, "description"), "Description should be visible");
-  is(get_node(addon, "description").value, "A test add-on with a new description", "Description should be correct");
   is_element_hidden(get_class_node(addon, "disabled-postfix"), "Disabled postfix should be hidden");
   is_element_hidden(get_class_node(addon, "update-postfix"), "Update postfix should be hidden");
   is(get_node(addon, "date-updated").value, formatDate(gDate), "Update date should be correct");
 
   is_element_hidden(get_node(addon, "preferences-btn"), "Preferences button should be hidden");
   is_element_hidden(get_node(addon, "enable-btn"), "Enable button should be hidden");
   is_element_visible(get_node(addon, "disable-btn"), "Disable button should be visible");
   is_element_visible(get_node(addon, "remove-btn"), "Remove button should be visible");
@@ -419,37 +417,33 @@ add_task(async function() {
   // Ignore the OSX full keyboard access setting
   Services.prefs.setBoolPref("accessibility.tabfocus_applies_to_xul", false);
 
   let items = get_test_items();
   is(Object.keys(items).length, EXPECTED_ADDONS, "Should be the right number of add-ons installed");
 
   let addon = items["Test add-on 6"];
   addon.parentNode.ensureElementIsVisible(addon);
-  EventUtils.synthesizeMouseAtCenter(addon, { }, gManagerWindow);
+  addon.parentNode.focus();
   is(Services.focus.focusedElement, addon.parentNode, "Focus should have moved to the list");
 
   EventUtils.synthesizeKey("VK_TAB", { }, gManagerWindow);
-  is(Services.focus.focusedElement, get_node(addon, "details-btn"), "Focus should have moved to the more button");
-
-  EventUtils.synthesizeKey("VK_TAB", { }, gManagerWindow);
   is(Services.focus.focusedElement, get_node(addon, "disable-btn"), "Focus should have moved to the disable button");
 
   EventUtils.synthesizeKey("VK_TAB", { }, gManagerWindow);
   is(Services.focus.focusedElement, get_node(addon, "remove-btn"), "Focus should have moved to the remove button");
 
   EventUtils.synthesizeKey("VK_TAB", { }, gManagerWindow);
   ok(!is_node_in_list(Services.focus.focusedElement), "Focus should be outside the list");
 
   EventUtils.synthesizeKey("VK_TAB", { shiftKey: true }, gManagerWindow);
   is(Services.focus.focusedElement, get_node(addon, "remove-btn"), "Focus should have moved to the remove button");
 
   EventUtils.synthesizeKey("VK_TAB", { shiftKey: true }, gManagerWindow);
-  EventUtils.synthesizeKey("VK_TAB", { shiftKey: true }, gManagerWindow);
-  is(Services.focus.focusedElement, get_node(addon, "details-btn"), "Focus should have moved to the more button");
+  is(Services.focus.focusedElement, get_node(addon, "disable-btn"), "Focus should have moved to the disable button");
 
   EventUtils.synthesizeKey("VK_TAB", { shiftKey: true }, gManagerWindow);
   is(Services.focus.focusedElement, addon.parentNode, "Focus should have moved to the list");
 
   EventUtils.synthesizeKey("VK_TAB", { shiftKey: true }, gManagerWindow);
   ok(!is_node_in_list(Services.focus.focusedElement), "Focus should be outside the list");
 
   try {
--- a/toolkit/mozapps/extensions/test/browser/browser_plugin_enabled_state_locked.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_plugin_enabled_state_locked.js
@@ -62,19 +62,17 @@ function checkStateMenu(locked) {
   is_element_visible(selectedMenuItem, "State menu's selected item should be visible.");
 }
 
 function checkStateMenuDetail(locked) {
   Assert.equal(Services.prefs.prefIsLocked(getTestPluginPref()), locked,
     "Preference should be " + (locked === true ? "" : "un") + "locked.");
 
   // open details menu
-  let details = gManagerWindow.document.getAnonymousElementByAttribute(gPluginElement, "anonid", "details-btn");
-  is_element_visible(details, "Details link should be visible.");
-  EventUtils.synthesizeMouseAtCenter(details, {}, gManagerWindow);
+  EventUtils.synthesizeMouseAtCenter(gPluginElement, {}, gManagerWindow);
 
   return new Promise(async resolve => {
     await wait_for_view_load(gManagerWindow);
     let menuList = gManagerWindow.document.getElementById("detail-state-menulist");
     is_element_visible(menuList, "Details state menu should be visible.");
     Assert.equal(menuList.disabled, locked,
       "Details state menu enabled state should be correct.");
     resolve();
--- a/toolkit/mozapps/extensions/test/browser/browser_pluginprefs.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_pluginprefs.js
@@ -34,18 +34,17 @@ add_test(async function() {
   let testPlugin = await AddonManager.getAddonByID(testPluginId);
   let pluginEl = get_addon_element(gManagerWindow, testPluginId);
   is(pluginEl.mAddon.optionsType, AddonManager.OPTIONS_TYPE_INLINE_BROWSER, "Options should be inline type");
   pluginEl.parentNode.ensureElementIsVisible(pluginEl);
 
   let button = gManagerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "preferences-btn");
   is_element_visible(button, "Preferences button should be visible");
 
-  button = gManagerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "details-btn");
-  EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
+  EventUtils.synthesizeMouseAtCenter(pluginEl, { clickCount: 1 }, gManagerWindow);
 
   Services.obs.addObserver(async function observer(subject, topic, data) {
     Services.obs.removeObserver(observer, topic);
 
     // Wait for PluginProvider to do its stuff.
     await new Promise(executeSoon);
 
     let doc = gManagerWindow.document.getElementById("addon-options").contentDocument;
--- a/toolkit/mozapps/extensions/test/browser/browser_uninstalling.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_uninstalling.js
@@ -235,18 +235,17 @@ add_test(async function() {
   let aAddon = await AddonManager.getAddonByID(ID);
   ok(aAddon.isActive, "Add-on should be active");
   ok(!(aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL), "Add-on should not require a restart to uninstall");
   ok(!(aAddon.pendingOperations & AddonManager.PENDING_UNINSTALL), "Add-on should not be pending uninstall");
 
   var item = get_item_in_list(ID, list);
   isnot(item, null, "Should have found the add-on in the list");
 
-  EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, gManagerWindow);
-  EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow);
+  item.click();
   await wait_for_view_load(gManagerWindow);
 
   // Test the uninstall.
   return test_uninstall_details(aAddon, ID);
 });
 
 // Tests that uninstalling a restartless add-on from directly loading the
 // details view switches back to the list view and can be undone
@@ -282,18 +281,17 @@ add_test(async function() {
 
   ok(!aAddon.isActive, "Add-on should be inactive");
   ok(!(aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL), "Add-on should not require a restart to uninstall");
   ok(!(aAddon.pendingOperations & AddonManager.PENDING_UNINSTALL), "Add-on should not be pending uninstall");
 
   var item = get_item_in_list(ID, list);
   isnot(item, null, "Should have found the add-on in the list");
 
-  EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, gManagerWindow);
-  EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow);
+  item.click();
   await wait_for_view_load(gManagerWindow);
   is(get_current_view(gManagerWindow).id, "detail-view", "Should be in the detail view");
 
   var button = gDocument.getElementById("detail-uninstall-btn");
   isnot(button, null, "Should have a remove button");
   ok(!button.disabled, "Button should not be disabled");
 
   EventUtils.synthesizeMouseAtCenter(button, { }, gManagerWindow);
--- a/toolkit/themes/shared/extensions/extensions.inc.css
+++ b/toolkit/themes/shared/extensions/extensions.inc.css
@@ -9,18 +9,18 @@
   padding: 0;
 }
 
 #nav-header {
   min-height: 39px;
 }
 
 .view-pane > .list > scrollbox {
-  padding-right: 48px;
-  padding-left: 48px;
+  padding-right: 24px;
+  padding-left: 24px;
 }
 
 
 /*** global warnings ***/
 
 .global-warning-container {
   overflow-x: hidden;
 }
@@ -221,34 +221,31 @@ button.warning {
 }
 #category-recentUpdates > .category-icon {
   list-style-image: url("chrome://mozapps/skin/extensions/category-recent.svg");
 }
 
 
 /*** header ***/
 
-#header {
-  margin-top: 20px;
-  margin-bottom: 20px;
-  margin-right: 48px;
-  margin-left: 48px;
+#header-inner {
+  margin: 20px 4px 30px;
+  width: 692px;
 }
 
+#header-search {
+  margin-top: 0;
+}:
+
 @media (max-width: 600px) {
   #header-search {
     width: 12em;
   }
 }
 
-.view-header {
-  margin: 0 48px;
-  border-bottom: 1px solid var(--in-content-box-border-color);
-}
-
 #header-utils-btn {
   height: 30px;
   line-height: 20px;
   border-color: var(--in-content-box-border-color);
   background-color: var(--in-content-page-background);
   padding-right: 10px;
   padding-left: 10px;
 }
@@ -318,63 +315,41 @@ button.warning {
 
 .list {
   -moz-appearance: none;
   margin: 0;
   border-width: 0 !important;
   background-color: transparent;
 }
 
-.list > scrollbox > .scrollbox-innerbox {
-  border: 1px dotted transparent;
-}
-
-.list:-moz-focusring > scrollbox > .scrollbox-innerbox {
-  border-color: var(--in-content-border-focus);
-}
-
 richlistbox.list > richlistitem.addon {
   color: var(--in-content-text-color);
-  border-bottom: 1px solid var(--in-content-box-border-color);
-  padding: 5px;
   background-origin: border-box;
 }
 
-.addon:not(:only-child):last-child {
-  border-bottom-width: 0;
-}
-
-.details {
-  cursor: pointer;
-  margin: 0;
-  margin-inline-start: 10px;
-}
-
-.icon-container {
-  width: 48px;
-  height: 48px;
-  margin: 3px 7px;
-  -moz-box-align: center;
-  -moz-box-pack: center;
-}
-
 .icon {
   list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric.svg");
-  max-width: 32px;
-  max-height: 32px;
+  max-width: 24px;
+  max-height: 24px;
+  margin-inline-end: 16px;
 }
 
 .content-inner-container {
   margin-inline-end: 5px;
 }
 
 .addon[active="false"] .icon {
   filter: grayscale(1);
 }
 
+.addon label,
+.addon {
+  cursor: pointer;
+}
+
 .addon-view[type="theme"] .icon {
   list-style-image: url("chrome://mozapps/skin/extensions/themeGeneric.svg");
 }
 
 .addon-view[type="locale"] .icon {
   list-style-image: url("chrome://mozapps/skin/extensions/localeGeneric.svg");
 }
 
@@ -386,18 +361,17 @@ richlistbox.list > richlistitem.addon {
   list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.svg");
 }
 
 .addon-view[type="experiment"] .icon {
   list-style-image: url("chrome://mozapps/skin/extensions/experimentGeneric.svg");
 }
 
 .name-container {
-  font-size: 1.3rem;
-  font-weight: bold;
+  font-weight: 600;
   -moz-box-align: end;
   -moz-box-flex: 1;
 }
 
 .legacy-warning {
   background-color: #FFE900;
   color: #3E2800;
   padding: 4px 5px 3px;
@@ -420,17 +394,17 @@ richlistbox.list > richlistitem.addon {
   color: #FFF;
 }
 
 #detail-view .legacy-warning {
   margin-top: 0.78rem;
 }
 
 .creator {
-  font-weight: bold;
+  font-size: 1.2rem;
 }
 
 .description-container {
   margin-inline-start: 6px;
   -moz-box-align: center;
   font-size: 1.25rem;
 }
 
@@ -472,18 +446,17 @@ richlistbox.list > richlistitem.addon {
   -moz-box-pack: center;
 }
 
 .relnotes-toggle-container,
 .icon-outer-container {
   -moz-box-pack: start;
 }
 
-.status-container,
-.control-container {
+.status-container {
   -moz-box-pack: end;
 }
 
 .addon-view .warning {
   color: #d8b826;
 }
 
 .addon-view .error {
@@ -554,20 +527,25 @@ richlistbox.list > richlistitem.addon {
 }
 
 .addon-view[pending="disable"],
 .addon-view[pending="uninstall"] {
   --view-highlight-color: #F2F2F2;
 }
 
 .list > .addon[selected] {
-  background-color: var(--in-content-page-background);
-  color: var(--in-content-page-color);
-  padding-inline-start: 1px; /* compensate the 4px border */
-  border-inline-start: solid 4px var(--in-content-border-focus);
+  background-color: var(--in-content-box-background);
+}
+
+.list:focus > .addon[selected] {
+  box-shadow: var(--card-shadow-focus);
+}
+
+.list > .addon {
+  margin: 8px;
 }
 
 #addon-list .addon[active="false"] > .content-container > .content-inner-container {
   color: #999;
 }
 
 #addon-list .addon[active="false"][selected] > .content-container > .content-inner-container {
   color: #777;
@@ -591,66 +569,67 @@ richlistbox.list > richlistitem.addon {
 .addon[status="uninstalled"][selected] {
   background-color: transparent;
 }
 
 
 /*** detail view ***/
 
 #detail-view > .scrollbox-innerbox {
-  margin-right: 48px;
-  margin-left: 48px;
+  margin: 32px;
 }
 
 #detail-view .loading {
   opacity: 0;
 }
 
 #detail-view[loading-extended] .loading {
   opacity: 1;
   transition-property: opacity;
   transition-duration: 1s;
 }
 
 .detail-view-container {
-  padding-inline-end: 2em;
-  padding-bottom: 2em;
-  font-size: 1.25rem;
-  color: #333;
+  width: 664px;
 }
 
 #detail-notifications {
   margin-top: 1em;
   margin-bottom: 2em;
 }
 
+#detail-view:not([notification="warning"]):not([notification="error"]):not([pending]) #detail-notifications {
+  display: none;
+}
+
 #detail-notifications .warning,
 #detail-notifications .pending,
 #detail-notifications .error {
   margin-inline-start: 0;
 }
 
 #detail-icon-container {
   width: 64px;
-  margin-inline-end: 10px;
   margin-top: 6px;
 }
 
 #detail-icon {
-  max-width: 64px;
-  max-height: 64px;
+  max-width: 32px;
+  max-height: 32px;
 }
 
-#detail-summary {
-  margin-bottom: 2em;
+.name-container > label,
+#detail-creator,
+#detail-name-container > label {
+  margin-inline-start: 0;
 }
 
-#detail-name-container {
-  font-size: 2.5rem;
-  font-weight: normal;
+#detail-controls {
+  margin-inline-start: -4px;
+  margin-inline-end: -4px;
 }
 
 #detail-screenshot-box {
   margin-inline-end: 2em;
   background-image: linear-gradient(rgba(255,255,255,.5), transparent);
   background-color: white;
   box-shadow: 0 1px 2px #666;
   border-radius: 2px;
@@ -674,21 +653,37 @@ richlistbox.list > richlistitem.addon {
   }
 }
 
 #detail-screenshot[loading="error"] {
   background-image: url("chrome://global/skin/media/error.png");
 }
 
 #detail-desc-container {
-  margin-bottom: 2em;
+  line-height: 1.3;
+  margin: 1em 0;
+}
+
+#detail-controls > button {
+  margin-bottom: 0;
+}
+
+.addon.card {
+  max-width: 664px;
+  /* The .addon-control element on the end has 4px of margin, remove it
+   * from the padding to stay balanced. */
+  padding-inline-end: 12px;
+}
+
+.addon-detail.card:hover {
+  box-shadow: none;
 }
 
 #detail-desc, #detail-fulldesc {
-  margin-inline-start: 6px;
+  margin-inline-start: 0;
   /* This is necessary to fix layout issues with multi-line descriptions, see
      bug 592712*/
   outline: solid transparent;
   white-space: pre-wrap;
   min-width: 10em;
 }
 
 #detail-fulldesc {
@@ -752,20 +747,16 @@ richlistbox.list > richlistitem.addon {
 .detail-row-complex {
   border-top: 1px solid var(--in-content-box-border-color);
   -moz-box-align: center;
   min-height: 35px;
   line-height: 20px;
   text-shadow: 0 1px 1px #fefffe;
 }
 
-#detail-controls {
-  margin-bottom: 1em;
-}
-
 .inline-options-browser {
   margin-top: 2em;
 }
 
 .preferences-alignment {
   min-height: 30px;
   -moz-box-align: center;
 }
@@ -919,16 +910,25 @@ richlistbox.list > richlistitem.addon {
 
 
 /*** buttons ***/
 
 .addon-control[disabled="true"]:not(.no-auto-hide) {
   display: none;
 }
 
+.addon-control {
+  cursor: default;
+  margin-top: 0;
+  margin-bottom: 0;
+  min-height: auto;
+  min-width: auto;
+  padding: 2px 4px;
+}
+
 .no-auto-hide .addon-control {
   display: block !important;
 }
 
 button.button-link {
   -moz-appearance: none;
   background: transparent;
   border: none;
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -35,23 +35,34 @@
   --in-content-link-color-active: #003eaa;
   --in-content-link-color-visited: #0a8dff;
   --in-content-primary-button-background: #0a84ff;
   --in-content-primary-button-background-hover: #0060df;
   --in-content-primary-button-background-active: #003EAA;
   --in-content-table-background: #ebebeb;
   --in-content-table-border-dark-color: #d1d1d1;
   --in-content-table-header-background: #0a84ff;
+
+  --blue-50: #0a84ff;
+  --blue-50-a30: rgba(10, 132, 255, 0.3);
   --grey-20: #ededf0;
+  --grey-30: #d7d7db;
+  --grey-60: #4a4a4f;
   --grey-90: #0c0c0d;
   --grey-90-a10: rgba(12, 12, 13, 0.1);
   --grey-90-a20: rgba(12, 12, 13, 0.2);
   --grey-90-a30: rgba(12, 12, 13, 0.3);
   --yellow-50: #ffe900;
   --yellow-90: #3e2800;
+
+  --shadow-10: 0 1px 4px var(--grey-90-a10);
+  --card-shadow: var(--shadow-10);
+  --card-outline-color: var(--grey-30);
+  --card-shadow-hover: var(--card-shadow), 0 0 0 5px var(--card-outline-color);
+  --card-shadow-focus: 0 0 0 2px var(--blue-50), 0 0 0 6px var(--blue-50-a30);
 }
 
 html|html,
 xul|page,
 xul|window {
   font: message-box;
   -moz-appearance: none;
   background-color: var(--in-content-page-background);
@@ -842,25 +853,26 @@ xul|treechildren::-moz-tree-image(select
   color: var(--yellow-90);
 }
 
 .message-bar-warning > .message-bar-icon {
   list-style-image: url("chrome://browser/skin/warning.svg");
 }
 
 .card {
-  background: #fff;
-  box-shadow: 0 0 1px rgba(0, 0, 0, 0.12);
+  background: var(--in-content-box-background);
+  border-radius: 4px;
+  box-shadow: var(--card-shadow);
   margin: 0 0 8px;
   padding: 16px;
   transition: box-shadow 150ms;
 }
 
 .card:hover {
-  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.24);
+  box-shadow: var(--card-shadow-hover);
 }
 
 .sidebar-footer-button {
   padding: 1px; /* Adding padding around help label in order to make entire keyboard focusing outline visible */
 }
 
 .sidebar-footer-button > .text-link {
   -moz-box-flex: 1;