Bug 1080934 - add radio buttons to about:welcomeback. r=Unfocused
authorMark Hammond <mhammond@skippinet.com.au>
Fri, 24 Oct 2014 10:56:33 +1100
changeset 212130 5cc3708f165a64ed29f76dcce34a40c77de44c33
parent 212129 c8e448fd5f6acaf8ac1f341ac397832688811e5b
child 212131 2b42c89f7343842f20d00fa1f1cff71f41f5dff5
push id27698
push usercbook@mozilla.com
push dateFri, 24 Oct 2014 13:53:50 +0000
treeherdermozilla-central@6e35802ae3e2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused
bugs1080934
milestone36.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 1080934 - add radio buttons to about:welcomeback. r=Unfocused
browser/components/migration/content/aboutWelcomeBack.xhtml
browser/components/sessionstore/content/aboutSessionRestore.js
browser/components/sessionstore/content/aboutSessionRestore.xhtml
browser/themes/shared/aboutWelcomeBack.css
--- a/browser/components/migration/content/aboutWelcomeBack.xhtml
+++ b/browser/components/migration/content/aboutWelcomeBack.xhtml
@@ -47,16 +47,30 @@
         </div>
 
         <!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
         <div id="errorLongDesc">
         </div>
 
         <!-- Short Description -->
         <div id="errorTrailerDesc">
