Bug 1484483 - Part 3: Show the list of flex container properites in the Flexbox panel. r=rcaliman
authorGabriel Luong <gabriel.luong@gmail.com>
Wed, 22 Aug 2018 21:07:08 -0400
changeset 490712 5d02165bc7675c9be1803a9425893ff010ff6ce4
parent 490711 b3d9ddf714d50a41300439fe698fffaa8ea9fa8d
child 490713 933160fab8222159598649dd312f0466f1943bf3
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrcaliman
bugs1484483
milestone63.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 1484483 - Part 3: Show the list of flex container properites in the Flexbox panel. r=rcaliman
devtools/client/inspector/boxmodel/components/BoxModelProperties.js
devtools/client/inspector/boxmodel/components/ComputedProperty.js
devtools/client/inspector/boxmodel/components/moz.build
devtools/client/inspector/boxmodel/test/browser_boxmodel_properties.js
devtools/client/inspector/flexbox/components/FlexContainerProperties.js
devtools/client/inspector/flexbox/components/Flexbox.js
devtools/client/inspector/flexbox/components/moz.build
devtools/client/inspector/flexbox/flexbox.js
devtools/client/inspector/flexbox/reducers/flexbox.js
devtools/client/inspector/flexbox/types.js
devtools/client/inspector/layout/components/ComputedProperty.js
devtools/client/inspector/layout/components/moz.build
devtools/client/locales/en-US/layout.properties
devtools/client/themes/boxmodel.css
devtools/client/themes/layout.css
--- a/devtools/client/inspector/boxmodel/components/BoxModelProperties.js
+++ b/devtools/client/inspector/boxmodel/components/BoxModelProperties.js
@@ -4,17 +4,17 @@
 
 "use strict";
 
 const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const { LocalizationHelper } = require("devtools/shared/l10n");
 
