Bug 790650 - It may be a good idea to have the debugger start with collapsed panels, r=past
authorVictor Porof <vporof@mozilla.com>
Mon, 01 Oct 2012 15:55:32 +0100
changeset 108837 9e8a91dfbc7e07bf80fcaba5db3aeb04ebee4989
parent 108836 d4355e045ea76e8bd1f473bdae0e52194e11a4f3
child 108838 573907d351e3e1d0a51dba223be15b76aa92fdeb
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewerspast
bugs790650
milestone18.0a1
Bug 790650 - It may be a good idea to have the debugger start with collapsed panels, r=past
browser/devtools/debugger/debugger-controller.js
browser/devtools/debugger/debugger-view.js
browser/devtools/debugger/test/browser_dbg_pane-collapse.js
browser/themes/gnomestripe/devtools/debugger.css
browser/themes/pinstripe/devtools/debugger.css
browser/themes/winstripe/devtools/debugger.css
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -55,17 +55,18 @@ let DebuggerController = {
     DebuggerView.initializeKeys();
     DebuggerView.initializePanes();
     DebuggerView.initializeEditor(function() {
       DebuggerView.GlobalSearch.initialize();
       DebuggerView.Scripts.initialize();
       DebuggerView.StackFrames.initialize();
       DebuggerView.Breakpoints.initialize();
       DebuggerView.Properties.initialize();
-      DebuggerView.showCloseButton(!this._isRemoteDebugger && !this._isChromeDebugger);
+      DebuggerView.toggleCloseButton(!this._isRemoteDebugger &&
+                                     !this._isChromeDebugger);
 
       this.dispatchEvent("Debugger:Loaded");
       this._connect();
     }.bind(this));
   },
 
   /**
    * Destroys the debugger view, disconnects the debugger client and cleans up
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -1,16 +1,17 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 "use strict";
 
 const BREAKPOINT_LINE_TOOLTIP_MAX_SIZE = 1000; // chars
+const PANES_APPEARANCE_DELAY = 50; // ms
 const PROPERTY_VIEW_FLASH_DURATION = 400; // ms
 const GLOBAL_SEARCH_MATCH_FLASH_DURATION = 100; // ms
 const GLOBAL_SEARCH_URL_MAX_SIZE = 100; // chars
 const GLOBAL_SEARCH_LINE_MAX_SIZE = 300; // chars
 const GLOBAL_SEARCH_ACTION_DELAY = 150; // ms
 
 const SEARCH_GLOBAL_FLAG = "!";
 const SEARCH_LINE_FLAG = ":";
@@ -98,18 +99,18 @@ let DebuggerView = {
    * Initializes UI properties for all the displayed panes.
    */
   initializePanes: function DV_initializePanes() {
     this._togglePanesButton.addEventListener("click", this._onTogglePanesButtonPressed);
 
     this._stackframesAndBreakpoints.setAttribute("width", Prefs.stackframesWidth);
     this._variables.setAttribute("width", Prefs.variablesWidth);
 
-    this.showStackframesAndBreakpointsPane(Prefs.stackframesPaneVisible);
-    this.showVariablesPane(Prefs.variablesPaneVisible);
+    this.toggleStackframesAndBreakpointsPane({ silent: true });
+    this.toggleVariablesPane({ silent: true });
   },
 
   /**
    * Initializes the SourceEditor instance.
    *
    * @param function aCallback
    *        Called after the editor finishes initializing.
    */
@@ -168,79 +169,140 @@ let DebuggerView = {
     DebuggerController.Breakpoints.initialize();
     this.editor.focus();
   },
 
   /**
    * Called when the panes toggle button is clicked.
    */
   _onTogglePanesButtonPressed: function DV__onTogglePanesButtonPressed() {
-    this.showStackframesAndBreakpointsPane(
-      this._togglePanesButton.getAttribute("stackframesAndBreakpointsHidden"), true);
-
-    this.showVariablesPane(
-      this._togglePanesButton.getAttribute("variablesHidden"), true);
+    this.toggleStackframesAndBreakpointsPane({
+      visible: !!this._togglePanesButton.getAttribute("stackframesAndBreakpointsHidden"),
+      animated: true
+    });
+    this.toggleVariablesPane({
+      visible: !!this._togglePanesButton.getAttribute("variablesHidden"),
+      animated: true
+    });
+    this._onPanesToggle();
   },
 
   /**
    * Sets the close button hidden or visible. It's hidden by default.
    * @param boolean aVisibleFlag
    */
