Bug 1534254 - The CFR doorhanger's animation cannot be resumed after is paused r=k88hudson
authorRicky Rosario <rickyrosario@gmail.com>
Tue, 12 Mar 2019 19:02:44 +0000
changeset 463731 da793f0fe362720f58903a2ea16d674e50feaa2b
parent 463730 4c52efb1430f4b71a272998add34b63e53b00210
child 463732 44fee8919949e9b0411ff723443a7b3ff6ae8b86
push id80330
push userrrosario@mozilla.com
push dateTue, 12 Mar 2019 21:37:52 +0000
treeherderautoland@da793f0fe362 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersk88hudson
bugs1534254
milestone67.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 1534254 - The CFR doorhanger's animation cannot be resumed after is paused r=k88hudson MozReview-Commit-ID: EXcdve68ijX Differential Revision: https://phabricator.services.mozilla.com/D23007
browser/components/newtab/data/content/assets/glyph-play-12.svg
browser/components/newtab/lib/CFRPageActions.jsm
browser/components/newtab/test/unit/asrouter/CFRPageActions.test.js
browser/themes/shared/browser.inc.css
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/data/content/assets/glyph-play-12.svg
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><path fill="context-fill" d="M2.128.13A.968.968 0 0 0 .676.964v10.068a.968.968 0 0 0 1.452.838l8.712-5.034a.968.968 0 0 0 0-1.676L2.128.13z"/></svg>
--- a/browser/components/newtab/lib/CFRPageActions.jsm
+++ b/browser/components/newtab/lib/CFRPageActions.jsm
@@ -7,17 +7,18 @@ const {XPCOMUtils} = ChromeUtils.import(
 const {DOMLocalization} = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm");
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]);
 
 ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 const POPUP_NOTIFICATION_ID = "contextual-feature-recommendation";
