Bug 644517 - Implement channel selector UI for updates, r=gavin
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Fri, 08 Apr 2011 10:26:51 -0700
changeset 67614 ce7276f42938df8a83b0556a70473fefe808c7c4
parent 67613 27d6a4a5e20f25c4833fa95e78d7f83a889ea2dd
child 67615 2ea06ff58dbe6299d60e734c4fde05e5b9542d2f
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs644517
milestone2.2a1pre
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 644517 - Implement channel selector UI for updates, r=gavin
browser/base/content/aboutDialog.css
browser/base/content/aboutDialog.js
browser/base/content/aboutDialog.xul
browser/locales/en-US/chrome/browser/aboutDialog.dtd
--- a/browser/base/content/aboutDialog.css
+++ b/browser/base/content/aboutDialog.css
@@ -1,14 +1,14 @@
 #aboutDialog {
   padding-top: 0;
   -moz-padding-end: 0;
   padding-bottom: 10px;
   -moz-padding-start: 0;
-  width: 600px;
+  width: 620px;
 }
 
 #clientBox {
   background-color: #F7F7F7;
   color: #222222;
 }
 
 #leftBox {
@@ -53,20 +53,16 @@
 }
 
 .text-blurb {
   margin-bottom: 10px;
   -moz-margin-start: 0;
   -moz-padding-start: 0;
 }
 
-#updateBox {
-  margin-bottom: 10px;
-}
-
 #updateButton,
 #updateDeck > hbox > label {
   -moz-margin-start: 0;
   -moz-padding-start: 0;
 }
 
 #updateDeck > hbox > label:not([class="text-link"]) {
   color: #909090;
@@ -94,8 +90,41 @@
 }
 
 #trademark {
   font-size: xx-small;
   text-align: center;
   color: #999999;
   margin-top: 10px;
 }
+
+#currentChannel {
+  margin: 0;
+  padding: 0;
+  font-weight: bold;
+}
+
+#channelSelector {
+  margin-top: 10px;
+}
+
+#channelMenulist {
+  margin: 0;
+}
+
+.channel-description {
+  margin: 10px 0;
+  text-align: center;
+}
+
+#detailsBox,
+#channelSelector,
+.channel-description {
+  -moz-transition: opacity 250ms;
+}
+
+#contentDeck:not([selectedIndex="0"]) > #detailsBox,
+#contentDeck:not([selectedIndex="1"]) > #channelSelector,
+#channelDescriptionDeck:not([selectedIndex="0"]) > #releaseDescription,
+#channelDescriptionDeck:not([selectedIndex="1"]) > #betaDescription,
+#channelDescriptionDeck:not([selectedIndex="2"]) > #auroraDescription {
+  opacity: 0;
+}
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -83,16 +83,18 @@ function init(aEvent)
     document.getElementById("extra-trademark").hidden = true;
   }
 #endif
 
 #ifdef MOZ_UPDATER
   gAppUpdater = new appUpdater();
 #endif
 
+  gChannelSelector.init();
+
 #ifdef XP_MACOSX
   // it may not be sized at this point, and we need its width to calculate its position
   window.sizeToContent();
   window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
 #endif
 }
 
 #ifdef MOZ_UPDATER
@@ -567,8 +569,73 @@ appUpdater.prototype =
     if (!aIID.equals(Components.interfaces.nsIProgressEventSink) &&
         !aIID.equals(Components.interfaces.nsIRequestObserver) &&
         !aIID.equals(Components.interfaces.nsISupports))
       throw Components.results.NS_ERROR_NO_INTERFACE;
     return this;
   }
 };
 #endif