-  showCloseButton: function DV_showCloseButton(aVisibleFlag) {
+  toggleCloseButton: function DV_toggleCloseButton(aVisibleFlag) {
     document.getElementById("close").setAttribute("hidden", !aVisibleFlag);
   },
 
   /**
    * Sets the stackframes and breakpoints pane hidden or visible.
-   * @param boolean aVisibleFlag
-   * @param boolean aAnimatedFlag
+   *
+   * @param object aFlags [optional]
+   *        An object containing some of the following booleans:
+   *        - visible: true if the pane should be shown, false for hidden
+   *        - animated: true to display an animation on toggle
+   *        - silent: true to not update any designated prefs
    */
-  showStackframesAndBreakpointsPane:
-  function DV_showStackframesAndBreakpointsPane(aVisibleFlag, aAnimatedFlag) {
-    if (aAnimatedFlag) {
+  toggleStackframesAndBreakpointsPane:
+  function DV_toggleStackframesAndBreakpointsPane(aFlags = {}) {
+    if (aFlags.animated) {
       this._stackframesAndBreakpoints.setAttribute("animated", "");
     } else {
       this._stackframesAndBreakpoints.removeAttribute("animated");
     }
-    if (aVisibleFlag) {
+    if (aFlags.visible) {
       this._stackframesAndBreakpoints.style.marginLeft = "0";
       this._togglePanesButton.removeAttribute("stackframesAndBreakpointsHidden");
       this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("collapsePanes"));
     } else {
       let margin = parseInt(this._stackframesAndBreakpoints.getAttribute("width")) + 1;
       this._stackframesAndBreakpoints.style.marginLeft = -margin + "px";
       this._togglePanesButton.setAttribute("stackframesAndBreakpointsHidden", "true");
       this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("expandPanes"));
     }
-    Prefs.stackframesPaneVisible = aVisibleFlag;
+    if (!aFlags.silent) {
+      Prefs.stackframesPaneVisible = !!aFlags.visible;
+    }
   },
 
   /**
    * Sets the variable spane hidden or visible.
-   * @param boolean aVisibleFlag
-   * @param boolean aAnimatedFlag
+   *
+   * @param object aFlags [optional]
+   *        An object containing some of the following booleans:
+   *        - visible: true if the pane should be shown, false for hidden
+   *        - animated: true to display an animation on toggle
+   *        - silent: true to not update any designated prefs
    */
-  showVariablesPane:
-  function DV_showVariablesPane(aVisibleFlag, aAnimatedFlag) {
-    if (aAnimatedFlag) {
+  toggleVariablesPane:
+  function DV_toggleVariablesPane(aFlags = {}) {
+    if (aFlags.animated) {
       this._variables.setAttribute("animated", "");
     } else {
       this._variables.removeAttribute("animated");
     }
-    if (aVisibleFlag) {
+    if (aFlags.visible) {
       this._variables.style.marginRight = "0";
       this._togglePanesButton.removeAttribute("variablesHidden");
       this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("collapsePanes"));
     } else {
       let margin = parseInt(this._variables.getAttribute("width")) + 1;
       this._variables.style.marginRight = -margin + "px";
       this._togglePanesButton.setAttribute("variablesHidden", "true");
       this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("expandPanes"));
     }
-    Prefs.variablesPaneVisible = aVisibleFlag;
+    if (!aFlags.silent) {
+      Prefs.variablesPaneVisible = !!aFlags.visible;
+    }
+  },
+
+  /**
+   * Shows the stackframes, breakpoints and variable panes if currently hidden
+   * and the preferences dictate otherwise.
+   */
+  showPanesIfAllowed: function DV_showPanesIfAllowed() {
+    // Try to keep animations as smooth as possible, so wait a few cycles.
+    window.setTimeout(function() {
+      let shown;
+
+      if (Prefs.stackframesPaneVisible &&
+          this._togglePanesButton.getAttribute("stackframesAndBreakpointsHidden")) {
+        this.toggleStackframesAndBreakpointsPane({
+          visible: true,
+          animated: true,
+          silent: true
+        });
+        shown = true;
+      }
+      if (Prefs.variablesPaneVisible &&
+          this._togglePanesButton.getAttribute("variablesHidden")) {
+        this.toggleVariablesPane({
+          visible: true,
+          animated: true,
+          silent: true
+        });
+        shown = true;
+      }
+      if (shown) {
+        this._onPanesToggle();
+      }
+    }.bind(this), PANES_APPEARANCE_DELAY);
+  },
+
+  /**
+   * Displaying the panes may have the effect of triggering scrollbars to
+   * appear in the source editor, which would render the currently highlighted
+   * line to appear behind them in some cases.
+   */
+  _onPanesToggle: function DV__onPanesToggle() {
+    document.addEventListener("transitionend", function onEvent() {
+      document.removeEventListener("transitionend", onEvent);
+      DebuggerController.StackFrames.updateEditorLocation();
+    });
   },
 
   /**
    * The cached global view elements.
    */
   _togglePanesButton: null,
   _stackframesAndBreakpoints: null,
   _stackframes: null,
@@ -1620,16 +1682,18 @@ StackFramesView.prototype = {
    * @return object
    *         The newly created html node representing the added frame.
    */
   addFrame: function DVF_addFrame(aDepth, aFrameNameText, aFrameDetailsText) {
     // Make sure we don't duplicate anything.
     if (document.getElementById("stackframe-" + aDepth)) {
       return null;
     }
+    // Stackframes are UI elements which benefit from visible panes.
+    DebuggerView.showPanesIfAllowed();
 
     let frame = document.createElement("box");
     let frameName = document.createElement("label");
     let frameDetails = document.createElement("label");
 
     // Create a list item to be added to the stackframes container.
     frame.id = "stackframe-" + aDepth;
     frame.className = "dbg-stackframe list-item";
--- a/browser/devtools/debugger/test/browser_dbg_pane-collapse.js
+++ b/browser/devtools/debugger/test/browser_dbg_pane-collapse.js
@@ -14,42 +14,62 @@ var gView = null;
 function test() {
   debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.contentWindow;
     gView = gDebugger.DebuggerView;
 
+    testPanesState();
+
+    gView.toggleStackframesAndBreakpointsPane({ visible: true });
+    gView.toggleVariablesPane({ visible: true });
     testPaneCollapse1();
     testPaneCollapse2();
+
     closeDebuggerAndFinish();
   });
 }
 
+function testPanesState() {
+  let togglePanesButton =
+    gDebugger.document.getElementById("toggle-panes");
+
+  ok(togglePanesButton.getAttribute("stackframesAndBreakpointsHidden"),
+    "The stackframes and breakpoints pane should initially be invisible.");
+  is(gDebugger.Prefs.stackframesPaneVisible, true,
+    "The stackframes and breakpoints pane should initially be preffed as visible.");
+
+  ok(togglePanesButton.getAttribute("variablesHidden"),
+    "The stackframes and breakpoints pane should initially be invisible.");
+  is(gDebugger.Prefs.variablesPaneVisible, true,
+    "The stackframes and breakpoints pane should initially be preffed as visible.");
+}
+
 function testPaneCollapse1() {
   let stackframesAndBrekpoints =
     gDebugger.document.getElementById("stackframes+breakpoints");
   let togglePanesButton =
     gDebugger.document.getElementById("toggle-panes");
 
   let width = parseInt(stackframesAndBrekpoints.getAttribute("width"));
   is(width, gDebugger.Prefs.stackframesWidth,
     "The stackframes and breakpoints pane has an incorrect width.");
   is(stackframesAndBrekpoints.style.marginLeft, "0px",
-    "The stackframes and breakpoints pane has an incorrect initial left margin.");
+    "The stackframes and breakpoints pane has an incorrect left margin.");
   ok(!stackframesAndBrekpoints.hasAttribute("animated"),
-    "The stackframes and breakpoints pane has an incorrect initial animated attribute.");
+    "The stackframes and breakpoints pane has an incorrect animated attribute.");
   ok(!togglePanesButton.getAttribute("stackframesAndBreakpointsHidden"),
-    "The stackframes and breakpoints pane should initially be visible.");
+    "The stackframes and breakpoints pane should at this point be visible.");
 
   is(gDebugger.Prefs.stackframesPaneVisible, true,
-    "The stackframes and breakpoints pane should initially be visible.");
+    "The stackframes and breakpoints pane should at this point be visible.");
 
