Bug 819493: the Know Your Rights notification box has moved to be shown as default snippet on first startup. r=gavin
authorMike de Boer <mdeboer@mozilla.com>
Tue, 09 Apr 2013 16:48:30 -0700
changeset 128457 c950d2ea4c5bd2c0bc6d6e2a9e7da0542bc47b9c
parent 128456 afc39d8b649af0c4a4b667f63ca6fc2c803ba66d
child 128458 7b8ed29c6bc0126f8f5f704ff279e3608ea2d75e
push id24528
push userryanvm@gmail.com
push dateThu, 11 Apr 2013 19:19:41 +0000
treeherdermozilla-central@7b8ed29c6bc0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs819493
milestone23.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 819493: the Know Your Rights notification box has moved to be shown as default snippet on first startup. r=gavin
browser/base/content/abouthome/aboutHome.css
browser/base/content/abouthome/aboutHome.js
browser/base/content/abouthome/aboutHome.xhtml
browser/base/content/browser.js
browser/base/content/test/browser_aboutHome.js
browser/components/Makefile.in
browser/components/nsBrowserGlue.js
browser/locales/en-US/chrome/browser/aboutHome.dtd
browser/modules/AboutHomeUtils.jsm
browser/modules/Makefile.in
toolkit/locales/en-US/chrome/global/aboutRights.properties
toolkit/locales/jar.mn
--- a/browser/base/content/abouthome/aboutHome.css
+++ b/browser/base/content/abouthome/aboutHome.css
@@ -135,26 +135,32 @@ a {
 
 #searchText + #searchSubmit:hover:active {
   box-shadow: 0 1px 1px hsla(211,79%,6%,.1) inset,
               0 0 1px hsla(211,79%,6%,.2) inset;
   transition-duration: 0ms;
 }
 
 #defaultSnippet1,
-#defaultSnippet2 {
+#defaultSnippet2,
+#rightsSnippet {
   display: block;
   min-height: 38px;
   background: 30px center no-repeat;
   padding: 6px 0;
   -moz-padding-start: 79px;
 }
 
+#rightsSnippet[hidden] {
+  display: none;
+}
+
 #defaultSnippet1:-moz-dir(rtl),
-#defaultSnippet2:-moz-dir(rtl) {
+#defaultSnippet2:-moz-dir(rtl),
+#rightsSnippet:-moz-dir(rtl) {
   background-position: right 30px center;
 }
 
 #defaultSnippet1 {
   background-image: url("chrome://browser/content/abouthome/snippet1.png");
 }
 
 #defaultSnippet2 {
@@ -346,17 +352,18 @@ body[narrow] #restorePreviousSession::be
 }
 
 /* [HiDPI]
  * At resolutions above 1dppx, prefer downscaling the 2x Retina graphics
  * rather than upscaling the original-size ones (bug 818940).
  */
 @media not all and (max-resolution: 1dppx) {
   #defaultSnippet1,
-  #defaultSnippet2 {
+  #defaultSnippet2,
+  #rightsSnippet {
     background-size: 40px;
   }
 
   #defaultSnippet1 {
     background-image: url("chrome://browser/content/abouthome/snippet1@2x.png");
   }
 
   #defaultSnippet2 {