-const ComputedProperty = createFactory(require("./ComputedProperty"));
+const ComputedProperty = createFactory(require("devtools/client/inspector/layout/components/ComputedProperty"));
 
 const Types = require("../types");
 
 const BOXMODEL_STRINGS_URI = "devtools/client/locales/boxmodel.properties";
 const BOXMODEL_L10N = new LocalizationHelper(BOXMODEL_STRINGS_URI);
 
 class BoxModelProperties extends PureComponent {
   static get propTypes() {
@@ -81,45 +81,45 @@ class BoxModelProperties extends PureCom
 
     const layoutInfo = ["box-sizing", "display", "float",
                         "line-height", "position", "z-index"];
 
     const properties = layoutInfo.map(info => {
       const { referenceElement, referenceElementType } = this.getReferenceElement(info);
 
       return ComputedProperty({
+        key: info,
         name: info,
-        key: info,
         onHideBoxModelHighlighter,
         onShowBoxModelHighlighterForNode,
         referenceElement,
         referenceElementType,
         setSelectedNode,
         value: layout[info],
       });
     });
 
-    return dom.div({ className: "boxmodel-properties" },
+    return dom.div({ className: "layout-properties" },
       dom.div(
         {
-          className: "boxmodel-properties-header",
+          className: "layout-properties-header",
           onDoubleClick: this.onToggleExpander,
         },
         dom.span(
           {
-            className: "boxmodel-properties-expander theme-twisty",
+            className: "layout-properties-expander theme-twisty",
             open: this.state.isOpen,
             onClick: this.onToggleExpander,
           }
         ),
         BOXMODEL_L10N.getStr("boxmodel.propertiesLabel")
       ),
       dom.div(
         {
-          className: "boxmodel-properties-wrapper devtools-monospace",
+          className: "layout-properties-wrapper devtools-monospace",
           hidden: !this.state.isOpen,
           tabIndex: 0,
         },
         properties
       )
     );
   }
 }
--- a/devtools/client/inspector/boxmodel/components/moz.build
+++ b/devtools/client/inspector/boxmodel/components/moz.build
@@ -5,10 +5,9 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DevToolsModules(
     'BoxModel.js',
     'BoxModelEditable.js',
     'BoxModelInfo.js',
     'BoxModelMain.js',
     'BoxModelProperties.js',
-    'ComputedProperty.js',
 )
--- a/devtools/client/inspector/boxmodel/test/browser_boxmodel_properties.js
+++ b/devtools/client/inspector/boxmodel/test/browser_boxmodel_properties.js
@@ -110,11 +110,11 @@ async function testChangingValues(inspec
 
   for (const { property, value } of res2) {
     const elt = doc.querySelector(getPropertySelector(property));
     is(elt.textContent, value, property + " has the right value after style update.");
   }
 }
 
 function getPropertySelector(propertyName) {
-  return `.boxmodel-properties-wrapper .computed-property-view` +
+  return `.boxmodel-container .computed-property-view` +
   `[data-property-name=${propertyName}] .computed-property-value`;
 }
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/flexbox/components/FlexContainerProperties.js
@@ -0,0 +1,82 @@
+/* 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 { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+const { getStr } = require("devtools/client/inspector/layout/utils/l10n");
+
+const ComputedProperty = createFactory(require("devtools/client/inspector/layout/components/ComputedProperty"));
+
+class FlexContainerProperties extends PureComponent {
+  static get propTypes() {
+    return {
+      properties: PropTypes.object.isRequired,
+    };
+  }
+
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      // Whether or not the properties are shown.
+      isShown: true,
+    };
+
+    this.onToggleExpander = this.onToggleExpander.bind(this);
+  }
+
+  onToggleExpander(event) {
+    event.stopPropagation();
+
+    this.setState((prevState) => {
+      return {
+        isShown: !prevState.isShown,
+      };
+    });
+  }
+
+  render() {
+    const { properties } =  this.props;
+
+    return (
+      dom.div(
+        {
+          id: "flex-container-properties",
+          className: "flexbox-container",
+        },
+        dom.div(
+          {
+            className: "layout-properties-header",
+            onDoubleClick: this.onToggleExpander,
+          },
+          dom.span(
+            {
+              className: "layout-properties-expander theme-twisty",
+              open: this.state.isShown,
+              onClick: this.onToggleExpander,
+            }
+          ),
+          getStr("flexbox.flexContainerProperties")
+        ),
+        dom.div(
+          {
+            className: "layout-properties-wrapper devtools-monospace",
+            hidden: !this.state.isShown,
+            tabIndex: 0,
+          },
+          Object.entries(properties).map(([name, value]) => ComputedProperty({
+            key: name,
+            name,
+            value,
+          }))
+        )
+      )
+    );
+  }
+}
+
+module.exports = FlexContainerProperties;
--- a/devtools/client/inspector/flexbox/components/Flexbox.js
+++ b/devtools/client/inspector/flexbox/components/Flexbox.js
@@ -7,16 +7,19 @@
 const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const { getStr } = require("devtools/client/inspector/layout/utils/l10n");
 
 loader.lazyGetter(this, "FlexContainerList", function() {
   return createFactory(require("./FlexContainerList"));
 });
+loader.lazyGetter(this, "FlexContainerProperties", function() {
+  return createFactory(require("./FlexContainerProperties"));
+});
 
 const Types = require("../types");
 
 class Flexbox extends PureComponent {
   static get propTypes() {
     return {
       flexbox: PropTypes.shape(Types.flexbox).isRequired,
       getSwatchColorPickerTooltip: PropTypes.func.isRequired,
@@ -54,15 +57,18 @@ class Flexbox extends PureComponent {
             flexbox,
             getSwatchColorPickerTooltip,
             onHideBoxModelHighlighter,
             onSetFlexboxOverlayColor,
             onShowBoxModelHighlighterForNode,
             onToggleFlexboxHighlighter,
             setSelectedNode,
           })
-        )
+        ),
+        FlexContainerProperties({
+          properties: flexbox.properties,
+        })
       )
     );
   }
 }
 
 module.exports = Flexbox;
--- a/devtools/client/inspector/flexbox/components/moz.build
+++ b/devtools/client/inspector/flexbox/components/moz.build
@@ -3,9 +3,10 @@
 # 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/.
 
 DevToolsModules(
     'Flexbox.js',
     'FlexContainerItem.js',
     'FlexContainerList.js',
+    'FlexContainerProperties.js',
 )
--- a/devtools/client/inspector/flexbox/flexbox.js
+++ b/devtools/client/inspector/flexbox/flexbox.js
@@ -341,13 +341,14 @@ class FlexboxInspector {
     const customColors = await this.getCustomFlexboxColors();
     const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR;
 
     this.store.dispatch(updateFlexbox({
       actorID: flexboxFront.actorID,
       color,
       highlighted,
       nodeFront,
+      properties: flexboxFront.properties,
     }));
   }
 }
 
 module.exports = FlexboxInspector;
--- a/devtools/client/inspector/flexbox/reducers/flexbox.js
+++ b/devtools/client/inspector/flexbox/reducers/flexbox.js
@@ -15,16 +15,18 @@ const INITIAL_FLEXBOX = {
   // The actor ID of the flex container.
   actorID: null,
   // The color of the flexbox highlighter overlay.
   color: "",
   // Whether or not the flexbox highlighter is highlighting the flex container.
   highlighted: false,
   // The NodeFront of the flex container.
   nodeFront: null,
+  // The computed style properties of the flex container.
+  properties: {},
 };
 
 const reducers = {
 
   [CLEAR_FLEXBOX](flexbox, _) {
     return INITIAL_FLEXBOX;
   },
 
--- a/devtools/client/inspector/flexbox/types.js
+++ b/devtools/client/inspector/flexbox/types.js
@@ -15,9 +15,12 @@ exports.flexbox = {
   color: PropTypes.string,
 
   // Whether or not the flexbox highlighter is highlighting the flex container.
   highlighted: PropTypes.bool,
 
   // The NodeFront of the flex container.
   nodeFront: PropTypes.object,
 
+  // The computed style properties of the flex container.
+  properties: PropTypes.object,
+
 };
rename from devtools/client/inspector/boxmodel/components/ComputedProperty.js
rename to devtools/client/inspector/layout/components/ComputedProperty.js
--- a/devtools/client/inspector/boxmodel/components/ComputedProperty.js
+++ b/devtools/client/inspector/layout/components/ComputedProperty.js
@@ -11,103 +11,99 @@ const { translateNodeFrontToGrip } = req
 
 const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
 const { Rep } = REPS;
 
 class ComputedProperty extends PureComponent {
   static get propTypes() {
     return {
       name: PropTypes.string.isRequired,
+      onHideBoxModelHighlighter: PropTypes.func,
+      onShowBoxModelHighlighterForNode: PropTypes.func,
       referenceElement: PropTypes.object,
       referenceElementType: PropTypes.string,
-      setSelectedNode: PropTypes.func.isRequired,
+      setSelectedNode: PropTypes.func,
       value: PropTypes.string,
-      onHideBoxModelHighlighter: PropTypes.func.isRequired,
-      onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
     };
   }
 
   constructor(props) {
     super(props);
+
+    this.onFocus = this.onFocus.bind(this);
     this.renderReferenceElementPreview = this.renderReferenceElementPreview.bind(this);
-    this.onFocus = this.onFocus.bind(this);
+  }
+
+  onFocus() {
+    this.container.focus();
   }
 
   renderReferenceElementPreview() {
     const {
+      onShowBoxModelHighlighterForNode,
+      onHideBoxModelHighlighter,
       referenceElement,
       referenceElementType,
       setSelectedNode,
-      onShowBoxModelHighlighterForNode,
-      onHideBoxModelHighlighter
     } = this.props;
 
     if (!referenceElement) {
       return null;
     }
 
-    return dom.div(
-      {
-        className: "reference-element"
-      },
-      dom.span({ className: "reference-element-type" }, referenceElementType),
-      Rep({
-        defaultRep: referenceElement,
-        mode: MODE.TINY,
-        object: translateNodeFrontToGrip(referenceElement),
-        onInspectIconClick: () => setSelectedNode(referenceElement,
-          { reason: "box-model" }),
-        onDOMNodeMouseOver: () => onShowBoxModelHighlighterForNode(referenceElement),
-        onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
-      })
+    return (
+      dom.div({ className: "reference-element" },
+        dom.span({ className: "reference-element-type" }, referenceElementType),
+        Rep({
+          defaultRep: referenceElement,
+          mode: MODE.TINY,
+          object: translateNodeFrontToGrip(referenceElement),
+          onInspectIconClick: () => setSelectedNode(referenceElement,
+            { reason: "box-model" }),
+          onDOMNodeMouseOver: () => onShowBoxModelHighlighterForNode(referenceElement),
+          onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
+        })
+      )
     );
   }
 
-  onFocus() {
-    this.container.focus();
-  }
-
   render() {
     const { name, value } = this.props;
 
-    return dom.div(
-      {
-        className: "computed-property-view",
-        "data-property-name": name,
-        tabIndex: "0",
-        ref: container => {
-          this.container = container;
-        },
-      },
+    return (
       dom.div(
         {
-          className: "computed-property-name-container",
+          className: "computed-property-view",
+          "data-property-name": name,
+          tabIndex: "0",
+          ref: container => {
+            this.container = container;
+          },
         },
-        dom.div(
-          {
-            className: "computed-property-name theme-fg-color5",
-            tabIndex: "",
-            title: name,
-            onClick: this.onFocus,
-          },
-          name
+        dom.div({ className: "computed-property-name-container" },
+          dom.div(
+            {
+              className: "computed-property-name theme-fg-color5",
+              tabIndex: "",
+              title: name,
+              onClick: this.onFocus,
+            },
+            name
+          )
+        ),
+        dom.div({ className: "computed-property-value-container" },
+          dom.div(
+            {
+              className: "computed-property-value theme-fg-color1",
+              dir: "ltr",
+              tabIndex: "",
+              onClick: this.onFocus,
+            },
+            value
+          ),
+          this.renderReferenceElementPreview()
         )
-      ),
-      dom.div(
-        {
-          className: "computed-property-value-container",
-        },
-        dom.div(
-          {
-            className: "computed-property-value theme-fg-color1",
-            dir: "ltr",
-            tabIndex: "",
-            onClick: this.onFocus,
-          },
-          value
-        ),
-        this.renderReferenceElementPreview()
       )
     );
   }
 }
 
 module.exports = ComputedProperty;
--- a/devtools/client/inspector/layout/components/moz.build
+++ b/devtools/client/inspector/layout/components/moz.build
@@ -2,10 +2,11 @@
 # vim: set filetype=python:
 # 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/.
 
 DevToolsModules(
     'Accordion.css',
     'Accordion.js',
+    'ComputedProperty.js',
     'LayoutApp.js',
 )
--- a/devtools/client/locales/en-US/layout.properties
+++ b/devtools/client/locales/en-US/layout.properties
@@ -11,16 +11,20 @@ flexbox.header=Flexbox
 # LOCALIZATION NOTE (flexbox.noFlexboxeOnThisPage): In the case where there are no CSS
 # flex containers to display.
 flexbox.noFlexboxeOnThisPage=Select a Flex container or item to continue.
 
 # LOCALIZATION NOTE (flexbox.overlayFlexbox): Header for the list of flex container
 # elements if only one item can be selected.
 flexbox.overlayFlexbox=Overlay Flexbox
 
+# LOCALIZATION NOTE (flexbox.flexContainerProperties): Header for the flex container
+# properties in the Flexbox panel.
+flexbox.flexContainerProperties=Flex Container Properties
+
 # LOCALIZATION NOTE (layout.cannotShowGridOutline, layout.cannotSHowGridOutline.title):
 # In the case where the grid outline cannot be effectively displayed.
 layout.cannotShowGridOutline=Cannot show outline for this grid
 layout.cannotShowGridOutline.title=The selected grid’s outline cannot effectively fit inside the layout panel for it to be usable.
 
 # LOCALIZATION NOTE (layout.displayAreaNames): Label of the display area names setting
 # option in the CSS Grid pane.
 layout.displayAreaNames=Display area names
--- a/devtools/client/themes/boxmodel.css
+++ b/devtools/client/themes/boxmodel.css
@@ -359,56 +359,24 @@
   flex: 1;
 }
 
 .boxmodel-position-group {
   display: flex;
   align-items: center;
 }
 
-/* Box Model Properties: contains a list of relevant box model properties */
-
-.boxmodel-properties-header {
-  padding: 2px 3px;
-}
-
-.boxmodel-properties-expander {
-  vertical-align: middle;
-  display: inline-block;
-  margin-inline-start: 2px;
-  margin-inline-end: 1px;
-}
-
-.boxmodel-properties-wrapper {
-  column-width: 250px;
-  column-gap: 20px;
-  column-rule: 1px solid var(--theme-splitter-color);
-}
-
-.boxmodel-properties-wrapper .computed-property-view {
-  padding-inline-start: 20px;
-}
-
-.boxmodel-properties-wrapper .computed-property-name-container {
-  flex: 1;
-}
-
-.boxmodel-properties-wrapper .computed-property-value-container {
-  flex: 1;
-  display: block;
-}
+/* Tag displayed next to DOM Node previews (used to display reference elements) */
 
 .boxmodel-container .reference-element {
   margin-inline-start: 14px;
   margin-block-start: 4px;
   display: block;
 }
 
-/* Tag displayed next to DOM Node previews (used to display reference elements) */
-
 .boxmodel-container .reference-element-type {
   background: var(--theme-highlight-purple);
   color: white;
   padding: 1px 2px;
   border-radius: 2px;
   font-size: 9px;
   margin-inline-end: 5px;
 }
--- a/devtools/client/themes/layout.css
+++ b/devtools/client/themes/layout.css
@@ -51,16 +51,57 @@
   vertical-align: middle;
 }
 
 .flexbox-container label,
 .grid-container label {
   margin-inline-start: -3px;
 }
 
+/* Layout Properties: Common styles used for the Box Model and Flexbox Properties */
+
+.layout-properties-header {
+  padding: 2px 3px;
+  -moz-user-select: none;
+}
+
+.layout-properties-expander {
+  vertical-align: middle;
+  display: inline-block;
+  margin-inline-start: 2px;
+  margin-inline-end: 1px;
+}
+
+.layout-properties-wrapper {
+  column-width: 250px;
+  column-gap: 20px;
+  column-rule: 1px solid var(--theme-splitter-color);
+}
+
+.layout-properties-wrapper .computed-property-view {
+  padding-inline-start: 20px;
+}
+
+.layout-properties-wrapper .computed-property-name-container {
+  flex: 1;
+}
+
+.layout-properties-wrapper .computed-property-value-container {
+  flex: 1;
+  display: block;
+}
+
+/**
+ * Flex Container Properties
+ */
+
+#flex-container-properties {
+  margin: 0 0 5px 0;
+}
+
 /**
  * Grid Container
  */
 
 #layout-flexbox-container,
 #layout-grid-container {
   display: flex;
   flex-direction: column;