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 521606 da793f0fe362
parent 521605 4c52efb1430f
child 521607 44fee8919949
push id10867
push userdvarga@mozilla.com
push dateThu, 14 Mar 2019 15:20:45 +0000
treeherdermozilla-beta@abad13547875 [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);
 }