+
+var gChannelSelector = {
+  validChannels: { release: 1, beta: 1, aurora: 1 },
+  
+  init: function() {
+    try {
+      this.channelValue = Services.prefs.getCharPref("app.update.desiredChannel");
+    } catch (e) {
+      let defaults = Services.prefs.getDefaultBranch("");
+      this.channelValue = defaults.getCharPref("app.update.channel");
+    }
+
+    // Only show channel selector UI on valid update channels.
+    if (this.channelValue in this.validChannels) {
+      document.getElementById("currentChannelText").hidden = false;
+      this.setChannelLabel(this.channelValue);
+      this.setChannelMenuitem(this.channelValue);
+    }
+  },
+
+  selectChannel: function(aSelectedItem) {
+    document.getElementById("channelDescriptionDeck").selectedPanel =
+      document.getElementById(aSelectedItem.value + "Description");
+  },
+
+  cancel: function() {
+    this.setChannelMenuitem(this.channelValue);
+    this.hide();
+  },
+
+  apply: function() {
+    this.channelValue = document.getElementById("channelMenulist").selectedItem.value;
+    this.setChannelLabel(this.channelValue);
+
+    // Change app update channel.
+    Services.prefs.setCharPref("app.update.desiredChannel", this.channelValue);
+
+    // App updater will look at app.update.desiredChannel for new channel value
+    // and will clear it when the update is complete.
+    gAppUpdater.isChecking = true;
+    gAppUpdater.checker.checkForUpdates(gAppUpdater.updateCheckListener, true);
+
+    this.hide();
+  },
+
+  show: function() {
+    document.getElementById("contentDeck").selectedPanel =
+      document.getElementById("channelSelector");
+  },
+
+  hide: function() {
+    document.getElementById("contentDeck").selectedPanel =
+      document.getElementById("detailsBox");  
+  },
+
+  setChannelLabel: function(aValue) {
+    let channelLabel = document.getElementById("currentChannel");
+    channelLabel.value = document.getElementById(aValue + "Menuitem").label;
+  },
+
+  setChannelMenuitem: function(aValue) {
+    document.getElementById("channelMenulist").selectedItem =
+      document.getElementById(aValue + "Menuitem");
+  }
+}
--- a/browser/base/content/aboutDialog.xul
+++ b/browser/base/content/aboutDialog.xul
@@ -72,54 +72,91 @@
 
   <vbox>
     <hbox id="clientBox">
       <vbox id="leftBox" flex="1"/>
       <vbox id="rightBox" flex="1">
 #expand <label id="version" value="__MOZ_APP_VERSION__"/>
         <label id="distribution" class="text-blurb"/>
         <label id="distributionId" class="text-blurb"/>
-        <vbox id="updateBox">
+
+        <!-- Make sure the selectedIndex attribute is always set so that the CSS
+             selectors for transitions work -->        
+        <deck id="contentDeck" selectedIndex="0">
+          <vbox id="detailsBox">
+            <vbox id="updateBox">
 #ifdef MOZ_UPDATER
-          <deck id="updateDeck" orient="vertical">
-            <hbox id="updateButtonBox" align="center">
-              <button id="updateButton" align="start"
-                      oncommand="gAppUpdater.buttonOnCommand();"/>
-              <spacer flex="1"/>
-            </hbox>
-            <hbox id="checkingForUpdates" align="center">
-              <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
-            </hbox>
-            <hbox id="checkingAddonCompat" align="center">
-              <image class="update-throbber"/><label>&update.checkingAddonCompat;</label>
-            </hbox>
-            <hbox id="downloading" align="center">
-              <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
+              <deck id="updateDeck" orient="vertical">
+                <hbox id="updateButtonBox" align="center">
+                  <button id="updateButton" align="start"
+                          oncommand="gAppUpdater.buttonOnCommand();"/>
+                  <spacer flex="1"/>
+                </hbox>
+                <hbox id="checkingForUpdates" align="center">
+                  <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
+                </hbox>
+                <hbox id="checkingAddonCompat" align="center">
+                  <image class="update-throbber"/><label>&update.checkingAddonCompat;</label>
+                </hbox>
+                <hbox id="downloading" align="center">
+                  <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
+                </hbox>
+                <hbox id="downloadFailed" align="center">
+                  <label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
+                </hbox>
+                <hbox id="adminDisabled" align="center">
+                  <label>&update.adminDisabled;</label>
+                </hbox>
+                <hbox id="noUpdatesFound" align="center">
+                  <label>&update.noUpdatesFound;</label>
+                </hbox>
+                <hbox id="manualUpdate" align="center">
+                  <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
+                </hbox>
+              </deck>
+#endif
+            </vbox>
+
+            <description class="text-blurb" id="currentChannelText" hidden="true">
+              &channel.description.start;<label id="currentChannel"/>&channel.description.end;<label id="channelChangeLink" class="text-link" onclick="gChannelSelector.show();">&channel.change;</label>
+            </description>
+            <description class="text-blurb">
+              &community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end2;
+            </description>
+            <description class="text-blurb">
+              &contribute.start;<label class="text-link" href="http://www.mozilla.org/contribute/">&contribute.getInvolvedLink;</label>&contribute.end;
+            </description>
+          </vbox>
+
+          <vbox id="channelSelector">
+            <hbox pack="center" align="center">
+              <label>&channel.selector.start;</label>
+              <menulist id="channelMenulist" onselect="gChannelSelector.selectChannel(this.selectedItem);">
+                <menupopup>
+                  <menuitem id="releaseMenuitem" label="Release" value="release"/>
+                  <menuitem id="betaMenuitem" label="Beta" value="beta"/>
+                  <menuseparator/>
+                  <menuitem id="auroraMenuitem" label="Aurora" value="aurora"/>
+                </menupopup>
+              </menulist>
+              <label>&channel.selector.end;</label>
             </hbox>
