Bug 1221500 - use a notification to warn people that panorama is going away, r=ttaubert, a=ritu l10n=ritu
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Mon, 09 Nov 2015 11:11:12 +0000
changeset 305425 07fa57ab14896f4ca6f3f91c7b6178c8dea2edb2
parent 305424 cafe4b776cac0e837a746ee638c2cbbe4b89dcc7
child 305426 b797300e0d27762ffbc057d4328ea57abe6c2a9f
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersttaubert, ritu
bugs1221500
milestone44.0a2
Bug 1221500 - use a notification to warn people that panorama is going away, r=ttaubert, a=ritu l10n=ritu
browser/components/nsBrowserGlue.js
browser/components/tabview/test/browser_tabview_bug626791.js
browser/components/tabview/test/browser_tabview_bug656778.js
browser/components/tabview/ui.js
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/linux/tabview/tabview.css
browser/themes/osx/tabview/tabview.css
browser/themes/windows/tabview/tabview.css
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1321,16 +1321,31 @@ BrowserGlue.prototype = {
 
       if (willPrompt) {
         Services.tm.mainThread.dispatch(function() {
           DefaultBrowserCheck.prompt(RecentWindow.getMostRecentBrowserWindow());
         }.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
       }
     }
 
+    if (this._mayNeedToWarnAboutTabGroups) {
+      let haveTabGroups = false;
+      let wins = Services.wm.getEnumerator("navigator:browser");
+      while (wins.hasMoreElements()) {
+        let win = wins.getNext();
+        if (win.TabView._tabBrowserHasHiddenTabs() && win.TabView.firstUseExperienced()) {
+          haveTabGroups = true;
+          break;
+        }
+      }
+      if (haveTabGroups) {
+        this._showTabGroupsDeprecationNotification();
+      }
+    }
+
 #ifdef E10S_TESTING_ONLY
     E10SUINotification.checkStatus();
 #endif
   },
 
 #ifdef MOZ_DEV_EDITION
   _createExtraDefaultProfile: function () {
     // If Developer Edition is the only installed Firefox version and no other
@@ -1359,16 +1374,37 @@ BrowserGlue.prototype = {
         }).then(null, e => {
           Cu.reportError("Could not empty profile 'default': " + e);
         });
       }
     }
   },
 #endif
 