-const PAUSE_BUTTON_ID = "cfr-notification-footer-pause-button";
+const ANIMATION_BUTTON_ID = "cfr-notification-footer-animation-button";
+const ANIMATION_LABEL_ID = "cfr-notification-footer-animation-label";
 const SUMO_BASE_URL = Services.urlFormatter.formatURLPref("app.support.baseURL");
 const ADDONS_API_URL = "https://services.addons.mozilla.org/api/v3/addons/addon";
 const ANIMATIONS_ENABLED_PREF = "toolkit.cosmeticAnimations.enabled";
 
 const DELAY_BEFORE_EXPAND_MS = 1000;
 const CATEGORY_ICONS = {
   "cfrAddons": "webextensions-icon",
   "cfrFeatures": "recommendations-icon",
@@ -136,19 +137,19 @@ class PageAction {
       this._clearScheduledStateChanges();
       if (this.urlbar.getAttribute("cfr-recommendation-state") === "expanded") {
         this.urlbar.setAttribute("cfr-recommendation-state", "collapsed");
       }
     }
 
     // TODO: FIXME: find a nicer way of cleaning this up. Maybe listening to "popuphidden"?
     // Remove click listener on pause button;
-    if (this.onPauseClick) {
-      this.window.document.getElementById(PAUSE_BUTTON_ID).removeEventListener("click", this.onPauseClick);
-      delete this.onPauseClick;
+    if (this.onAnimationButtonClick) {
+      this.window.document.getElementById(ANIMATION_BUTTON_ID).removeEventListener("click", this.onAnimationButtonClick);
+      delete this.onAnimationButtonClick;
     }
   }
 
   _clearScheduledStateChanges() {
     while (this.stateTransitionTimeoutIDs.length > 0) {
       // clearTimeout is safe even with invalid/expired IDs
       this.window.clearTimeout(this.stateTransitionTimeoutIDs.pop());
     }
@@ -300,42 +301,45 @@ class PageAction {
 
   async _renderPinTabAnimation() {
     const ANIMATION_CONTAINER_ID = "cfr-notification-footer-pintab-animation-container";
     const footer = this.window.document.getElementById("cfr-notification-footer");
     let animationContainer = this.window.document.getElementById(ANIMATION_CONTAINER_ID);
     if (!animationContainer) {
       animationContainer = this._createElementAndAppend({type: "vbox", id: ANIMATION_CONTAINER_ID}, footer);
 
-      // spacer
-      this._createElementAndAppend("vbox", animationContainer).setAttribute("flex", 1);
-
       let controlsContainer = this._createElementAndAppend(
         {type: "hbox", id: "cfr-notification-footer-animation-controls"}, animationContainer);
 
       // spacer
       this._createElementAndAppend({type: "vbox"}, controlsContainer).setAttribute("flex", 1);
 
-      let pauseButton = this._createElementAndAppend({type: "hbox", id: PAUSE_BUTTON_ID}, controlsContainer);
+      let animationButton = this._createElementAndAppend({type: "hbox", id: ANIMATION_BUTTON_ID}, controlsContainer);
 
-      let pauseLabel = this._createElementAndAppend(
-        {type: "label", id: "cfr-notification-footer-pause-label"}, pauseButton);
-      pauseLabel.textContent = await this.getStrings({"string_id": "cfr-doorhanger-pintab-animation-pause"});
-
-      // pause icon
-      this._createElementAndAppend({type: "image", id: "cfr-notification-footer-pause-icon"}, pauseButton);
+      // animation button label
+      this._createElementAndAppend({type: "label", id: ANIMATION_LABEL_ID}, animationButton);
     }
 
     animationContainer.toggleAttribute("animate", Services.prefs.getBoolPref(ANIMATIONS_ENABLED_PREF, true));
     animationContainer.removeAttribute("paused");
 
-    if (!this.onPauseClick) {
-      let pauseButton = this.window.document.getElementById(PAUSE_BUTTON_ID);
-      this.onPauseClick = () => { animationContainer.setAttribute("paused", true); };
-      pauseButton.addEventListener("click", this.onPauseClick);
+    this.window.document.getElementById(ANIMATION_LABEL_ID).textContent = await this.getStrings(
+      {"string_id": "cfr-doorhanger-pintab-animation-pause"});
+
+    if (!this.onAnimationButtonClick) {
+      let animationButton = this.window.document.getElementById(ANIMATION_BUTTON_ID);
+      this.onAnimationButtonClick = async () => {
+        let animationLabel = this.window.document.getElementById(ANIMATION_LABEL_ID);
+        if (animationContainer.toggleAttribute("paused")) {
+          animationLabel.textContent = await this.getStrings({"string_id": "cfr-doorhanger-pintab-animation-resume"});
+        } else {
+          animationLabel.textContent = await this.getStrings({"string_id": "cfr-doorhanger-pintab-animation-pause"});
+        }
+      };
+      animationButton.addEventListener("click", this.onAnimationButtonClick);
     }
   }
 
   async _renderPopup(message, browser) {
     const {id, content} = message;
 
     const headerLabel = this.window.document.getElementById("cfr-notification-header-label");
     const headerLink = this.window.document.getElementById("cfr-notification-header-link");
--- a/browser/components/newtab/test/unit/asrouter/CFRPageActions.test.js
+++ b/browser/components/newtab/test/unit/asrouter/CFRPageActions.test.js
@@ -25,17 +25,17 @@ describe("CFRPageActions", () => {
     "cfr-notification-footer",
     "cfr-notification-footer-text",
     "cfr-notification-footer-filled-stars",
     "cfr-notification-footer-empty-stars",
     "cfr-notification-footer-users",
     "cfr-notification-footer-spacer",
     "cfr-notification-footer-learn-more-link",
     "cfr-notification-footer-pintab-animation-container",
-    "cfr-notification-footer-pause-button",
+    "cfr-notification-footer-animation-button",
   ];
   const elementClassNames = [
     "popup-notification-body-container",
   ];
 
   beforeEach(() => {
     sandbox = sinon.createSandbox();
     clock = sandbox.useFakeTimers();
--- a/browser/themes/shared/browser.inc.css
+++ b/browser/themes/shared/browser.inc.css
@@ -322,16 +322,17 @@
   flex-grow: 1;
 }
 
 #cfr-notification-footer-pintab-animation-container {
   background-image: url("resource://activity-stream/data/content/assets/cfr_pinnedtab_animated.png");
   background-position: top center;
   background-repeat: no-repeat;
   height: 173px;
+  padding-top: 129px;
   width: 343px;
 }
 
 #contextual-feature-recommendation-notification[data-notification-category="cfrAddons"] #cfr-notification-footer-pintab-animation-container {
   display: none;
 }
 
 #cfr-notification-footer-pintab-animation-container:not([animate]),
@@ -349,38 +350,44 @@
   background: linear-gradient(transparent 0%, rgba(255, 255, 255, 0.95) 35%);
   padding: 20px var(--arrowpanel-padding) 10px;
 }
 
 :root[lwt-popup-brighttext] #cfr-notification-footer-animation-controls {
   margin-left: 13px;
 }
 
-#cfr-notification-footer-pintab-animation-container:not([animate]) #cfr-notification-footer-animation-controls,
-#cfr-notification-footer-pintab-animation-container[paused] #cfr-notification-footer-animation-controls {
+#cfr-notification-footer-pintab-animation-container:not([animate]) #cfr-notification-footer-animation-controls {
   visibility: hidden;
 }
 
-#cfr-notification-footer-pause-label {
+#cfr-notification-footer-animation-button {
+  background-image: url("resource://activity-stream/data/content/assets/glyph-pause-12.svg");
+  background-position: right center;
+  background-repeat: no-repeat;
+  background-size: 12px 10px;
+  -moz-context-properties: fill;
+  fill: rgba(12, 12, 13, 0.8);
+  padding-inline-end: 10px;
+}
+
+#cfr-notification-footer-pintab-animation-container[paused] #cfr-notification-footer-animation-button {
+  background-image: url("resource://activity-stream/data/content/assets/glyph-play-12.svg");
+}
+
+#cfr-notification-footer-animation-button:-moz-locale-dir(rtl) {
+  background-position-x: left;
+}
+
+#cfr-notification-footer-animation-label {
   font-weight: 600;
   line-height: 11px;
 }
 
-#cfr-notification-footer-pause-button,
-#cfr-notification-footer-pause-label {
+#cfr-notification-footer-animation-button,
+#cfr-notification-footer-animation-label {
   color: rgba(12, 12, 13, 0.8);
   cursor: pointer;
 }
 
-#cfr-notification-footer-pause-icon {
-  background-image: url("resource://activity-stream/data/content/assets/glyph-pause-12.svg");
-  background-position: center center;
-  background-repeat: no-repeat;
-  background-size: 12px 10px;
-  -moz-context-properties: fill;
-  fill: rgba(12, 12, 13, 0.8);
-  height: 12px;
-  width: 10px;
-}
-
 #content-mask {
   background: rgba(0, 0, 0, 0.5);
 }