-  gView.showStackframesAndBreakpointsPane(false, true);
+  gView.toggleStackframesAndBreakpointsPane({ visible: false, animated: true });
 
   is(gDebugger.Prefs.stackframesPaneVisible, false,
     "The stackframes and breakpoints pane should be hidden after collapsing.");
 
   let margin = -(width + 1) + "px";
   is(width, gDebugger.Prefs.stackframesWidth,
     "The stackframes and breakpoints pane has an incorrect width after collapsing.");
   is(stackframesAndBrekpoints.style.marginLeft, margin,
@@ -57,17 +77,17 @@ function testPaneCollapse1() {
   ok(stackframesAndBrekpoints.hasAttribute("animated"),
     "The stackframes and breakpoints pane has an incorrect attribute after an animated collapsing.");
   ok(togglePanesButton.hasAttribute("stackframesAndBreakpointsHidden"),
     "The stackframes and breakpoints pane should not be visible after collapsing.");
 
   is(gDebugger.Prefs.stackframesPaneVisible, false,
     "The stackframes and breakpoints pane should be hidden before uncollapsing.");
 
-  gView.showStackframesAndBreakpointsPane(true, false);
+  gView.toggleStackframesAndBreakpointsPane({ visible: true, animated: false });
 
   is(gDebugger.Prefs.stackframesPaneVisible, true,
     "The stackframes and breakpoints pane should be visible after uncollapsing.");
 
   is(width, gDebugger.Prefs.stackframesWidth,
     "The stackframes and breakpoints pane has an incorrect width after uncollapsing.");
   is(stackframesAndBrekpoints.style.marginLeft, "0px",
     "The stackframes and breakpoints pane has an incorrect left margin after uncollapsing.");
@@ -82,26 +102,26 @@ function testPaneCollapse2() {
     gDebugger.document.getElementById("variables");
   let togglePanesButton =
     gDebugger.document.getElementById("toggle-panes");
 
   let width = parseInt(variables.getAttribute("width"));
   is(width, gDebugger.Prefs.variablesWidth,
     "The variables pane has an incorrect width.");
   is(variables.style.marginRight, "0px",
-    "The variables pane has an incorrect initial right margin.");
+    "The variables pane has an incorrect right margin.");
   ok(!variables.hasAttribute("animated"),
-    "The variables pane has an incorrect initial animated attribute.");
+    "The variables pane has an incorrect animated attribute.");
   ok(!togglePanesButton.getAttribute("variablesHidden"),
-    "The variables pane should initially be visible.");
+    "The variables pane should at this point be visible.");
 
   is(gDebugger.Prefs.variablesPaneVisible, true,
-    "The variables pane should initially be visible.");
+    "The variables pane should at this point be visible.");
 