+  _showTabGroupsDeprecationNotification() {
+    let brandShortName = gBrandBundle.GetStringFromName("brandShortName");
+    let text = gBrowserBundle.formatStringFromName("tabgroups.deprecationwarning.description",
+                                                   [brandShortName], 1);
+    let learnMore = gBrowserBundle.GetStringFromName("tabgroups.deprecationwarning.learnMore.label");
+    let learnMoreKey = gBrowserBundle.GetStringFromName("tabgroups.deprecationwarning.learnMore.accesskey");
+
+    let win = RecentWindow.getMostRecentBrowserWindow();
+    let notifyBox = win.document.getElementById("high-priority-global-notificationbox");
+    let button = {
+      label: learnMore,
+      accessKey: learnMoreKey,
+      callback: function(aNotificationBar, aButton) {
+        win.openUILinkIn("https://support.mozilla.org/kb/tab-groups-removal", "tab");
+      },
+    };
+
+    notifyBox.appendNotification(text, "tabgroups-removal-notification", null,
+                                 notifyBox.PRIORITY_WARNING_MEDIUM, [button]);
+  },
+
   _onQuitRequest: function BG__onQuitRequest(aCancelQuit, aQuitType) {
     // If user has already dismissed quit request, then do nothing
     if ((aCancelQuit instanceof Ci.nsISupportsPRBool) && aCancelQuit.data)
       return;
 
     // There are several cases where we won't show a dialog here:
     // 1. There is only 1 tab open in 1 window
     // 2. The session will be restored at startup, indicated by
@@ -1866,17 +1902,17 @@ BrowserGlue.prototype = {
     var notifyBox = win.gBrowser.getNotificationBox();
     var notification = notifyBox.appendNotification(text, title, null,
                                                     notifyBox.PRIORITY_CRITICAL_MEDIUM,
                                                     buttons);
     notification.persistence = -1; // Until user closes it
   },
 
   _migrateUI: function BG__migrateUI() {
-    const UI_VERSION = 32;
+    const UI_VERSION = 33;
     const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
     let currentUIVersion = 0;
     try {
       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
     } catch(ex) {}
     if (currentUIVersion >= UI_VERSION)
       return;
 
@@ -2211,16 +2247,21 @@ BrowserGlue.prototype = {
       xulStore.removeValue(BROWSER_DOCURL, "bookmarks-menu-button", "class");
       xulStore.removeValue(BROWSER_DOCURL, "home-button", "class");
     }
 
     if (currentUIVersion < 32) {
       this._notifyNotificationsUpgrade();
     }
 
+    if (currentUIVersion < 33) {
+      // We'll do something once windows are open:
+      this._mayNeedToWarnAboutTabGroups = true;
+    }
+
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _hasExistingNotificationPermission: function BG__hasExistingNotificationPermission() {
     let enumerator = Services.perms.enumerator;
     while (enumerator.hasMoreElements()) {
       let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
--- a/browser/components/tabview/test/browser_tabview_bug626791.js
+++ b/browser/components/tabview/test/browser_tabview_bug626791.js
@@ -153,16 +153,18 @@ function test() {
     let onLoad = function (newWin) {
       win = newWin;
       removeToolbarButton();
     };
 
     let onShow = function () {
       cw = win.TabView.getContentWindow();
 
+      cw.document.querySelector('.banner').remove();
+
       let groupItem = cw.GroupItems.groupItems[0];
       groupItem.setSize(200, 200, true);
       groupItem.setUserSize();
 
       SimpleTest.waitForFocus(function () {
         assertToolbarButtonNotExists();
         test();
       }, cw);
--- a/browser/components/tabview/test/browser_tabview_bug656778.js
+++ b/browser/components/tabview/test/browser_tabview_bug656778.js
@@ -27,22 +27,22 @@ function test() {
   let assertPreferences = function (startupPage, firstRun, enabledOnce) {
     assertIntPref(TabView.PREF_STARTUP_PAGE, startupPage);
     assertBoolPref(TabView.PREF_FIRST_RUN, firstRun);
     assertBoolPref(TabView.PREF_RESTORE_ENABLED_ONCE, enabledOnce);
   };
 
   let assertNotificationBannerVisible = function (win) {
     let cw = win.TabView.getContentWindow();
-    is(cw.iQ(".banner").length, 1, "notification banner is visible");
+    is(cw.iQ(".banner").length, 2, "notification banner is visible");
   };
 
   let assertNotificationBannerNotVisible = function (win) {
     let cw = win.TabView.getContentWindow();
-    is(cw.iQ(".banner").length, 0, "notification banner is not visible");
+    is(cw.iQ(".banner").length, 1, "notification banner is not visible");
   };
 
   let next = function () {
     if (tests.length == 0) {
       waitForFocus(finish);
       return;
     }
 
--- a/browser/components/tabview/ui.js
+++ b/browser/components/tabview/ui.js
@@ -506,27 +506,31 @@ var UI = {
       dispatchEvent(event);
 
       // Flush pending updates
       GroupItems.flushAppTabUpdates();
 
       TabItems.resumePainting();
     }
 
+    this.notifyDeprecation();
+
     if (gTabView.firstUseExperienced)
       gTabView.enableSessionRestore();
   },
 
   // ----------
   // Function: hideTabView
   // Hides TabView and shows the main browser UI.
   hideTabView: function UI_hideTabView() {
     if (!this.isTabViewVisible() || this._isChangingVisibility)
       return;
 
+    iQ(".banner").remove();
+
     // another tab might be select if user decides to stay on a page when
     // a onclose confirmation prompts.
     GroupItems.removeHiddenGroups();
 
     // We need to set this after removing the hidden groups because doing so
     // might show prompts which will cause us to be called again, and we'd get
     // stuck if we prevent re-entrancy before doing that.
     this._isChangingVisibility = true;
@@ -1536,13 +1540,43 @@ var UI = {
 
     let onFadeIn = function () {
       setTimeout(function () {
         banner.animate({opacity: 0}, {duration: 1500, complete: onFadeOut});
       }, 5000);
     };
 
     banner.animate({opacity: 0.7}, {duration: 1500, complete: onFadeIn});
-  }
+  },
+
+  // Function: notifyDeprecation
+  // Notify the user that tab groups will be deprecated soon.
+  notifyDeprecation() {
+    let brandBundle = gWindow.document.getElementById("bundle_brand");
+    let brandShortName = brandBundle.getString("brandShortName");
+    let browserBundle = gWindow.document.getElementById("bundle_browser");
+    let notificationText = browserBundle.getFormattedString(
+      "tabgroups.deprecationwarning.description", [brandShortName]);
+
+    let learnMoreText = browserBundle.getString("tabgroups.deprecationwarning.learnMore.label");
+
+    let onButtonClick = () => {
+      this.hideTabView();
+      gWindow.openUILinkIn("https://support.mozilla.org/kb/tab-groups-removal", "tab");
+    };
+
+    let button = iQ("<button>")
+      .text(learnMoreText)
+      .css('-moz-margin-start', '10px')
+      .one('click', onButtonClick);
+
+    let banner = iQ("<div>")
+      .text(notificationText)
+      .addClass("banner")
+      .append(button)
+      .appendTo("body");
+
+    banner.animate({opacity: 0.7}, {duration: 1500});
+  },
 };
 
 // ----------
 UI.init();
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -788,8 +788,14 @@ usercontext.personal.label = Personal
 usercontext.work.label = Work
 usercontext.shopping.label = Shopping
 usercontext.banking.label = Banking
 
 muteTab.label = Mute Tab
 muteTab.accesskey = M
 unmuteTab.label = Unmute Tab
 unmuteTab.accesskey = M
+
+# LOCALIZATION NOTE (tabgroups.deprecationwarning.description):
+# %S is brandShortName
+tabgroups.deprecationwarning.description         = Heads up! Tab Groups will be removed from %S soon.
+tabgroups.deprecationwarning.learnMore.label     = Learn More
+tabgroups.deprecationwarning.learnMore.accesskey = L
--- a/browser/themes/linux/tabview/tabview.css
+++ b/browser/themes/linux/tabview/tabview.css
@@ -559,17 +559,17 @@ html[dir=rtl] .iq-resizable-se {
 #searchshade{
   background-color: rgba(0,0,0,.42);
   width: 100%;
   height: 100%;
 }
 
 #search{
   width: 100%;
-  height: 100%;
+  height: calc(100% - 1.7em - 20px); /* leave room for banner */
 }
 
 #searchbox{
   width: 270px;
   max-width: -moz-available;
   -moz-margin-start: 20px;
   height: 30px;
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,1), 0px 0px 9px rgba(0,0,0,.8);
--- a/browser/themes/osx/tabview/tabview.css
+++ b/browser/themes/osx/tabview/tabview.css
@@ -547,17 +547,17 @@ html[dir=rtl] .iq-resizable-se {
 }
 
 #searchshade:-moz-window-inactive {
   background: linear-gradient(rgba(237,237,237,0.42), rgba(216,216,216,0.42));
 }
 
 #search{
   width: 100%;
-  height: 100%;
+  height: calc(100% - 1.7em - 20px); /* leave room for banner */
 }
 
 #searchbox {
   width: 270px;
   max-width: -moz-available;
   -moz-margin-start: 20px;
   height: 30px;
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,1), 0px 0px 13px rgba(0,0,0,.8);
--- a/browser/themes/windows/tabview/tabview.css
+++ b/browser/themes/windows/tabview/tabview.css
@@ -564,17 +564,17 @@ html[dir=rtl] .iq-resizable-se {
 #searchshade{
   background-color: rgba(0,0,0,.42);
   width: 100%;
   height: 100%;
 }
 
 #search{
   width: 100%;
-  height: 100%;
+  height: calc(100% - 1.7em - 20px); /* leave room for banner */
 }
 
 #searchbox{
   width: 270px;
   max-width: -moz-available;
   -moz-margin-start: 20px;
   height: 30px;
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,1), 0px 0px 9px rgba(0,0,0,.8);