Bug 1592324 - Add button to extensions and themes page. r=mstriemer
authorjayati <gaurijove@gmail.com>
Thu, 02 Apr 2020 16:36:39 +0000
changeset 521887 8f4d397702a005b336144898dd691d660a260b4a
parent 521886 fe77998cc746e83e51b94292400058c8988a28ff
child 521888 dc1a253fc94b4dc6af8744602c8820b9ee350de0
push id111885
push usermstriemer@mozilla.com
push dateThu, 02 Apr 2020 16:37:12 +0000
treeherderautoland@8f4d397702a0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstriemer
bugs1592324
milestone76.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 1592324 - Add button to extensions and themes page. r=mstriemer Differential Revision: https://phabricator.services.mozilla.com/D66371
toolkit/mozapps/extensions/content/aboutaddons.css
toolkit/mozapps/extensions/content/aboutaddons.html
toolkit/mozapps/extensions/content/aboutaddons.js
toolkit/mozapps/extensions/test/browser/browser_html_list_view_recommendations.js
--- a/toolkit/mozapps/extensions/content/aboutaddons.css
+++ b/toolkit/mozapps/extensions/content/aboutaddons.css
@@ -427,16 +427,20 @@ recommended-addon-card .addon-descriptio
 .view-footer-item {
   margin-top: 30px;
 }
 
 .privacy-policy-link {
   font-size: small;
 }
 
+.theme-recommendation {
+  text-align: start;
+}
+
 addon-details {
   color: var(--in-content-deemphasized-text);
 }
 
 .addon-detail-description {
   margin: 16px 0;
 }
 
--- a/toolkit/mozapps/extensions/content/aboutaddons.html
+++ b/toolkit/mozapps/extensions/content/aboutaddons.html
@@ -327,29 +327,32 @@
       <recommended-addon-list></recommended-addon-list>
       <footer is="recommended-footer" class="view-footer"></footer>
     </template>
 
     <template name="recommended-extensions-section">
       <h2 data-l10n-id="recommended-extensions-heading" class="header-name recommended-heading"></h2>
       <taar-notice></taar-notice>
       <recommended-addon-list type="extension" hide-installed></recommended-addon-list>
-      <footer is="recommended-footer" class="view-footer hide-amo-link"></footer>
+      <footer is="recommended-footer" class="view-footer"></footer>
+    </template>
+
+    <template name="recommended-themes-footer">
+      <p data-l10n-id="recommended-theme-1" class="theme-recommendation">
+          <a data-l10n-name="link" target="_blank"></a>
+      </p>
+      <div class="amo-link-container view-footer-item">
+        <button class="primary" action="open-amo" data-l10n-id="find-more-addons"></button>
+      </div>
     </template>
 
     <template name="recommended-themes-section">
       <h2 data-l10n-id="recommended-themes-heading" class="header-name recommended-heading"></h2>
       <recommended-addon-list type="theme" hide-installed></recommended-addon-list>
-      <footer>
-        <div>
-          <p data-l10n-id="recommended-theme-1" class="theme-recommendation">
-            <a data-l10n-name="link" target="_blank"></a>
-          </p>
-        </div>
-      </footer>
+      <footer is="recommended-themes-footer" class="view-footer"></footer>
     </template>
 
     <template id="shortcut-view">
       <div class="error-message">
         <img class="error-message-icon" src="chrome://global/skin/arrow/panelarrow-vertical.svg">
         <div class="error-message-label"></div>
       </div>
       <message-bar-stack id="duplicate-warning-messages" reverse max-message-bar-count="5">
--- a/toolkit/mozapps/extensions/content/aboutaddons.js
+++ b/toolkit/mozapps/extensions/content/aboutaddons.js
@@ -4152,37 +4152,54 @@ class RecommendedFooter extends HTMLElem
       this.addEventListener("click", this);
     }
   }
 
   handleEvent(event) {
     let action = event.target.getAttribute("action");
     switch (action) {
       case "open-amo":
-        // The element is a button but opens a URL, so record as link.
-        AMTelemetry.recordLinkEvent({
-          object: "aboutAddons",
-          value: "discomore",
-          extra: {
-            view: "discover",
-          },
-        });
-        let amoUrl = Services.urlFormatter.formatURLPref(
-          "extensions.getAddons.link.url"
-        );
-        amoUrl = formatAmoUrl("find-more-link-bottom", amoUrl);
-        windowRoot.ownerGlobal.openTrustedLinkIn(amoUrl, "tab");
+        openAmoInTab(this);
         break;
     }
   }
 }
 customElements.define("recommended-footer", RecommendedFooter, {
   extends: "footer",
 });
 
