Bug 940275 - Part 1: Add positioning properties to box model r?gl
MozReview-Commit-ID: AB5fREjDhsD
--- a/devtools/client/inspector/boxmodel/box-model.js
+++ b/devtools/client/inspector/boxmodel/box-model.js
@@ -235,16 +235,20 @@ BoxModel.prototype = {
if (property.substring(0, 7) == "border-") {
let bprop = property.substring(0, property.length - 5) + "style";
let style = session.getProperty(bprop);
if (!style || style == "none" || style == "hidden") {
properties.push({ name: bprop, value: "solid" });
}
}
+ if (property.substring(0, 9) == "position-") {
+ properties[0].name = property.substring(9);
+ }
+
session.setProperties(properties).catch(e => console.error(e));
},
done: (value, commit) => {
editor.elt.parentNode.classList.remove("boxmodel-editing");
if (!commit) {
session.revert().then(() => {
session.destroy();
}, e => console.error(e));
--- a/devtools/client/inspector/boxmodel/components/BoxModelMain.js
+++ b/devtools/client/inspector/boxmodel/components/BoxModelMain.js
@@ -78,108 +78,179 @@ module.exports = createClass({
value = "auto";
} else if (layout[property]) {
value = parseFloat(layout[property]);
}
return value;
},
+ getPositionValue(property) {
+ let { layout } = this.props.boxModel;
+
+ if (layout.position === "static") {
+ return "-";
+ }
+ return layout[property] ? parseFloat(layout[property]) : "-";
+ },
+
onHighlightMouseOver(event) {
let region = event.target.getAttribute("data-box");
if (!region) {
this.props.onHideBoxModelHighlighter();
}
this.props.onShowBoxModelHighlighter({
region,
showOnly: region,
onlyRegionArea: true,
});
},
render() {
let { boxModel, onShowBoxModelEditor } = this.props;
let { layout } = boxModel;
- let { height, width } = layout;
+ let { height, width, position } = layout;
let borderTop = this.getBorderOrPaddingValue("border-top-width");
let borderRight = this.getBorderOrPaddingValue("border-right-width");
let borderBottom = this.getBorderOrPaddingValue("border-bottom-width");
let borderLeft = this.getBorderOrPaddingValue("border-left-width");
let paddingTop = this.getBorderOrPaddingValue("padding-top");
let paddingRight = this.getBorderOrPaddingValue("padding-right");
let paddingBottom = this.getBorderOrPaddingValue("padding-bottom");
let paddingLeft = this.getBorderOrPaddingValue("padding-left");
+ let displayPosition = layout.position && layout.position != "static";
+ let positionTop = this.getPositionValue("top");
+ let positionRight = this.getPositionValue("right");
+ let positionBottom = this.getPositionValue("bottom");
+ let positionLeft = this.getPositionValue("left");
+
let marginTop = this.getMarginValue("margin-top", "top");
let marginRight = this.getMarginValue("margin-right", "right");
let marginBottom = this.getMarginValue("margin-bottom", "bottom");
let marginLeft = this.getMarginValue("margin-left", "left");
height = this.getHeightValue(height);
width = this.getWidthValue(width);
return dom.div(
{
className: "boxmodel-main",
onMouseOver: this.onHighlightMouseOver,
onMouseOut: this.props.onHideBoxModelHighlighter,
},
- dom.span(
- {
- className: "boxmodel-legend",
- "data-box": "margin",
- title: BOXMODEL_L10N.getStr("boxmodel.margin"),
- },
- BOXMODEL_L10N.getStr("boxmodel.margin")
- ),
+ displayPosition ?
+ dom.span(
+ {
+ className: "boxmodel-legend",
+ "data-box": "position",
+ title: BOXMODEL_L10N.getFormatStr("boxmodel.position", position),
+ },
+ BOXMODEL_L10N.getFormatStr("boxmodel.position", position)
+ )
+ :
+ null,
dom.div(
{
- className: "boxmodel-margins",
- "data-box": "margin",
- title: BOXMODEL_L10N.getStr("boxmodel.margin"),
+ className: "boxmodel-box"
},
dom.span(
{
className: "boxmodel-legend",
- "data-box": "border",
- title: BOXMODEL_L10N.getStr("boxmodel.border"),
+ "data-box": "margin",
+ title: BOXMODEL_L10N.getStr("boxmodel.margin"),
},
- BOXMODEL_L10N.getStr("boxmodel.border")
+ BOXMODEL_L10N.getStr("boxmodel.margin")
),
dom.div(
{
- className: "boxmodel-borders",
- "data-box": "border",
- title: BOXMODEL_L10N.getStr("boxmodel.border"),
+ className: "boxmodel-margins",
+ "data-box": "margin",
+ title: BOXMODEL_L10N.getStr("boxmodel.margin"),
},
dom.span(
{
className: "boxmodel-legend",
- "data-box": "padding",
- title: BOXMODEL_L10N.getStr("boxmodel.padding"),
+ "data-box": "border",
+ title: BOXMODEL_L10N.getStr("boxmodel.border"),
},
- BOXMODEL_L10N.getStr("boxmodel.padding")
+ BOXMODEL_L10N.getStr("boxmodel.border")
),
dom.div(
{
- className: "boxmodel-paddings",
- "data-box": "padding",
- title: BOXMODEL_L10N.getStr("boxmodel.padding"),
+ className: "boxmodel-borders",
+ "data-box": "border",
+ title: BOXMODEL_L10N.getStr("boxmodel.border"),
},
- dom.div({
- className: "boxmodel-content",
- "data-box": "content",
- title: BOXMODEL_L10N.getStr("boxmodel.content"),
- })
+ dom.span(
+ {
+ className: "boxmodel-legend",
+ "data-box": "padding",
+ title: BOXMODEL_L10N.getStr("boxmodel.padding"),
+ },
+ BOXMODEL_L10N.getStr("boxmodel.padding")
+ ),
+ dom.div(
+ {
+ className: "boxmodel-paddings",
+ "data-box": "padding",
+ title: BOXMODEL_L10N.getStr("boxmodel.padding"),
+ },
+ dom.div({
+ className: "boxmodel-content",
+ "data-box": "content",
+ title: BOXMODEL_L10N.getStr("boxmodel.content"),
+ })
+ )
)
)
),
+ displayPosition ?
+ BoxModelEditable({
+ box: "position",
+ direction: "top",
+ property: "position-top",
+ textContent: positionTop,
+ onShowBoxModelEditor,
+ })
+ :
+ null,
+ displayPosition ?
+ BoxModelEditable({
+ box: "position",
+ direction: "right",
+ property: "position-right",
+ textContent: positionRight,
+ onShowBoxModelEditor,
+ })
+ :
+ null,
+ displayPosition ?
+ BoxModelEditable({
+ box: "position",
+ direction: "bottom",
+ property: "position-bottom",
+ textContent: positionBottom,
+ onShowBoxModelEditor,
+ })
+ :
+ null,
+ displayPosition ?
+ BoxModelEditable({
+ box: "position",
+ direction: "left",
+ property: "position-left",
+ textContent: positionLeft,
+ onShowBoxModelEditor,
+ })
+ :
+ null,
BoxModelEditable({
box: "margin",
direction: "top",
property: "margin-top",
textContent: marginTop,
onShowBoxModelEditor,
}),
BoxModelEditable({
--- a/devtools/client/locales/en-US/boxmodel.properties
+++ b/devtools/client/locales/en-US/boxmodel.properties
@@ -10,16 +10,20 @@
# You want to make that choice consistent across the developer tools.
# A good criteria is the language in which you'd find the best
# documentation on web development on the web.
# LOCALIZATION NOTE (boxmodel.title) This is the title of the box model panel and is
# displayed as a label.
boxmodel.title=Box Model
+# LOCALIZATION NOTE (boxmodel.position) This refers to the position in the box model and
+# might be displayed as a label or as a tooltip.
+boxmodel.position=position: %S
+
# LOCALIZATION NOTE (boxmodel.margin) This refers to the margin in the box model and
# might be displayed as a label or as a tooltip.
boxmodel.margin=margin
# LOCALIZATION NOTE (boxmodel.border) This refers to the border in the box model and
# might be displayed as a label or as a tooltip.
boxmodel.border=border
--- a/devtools/client/themes/boxmodel.css
+++ b/devtools/client/themes/boxmodel.css
@@ -30,25 +30,29 @@
background: url(images/geometry-editor.svg) no-repeat center center / 16px 16px;
}
/* Main: contains the box-model regions */
.boxmodel-main {
position: relative;
box-sizing: border-box;
- /* The regions are semi-transparent, so the white background is partly
- visible */
- background-color: white;
color: var(--theme-selection-color);
/* Make sure there is some space between the window's edges and the regions */
margin: 14px 14px 4px 14px;
width: calc(100% - 2 * 14px);
}
+.boxmodel-box {
+ margin: 0 25px;
+ /* The regions are semi-transparent, so the white background is partly
+ visible */
+ background-color: white;
+}
+
.boxmodel-margin,
.boxmodel-size {
color: var(--theme-highlight-blue);
}
/* Regions are 3 nested elements with wide borders and outlines */
.boxmodel-content {
@@ -68,37 +72,32 @@
/* This opacity applies to all of the regions, since they are nested */
opacity: .8;
}
/* Regions colors */
.boxmodel-margins {
border-color: #edff64;
+ margin: 25px 0;
}
.boxmodel-borders {
border-color: #444444;
}
.boxmodel-paddings {
border-color: #6a5acd;
}
.boxmodel-content {
background-color: #87ceeb;
}
.theme-firebug .boxmodel-main,
-.theme-firebug .boxmodel-borders,
-.theme-firebug .boxmodel-content {
- border-style: solid;
-}
-
-.theme-firebug .boxmodel-main,
.theme-firebug .boxmodel-header {
font-family: var(--proportional-font-family);
}
.theme-firebug .boxmodel-main {
color: var(--theme-body-color);
font-size: var(--theme-toolbar-font-size);
}
@@ -150,81 +149,147 @@
top: 1px;
}
.boxmodel-margin.boxmodel-bottom {
bottom: 2px;
}
.boxmodel-size,
+.boxmodel-position.boxmodel-left,
+.boxmodel-position.boxmodel-right,
.boxmodel-margin.boxmodel-left,
.boxmodel-margin.boxmodel-right,
.boxmodel-border.boxmodel-left,
.boxmodel-border.boxmodel-right,
.boxmodel-padding.boxmodel-left,
.boxmodel-padding.boxmodel-right {
top: 22px;
line-height: 80px;
}
.boxmodel-size {
width: calc(100% - 2px);
}
+.boxmodel-position.boxmodel-top,
+.boxmodel-position.boxmodel-bottom,
+.boxmodel-position.boxmodel-left,
+.boxmodel-position.boxmodel-right,
.boxmodel-margin.boxmodel-right,
.boxmodel-margin.boxmodel-left,
.boxmodel-border.boxmodel-left,
.boxmodel-border.boxmodel-right,
.boxmodel-padding.boxmodel-right,
.boxmodel-padding.boxmodel-left {
width: 21px;
}
.boxmodel-padding.boxmodel-left {
- left: 35px;
+ left: 60px;
}
.boxmodel-padding.boxmodel-right {
- right: 35px;
+ right: 60px;
}
.boxmodel-border.boxmodel-left {
- left: 16px;
+ left: 41px;
}
.boxmodel-border.boxmodel-right {
- right: 17px;
+ right: 42px;
}
.boxmodel-margin.boxmodel-right {
- right: 0;
+ right: 25px;
}
.boxmodel-margin.boxmodel-left {
- left: 0;
+ left: 25px;
}
.boxmodel-rotate.boxmodel-left:not(.boxmodel-editing) {
transform: rotate(-90deg);
}
.boxmodel-rotate.boxmodel-right:not(.boxmodel-editing) {
transform: rotate(90deg);
}
+.boxmodel-rotate.boxmodel-left.boxmodel-position:not(.boxmodel-editing) {
+ border-top: none;
+ border-right: 1px solid var(--theme-highlight-purple);
+ width: auto;
+ height: 30px;
+}
+
+.boxmodel-rotate.boxmodel-right.boxmodel-position:not(.boxmodel-editing) {
+ border-top: none;
+ border-left: 1px solid var(--theme-highlight-purple);
+ width: auto;
+ height: 30px;
+}
+
+/* Box Model Positioning: contains top, right, bottom, left */
+
+.boxmodel-position {
+ color: var(--theme-highlight-purple);
+}
+
+.boxmodel-position.boxmodel-top,
+.boxmodel-position.boxmodel-bottom {
+ border-left: 1px solid var(--theme-highlight-purple);
+ left: 50%;
+ padding-left: 1px;
+}
+
+.boxmodel-position.boxmodel-right,
+.boxmodel-position.boxmodel-left {
+ border-top: 1px solid var(--theme-highlight-purple);
+ line-height: 15px;
+ top: 50%;
+ width: 30px;
+}
+
+.boxmodel-position.boxmodel-top {
+ top: -18px;
+}
+
+.boxmodel-position.boxmodel-right {
+ right: -9px;
+}
+
+.boxmodel-position.boxmodel-bottom {
+ bottom: -18px;
+}
+
+.boxmodel-position.boxmodel-left {
+ left: -9px;
+}
+
/* Legend: displayed inside regions */
.boxmodel-legend {
position: absolute;
margin: 2px 6px;
z-index: 1;
}
.boxmodel-legend[data-box="margin"] {
- color: var(--theme-highlight-blue);
+ color: var(--theme-highlight-purple);
+}
+
+.boxmodel-legend[data-box="position"] {
+ color: var(--theme-highlight-purple);
+ margin: -18px -9px;
+}
+
+.boxmodel-legend .boxmodel-element-position {
+ margin-left: 5px
}
/* Editable fields */
.boxmodel-editable {
border: 1px dashed transparent;
-moz-user-select: none;
}
@@ -240,21 +305,16 @@
}
/* Box Model Info: contains the position and size of the element */
.boxmodel-element-size {
flex: 1;
}
-.boxmodel-position-group {
- display: flex;
- align-items: center;
-}
-
/* Box Model Properties: contains a list of relevant box model properties */
.boxmodel-properties-header {
display: flex;
padding: 2px 0;
}
.boxmodel-properties-wrapper {
--- a/devtools/client/themes/layout.css
+++ b/devtools/client/themes/layout.css
@@ -1,16 +1,17 @@
/* 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/. */
#layout-container {
height: 100%;
width: 100%;
overflow: auto;
+ min-width: 200px;
}
/**
* Common styles for shared components
*/
.grid-container {
display: flex;
--- a/devtools/server/actors/styles.js
+++ b/devtools/server/actors/styles.js
@@ -766,16 +766,20 @@ var PageStyleActor = protocol.ActorClass
let clientRect = node.rawNode.getBoundingClientRect();
layout.width = parseFloat(clientRect.width.toPrecision(6));
layout.height = parseFloat(clientRect.height.toPrecision(6));
// We compute and update the values of margins & co.
let style = CssLogic.getComputedStyle(node.rawNode);
for (let prop of [
"position",
+ "top",
+ "right",
+ "bottom",
+ "left",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",