--- a/browser/base/content/abouthome/aboutHome.js
+++ b/browser/base/content/abouthome/aboutHome.js
@@ -338,27 +338,39 @@ function loadSnippets()
  * Shows locally cached remote snippets, or default ones when not available.
  *
  * @note: snippets should never invoke showSnippets(), or they may cause
  *        a "too much recursion" exception.
  */
 let _snippetsShown = false;
 function showSnippets()
 {
+  let snippetsElt = document.getElementById("snippets");
+
+  // Show about:rights notification, if needed.
+  let showRights = document.documentElement.getAttribute("showKnowYourRights");
+  if (showRights) {
+    let rightsElt = document.getElementById("rightsSnippet");
+    let anchor = rightsElt.getElementsByTagName("a")[0];
+    anchor.href = "about:rights";
+    snippetsElt.appendChild(rightsElt);
+    rightsElt.removeAttribute("hidden");
+    return;
+  }
+
   if (!gSnippetsMap)
     throw new Error("Snippets map has not properly been initialized");
   if (_snippetsShown) {
     // There's something wrong with the remote snippets, just in case fall back
     // to the default snippets.
     showDefaultSnippets();
     throw new Error("showSnippets should never be invoked multiple times");
   }
   _snippetsShown = true;
 
-  let snippetsElt = document.getElementById("snippets");
   let snippets = gSnippetsMap.get("snippets");
   // If there are remotely fetched snippets, try to to show them.
   if (snippets) {
     // Injecting snippets can throw if they're invalid XML.
     try {
       snippetsElt.innerHTML = snippets;
       // Scripts injected by innerHTML are inactive, so we have to relocate them
       // through DOM manipulation to activate their contents.
--- a/browser/base/content/abouthome/aboutHome.xhtml
+++ b/browser/base/content/abouthome/aboutHome.xhtml
@@ -44,16 +44,17 @@
         </form>
       </div>
 
       <div id="snippetContainer">
         <div id="defaultSnippets" hidden="true">
           <span id="defaultSnippet1">&abouthome.defaultSnippet1.v1;</span>
           <span id="defaultSnippet2">&abouthome.defaultSnippet2.v1;</span>
         </div>
+        <span id="rightsSnippet" hidden="true">&abouthome.rightsSnippet;</span>
         <div id="snippets"/>
       </div>
     </div>
     <div class="spacer"/>
 
     <div id="launcher">
       <button class="launchButton" id="downloads">&abouthome.downloadsButton.label;</button>
       <button class="launchButton" id="bookmarks">&abouthome.bookmarksButton.label;</button>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2271,17 +2271,25 @@ function BrowserOnAboutPageLoad(doc) {
     let ss = Components.classes["@mozilla.org/browser/sessionstore;1"].
              getService(Components.interfaces.nsISessionStore);
     if (ss.canRestoreLastSession &&
         !PrivateBrowsingUtils.isWindowPrivate(window))
       doc.getElementById("launcher").setAttribute("session", "true");
 
     // Inject search engine and snippets URL.
     let docElt = doc.documentElement;
+    // set the following attributes BEFORE searchEngineURL, which triggers to
+    // show the snippets when it's set.
     docElt.setAttribute("snippetsURL", AboutHomeUtils.snippetsURL);
+    if (AboutHomeUtils.showKnowYourRights) {
+      docElt.setAttribute("showKnowYourRights", "true");
+      // Set pref to indicate we've shown the notification.
+      let currentVersion = Services.prefs.getIntPref("browser.rights.version");
+      Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
+    }
     docElt.setAttribute("snippetsVersion", AboutHomeUtils.snippetsVersion);
     docElt.setAttribute("searchEngineName",
                         AboutHomeUtils.defaultSearchEngine.name);
     docElt.setAttribute("searchEngineURL",
                         AboutHomeUtils.defaultSearchEngine.searchURL);
 
 #ifdef MOZ_SERVICES_HEALTHREPORT
     doc.addEventListener("AboutHomeSearchEvent", function onSearch(e) {
--- a/browser/base/content/test/browser_aboutHome.js
+++ b/browser/base/content/test/browser_aboutHome.js
@@ -4,24 +4,24 @@
 
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
   "resource://gre/modules/commonjs/sdk/core/promise.js");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
   "resource:///modules/AboutHomeUtils.jsm");
 
+let gRightsVersion = Services.prefs.getIntPref("browser.rights.version");
+
 registerCleanupFunction(function() {
   // Ensure we don't pollute prefs for next tests.
-  try {
-    Services.prefs.clearUserPref("network.cookies.cookieBehavior");
-  } catch (ex) {}
-  try {
-    Services.prefs.clearUserPref("network.cookie.lifetimePolicy");
-  } catch (ex) {}
+  Services.prefs.clearUserPref("network.cookies.cookieBehavior");
+  Services.prefs.clearUserPref("network.cookie.lifetimePolicy");
+  Services.prefs.clearUserPref("browser.rights.override");
+  Services.prefs.clearUserPref("browser.rights." + gRightsVersion + ".shown");
 });
 
 let gTests = [
 
 {
   desc: "Check that clearing cookies does not clear storage",
   setup: function ()
   {
@@ -195,26 +195,73 @@ let gTests = [
     is(aSnippetsMap.get("snippets"), "test", "snippets still cached");
     is(aSnippetsMap.get("snippets-cached-version"),
        AboutHomeUtils.snippetsVersion,
        "cached-version is correct");
     ok(aSnippetsMap.has("snippets-last-update"), "last-update still exists");
   }
 },
 
+{
+  desc: "Check if the 'Know Your Rights default snippet is shown when 'browser.rights.override' pref is set",
+  beforeRun: function ()
+  {
+    Services.prefs.setBoolPref("browser.rights.override", false);
+  },
+  setup: function () { },
+  run: function (aSnippetsMap)
+  {
+    let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
+    let showRights = AboutHomeUtils.showKnowYourRights;
+
+    ok(showRights, "AboutHomeUtils.showKnowYourRights should be TRUE");
+
+    let snippetsElt = doc.getElementById("snippets");
+    ok(snippetsElt, "Found snippets element");
+    is(snippetsElt.getElementsByTagName("a")[0].href, "about:rights", "Snippet link is present.");
+
+    Services.prefs.clearUserPref("browser.rights.override");
+  }
+},
+
+{
+  desc: "Check if the 'Know Your Rights default snippet is NOT shown when 'browser.rights.override' pref is NOT set",
+  beforeRun: function ()
+  {
+    Services.prefs.setBoolPref("browser.rights.override", true);
+  },
+  setup: function () { },
+  run: function (aSnippetsMap)
+  {
+    let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
+    let rightsData = AboutHomeUtils.knowYourRightsData;
+    
+    ok(!rightsData, "AboutHomeUtils.knowYourRightsData should be FALSE");
+
+    let snippetsElt = doc.getElementById("snippets");
+    ok(snippetsElt, "Found snippets element");
+    ok(snippetsElt.getElementsByTagName("a")[0].href != "about:rights", "Snippet link should not point to about:rights.");
+
+    Services.prefs.clearUserPref("browser.rights.override");
+  }
+}
+
 ];
 
 function test()
 {
   waitForExplicitFinish();
 
   Task.spawn(function () {
     for (let test of gTests) {
       info(test.desc);
 
+      if (test.beforeRun)
+        yield test.beforeRun();
+
       let tab = yield promiseNewTabLoadEvent("about:home", "DOMContentLoaded");
 
       // Must wait for both the snippets map and the browser attributes, since
       // can't guess the order they will happen.
       // So, start listening now, but verify the promise is fulfilled only
       // after the snippets map setup.
       let promise = promiseBrowserAttributes(tab);
       // Prepare the snippets map with default values, then run the test setup.
--- a/browser/components/Makefile.in
+++ b/browser/components/Makefile.in
@@ -15,13 +15,9 @@ EXTRA_COMPONENTS = \
 
 EXTRA_PP_COMPONENTS = \
   nsBrowserContentHandler.js \
   nsBrowserGlue.js \
   $(NULL)
 
 EXTRA_JS_MODULES = distribution.js
 
-ifdef MOZILLA_OFFICIAL
-DEFINES += -DOFFICIAL_BUILD=1
-endif
-
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -516,21 +516,16 @@ BrowserGlue.prototype = {
     webappsUI.uninit();
     SignInToWebsiteUX.uninit();
     webrtcUI.uninit();
     this._dispose();
   },
 
   // All initial windows have opened.
   _onWindowsRestored: function BG__onWindowsRestored() {
-    // Show about:rights notification, if needed.
-    if (this._shouldShowRights()) {
-      this._showRightsNotification();
-    }
-
     // Show update notification, if needed.
     if (Services.prefs.prefHasUserValue("app.update.postupdate"))
       this._showUpdateNotification();
 
     // Load the "more info" page for a locked places.sqlite
     // This property is set earlier by places-database-locked topic.
     if (this._isPlacesDatabaseLocked) {
       this._showPlacesLockedNotificationBox();
@@ -746,88 +741,16 @@ BrowserGlue.prototype = {
       if (neverAsk.value) {
         // always save state when shutting down
         Services.prefs.setIntPref("browser.startup.page", 3);
       }
       break;
     }
   },
 
-  /*
-   * _shouldShowRights - Determines if the user should be shown the
-   * about:rights notification. The notification should *not* be shown if
-   * we've already shown the current version, or if the override pref says to
-   * never show it. The notification *should* be shown if it's never been seen
-   * before, if a newer version is available, or if the override pref says to
-   * always show it.
-   */
-  _shouldShowRights: function BG__shouldShowRights() {
-    // Look for an unconditional override pref. If set, do what it says.
-    // (true --> never show, false --> always show)
-    try {
-      return !Services.prefs.getBoolPref("browser.rights.override");
-    } catch (e) { }
-    // Ditto, for the legacy EULA pref.
-    try {
-      return !Services.prefs.getBoolPref("browser.EULA.override");
-    } catch (e) { }
-
-#ifndef OFFICIAL_BUILD
-    // Non-official builds shouldn't shouldn't show the notification.
-    return false;
-#endif
-
-    // Look to see if the user has seen the current version or not.
-    var currentVersion = Services.prefs.getIntPref("browser.rights.version");
-    try {
-      return !Services.prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
-    } catch (e) { }
-
-    // Legacy: If the user accepted a EULA, we won't annoy them with the
-    // equivalent about:rights page until the version changes.
-    try {
-      return !Services.prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
-    } catch (e) { }
-
-    // We haven't shown the notification before, so do so now.
-    return true;
-  },
-
-  _showRightsNotification: function BG__showRightsNotification() {
-    // Stick the notification onto the selected tab of the active browser window.
-    var win = this.getMostRecentBrowserWindow();
-    var notifyBox = win.gBrowser.getNotificationBox();
-
-    var brandBundle  = Services.strings.createBundle("chrome://branding/locale/brand.properties");
-    var rightsBundle = Services.strings.createBundle("chrome://global/locale/aboutRights.properties");
-
-    var buttonLabel      = rightsBundle.GetStringFromName("buttonLabel");
-    var buttonAccessKey  = rightsBundle.GetStringFromName("buttonAccessKey");
-    var productName      = brandBundle.GetStringFromName("brandFullName");
-    var notifyRightsText = rightsBundle.formatStringFromName("notifyRightsText", [productName], 1);
-
-    var buttons = [
-                    {
-                      label:     buttonLabel,
-                      accessKey: buttonAccessKey,
-                      popup:     null,
-                      callback: function(aNotificationBar, aButton) {
-                        win.openUILinkIn("about:rights", "tab");
-                      }
-                    }
-                  ];
-
-    // Set pref to indicate we've shown the notification.
-    var currentVersion = Services.prefs.getIntPref("browser.rights.version");
-    Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
-
-    var notification = notifyBox.appendNotification(notifyRightsText, "about-rights", null, notifyBox.PRIORITY_INFO_LOW, buttons);
-    notification.persistence = -1; // Until user closes it
-  },
-
   _showUpdateNotification: function BG__showUpdateNotification() {
     Services.prefs.clearUserPref("app.update.postupdate");
 
     var um = Cc["@mozilla.org/updates/update-manager;1"].
              getService(Ci.nsIUpdateManager);
     try {
       // If the updates.xml file is deleted then getUpdateAt will throw.
       var update = um.getUpdateAt(0).QueryInterface(Ci.nsIPropertyBag);
--- a/browser/locales/en-US/chrome/browser/aboutHome.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutHome.dtd
@@ -16,16 +16,18 @@
 <!-- LOCALIZATION NOTE (abouthome.defaultSnippet1.v1):
      text in <a/> will be linked to the Firefox features page on mozilla.com
 -->
 <!ENTITY abouthome.defaultSnippet1.v1 "Thanks for choosing Firefox! To get the most out of your browser, learn more about the <a>latest features</a>.">
 <!-- LOCALIZATION NOTE (abouthome.defaultSnippet2.v1):
      text in <a/> will be linked to the featured add-ons on addons.mozilla.org
 -->
 <!ENTITY abouthome.defaultSnippet2.v1 "It's easy to customize your Firefox exactly the way you want it. <a>Choose from thousands of add-ons</a>.">
+<!-- LOCALIZATION NOTE (abouthome.rightsSnippet): text in <a/> will be linked to about:rights -->
+<!ENTITY abouthome.rightsSnippet "&brandFullName; is free and open source software from the non-profit Mozilla Foundation. <a>Know your rights…</a>">
 
 <!ENTITY abouthome.bookmarksButton.label "Bookmarks">
 <!ENTITY abouthome.historyButton.label   "History">
 <!ENTITY abouthome.settingsButton.label  "Settings">
 <!ENTITY abouthome.addonsButton.label    "Add-ons">
 <!ENTITY abouthome.appsButton.label      "Marketplace">
 <!ENTITY abouthome.downloadsButton.label "Downloads">
 <!ENTITY abouthome.syncButton.label      "&syncBrand.shortName.label;">
--- a/browser/modules/AboutHomeUtils.jsm
+++ b/browser/modules/AboutHomeUtils.jsm
@@ -28,16 +28,56 @@ this.AboutHomeUtils = {
     if (submission.postData) {
       throw new Error("Home page does not support POST search engines.");
     }
   
     return Object.freeze({
       name: defaultEngine.name,
       searchURL: submission.uri.spec
     });
+  },
+
+  /*
+   * showKnowYourRights - Determines if the user should be shown the
+   * about:rights notification. The notification should *not* be shown if
+   * we've already shown the current version, or if the override pref says to
+   * never show it. The notification *should* be shown if it's never been seen
+   * before, if a newer version is available, or if the override pref says to
+   * always show it.
+   */
+  get showKnowYourRights() {
+    // Look for an unconditional override pref. If set, do what it says.
+    // (true --> never show, false --> always show)
+    try {
+      return !Services.prefs.getBoolPref("browser.rights.override");
+    } catch (e) { }
+    // Ditto, for the legacy EULA pref.
+    try {
+      return !Services.prefs.getBoolPref("browser.EULA.override");
+    } catch (e) { }
+
+#ifndef MOZILLA_OFFICIAL
+    // Non-official builds shouldn't show the notification.
+    return false;
+#endif
+
+    // Look to see if the user has seen the current version or not.
+    var currentVersion = Services.prefs.getIntPref("browser.rights.version");
+    try {
+      return !Services.prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
+    } catch (e) { }
+
+    // Legacy: If the user accepted a EULA, we won't annoy them with the
+    // equivalent about:rights page until the version changes.
+    try {
+      return !Services.prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
+    } catch (e) { }
+
+    // We haven't shown the notification before, so do so now.
+    return true;
   }
 };
 
 /**
  * Returns the URL to fetch snippets from, in the urlFormatter service format.
  */
 XPCOMUtils.defineLazyGetter(AboutHomeUtils, "snippetsURL", function() {
   let updateURL = Services.prefs
--- a/browser/modules/Makefile.in
+++ b/browser/modules/Makefile.in
@@ -7,33 +7,37 @@ topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/config.mk
 
 EXTRA_JS_MODULES = \
-	AboutHomeUtils.jsm \
 	BrowserNewTabPreloader.jsm \
 	openLocationLastURL.jsm \
 	NetworkPrioritizer.jsm \
 	offlineAppCache.jsm \
 	SignInToWebsite.jsm \
 	webappsUI.jsm \
 	webrtcUI.jsm \
 	Social.jsm \
 	SharedFrame.jsm \
 	$(NULL)
 
 EXTRA_PP_JS_MODULES = \
+	AboutHomeUtils.jsm \
 	RecentWindow.jsm \
 	$(NULL)
 
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 EXTRA_JS_MODULES += \
 	WindowsJumpLists.jsm \
 	WindowsPreviewPerTab.jsm \
 	$(NULL)
 endif
 
+ifdef MOZILLA_OFFICIAL
+DEFINES += -DMOZILLA_OFFICIAL=1
+endif
+
 include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/toolkit/locales/en-US/chrome/global/aboutRights.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-buttonLabel = Know your rights…
-buttonAccessKey = K
-notifyRightsText = %S is free and open source software from the non-profit Mozilla Foundation.
--- a/toolkit/locales/jar.mn
+++ b/toolkit/locales/jar.mn
@@ -4,17 +4,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 @AB_CD@.jar:
 % locale global @AB_CD@ %locale/@AB_CD@/global/
   locale/@AB_CD@/global/about.dtd                       (%chrome/global/about.dtd)
   locale/@AB_CD@/global/aboutAbout.dtd                  (%chrome/global/aboutAbout.dtd)
   locale/@AB_CD@/global/aboutRights.dtd                 (%chrome/global/aboutRights.dtd)
-  locale/@AB_CD@/global/aboutRights.properties          (%chrome/global/aboutRights.properties)
   locale/@AB_CD@/global/aboutSupport.dtd                (%chrome/global/aboutSupport.dtd)
   locale/@AB_CD@/global/aboutSupport.properties         (%chrome/global/aboutSupport.properties)
   locale/@AB_CD@/global/aboutTelemetry.dtd              (%chrome/global/aboutTelemetry.dtd)
   locale/@AB_CD@/global/aboutTelemetry.properties       (%chrome/global/aboutTelemetry.properties)
   locale/@AB_CD@/global/actions.dtd                     (%chrome/global/actions.dtd)
   locale/@AB_CD@/global/appPicker.dtd                   (%chrome/global/appPicker.dtd)
   locale/@AB_CD@/global/brand.dtd                       (generic/chrome/global/brand.dtd)
   locale/@AB_CD@/global/browser.properties              (%chrome/global/browser.properties)