+          <div>
+            <div class="radioRestoreContainer">
+              <input class="radioRestoreButton" id="radioRestoreAll" type="radio"
+                     name="restore" checked="checked"/>
+              <label class="radioRestoreLabel" for="radioRestoreAll">&welcomeback2.label.restoreAll;</label>
+            </div>
+
+            <div class="radioRestoreContainer">
+              <input class="radioRestoreButton" id="radioRestoreChoose" type="radio"
+                     name="restore"/>
+              <label class="radioRestoreLabel" for="radioRestoreChoose">&welcomeback2.label.restoreSome;</label>
+            </div>
+          </div>
+
           <tree xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
                 id="tabList" flex="1" seltype="single" hidecolumnpicker="true"
                 onclick="onListClick(event);" onkeydown="onListKeyDown(event);"
                 _window_label="&restorepage.windowLabel;">
             <treecols>
               <treecol cycler="true" id="restore" type="checkbox" label="&restorepage.restoreHeader;"/>
               <splitter class="tree-splitter"/>
               <treecol primary="true" id="title" label="&restorepage.listHeader;" flex="1"/>
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -15,16 +15,24 @@ window.onload = function() {
   // pages used by this script may have a link that needs to be updated to
   // the in-product link.
   let anchor = document.getElementById("linkMoreTroubleshooting");
   if (anchor) {
     let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
     anchor.setAttribute("href", baseURL + "troubleshooting");
   }
 
+  // wire up click handlers for the radio buttons if they exist.
+  for (let radioId of ["radioRestoreAll", "radioRestoreChoose"]) {
+    let button = document.getElementById(radioId);
+    if (button) {
+      button.addEventListener("click", updateTabListVisibility);
+    }
+  }
+
   // the crashed session state is kept inside a textbox so that SessionStore picks it up
   // (for when the tab is closed or the session crashes right again)
   var sessionData = document.getElementById("sessionData");
   if (!sessionData.value) {
     document.getElementById("errorTryAgain").disabled = true;
     return;
   }
 
@@ -35,17 +43,27 @@ window.onload = function() {
   event.initUIEvent("input", true, true, window, 0);
   sessionData.dispatchEvent(event);
 
   initTreeView();
 
   document.getElementById("errorTryAgain").focus();
 };
 
+function isTreeViewVisible() {
+  let tabList = document.getElementById("tabList");
+  return tabList.hasAttribute("available");
+}
+
 function initTreeView() {
+  // If we aren't visible we initialize as we are made visible (and it's OK
+  // to initialize multiple times)
+  if (!isTreeViewVisible()) {
+    return;
+  }
   var tabList = document.getElementById("tabList");
   var winLabel = tabList.getAttribute("_window_label");
 
   gTreeData = [];
   gStateObject.windows.forEach(function(aWinData, aIx) {
     var winState = {
       label: winLabel.replace("%S", (aIx + 1)),
       open: true,
@@ -70,41 +88,52 @@ function initTreeView() {
       gTreeData.push(tab);
   }, this);
 
   tabList.view = treeView;
   tabList.view.selection.select(0);
 }
 
 // User actions
+function updateTabListVisibility() {
+  let tabList = document.getElementById("tabList");
+  if (document.getElementById("radioRestoreChoose").checked) {
+    tabList.setAttribute("available", "true");
+  } else {
+    tabList.removeAttribute("available");
+  }
+  initTreeView();
+}
 
 function restoreSession() {
   document.getElementById("errorTryAgain").disabled = true;
 
-  if (!gTreeData.some(aItem => aItem.checked)) {
-    // This should only be possible when we have no "cancel" button, and thus
-    // the "Restore session" button always remains enabled.  In that case and
-    // when nothing is selected, we just want a new session.
-    startNewSession();
-    return;
-  }
+  if (isTreeViewVisible()) {
+    if (!gTreeData.some(aItem => aItem.checked)) {
+      // This should only be possible when we have no "cancel" button, and thus
+      // the "Restore session" button always remains enabled.  In that case and
+      // when nothing is selected, we just want a new session.
+      startNewSession();
+      return;
+    }
 
-  // remove all unselected tabs from the state before restoring it
-  var ix = gStateObject.windows.length - 1;
-  for (var t = gTreeData.length - 1; t >= 0; t--) {
-    if (treeView.isContainer(t)) {
-      if (gTreeData[t].checked === 0)
-        // this window will be restored partially
-        gStateObject.windows[ix].tabs =
-          gStateObject.windows[ix].tabs.filter(function(aTabData, aIx)
-                                                 gTreeData[t].tabs[aIx].checked);
-      else if (!gTreeData[t].checked)
-        // this window won't be restored at all
-        gStateObject.windows.splice(ix, 1);
-      ix--;
+    // remove all unselected tabs from the state before restoring it
+    var ix = gStateObject.windows.length - 1;
+    for (var t = gTreeData.length - 1; t >= 0; t--) {
+      if (treeView.isContainer(t)) {
+        if (gTreeData[t].checked === 0)
+          // this window will be restored partially
+          gStateObject.windows[ix].tabs =
+            gStateObject.windows[ix].tabs.filter(function(aTabData, aIx)
+                                                   gTreeData[t].tabs[aIx].checked);
+        else if (!gTreeData[t].checked)
+          // this window won't be restored at all
+          gStateObject.windows.splice(ix, 1);
+        ix--;
+      }
     }
   }
   var stateString = JSON.stringify(gStateObject);
 
   var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
   var top = getBrowserWindow();
 
   // if there's only this page open, reuse the window for restoring the session
--- a/browser/components/sessionstore/content/aboutSessionRestore.xhtml
+++ b/browser/components/sessionstore/content/aboutSessionRestore.xhtml
@@ -52,17 +52,17 @@
           </ul>
         </div>
 
         <!-- Short Description -->
         <div id="errorTrailerDesc">
           <tree xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
                 id="tabList" flex="1" seltype="single" hidecolumnpicker="true"
                 onclick="onListClick(event);" onkeydown="onListKeyDown(event);"
-                _window_label="&restorepage.windowLabel;">
+                available="true" _window_label="&restorepage.windowLabel;">
             <treecols>
               <treecol cycler="true" id="restore" type="checkbox" label="&restorepage.restoreHeader;"/>
               <splitter class="tree-splitter"/>
               <treecol primary="true" id="title" label="&restorepage.listHeader;" flex="1"/>
             </treecols>
             <treechildren flex="1"/>
           </tree>
         </div>
--- a/browser/themes/shared/aboutWelcomeBack.css
+++ b/browser/themes/shared/aboutWelcomeBack.css
@@ -1,7 +1,42 @@
 /* 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/. */
 
 #errorPageContainer {
   background-image: url("chrome://global/skin/icons/information-64.png");
+  height: auto;
 }
+
+/* tablist starts out hidden, but JS may make it visible in response to
+   clicks on the radio buttons by setting an "available" attribute.
+*/
+#tabList {
+  display: none;
+}
+
+#tabList[available] {
+  display: -moz-box;
+}
+
+.radioRestoreContainer {
+  display: flex;
+}
+
+.radioRestoreButton {
+  flex: 0 0 auto;
+}
+
+.radioRestoreButton:-moz-focusring {
+  outline: 1px dotted black;
+}
+
+.radioChooseLabel {
+  flex: 1 1 auto;
+}
+
+/* We want errorTrailerDesc to have the same padding-top as errorShortDesc
+   has padding-bottom
+*/
+#errorTrailerDesc {
+  padding-top: 1em;
+}