-  gView.showVariablesPane(false, true);
+  gView.toggleVariablesPane({ visible: false, animated: true });
 
   is(gDebugger.Prefs.variablesPaneVisible, false,
     "The variables pane should be hidden after collapsing.");
 
   let margin = -(width + 1) + "px";
   is(width, gDebugger.Prefs.variablesWidth,
     "The variables pane has an incorrect width after collapsing.");
   is(variables.style.marginRight, margin,
@@ -109,17 +129,17 @@ function testPaneCollapse2() {
   ok(variables.hasAttribute("animated"),
     "The variables pane has an incorrect attribute after an animated collapsing.");
   ok(togglePanesButton.hasAttribute("variablesHidden"),
     "The variables pane should not be visible after collapsing.");
 
   is(gDebugger.Prefs.variablesPaneVisible, false,
     "The variables pane should be hidden before uncollapsing.");
 
-  gView.showVariablesPane(true, false);
+  gView.toggleVariablesPane({ visible: true, animated: false });
 
   is(gDebugger.Prefs.variablesPaneVisible, true,
     "The variables pane should be visible after uncollapsing.");
 
   is(width, gDebugger.Prefs.variablesWidth,
     "The variables pane has an incorrect width after uncollapsing.");
   is(variables.style.marginRight, "0px",
     "The variables pane has an incorrect right margin after uncollapsing.");
--- a/browser/themes/gnomestripe/devtools/debugger.css
+++ b/browser/themes/gnomestripe/devtools/debugger.css
@@ -1,16 +1,16 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #body {
-  background: -moz-dialog;
+  background-color: white;
 }
 
 /**
  * Debugger content
  */
 
 #dbg-content {
   padding: 0;
--- a/browser/themes/pinstripe/devtools/debugger.css
+++ b/browser/themes/pinstripe/devtools/debugger.css
@@ -2,17 +2,17 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 %include ../shared.inc
 
 #body {
-  background: -moz-dialog;
+  background-color: white;
 }
 
 /**
  * Debugger content
  */
 
 #dbg-content {
   padding: 0;
--- a/browser/themes/winstripe/devtools/debugger.css
+++ b/browser/themes/winstripe/devtools/debugger.css
@@ -1,16 +1,16 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #body {
-  background: -moz-dialog;
+  background-color: white;
 }
 
 /**
  * Debugger content
  */
 
 #dbg-content {
   padding: 0;