+class RecommendedThemesFooter extends HTMLElement {
+  connectedCallback() {
+    if (this.childElementCount == 0) {
+      this.appendChild(importTemplate("recommended-themes-footer"));
+      let themeRecommendationRow = this.querySelector(".theme-recommendation");
+      let themeRecommendationUrl = Services.prefs.getStringPref(
+        PREF_THEME_RECOMMENDATION_URL
+      );
+      if (themeRecommendationUrl) {
+        themeRecommendationRow.querySelector("a").href = themeRecommendationUrl;
+      }
+      themeRecommendationRow.hidden = !themeRecommendationUrl;
+      this.addEventListener("click", this);
+    }
+  }
+
+  handleEvent(event) {
+    let action = event.target.getAttribute("action");
+    switch (action) {
+      case "open-amo":
+        openAmoInTab(this);
+        break;
+    }
+  }
+}
+customElements.define("recommended-themes-footer", RecommendedThemesFooter, {
+  extends: "footer",
+});
+
 /**
  * This element will handle showing recommendations with a
  * <recommended-addon-list> and a <footer>. The footer will be hidden until
  * the <recommended-addon-list> is done making its request so the footer
  * doesn't move around.
  *
  * Subclass this element to use it and define a `template` property to pull
  * the template from. Expected template:
@@ -4219,62 +4236,26 @@ class RecommendedSection extends HTMLEle
     });
   }
 }
 
 class RecommendedExtensionsSection extends RecommendedSection {
   get template() {
     return "recommended-extensions-section";
   }
-
-  setAmoButtonVisibility() {
-    // Show the AMO button if there are no cards, this is mostly for the case
-    // where the user has no extensions and is offline.
-    let cards = Array.from(this.list.children);
-    let cardVisible = cards.some(card => !card.hidden);
-    this.footer.classList.toggle("hide-amo-link", cardVisible);
-  }
-
-  render() {
-    super.render();
-    let { list } = this;
-    list.cardsReady.then(() => this.setAmoButtonVisibility());
-    list.addEventListener("card-hidden", this);
-    list.addEventListener("card-shown", this);
-  }
-
-  handleEvent(e) {
-    if (e.type == "card-hidden") {
-      this.setAmoButtonVisibility();
-    } else if (e.type == "card-shown") {
-      this.footer.classList.add("hide-amo-link");
-    }
-  }
 }
 customElements.define(
   "recommended-extensions-section",
   RecommendedExtensionsSection
 );
 
 class RecommendedThemesSection extends RecommendedSection {
   get template() {
     return "recommended-themes-section";
   }
-
-  render() {
-    super.render();
-    let themeRecommendationRow = this.querySelector(".theme-recommendation");
-    let themeRecommendationUrl = Services.prefs.getStringPref(
-      PREF_THEME_RECOMMENDATION_URL
-    );
-    if (themeRecommendationUrl) {
-      themeRecommendationRow.querySelector("a").href = themeRecommendationUrl;
-    }
-    themeRecommendationRow.hidden = !themeRecommendationUrl;
-  }
 }
 customElements.define("recommended-themes-section", RecommendedThemesSection);
 
 class DiscoveryPane extends RecommendedSection {
   get template() {
     return "discopane";
   }
 }
@@ -4438,16 +4419,35 @@ let categoriesBox = null;
  */
 function getTelemetryViewName(el) {
   let root =
     el.closest("[current-view]") || document.querySelector("[current-view]");
   return root.getAttribute("current-view");
 }
 
 /**
+ * @param {Element} el The button element.
+ */
+function openAmoInTab(el) {
+  // The element is a button but opens a URL, so record as link.
+  AMTelemetry.recordLinkEvent({
+    object: "aboutAddons",
+    value: "discomore",
+    extra: {
+      view: getTelemetryViewName(el),
+    },
+  });
+  let amoUrl = Services.urlFormatter.formatURLPref(
+    "extensions.getAddons.link.url"
+  );
+  amoUrl = formatAmoUrl("find-more-link-bottom", amoUrl);
+  windowRoot.ownerGlobal.openTrustedLinkIn(amoUrl, "tab");
+}
+
+/**
  * Helper for saving and restoring the scroll offsets when a previously loaded
  * view is accessed again.
  */
 var ScrollOffsets = {
   _key: null,
   _offsets: new Map(),
   canRestore: true,
 
--- a/toolkit/mozapps/extensions/test/browser/browser_html_list_view_recommendations.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_html_list_view_recommendations.js
@@ -46,41 +46,34 @@ add_task(async function setup() {
         "extensions.recommendations.themeRecommendationUrl",
         "https://example.com/theme",
       ],
     ],
   });
 });
 
 function checkExtraContents(doc, type, opts = {}) {
-  let {
-    showAmoButton = false,
-    showThemeRecommendationFooter = type === "theme",
-  } = opts;
+  let { showThemeRecommendationFooter = type === "theme" } = opts;
   let footer = doc.querySelector("footer");
   let amoButton = footer.querySelector('[action="open-amo"]');
   let privacyPolicyLink = footer.querySelector(".privacy-policy-link");
   let themeRecommendationFooter = footer.querySelector(".theme-recommendation");
   let themeRecommendationLink =
     themeRecommendationFooter && themeRecommendationFooter.querySelector("a");
   let taarNotice = doc.querySelector("taar-notice");
 
   is_element_visible(footer, "The footer is visible");
 
   if (type == "extension") {
     ok(taarNotice, "There is a TAAR notice");
-    if (showAmoButton) {
-      is_element_visible(amoButton, "The AMO button is shown");
-    } else {
-      is_element_hidden(amoButton, "The AMO button is hidden");
-    }
+    is_element_visible(amoButton, "The AMO button is shown");
     is_element_visible(privacyPolicyLink, "The privacy policy is visible");
   } else if (type == "theme") {
     ok(!taarNotice, "There is no TAAR notice");
-    ok(!amoButton, "There is no AMO button");
+    ok(amoButton, "AMO button is shown");
     ok(!privacyPolicyLink, "There is no privacy policy");
   } else {
     throw new Error(`Unknown type ${type}`);
   }
 
   if (showThemeRecommendationFooter) {
     is_element_visible(
       themeRecommendationFooter,
@@ -227,36 +220,36 @@ add_task(async function testInstallAllEx
   let type = "extension";
   let win = await loadInitialView(type);
   let doc = win.document;
 
   // Wait for the list to render, rendering is tested with the discovery pane.
   let recommendedList = doc.querySelector("recommended-addon-list");
   await recommendedList.cardsReady;
 
-  // Find more button is hidden.
+  // Find more button is shown.
   checkExtraContents(doc, type);
 
   let cards = Array.from(doc.querySelectorAll("recommended-addon-card"));
   is(cards.length, 3, "We found some cards");
 
   let extensions = await Promise.all(
     cards.map(card => installAddon({ card, recommendedList }))
   );
 
-  // The find more on AMO button is now shown.
-  checkExtraContents(doc, type, { showAmoButton: true });
+  // The find more on AMO button is shown.
+  checkExtraContents(doc, type);
 
-  // Uninstall one of the extensions, the button should be hidden again.
+  // Uninstall one of the extensions, the button should still be shown.
   let extension = extensions.pop();
   let shown = BrowserTestUtils.waitForEvent(recommendedList, "card-shown");
   await extension.unload();
   await shown;
 
-  // The find more on AMO button is now hidden.
+  // The find more on AMO button is shown.
   checkExtraContents(doc, type);
 
   await Promise.all(extensions.map(extension => extension.unload()));
   await closeView(win);
 });
 
 add_task(async function testError() {
   await SpecialPowers.pushPrefEnv({
@@ -265,17 +258,17 @@ add_task(async function testError() {
 
   let win = await loadInitialView("extension");
   let doc = win.document;
 
   // Wait for the list to render, rendering is tested with the discovery pane.
   let recommendedList = doc.querySelector("recommended-addon-list");
   await recommendedList.cardsReady;
 
-  checkExtraContents(doc, "extension", { showAmoButton: true });
+  checkExtraContents(doc, "extension");
 
   await closeView(win);
   await SpecialPowers.popPrefEnv();
 });
 
 add_task(async function testThemesNoRecommendationUrl() {
   await SpecialPowers.pushPrefEnv({
     set: [["extensions.recommendations.themeRecommendationUrl", ""]],