Bug 1433611 - Adjust the widths of the split box on toggling of the split rule view. r=pbro draft
authorGabriel Luong <gabriel.luong@gmail.com>
Thu, 05 Apr 2018 04:10:35 -0400
changeset 777739 9bf0759d963ee277b36e42862f99b71e6214d984
parent 777738 f2351acd6c6b73ee201e0a35f7c9eb9ac57c8094
push id105269
push userbmo:gl@mozilla.com
push dateThu, 05 Apr 2018 08:11:19 +0000
reviewerspbro
bugs1433611
milestone61.0a1
Bug 1433611 - Adjust the widths of the split box on toggling of the split rule view. r=pbro When the inspector is in landscape mode, it will first try to toggle on the 3 pane mode by creating a middle/bottom-left panel with the same sidebar width, but if doubling the original sidebar width will be bigger than half of the toolbox's width, we will instead toggle on the 3 pane mode with all panels being of equal widths. When the inspector is in portrait mode, it will just toggle on its T shape pane such that the 2 bottom panes are equal widths. We also increased the breakpoint width of the toolbox's side view to 1000px so that it will keep its T shape in portrait mode until the toolbox's width is bigger than 1000px. MozReview-Commit-ID: A5HngPkqHXe
devtools/client/inspector/grids/grid-inspector.js
devtools/client/inspector/inspector.js
devtools/client/inspector/test/browser.ini
devtools/client/inspector/test/browser_inspector_pane-toggle-01.js
devtools/client/inspector/test/browser_inspector_pane-toggle-02.js
devtools/client/inspector/test/browser_inspector_pane-toggle-03.js
devtools/client/inspector/test/browser_inspector_pane-toggle-04.js
devtools/client/shared/components/splitter/SplitBox.js
devtools/client/themes/inspector.css
--- a/devtools/client/inspector/grids/grid-inspector.js
+++ b/devtools/client/inspector/grids/grid-inspector.js
@@ -78,17 +78,23 @@ class GridInspector {
    * Initializes the grid inspector by fetching the LayoutFront from the walker, loading
    * the highlighter settings and initalizing the SwatchColorPicker instance.
    */
   async init() {
     if (!this.inspector) {
       return;
     }
 
-    this.layoutInspector = await this.inspector.walker.getLayoutInspector();
+    try {
+      this.layoutInspector = await this.inspector.walker.getLayoutInspector();
+    } catch (e) {
+      // This call might fail if called asynchrously after the toolbox is finished
+      // closing.
+      return;
+    }
 
     this.loadHighlighterSettings();
 
     // Create a shared SwatchColorPicker instance to be reused by all GridItem components.
     this.swatchColorPickerTooltip = new SwatchColorPickerTooltip(
       this.inspector.toolbox.doc,
       this.inspector,
       {
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -7,16 +7,17 @@
 /* global window, BrowserLoader */
 
 "use strict";
 
 const Services = require("Services");
 const promise = require("promise");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {executeSoon} = require("devtools/shared/DevToolsUtils");
+const {Toolbox} = require("devtools/client/framework/toolbox");
 const {PrefObserver} = require("devtools/client/shared/prefs");
 const Telemetry = require("devtools/client/shared/telemetry");
 const HighlightersOverlay = require("devtools/client/inspector/shared/highlighters-overlay");
 const ReflowTracker = require("devtools/client/inspector/shared/reflow-tracker");
 const Store = require("devtools/client/inspector/store");
 const InspectorStyleChangeTracker = require("devtools/client/inspector/shared/style-change-tracker");
 
 // Use privileged promise in panel documents to prevent having them to freeze
@@ -41,19 +42,23 @@ const INSPECTOR_L10N =
       new LocalizationHelper("devtools/client/locales/inspector.properties");
 loader.lazyGetter(this, "TOOLBOX_L10N", function() {
   return new LocalizationHelper("devtools/client/locales/toolbox.properties");
 });
 
 // Sidebar dimensions
 const INITIAL_SIDEBAR_SIZE = 350;
 
-// If the toolbox width is smaller than given amount of pixels,
-// the sidebar automatically switches from 'landscape' to 'portrait' mode.
-const PORTRAIT_MODE_WIDTH = 700;
+// If the toolbox's width is smaller than the given amount of pixels, the sidebar
+// automatically switches from 'landscape/horizontal' to 'portrait/vertical' mode.
+const PORTRAIT_MODE_WIDTH_THRESHOLD = 700;
+// If the toolbox's width docked to the side is smaller than the given amount of pixels,
+// the sidebar automatically switches from 'landscape/horizontal' to 'portrait/vertical'
+// mode.
+const SIDE_PORTAIT_MODE_WIDTH_THRESHOLD = 1000;
 
 const SHOW_SPLIT_SIDEBAR_TOGGLE_PREF = "devtools.inspector.split-sidebar-toggle";
 const SPLIT_RULE_VIEW_PREF = "devtools.inspector.split-rule-enabled";
 
 /**
  * Represents an open instance of the Inspector for a tab.
  * The inspector controls the breadcrumbs, the markup view, and the sidebar
  * (computed view, rule view, font view and animation inspector).
@@ -450,17 +455,19 @@ Inspector.prototype = {
 
   /**
    * Check if the inspector should use the landscape mode.
    *
    * @return {Boolean} true if the inspector should be in landscape mode.
    */
   useLandscapeMode: function() {
     let { clientWidth } = this.panelDoc.getElementById("inspector-splitter-box");
-    return clientWidth > PORTRAIT_MODE_WIDTH;
+    return this.isSplitRuleViewEnabled && this.toolbox.hostType == Toolbox.HostType.SIDE ?
+      clientWidth > SIDE_PORTAIT_MODE_WIDTH_THRESHOLD :
+      clientWidth > PORTRAIT_MODE_WIDTH_THRESHOLD;
   },
 
   /**
    * Build Splitter located between the main and side area of
    * the Inspector panel.
    */
   setupSplitter: function() {
     let SplitBox = this.React.createFactory(this.browserRequire(
@@ -478,17 +485,17 @@ Inspector.prototype = {
       startPanel: this.InspectorTabPanel({
         id: "inspector-main-content"
       }),
       endPanel: SplitBox({
         initialWidth: splitSidebarWidth,
         minSize: 10,
         maxSize: "80%",
         splitterSize: this.isSplitRuleViewEnabled ? 1 : 0,
-        endPanelControl: false,
+        endPanelControl: this.isSplitRuleViewEnabled,
         startPanel: this.InspectorTabPanel({
           id: "inspector-rules-container"
         }),
         endPanel: this.InspectorTabPanel({
           id: "inspector-sidebar-container"
         }),
         ref: splitbox => {
           this.sidebarSplitBox = splitbox;
@@ -584,64 +591,119 @@ Inspector.prototype = {
     this.isSplitRuleViewEnabled = !this.isSplitRuleViewEnabled;
     Services.prefs.setBoolPref(SPLIT_RULE_VIEW_PREF, this.isSplitRuleViewEnabled);
 
     await this.setupToolbar();
     await this.addRuleView();
   },
 
   /**
-   * Adds the rule view to the main or split sidebar depending on whether or not it is
-   * split view mode. The default tab specifies whether or not the rule view should be
-   * selected. The defaultTab defaults to the rule view when the rule view is being merged
-   * back into the sidebar from the split sidebar. Otherwise, we specify the default tab
-   * when handling the sidebar setup.
+   * Adds the rule view to the middle/bottom-left panel or inspector sidebar depending on
+   * whether or not it is 3 pane mode. The default tab specifies whether or not the rule
+   * view should be selected. The defaultTab defaults to the rule view when reverting to
+   * the 2 pane mode and the rule view is being merged back into the inspector sidebar
+   * from middle/bottom-left panel. Otherwise, we specify the default tab when handling
+   * the sidebar setup.
    *
    * @params {String} defaultTab
    *         Thie id of the default tab for the sidebar.
    */
   async addRuleView(defaultTab = "ruleview") {
-    let ruleViewSidebar = this.sidebarSplitBox.startPanelContainer;
+    const ruleViewSidebar = this.sidebarSplitBox.startPanelContainer;
+    const toolboxWidth =
+      this.panelDoc.getElementById("inspector-splitter-box").clientWidth;
 
     if (this.isSplitRuleViewEnabled) {
-      // Removes the rule view from the main sidebar and adds the rule view to the split
-      // sidebar.
+      // Convert to 3 pane mode by removing the rule view from the inspector sidebar
+      // and adding the rule view to the middle/bottom-left panel.
+
       ruleViewSidebar.style.display = "block";
 
-      // Show the splitter inside the sidebar split box.
-      this.sidebarSplitBox.setState({ splitterSize: 1 });
+      // Get the inspector sidebar's (right/bottom panel) width.
+      const sidebarWidth = this.splitBox.state.width;
+
+      // Whether or not doubling the inspector sidebar's (right/bottom panel) width will
+      // be bigger than half the size of the toolbox's width.
+      const canDoubleSidebarWidth = (sidebarWidth * 2) < (toolboxWidth / 2);
+      // This variable represents the width of the right/bottom-right panel width in 3
+      // pane mode.
+      let sidebarSplitboxWidth;
+
+      if (this.useLandscapeMode()) {
+        // Resize the main split box's end panel that contains the middle and right panel.
+        // Attempts to resize the main split box's end panel to be double the size of the
+        // existing sidebar's width when switching to 3 pane mode. However, if the middle
+        // and right panel's width together is greater than half of the toolbox's width,
+        // split all 3 panels to be equally sized by resizing the end panel to be 2/3 of
+        // the current toolbox's width.
+        this.splitBox.setState({
+          width: canDoubleSidebarWidth ? sidebarWidth * 2 : toolboxWidth * 2 / 3,
+        });
+
+        // In landscape/horizontal mode, set the right panel back to its original
+        // inspector sidebar width if we can double the sidebar width. Otherwise, set
+        // the width of the right panel to be 1/3 of the toolbox's width since all 3
+        // panels will be equally sized.
+        sidebarSplitboxWidth = canDoubleSidebarWidth ? sidebarWidth : toolboxWidth / 3;
+      } else {
+        // In portrait/vertical mode, set the bottom-right panel to be 1/2 of the
+        // toolbox's width.
+        sidebarSplitboxWidth = toolboxWidth / 2;
+      }
+
+      // Show the splitter inside the sidebar split box. Sets the width of the inspector
+      // sidebar and specify that the end (right/bottom-right) panel of the sidebar split
+      // box should be controlled when resizing.
+      this.sidebarSplitBox.setState({
+        endPanelControl: true,
+        splitterSize: 1,
+        width: sidebarSplitboxWidth,
+      });
 
       // Force the rule view panel creation by calling getPanel
       this.getPanel("ruleview");
 
       await this.sidebar.removeTab("ruleview");
 
       this.ruleViewSideBar.addExistingTab(
         "ruleview",
         INSPECTOR_L10N.getStr("inspector.sidebar.ruleViewTitle"),
         true);
 
       this.ruleViewSideBar.show("ruleview");
     } else {
-      // Removes the rule view from the split sidebar and adds the rule view to the main
-      // sidebar.
+      // Removes the rule view from the 3 pane mode and adds the rule view to the main
+      // inspector sidebar.
+
       ruleViewSidebar.style.display = "none";
 
-      // Hide the splitter to prevent any drag events in the sidebar split box.
-      this.sidebarSplitBox.setState({ splitterSize: 0 });
+      // Set the width of the split box (right/bottom panel) to be the width of the
+      // inspector sidebar.
+      this.splitBox.setState({
+        width: this.useLandscapeMode() ? this.sidebarSplitBox.state.width : toolboxWidth,
+      });
+
+      // Hide the splitter to prevent any drag events in the sidebar split box and
+      // specify that the end (right/bottom) panel should be uncontrolled when resizing.
+      this.sidebarSplitBox.setState({
+        endPanelControl: false,
+        splitterSize: 0,
+      });
 
       this.ruleViewSideBar.hide();
       await this.ruleViewSideBar.removeTab("ruleview");
 
       this.sidebar.addExistingTab(
         "ruleview",
         INSPECTOR_L10N.getStr("inspector.sidebar.ruleViewTitle"),
         defaultTab == "ruleview",
         0);
     }
+
+    this.emit("ruleview-added");
   },
 
   /**
    * Lazily get and create panel instances displayed in the sidebar
    */
   getPanel: function(id) {
     if (this._panels.has(id)) {
       return this._panels.get(id);
--- a/devtools/client/inspector/test/browser.ini
+++ b/devtools/client/inspector/test/browser.ini
@@ -156,16 +156,20 @@ skip-if = (os == 'linux' && bits == 32 &
 subsuite = clipboard
 skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
 [browser_inspector_menu-04-use-in-console.js]
 [browser_inspector_menu-05-attribute-items.js]
 [browser_inspector_menu-06-other.js]
 [browser_inspector_navigation.js]
 [browser_inspector_navigate_to_errors.js]
 [browser_inspector_open_on_neterror.js]
+[browser_inspector_pane-toggle-01.js]
+[browser_inspector_pane-toggle-02.js]
+[browser_inspector_pane-toggle-03.js]
+[browser_inspector_pane-toggle-04.js]
 [browser_inspector_picker-stop-on-destroy.js]
 [browser_inspector_picker-stop-on-tool-change.js]
 [browser_inspector_portrait_mode.js]
 [browser_inspector_pseudoclass-lock.js]
 [browser_inspector_pseudoclass-menu.js]
 [browser_inspector_reload-01.js]
 [browser_inspector_reload-02.js]
 [browser_inspector_remove-iframe-during-load.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_pane-toggle-01.js
@@ -0,0 +1,32 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests that the inspector panel has a 3 pane toggle button, and that
+// this button is visible both in BOTTOM and SIDE hosts.
+
+Services.prefs.setBoolPref("devtools.inspector.split-sidebar-toggle", true);
+
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.inspector.split-sidebar-toggle");
+});
+
+add_task(async function() {
+  info("Open the inspector in a bottom toolbox host");
+  const { inspector, toolbox } = await openInspectorForURL("about:blank", "bottom");
+
+  const button = inspector.panelDoc.querySelector(".sidebar-toggle");
+  ok(button, "The toggle button exists in the DOM");
+  ok(button.getAttribute("title"), "The title tooltip has initial state");
+  ok(button.classList.contains("pane-collapsed"), "The button is in collapsed state");
+  ok(!!button.getClientRects().length, "The button is visible");
+
+  info("Switch the host to side type");
+  await toolbox.switchHost("side");
+
+  ok(!!button.getClientRects().length, "The button is still visible");
+  ok(button.classList.contains("pane-collapsed"),
+    "The button is still in collapsed state");
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_pane-toggle-02.js
@@ -0,0 +1,51 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests that the 3 pane toggle button can toggle on and off the inspector's 3 pane mode,
+// and the 3 panes rendered are all of equal widths in the BOTTOM host.
+
+Services.prefs.setBoolPref("devtools.inspector.split-sidebar-toggle", true);
+
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.inspector.split-sidebar-toggle");
+});
+
+add_task(async function() {
+  const { inspector } = await openInspectorForURL("about:blank");
+  const { panelDoc: doc } = inspector;
+  const button = doc.querySelector(".sidebar-toggle");
+  const ruleViewSidebar = inspector.sidebarSplitBox.startPanelContainer;
+  const toolboxWidth = doc.getElementById("inspector-splitter-box").clientWidth;
+
+  ok(button.classList.contains("pane-collapsed"), "The button is in collapsed state");
+
+  info("Click on the toggle button to toggle ON 3 pane inspector");
+  EventUtils.synthesizeMouseAtCenter(button, {}, inspector.panelDoc.defaultView);
+  await inspector.once("ruleview-added");
+
+  info("Checking the state of the 3 pane inspector");
+  let sidebarWidth = inspector.splitBox.state.width;
+  let sidebarSplitBoxWidth = inspector.sidebarSplitBox.state.width;
+  ok(!button.classList.contains("pane-collapsed"), "The button is in expanded state");
+  ok(doc.getElementById("ruleview-panel"), "The rule view panel exist");
+  is(inspector.sidebar.getCurrentTabID(), "layoutview",
+    "Layout view is shown in the sidebar");
+  is(ruleViewSidebar.style.display, "block", "The split rule view sidebar is displayed");
+  is(sidebarWidth, toolboxWidth * 2 / 3, "Got correct main split box width");
+  is(sidebarSplitBoxWidth, toolboxWidth / 3, "Got correct sidebar split box width");
+
+  info("Click on the toggle button to toggle OFF the 3 pane inspector");
+  EventUtils.synthesizeMouseAtCenter(button, {}, inspector.panelDoc.defaultView);
+  await inspector.once("ruleview-added");
+
+  info("Checking the state of the 2 pane inspector");
+  sidebarWidth = inspector.splitBox.state.width;
+  ok(button.classList.contains("pane-collapsed"), "The button is in collapsed state");
+  is(inspector.sidebar.getCurrentTabID(), "ruleview",
+    "Rule view is shown in the sidebar");
+  is(ruleViewSidebar.style.display, "none", "The split rule view sidebar is hidden");
+  is(sidebarWidth, sidebarSplitBoxWidth, "Got correct sidebar width");
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_pane-toggle-03.js
@@ -0,0 +1,44 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests that the 3 pane inspector toggle can render the middle and right panels of equal
+// sizes when the original sidebar can be doubled in width and be smaller than half the
+// toolbox's width in the BOTTOM host.
+
+Services.prefs.setBoolPref("devtools.inspector.split-sidebar-toggle", true);
+
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.inspector.split-sidebar-toggle");
+});
+
+const SIDEBAR_WIDTH = 200;
+
+add_task(async function() {
+  const { inspector } = await openInspectorForURL("about:blank");
+  const { panelDoc: doc } = inspector;
+  const button = doc.querySelector(".sidebar-toggle");
+
+  info("Set the sidebar width to 200px");
+  inspector.splitBox.setState({ width: SIDEBAR_WIDTH });
+
+  info("Click on the toggle button to toggle ON 3 pane inspector");
+  EventUtils.synthesizeMouseAtCenter(button, {}, inspector.panelDoc.defaultView);
+  await inspector.once("ruleview-added");
+
+  info("Checking the sizes of the 3 pane inspector");
+  let sidebarWidth = inspector.splitBox.state.width;
+  let sidebarSplitBoxWidth = inspector.sidebarSplitBox.state.width;
+  is(sidebarWidth, SIDEBAR_WIDTH * 2, "Got correct main split box width");
+  is(sidebarSplitBoxWidth, SIDEBAR_WIDTH, "Got correct sidebar split box width");
+
+  info("Click on the toggle button to toggle OFF the 3 pane inspector");
+  EventUtils.synthesizeMouseAtCenter(button, {}, inspector.panelDoc.defaultView);
+  await inspector.once("ruleview-added");
+
+  info("Checking the sidebar size of the 2 pane inspector");
+  sidebarWidth = inspector.splitBox.state.width;
+  is(sidebarWidth, SIDEBAR_WIDTH, "Got correct sidebar width");
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_pane-toggle-04.js
@@ -0,0 +1,41 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests that the 3 pane inspector toggle button can render the bottom-left and
+// bottom-right panels of equal sizes in the SIDE host.
+
+Services.prefs.setBoolPref("devtools.inspector.split-sidebar-toggle", true);
+
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.inspector.split-sidebar-toggle");
+});
+
+add_task(async function() {
+  const { inspector, toolbox } = await openInspectorForURL("about:blank");
+  const { panelDoc: doc } = inspector;
+
+  info("Switch the host to side type");
+  await toolbox.switchHost("side");
+
+  const button = doc.querySelector(".sidebar-toggle");
+  const toolboxWidth = doc.getElementById("inspector-splitter-box").clientWidth;
+
+  info("Click on the toggle button to toggle ON 3 pane inspector");
+  EventUtils.synthesizeMouseAtCenter(button, {}, inspector.panelDoc.defaultView);
+  await inspector.once("ruleview-added");
+
+  info("Checking the sizes of the 3 pane inspector");
+  let sidebarSplitBoxWidth = inspector.sidebarSplitBox.state.width;
+  is(sidebarSplitBoxWidth, toolboxWidth / 2, "Got correct sidebar split box width");
+
+  info("Click on the toggle button to toggle OFF the 3 pane inspector");
+  EventUtils.synthesizeMouseAtCenter(button, {}, inspector.panelDoc.defaultView);
+  await inspector.once("ruleview-added");
+  debugger;
+  info("Checking the sidebar size of the 2 pane inspector");
+  let sidebarWidth = inspector.splitBox.state.width;
+  is(sidebarWidth, toolboxWidth, "Got correct sidebar width");
+});
--- a/devtools/client/shared/components/splitter/SplitBox.js
+++ b/devtools/client/shared/components/splitter/SplitBox.js
@@ -70,47 +70,56 @@ class SplitBox extends Component {
     super(props);
 
     /**
      * The state stores the current orientation (vertical or horizontal)
      * and the current size (width/height). All these values can change
      * during the component's life time.
      */
     this.state = {
+      endPanelControl: props.endPanelControl,
       vert: props.vert,
       splitterSize: props.splitterSize,
       width: props.initialWidth || props.initialSize,
       height: props.initialHeight || props.initialSize
     };
 
     this.onStartMove = this.onStartMove.bind(this);
     this.onStopMove = this.onStopMove.bind(this);
     this.onMove = this.onMove.bind(this);
   }
 
   componentWillReceiveProps(nextProps) {
-    let { splitterSize, vert } = nextProps;
+    let {
+      endPanelControl,
+      splitterSize,
+      vert,
+    } = nextProps;
+
+    if (endPanelControl != this.props.endPanelControl) {
+      this.setState({ endPanelControl });
+    }
 
     if (splitterSize != this.props.splitterSize) {
       this.setState({ splitterSize });
     }
 
     if (vert !== this.props.vert) {
       this.setState({ vert });
     }
   }
 
   shouldComponentUpdate(nextProps, nextState) {
     return nextState.width != this.state.width ||
+      nextState.endPanelControl != this.props.endPanelControl ||
       nextState.height != this.state.height ||
       nextState.vert != this.state.vert ||
       nextState.splitterSize != this.state.splitterSize ||
       nextProps.startPanel != this.props.startPanel ||
       nextProps.endPanel != this.props.endPanel ||
-      nextProps.endPanelControl != this.props.endPanelControl ||
       nextProps.minSize != this.props.minSize ||
       nextProps.maxSize != this.props.maxSize;
   }
 
   componentDidUpdate(prevProps, prevState) {
     if (this.props.onControlledPanelResized && (prevState.width !== this.state.width ||
                                                 prevState.height !== this.state.height)) {
       this.props.onControlledPanelResized(this.state.width, this.state.height);
@@ -149,19 +158,19 @@ class SplitBox extends Component {
    * Adjust size of the controlled panel. Depending on the current
    * orientation we either remember the width or height of
    * the splitter box.
    */
   onMove(x, y) {
     const node = ReactDOM.findDOMNode(this);
 
     let size;
-    let { endPanelControl } = this.props;
+    let { endPanelControl, vert } = this.state;
 
-    if (this.state.vert) {
+    if (vert) {
       // Switch the control flag in case of RTL. Note that RTL
       // has impact on vertical splitter only.
       if (document.dir === "rtl") {
         endPanelControl = !endPanelControl;
       }
 
       size = endPanelControl ?
         (node.offsetLeft + node.offsetWidth) - x :
@@ -179,18 +188,18 @@ class SplitBox extends Component {
         height: size
       });
     }
   }
 
   // Rendering
 
   render() {
-    const { splitterSize, vert } = this.state;
-    const { startPanel, endPanel, endPanelControl, minSize, maxSize } = this.props;
+    const { endPanelControl, splitterSize, vert } = this.state;
+    const { startPanel, endPanel, minSize, maxSize } = this.props;
 
     let style = Object.assign({}, this.props.style);
 
     // Calculate class names list.
     let classNames = ["split-box"];
     classNames.push(vert ? "vert" : "horz");
     if (this.props.className) {
       classNames = classNames.concat(this.props.className.split(" "));
--- a/devtools/client/themes/inspector.css
+++ b/devtools/client/themes/inspector.css
@@ -62,16 +62,20 @@ window {
 .inspector-tabpanel {
   min-width: 200px;
 }
 
 #inspector-splitter-box .controlled.pane-collapsed {
   visibility: collapse;
 }
 
+#inspector-splitter-box .sidebar-toggle::before {
+  transform: unset;
+}
+
 /* Use flex layout for the Inspector toolbar. For now, it's done
    specifically for the Inspector toolbar since general rule applied
    on .devtools-toolbar breaks breadcrumbs and also toolbars in other
    panels (e.g. webconsole, debugger), these are not ready for HTML
    layout yet. */
 #inspector-toolbar.devtools-toolbar {
   display: flex;
 }