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 236444 5cc3708f165a64ed29f76dcce34a40c77de44c33
parent 236443 c8e448fd5f6acaf8ac1f341ac397832688811e5b
child 236445 2b42c89f7343842f20d00fa1f1cff71f41f5dff5
push idunknown
push userunknown
push dateunknown
reviewersUnfocused
bugs1080934
milestone36.0a1
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;
+}