-            <hbox id="downloadFailed" align="center">
-              <label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
-            </hbox>
-            <hbox id="adminDisabled" align="center">
-              <label>&update.adminDisabled;</label>
-            </hbox>
-            <hbox id="noUpdatesFound" align="center">
-              <label>&update.noUpdatesFound;</label>
+
+            <deck id="channelDescriptionDeck" selectedIndex="0">
+              <description id="releaseDescription" class="channel-description">&channel.release.description;</description>
+              <description id="betaDescription" class="channel-description">&channel.beta.description;</description>
+              <description id="auroraDescription" class="channel-description">&channel.aurora.description;</description>
+            </deck>
+
+            <hbox id="channelSelectorButtons" pack="center">
+              <button oncommand="gChannelSelector.apply();" label="&channel.selector.applyButton;"/>
+              <button oncommand="gChannelSelector.cancel();" label="&channel.selector.cancelButton;"/>
             </hbox>
-            <hbox id="manualUpdate" align="center">
-              <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
-            </hbox>
-          </deck>
-#endif
-        </vbox>
-        <description class="text-blurb">
-          &community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end2;
-        </description>
-        <description class="text-blurb">
-          &contribute.start;<label class="text-link" href="http://www.mozilla.org/contribute/">&contribute.getInvolvedLink;</label>&contribute.end;
-        </description>
+          </vbox>
+        </deck>
       </vbox>
     </hbox>
     <vbox id="bottomBox">
       <hbox pack="center">
         <label class="text-link bottom-link" href="about:license">&bottomLinks.license;</label>
         <label class="text-link bottom-link" href="about:rights">&bottomLinks.rights;</label>
         <label class="text-link bottom-link" href="http://www.mozilla.com/legal/privacy/">&bottomLinks.privacy;</label>
       </hbox>
--- a/browser/locales/en-US/chrome/browser/aboutDialog.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutDialog.dtd
@@ -49,8 +49,32 @@
 
 <!-- LOCALIZATION NOTE (update.downloading.start,update.downloading.end): update.downloading.start and 
      update.downloading.end all go into one line, with the amount downloaded inserted in between. As this
      is all in one line, try to make the localized text short (see bug 596813 for screenshots). The — is
      the "em dash" (long dash).
      example: Downloading update — 111 KB of 13 MB -->
 <!ENTITY update.downloading.start   "Downloading update — ">
 <!ENTITY update.downloading.end     "">
+
+<!-- LOCALIZATION NOTE (channel.description.start,channel.description.end): channel.description.start and
+     channel.description.end create one sentence, with the current channel label inserted in between.
+     example: You are currently on the _Stable_ update channel. -->
+<!ENTITY channel.description.start  "You are currently on the ">
+<!ENTITY channel.description.end    " update channel. ">
+
+<!ENTITY channel.change             "Change">
+
+<!ENTITY channel.release.description       "Enjoy the tried and tested final release being used by hundreds of millions around the world. Stay in control of your online experience with super speed, easy customization and the latest Web technologies.">
+<!ENTITY channel.beta.description          "Experience cutting edge features with more stability. Provide feedback to help refine and polish what will be in the final release.">
+<!ENTITY channel.aurora.description        "Experience the newest innovations in an unstable environment that's not for the faint of heart. Provide feedback on features and performance to help determine what makes the final release.">
+
+<!-- LOCALIZATION NOTE (channel.selector.start,channel.selector.end): channel.selector.start and
+     channel.selector.end create one sentence, with a channel selection menulist instered in between.
+     This is all in one line, so try to make the localized text short.
+     example: Switch to the [Stable] update channel. -->
+<!ENTITY channel.selector.start          "Switch to the">
+<!ENTITY channel.selector.end            "update channel.">
+
+<!-- LOCALIZATION NOTE (channel.selector.applyButton): This button applies the user's choice to switch
+     to a new update channel and starts the application update process. -->
+<!ENTITY channel.selector.applyButton    "Apply and Update">
+<!ENTITY channel.selector.cancelButton   "Cancel">