зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1478397
- Part 19: Show both the flex container and flex item sizing properties when the selected element is both a flex item and container. r=pbro
This commit is contained in:
Родитель
ae143565fe
Коммит
3e721cf4f1
|
@ -6,7 +6,6 @@
|
|||
|
||||
const {
|
||||
CLEAR_FLEXBOX,
|
||||
TOGGLE_FLEX_ITEM_SHOWN,
|
||||
UPDATE_FLEXBOX,
|
||||
UPDATE_FLEXBOX_COLOR,
|
||||
UPDATE_FLEXBOX_HIGHLIGHTED,
|
||||
|
@ -23,21 +22,6 @@ module.exports = {
|
|||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the display of flex item sizing information shown for the given flex item
|
||||
* actor ID.
|
||||
*
|
||||
* @param {NodeFront} nodeFront
|
||||
* The NodeFront of the flex item to toggle the sizing information displayed
|
||||
* for.
|
||||
*/
|
||||
toggleFlexItemShown(nodeFront) {
|
||||
return {
|
||||
type: TOGGLE_FLEX_ITEM_SHOWN,
|
||||
nodeFront,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the flexbox state with the newly selected flexbox.
|
||||
*/
|
||||
|
|
|
@ -11,9 +11,6 @@ createEnum([
|
|||
// Clears the flexbox state by resetting it back to the initial flexbox state.
|
||||
"CLEAR_FLEXBOX",
|
||||
|
||||
// Toggles the display of flex item sizing information shown.
|
||||
"TOGGLE_FLEX_ITEM_SHOWN",
|
||||
|
||||
// Updates the flexbox state with the newly selected flexbox.
|
||||
"UPDATE_FLEXBOX",
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ const {
|
|||
} = 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 { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
const { translateNodeFrontToGrip } = require("devtools/client/inspector/shared/utils");
|
||||
|
||||
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
|
||||
|
@ -23,7 +24,8 @@ const Types = require("../types");
|
|||
class FlexContainer extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
flexbox: PropTypes.shape(Types.flexbox).isRequired,
|
||||
color: PropTypes.string.isRequired,
|
||||
flexContainer: PropTypes.shape(Types.flexContainer).isRequired,
|
||||
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
|
||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
onSetFlexboxOverlayColor: PropTypes.func.isRequired,
|
||||
|
@ -43,23 +45,17 @@ class FlexContainer extends PureComponent {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {
|
||||
flexbox,
|
||||
getSwatchColorPickerTooltip,
|
||||
onSetFlexboxOverlayColor,
|
||||
} = this.props;
|
||||
|
||||
const tooltip = getSwatchColorPickerTooltip();
|
||||
const tooltip = this.props.getSwatchColorPickerTooltip();
|
||||
|
||||
let previousColor;
|
||||
tooltip.addSwatch(this.swatchEl.current, {
|
||||
onCommit: this.setFlexboxColor,
|
||||
onPreview: this.setFlexboxColor,
|
||||
onRevert: () => {
|
||||
onSetFlexboxOverlayColor(previousColor);
|
||||
this.props.onSetFlexboxOverlayColor(previousColor);
|
||||
},
|
||||
onShow: () => {
|
||||
previousColor = flexbox.color;
|
||||
previousColor = this.props.color;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -75,21 +71,18 @@ class FlexContainer extends PureComponent {
|
|||
}
|
||||
|
||||
onFlexboxInspectIconClick(nodeFront) {
|
||||
const { setSelectedNode } = this.props;
|
||||
setSelectedNode(nodeFront, { reason: "layout-panel" });
|
||||
this.props.setSelectedNode(nodeFront, { reason: "layout-panel" });
|
||||
nodeFront.scrollIntoView().catch(e => console.error(e));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
flexbox,
|
||||
color,
|
||||
flexContainer,
|
||||
onHideBoxModelHighlighter,
|
||||
onShowBoxModelHighlighterForNode,
|
||||
} = this.props;
|
||||
const {
|
||||
color,
|
||||
nodeFront,
|
||||
} = flexbox;
|
||||
const { nodeFront } = flexContainer;
|
||||
|
||||
return createElement(Fragment, null,
|
||||
Rep({
|
||||
|
@ -123,4 +116,10 @@ class FlexContainer extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = FlexContainer;
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
color: state.flexbox.color,
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = connect(mapStateToProps)(FlexContainer);
|
||||
|
|
|
@ -23,23 +23,19 @@ class FlexItem extends PureComponent {
|
|||
static get propTypes() {
|
||||
return {
|
||||
flexItem: PropTypes.shape(Types.flexItem).isRequired,
|
||||
onToggleFlexItemShown: PropTypes.func.isRequired,
|
||||
setSelectedNode: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
flexItem,
|
||||
onToggleFlexItemShown,
|
||||
} = this.props;
|
||||
const { nodeFront } = flexItem;
|
||||
const { nodeFront } = this.props.flexItem;
|
||||
|
||||
return (
|
||||
dom.li({},
|
||||
dom.button(
|
||||
{
|
||||
className: "devtools-button devtools-monospace",
|
||||
onClick: () => onToggleFlexItemShown(nodeFront),
|
||||
onClick: () => this.props.setSelectedNode(nodeFront),
|
||||
},
|
||||
Rep({
|
||||
defaultRep: Rep.ElementNode,
|
||||
|
|
|
@ -16,14 +16,14 @@ class FlexItemList extends PureComponent {
|
|||
static get propTypes() {
|
||||
return {
|
||||
flexItems: PropTypes.arrayOf(PropTypes.shape(Types.flexItem)).isRequired,
|
||||
onToggleFlexItemShown: PropTypes.func.isRequired,
|
||||
setSelectedNode: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
flexItems,
|
||||
onToggleFlexItemShown,
|
||||
setSelectedNode,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
@ -32,7 +32,7 @@ class FlexItemList extends PureComponent {
|
|||
flexItems.map(flexItem => FlexItem({
|
||||
key: flexItem.actorID,
|
||||
flexItem,
|
||||
onToggleFlexItemShown,
|
||||
setSelectedNode,
|
||||
}))
|
||||
)
|
||||
);
|
||||
|
|
|
@ -25,7 +25,7 @@ class FlexItemSelector extends PureComponent {
|
|||
return {
|
||||
flexItem: PropTypes.shape(Types.flexItem).isRequired,
|
||||
flexItems: PropTypes.arrayOf(PropTypes.shape(Types.flexItem)).isRequired,
|
||||
onToggleFlexItemShown: PropTypes.func.isRequired,
|
||||
setSelectedNode: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ class FlexItemSelector extends PureComponent {
|
|||
const {
|
||||
flexItem,
|
||||
flexItems,
|
||||
onToggleFlexItemShown,
|
||||
setSelectedNode,
|
||||
} = this.props;
|
||||
const menuItems = [];
|
||||
|
||||
|
@ -48,7 +48,7 @@ class FlexItemSelector extends PureComponent {
|
|||
label: getSelectorFromGrip(grip),
|
||||
type: "checkbox",
|
||||
checked: item === flexItem,
|
||||
click: () => onToggleFlexItemShown(item.nodeFront),
|
||||
click: () => setSelectedNode(item.nodeFront),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -27,67 +27,68 @@ const Types = require("../types");
|
|||
class Flexbox extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
flexbox: PropTypes.shape(Types.flexbox).isRequired,
|
||||
flexContainer: PropTypes.shape(Types.flexContainer).isRequired,
|
||||
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
|
||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
onSetFlexboxOverlayColor: PropTypes.func.isRequired,
|
||||
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
|
||||
onToggleFlexboxHighlighter: PropTypes.func.isRequired,
|
||||
onToggleFlexItemShown: PropTypes.func.isRequired,
|
||||
setSelectedNode: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
renderFlexItemList() {
|
||||
const {
|
||||
flexbox,
|
||||
onToggleFlexItemShown,
|
||||
} = this.props;
|
||||
const {
|
||||
flexItems,
|
||||
flexItemShown,
|
||||
} = flexbox;
|
||||
|
||||
if (flexItemShown || !flexItems.length) {
|
||||
renderFlexContainerProperties() {
|
||||
// Don't show the flex container properties for the parent flex container of the
|
||||
// selected element.
|
||||
if (this.props.flexContainer.isFlexItemContainer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return FlexItemList({
|
||||
flexItems,
|
||||
onToggleFlexItemShown,
|
||||
return FlexContainerProperties({
|
||||
properties: this.props.flexContainer.properties,
|
||||
});
|
||||
}
|
||||
|
||||
renderFlexItemSizingProperties() {
|
||||
const { flexbox } = this.props;
|
||||
renderFlexItemList() {
|
||||
const { setSelectedNode } = this.props;
|
||||
const { flexItems } = this.props.flexContainer;
|
||||
|
||||
return FlexItemList({
|
||||
flexItems,
|
||||
setSelectedNode,
|
||||
});
|
||||
}
|
||||
|
||||
renderFlexItemSizing() {
|
||||
const {
|
||||
flexItems,
|
||||
flexItemShown,
|
||||
} = flexbox;
|
||||
properties,
|
||||
} = this.props.flexContainer;
|
||||
|
||||
if (!flexItemShown) {
|
||||
const flexItem = flexItems.find(item => item.nodeFront.actorID === flexItemShown);
|
||||
if (!flexItem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return FlexItemSizingProperties({
|
||||
flexDirection: flexbox.properties["flex-direction"],
|
||||
flexItem: flexItems.find(item => item.nodeFront.actorID === flexItemShown),
|
||||
flexDirection: properties["flex-direction"],
|
||||
flexItem,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
flexbox,
|
||||
flexContainer,
|
||||
getSwatchColorPickerTooltip,
|
||||
onHideBoxModelHighlighter,
|
||||
onSetFlexboxOverlayColor,
|
||||
onShowBoxModelHighlighterForNode,
|
||||
onToggleFlexboxHighlighter,
|
||||
onToggleFlexItemShown,
|
||||
setSelectedNode,
|
||||
} = this.props;
|
||||
|
||||
if (!flexbox.actorID) {
|
||||
if (!flexContainer.actorID) {
|
||||
return (
|
||||
dom.div({ className: "devtools-sidepanel-no-result" },
|
||||
getStr("flexbox.noFlexboxeOnThisPage")
|
||||
|
@ -95,23 +96,25 @@ class Flexbox extends PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
const {
|
||||
flexItems,
|
||||
flexItemShown,
|
||||
} = flexContainer;
|
||||
|
||||
return (
|
||||
dom.div({ id: "layout-flexbox-container" },
|
||||
Header({
|
||||
flexbox,
|
||||
flexContainer,
|
||||
getSwatchColorPickerTooltip,
|
||||
onHideBoxModelHighlighter,
|
||||
onSetFlexboxOverlayColor,
|
||||
onShowBoxModelHighlighterForNode,
|
||||
onToggleFlexboxHighlighter,
|
||||
onToggleFlexItemShown,
|
||||
setSelectedNode,
|
||||
}),
|
||||
this.renderFlexItemList(),
|
||||
this.renderFlexItemSizingProperties(),
|
||||
FlexContainerProperties({
|
||||
properties: flexbox.properties,
|
||||
})
|
||||
!flexItemShown && flexItems.length > 0 ? this.renderFlexItemList() : null,
|
||||
flexItemShown ? this.renderFlexItemSizing() : null,
|
||||
this.renderFlexContainerProperties()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,15 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createElement,
|
||||
createFactory,
|
||||
Fragment,
|
||||
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 { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const FlexContainer = createFactory(require("./FlexContainer"));
|
||||
const FlexItemSelector = createFactory(require("./FlexItemSelector"));
|
||||
|
@ -16,13 +22,13 @@ const Types = require("../types");
|
|||
class Header extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
flexbox: PropTypes.shape(Types.flexbox).isRequired,
|
||||
flexContainer: PropTypes.shape(Types.flexContainer).isRequired,
|
||||
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
|
||||
highlighted: PropTypes.bool.isRequired,
|
||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
onSetFlexboxOverlayColor: PropTypes.func.isRequired,
|
||||
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
|
||||
onToggleFlexboxHighlighter: PropTypes.func.isRequired,
|
||||
onToggleFlexItemShown: PropTypes.func.isRequired,
|
||||
setSelectedNode: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
@ -33,21 +39,34 @@ class Header extends PureComponent {
|
|||
}
|
||||
|
||||
onFlexboxCheckboxClick() {
|
||||
const {
|
||||
flexbox,
|
||||
onToggleFlexboxHighlighter,
|
||||
} = this.props;
|
||||
this.props.onToggleFlexboxHighlighter(this.props.flexContainer.nodeFront);
|
||||
}
|
||||
|
||||
onToggleFlexboxHighlighter(flexbox.nodeFront);
|
||||
renderFlexboxHighlighterToggle() {
|
||||
// Don't show the flexbox highlighter toggle for the parent flex container of the
|
||||
// selected element.
|
||||
if (this.props.flexContainer.isFlexItemContainer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return createElement(Fragment, null,
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
dom.input({
|
||||
className: "devtools-checkbox-toggle",
|
||||
checked: this.props.highlighted,
|
||||
onChange: this.onFlexboxCheckboxClick,
|
||||
type: "checkbox",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
renderFlexContainer() {
|
||||
if (this.props.flexbox.flexItemShown) {
|
||||
if (this.props.flexContainer.flexItemShown) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
flexbox,
|
||||
flexContainer,
|
||||
getSwatchColorPickerTooltip,
|
||||
onHideBoxModelHighlighter,
|
||||
onSetFlexboxOverlayColor,
|
||||
|
@ -56,7 +75,7 @@ class Header extends PureComponent {
|
|||
} = this.props;
|
||||
|
||||
return FlexContainer({
|
||||
flexbox,
|
||||
flexContainer,
|
||||
getSwatchColorPickerTooltip,
|
||||
onHideBoxModelHighlighter,
|
||||
onSetFlexboxOverlayColor,
|
||||
|
@ -66,42 +85,42 @@ class Header extends PureComponent {
|
|||
}
|
||||
|
||||
renderFlexItemSelector() {
|
||||
if (!this.props.flexbox.flexItemShown) {
|
||||
if (!this.props.flexContainer.flexItemShown) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
flexbox,
|
||||
onToggleFlexItemShown,
|
||||
flexContainer,
|
||||
setSelectedNode,
|
||||
} = this.props;
|
||||
const {
|
||||
flexItems,
|
||||
flexItemShown,
|
||||
} = flexbox;
|
||||
} = flexContainer;
|
||||
|
||||
return FlexItemSelector({
|
||||
flexItem: flexItems.find(item => item.nodeFront.actorID === flexItemShown),
|
||||
flexItems,
|
||||
onToggleFlexItemShown,
|
||||
setSelectedNode,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
flexbox,
|
||||
onToggleFlexItemShown,
|
||||
flexContainer,
|
||||
setSelectedNode,
|
||||
} = this.props;
|
||||
const {
|
||||
flexItemShown,
|
||||
highlighted,
|
||||
} = flexbox;
|
||||
nodeFront,
|
||||
} = flexContainer;
|
||||
|
||||
return (
|
||||
dom.div({ className: "flex-header devtools-monospace" },
|
||||
flexItemShown ?
|
||||
dom.button({
|
||||
className: "flex-header-button-prev devtools-button",
|
||||
onClick: () => onToggleFlexItemShown(),
|
||||
onClick: () => setSelectedNode(nodeFront),
|
||||
})
|
||||
:
|
||||
null,
|
||||
|
@ -113,16 +132,16 @@ class Header extends PureComponent {
|
|||
this.renderFlexContainer(),
|
||||
this.renderFlexItemSelector()
|
||||
),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
dom.input({
|
||||
className: "devtools-checkbox-toggle",
|
||||
checked: highlighted,
|
||||
onChange: this.onFlexboxCheckboxClick,
|
||||
type: "checkbox",
|
||||
})
|
||||
this.renderFlexboxHighlighterToggle()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Header;
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
highlighted: state.flexbox.highlighted,
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = connect(mapStateToProps)(Header);
|
||||
|
|
|
@ -9,7 +9,6 @@ const { throttle } = require("devtools/shared/throttle");
|
|||
|
||||
const {
|
||||
clearFlexbox,
|
||||
toggleFlexItemShown,
|
||||
updateFlexbox,
|
||||
updateFlexboxColor,
|
||||
updateFlexboxHighlighted,
|
||||
|
@ -35,7 +34,6 @@ class FlexboxInspector {
|
|||
this.onSetFlexboxOverlayColor = this.onSetFlexboxOverlayColor.bind(this);
|
||||
this.onSidebarSelect = this.onSidebarSelect.bind(this);
|
||||
this.onToggleFlexboxHighlighter = this.onToggleFlexboxHighlighter.bind(this);
|
||||
this.onToggleFlexItemShown = this.onToggleFlexItemShown.bind(this);
|
||||
this.onUpdatePanel = this.onUpdatePanel.bind(this);
|
||||
|
||||
this.init();
|
||||
|
@ -105,11 +103,55 @@ class FlexboxInspector {
|
|||
this.walker = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the current selected node is a flex container, check if it is also a flex item of
|
||||
* a parent flex container and get its parent flex container if any and returns an
|
||||
* object that consists of the parent flex container's items and properties.
|
||||
*
|
||||
* @param {NodeFront} containerNodeFront
|
||||
* The current flex container of the selected node.
|
||||
* @return {Object} consiting of the parent flex container's flex items and properties.
|
||||
*/
|
||||
async getAsFlexItem(containerNodeFront) {
|
||||
// If the current selected node is not a flex container, we know it is a flex item.
|
||||
// No need to look for the parent flex container.
|
||||
if (containerNodeFront !== this.selection.nodeFront) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const flexboxFront = await this.layoutInspector.getCurrentFlexbox(
|
||||
this.selection.nodeFront, true);
|
||||
|
||||
if (!flexboxFront) {
|
||||
return null;
|
||||
}
|
||||
|
||||
containerNodeFront = flexboxFront.containerNodeFront;
|
||||
if (!containerNodeFront) {
|
||||
containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID,
|
||||
["containerEl"]);
|
||||
}
|
||||
|
||||
let flexItemContainer = null;
|
||||
if (flexboxFront) {
|
||||
const flexItems = await this.getFlexItems(flexboxFront);
|
||||
flexItemContainer = {
|
||||
actorID: flexboxFront.actorID,
|
||||
flexItems,
|
||||
flexItemShown: this.selection.nodeFront.actorID,
|
||||
isFlexItemContainer: true,
|
||||
nodeFront: containerNodeFront,
|
||||
properties: flexboxFront.properties,
|
||||
};
|
||||
}
|
||||
|
||||
return flexItemContainer;
|
||||
}
|
||||
|
||||
getComponentProps() {
|
||||
return {
|
||||
onSetFlexboxOverlayColor: this.onSetFlexboxOverlayColor,
|
||||
onToggleFlexboxHighlighter: this.onToggleFlexboxHighlighter,
|
||||
onToggleFlexItemShown: this.onToggleFlexItemShown,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -230,7 +272,8 @@ class FlexboxInspector {
|
|||
onHighlighterChange(highlighted, nodeFront) {
|
||||
const { flexbox } = this.store.getState();
|
||||
|
||||
if (flexbox.nodeFront === nodeFront && flexbox.highlighted !== highlighted) {
|
||||
if (flexbox.flexContainer.nodeFront === nodeFront &&
|
||||
flexbox.highlighted !== highlighted) {
|
||||
this.store.dispatch(updateFlexboxHighlighted(highlighted));
|
||||
}
|
||||
}
|
||||
|
@ -341,24 +384,6 @@ class FlexboxInspector {
|
|||
this.highlighters.flexboxHighlighterShow));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for a change in the input checkbox in the FlexItem and Header component.
|
||||
* Toggles on/off the flex item highlighter for the provided flex item element and
|
||||
* changes the selection to the given node.
|
||||
*
|
||||
* @param {NodeFront|null} node
|
||||
* The NodeFront of the flex item element for which the flex item is toggled
|
||||
* on/off for.
|
||||
*/
|
||||
onToggleFlexItemShown(node) {
|
||||
this.highlighters.toggleFlexItemHighlighter(node);
|
||||
this.store.dispatch(toggleFlexItemShown(node));
|
||||
|
||||
if (node) {
|
||||
this.selection.setNodeFront(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for "new-root" event fired by the inspector and "new-node-front" event fired
|
||||
* by the inspector selection. Updates the flexbox panel if it is visible.
|
||||
|
@ -412,6 +437,7 @@ class FlexboxInspector {
|
|||
["containerEl"]);
|
||||
}
|
||||
|
||||
const flexItemContainer = await this.getAsFlexItem(containerNodeFront);
|
||||
const flexItems = await this.getFlexItems(flexboxFront);
|
||||
// If the current selected node is a flex item, display its flex item sizing
|
||||
// properties.
|
||||
|
@ -422,13 +448,17 @@ class FlexboxInspector {
|
|||
const color = await this.getOverlayColor();
|
||||
|
||||
this.store.dispatch(updateFlexbox({
|
||||
actorID: flexboxFront.actorID,
|
||||
color,
|
||||
flexItems,
|
||||
flexItemShown: flexItemShown ? flexItemShown.nodeFront.actorID : null,
|
||||
flexContainer: {
|
||||
actorID: flexboxFront.actorID,
|
||||
flexItems,
|
||||
flexItemShown: flexItemShown ? flexItemShown.nodeFront.actorID : null,
|
||||
isFlexItemContainer: false,
|
||||
nodeFront: containerNodeFront,
|
||||
properties: flexboxFront.properties,
|
||||
},
|
||||
flexItemContainer,
|
||||
highlighted,
|
||||
nodeFront: containerNodeFront,
|
||||
properties: flexboxFront.properties,
|
||||
}));
|
||||
} catch (e) {
|
||||
// This call might fail if called asynchrously after the toolbox is finished
|
||||
|
|
|
@ -6,27 +6,51 @@
|
|||
|
||||
const {
|
||||
CLEAR_FLEXBOX,
|
||||
TOGGLE_FLEX_ITEM_SHOWN,
|
||||
UPDATE_FLEXBOX,
|
||||
UPDATE_FLEXBOX_COLOR,
|
||||
UPDATE_FLEXBOX_HIGHLIGHTED,
|
||||
} = require("../actions/index");
|
||||
|
||||
const INITIAL_FLEXBOX = {
|
||||
// The actor ID of the flex container.
|
||||
actorID: null,
|
||||
// The color of the flexbox highlighter overlay.
|
||||
color: "",
|
||||
// An array of flex items belonging to the current flex container.
|
||||
flexItems: [],
|
||||
// The NodeFront actor ID of the flex item to display the flex item sizing properties.
|
||||
flexItemShown: null,
|
||||
// The flex container of the selected element.
|
||||
flexContainer: {
|
||||
// The actor ID of the selected flex container.
|
||||
actorID: "",
|
||||
// An array of flex items belonging to the selected flex container.
|
||||
flexItems: [],
|
||||
// The NodeFront actor ID of the flex item to display in the flex item sizing
|
||||
// properties.
|
||||
flexItemShown: null,
|
||||
// This flag specifies that the flex container data represents the selected flex
|
||||
// container.
|
||||
isFlexItemContainer: false,
|
||||
// The NodeFront of the selected flex container.
|
||||
nodeFront: null,
|
||||
// The computed style properties of the selected flex container.
|
||||
properties: null,
|
||||
},
|
||||
// The selected flex container can also be a flex item. This object contains the
|
||||
// parent flex container properties of the selected element.
|
||||
flexItemContainer: {
|
||||
// The actor ID of the parent flex container.
|
||||
actorID: "",
|
||||
// An array of flex items belonging to the parent flex container.
|
||||
flexItems: [],
|
||||
// The NodeFront actor ID of the flex item to display in the flex item sizing
|
||||
// properties.
|
||||
flexItemShown: null,
|
||||
// This flag specifies that the flex container data represents the parent flex
|
||||
// container of the selected element.
|
||||
isFlexItemContainer: true,
|
||||
// The NodeFront of the parent flex container.
|
||||
nodeFront: null,
|
||||
// The computed styles properties of the parent flex container.
|
||||
properties: null,
|
||||
},
|
||||
// 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 = {
|
||||
|
@ -35,34 +59,22 @@ const reducers = {
|
|||
return INITIAL_FLEXBOX;
|
||||
},
|
||||
|
||||
[TOGGLE_FLEX_ITEM_SHOWN](flexbox, { nodeFront }) {
|
||||
let flexItemShown = null;
|
||||
|
||||
// Get the NodeFront actor ID of the flex item.
|
||||
if (nodeFront) {
|
||||
const flexItem = flexbox.flexItems.find(item => item.nodeFront === nodeFront);
|
||||
flexItemShown = flexItem.nodeFront.actorID;
|
||||
}
|
||||
|
||||
return Object.assign({}, flexbox, {
|
||||
flexItemShown,
|
||||
});
|
||||
},
|
||||
|
||||
[UPDATE_FLEXBOX](_, { flexbox }) {
|
||||
return flexbox;
|
||||
},
|
||||
|
||||
[UPDATE_FLEXBOX_COLOR](flexbox, { color }) {
|
||||
return Object.assign({}, flexbox, {
|
||||
return {
|
||||
...flexbox,
|
||||
color,
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
[UPDATE_FLEXBOX_HIGHLIGHTED](flexbox, { highlighted }) {
|
||||
return Object.assign({}, flexbox, {
|
||||
return {
|
||||
...flexbox,
|
||||
highlighted,
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -108,22 +108,22 @@ const flexContainerProperties = exports.flexContainerProperties = {
|
|||
/**
|
||||
* A flex container data.
|
||||
*/
|
||||
exports.flexbox = {
|
||||
const flexContainer = exports.flexContainer = {
|
||||
|
||||
// The actor ID of the flex container.
|
||||
actorID: PropTypes.string,
|
||||
|
||||
// The color of the flexbox highlighter overlay.
|
||||
color: PropTypes.string,
|
||||
|
||||
// Array of flex container's flex items.
|
||||
// An array of flex items belonging to the flex container.
|
||||
flexItems: PropTypes.arrayOf(PropTypes.shape(flexItem)),
|
||||
|
||||
// The NodeFront actor ID of the flex item to display the flex item sizing properties.
|
||||
flexItemShown: PropTypes.string,
|
||||
// Whether or not the flex container data represents the selected flex container
|
||||
// or the parent flex container. This is true if the flex container data represents
|
||||
// the parent flex container.
|
||||
isFlexItemContainer: PropTypes.bool,
|
||||
|
||||
// Whether or not the flexbox highlighter is highlighting the flex container.
|
||||
highlighted: PropTypes.bool,
|
||||
// The NodeFront actor ID of the flex item to display in the flex item sizing
|
||||
// properties.
|
||||
flexItemShown: PropTypes.string,
|
||||
|
||||
// The NodeFront of the flex container.
|
||||
nodeFront: PropTypes.object,
|
||||
|
@ -132,3 +132,23 @@ exports.flexbox = {
|
|||
properties: PropTypes.shape(flexContainerProperties),
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The Flexbox UI state.
|
||||
*/
|
||||
exports.flexbox = {
|
||||
|
||||
// The color of the flexbox highlighter overlay.
|
||||
color: PropTypes.string,
|
||||
|
||||
// The selected flex container.
|
||||
flexContainer: PropTypes.shape(flexContainer),
|
||||
|
||||
// The selected flex container can also be a flex item. This object contains the
|
||||
// parent flex container properties.
|
||||
flexItemContainer: PropTypes.shape(flexContainer),
|
||||
|
||||
// Whether or not the flexbox highlighter is highlighting the flex container.
|
||||
highlighted: PropTypes.bool,
|
||||
|
||||
};
|
||||
|
|
|
@ -51,7 +51,6 @@ class LayoutApp extends PureComponent {
|
|||
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
|
||||
onShowGridOutlineHighlight: PropTypes.func.isRequired,
|
||||
onToggleFlexboxHighlighter: PropTypes.func.isRequired,
|
||||
onToggleFlexItemShown: PropTypes.func.isRequired,
|
||||
onToggleGeometryEditor: PropTypes.func.isRequired,
|
||||
onToggleGridHighlighter: PropTypes.func.isRequired,
|
||||
onToggleShowGridAreas: PropTypes.func.isRequired,
|
||||
|
@ -62,23 +61,21 @@ class LayoutApp extends PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
getFlexboxHeader() {
|
||||
const { flexbox } = this.props;
|
||||
|
||||
if (!flexbox.actorID) {
|
||||
getFlexboxHeader(flexContainer) {
|
||||
if (!flexContainer.actorID) {
|
||||
// No flex container or flex item selected.
|
||||
return LAYOUT_L10N.getStr("flexbox.header");
|
||||
} else if (!flexbox.flexItemShown) {
|
||||
} else if (!flexContainer.flexItemShown) {
|
||||
// No flex item selected.
|
||||
return LAYOUT_L10N.getStr("flexbox.flexContainer");
|
||||
}
|
||||
|
||||
const grip = translateNodeFrontToGrip(flexbox.nodeFront);
|
||||
const grip = translateNodeFrontToGrip(flexContainer.nodeFront);
|
||||
return LAYOUT_L10N.getFormatStr("flexbox.flexItemOf", getSelectorFromGrip(grip));
|
||||
}
|
||||
|
||||
render() {
|
||||
let items = [
|
||||
const items = [
|
||||
{
|
||||
component: Grid,
|
||||
componentProps: this.props,
|
||||
|
@ -102,19 +99,43 @@ class LayoutApp extends PureComponent {
|
|||
];
|
||||
|
||||
if (Services.prefs.getBoolPref(FLEXBOX_ENABLED_PREF)) {
|
||||
items = [
|
||||
{
|
||||
// Since the flexbox panel is hidden behind a pref. We insert the flexbox container
|
||||
// to the first index of the accordion item list.
|
||||
items.splice(0, 0, {
|
||||
component: Flexbox,
|
||||
componentProps: {
|
||||
...this.props,
|
||||
flexContainer: this.props.flexbox.flexContainer,
|
||||
},
|
||||
header: this.getFlexboxHeader(this.props.flexbox.flexContainer),
|
||||
opened: Services.prefs.getBoolPref(FLEXBOX_OPENED_PREF),
|
||||
onToggled: () => {
|
||||
const opened = Services.prefs.getBoolPref(FLEXBOX_OPENED_PREF);
|
||||
Services.prefs.setBoolPref(FLEXBOX_OPENED_PREF, !opened);
|
||||
}
|
||||
});
|
||||
|
||||
// If the current selected node is both a flex container and flex item. Render
|
||||
// an accordion with another Flexbox component where the flexbox to show is the
|
||||
// parent flex container of the current selected node.
|
||||
if (this.props.flexbox.flexItemContainer &&
|
||||
this.props.flexbox.flexItemContainer.actorID) {
|
||||
// Insert the parent flex container to the second index of the accordion item
|
||||
// list.
|
||||
items.splice(1, 0, {
|
||||
component: Flexbox,
|
||||
componentProps: this.props,
|
||||
header: this.getFlexboxHeader(),
|
||||
componentProps: {
|
||||
...this.props,
|
||||
flexContainer: this.props.flexbox.flexItemContainer,
|
||||
},
|
||||
header: this.getFlexboxHeader(this.props.flexbox.flexItemContainer),
|
||||
opened: Services.prefs.getBoolPref(FLEXBOX_OPENED_PREF),
|
||||
onToggled: () => {
|
||||
const opened = Services.prefs.getBoolPref(FLEXBOX_OPENED_PREF);
|
||||
Services.prefs.setBoolPref(FLEXBOX_OPENED_PREF, !opened);
|
||||
}
|
||||
},
|
||||
...items
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -47,7 +47,6 @@ class LayoutView {
|
|||
const {
|
||||
onSetFlexboxOverlayColor,
|
||||
onToggleFlexboxHighlighter,
|
||||
onToggleFlexItemShown,
|
||||
} = this.flexboxInspector.getComponentProps();
|
||||
|
||||
this.gridInspector = new GridInspector(this.inspector, this.inspector.panelWin);
|
||||
|
@ -70,7 +69,6 @@ class LayoutView {
|
|||
onShowBoxModelHighlighterForNode,
|
||||
onShowGridOutlineHighlight,
|
||||
onToggleFlexboxHighlighter,
|
||||
onToggleFlexItemShown,
|
||||
onToggleGeometryEditor,
|
||||
onToggleGridHighlighter,
|
||||
onToggleShowGridAreas,
|
||||
|
|
|
@ -12,6 +12,7 @@ const {
|
|||
gridSpec,
|
||||
layoutSpec,
|
||||
} = require("devtools/shared/specs/layout");
|
||||
const { ELEMENT_NODE } = require("devtools/shared/dom-node-constants");
|
||||
const { SHOW_ELEMENT } = require("devtools/shared/dom-node-filter-constants");
|
||||
const { getStringifiableFragments } =
|
||||
require("devtools/server/actors/utils/css-grid-utils");
|
||||
|
@ -102,6 +103,10 @@ const FlexboxActor = ActorClassWithSpec(flexboxSpec, {
|
|||
|
||||
for (const line of flex.getLines()) {
|
||||
for (const item of line.getItems()) {
|
||||
if (item.node.nodeType !== ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
flexItemActors.push(new FlexItemActor(this, item.node, {
|
||||
crossMaxSize: item.crossMaxSize,
|
||||
crossMinSize: item.crossMinSize,
|
||||
|
@ -152,17 +157,20 @@ const FlexItemActor = ActorClassWithSpec(flexItemSpec, {
|
|||
return this.actorID;
|
||||
}
|
||||
|
||||
const { flexDirection } = CssLogic.getComputedStyle(this.containerEl);
|
||||
const styles = CssLogic.getComputedStyle(this.element);
|
||||
const clientRect = this.element.getBoundingClientRect();
|
||||
const dimension = flexDirection.startsWith("row") ? "width" : "height";
|
||||
|
||||
const form = {
|
||||
actor: this.actorID,
|
||||
// The flex item sizing data.
|
||||
flexItemSizing: this.flexItemSizing,
|
||||
};
|
||||
|
||||
if (this.element.nodeType === ELEMENT_NODE) {
|
||||
const { flexDirection } = CssLogic.getComputedStyle(this.containerEl);
|
||||
const styles = CssLogic.getComputedStyle(this.element);
|
||||
const clientRect = this.element.getBoundingClientRect();
|
||||
const dimension = flexDirection.startsWith("row") ? "width" : "height";
|
||||
|
||||
// The computed style properties of the flex item.
|
||||
properties: {
|
||||
form.properties = {
|
||||
"flex-basis": styles.flexBasis,
|
||||
"flex-grow": styles.flexGrow,
|
||||
"flex-shrink": styles.flexShrink,
|
||||
|
@ -172,8 +180,8 @@ const FlexItemActor = ActorClassWithSpec(flexItemSpec, {
|
|||
[`max-${dimension}`]: styles[`max-${dimension}`],
|
||||
// Computed width/height of the flex item element.
|
||||
[dimension]: parseFloat(clientRect[dimension.toLowerCase()].toPrecision(6)),
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// If the WalkerActor already knows the flex item element, then also return its
|
||||
// ActorID so we avoid the client from doing another round trip to get it in many
|
||||
|
@ -261,15 +269,15 @@ const LayoutActor = ActorClassWithSpec(layoutSpec, {
|
|||
},
|
||||
|
||||
/**
|
||||
* Helper function for getCurrentGrid and getCurrentFlexbox. Returns the grid or
|
||||
* flex container (whichever is requested) found by iterating on the given selected
|
||||
* node. The current node can be a grid/flex container or grid/flex item. If it is a
|
||||
* grid/flex item, returns the parent grid/flex container. Otherwise, returns null
|
||||
* if the current or parent node is not a grid/flex container.
|
||||
* Helper function for getAsFlexItem, getCurrentGrid and getCurrentFlexbox. Returns the
|
||||
* grid or flex container (whichever is requested) found by iterating on the given
|
||||
* selected node. The current node can be a grid/flex container or grid/flex item.
|
||||
* If it is a grid/flex item, returns the parent grid/flex container. Otherwise, returns
|
||||
* null if the current or parent node is not a grid/flex container.
|
||||
*
|
||||
* @param {Node|NodeActor} node
|
||||
* The node to start iterating at.
|
||||
* @param {String} type
|
||||
* @param {String} type
|
||||
* Can be "grid" or "flex", the display type we are searching for.
|
||||
* @return {GridActor|FlexboxActor|null} The GridActor or FlexboxActor of the
|
||||
* grid/flex container of the give node. Otherwise, returns null.
|
||||
|
@ -300,7 +308,8 @@ const LayoutActor = ActorClassWithSpec(layoutSpec, {
|
|||
return new GridActor(this, currentNode);
|
||||
}
|
||||
|
||||
// Otherwise, check if this is a flex item or the parent node is a flex container.
|
||||
// Otherwise, check if this is a flex/grid item or the parent node is a flex/grid
|
||||
// container.
|
||||
while ((currentNode = treeWalker.parentNode())) {
|
||||
if (!currentNode) {
|
||||
break;
|
||||
|
@ -333,7 +342,7 @@ const LayoutActor = ActorClassWithSpec(layoutSpec, {
|
|||
*
|
||||
* @param {Node|NodeActor} node
|
||||
* The node to start iterating at.
|
||||
* @return {GridActor|null} The GridActor of the grid container of the give node.
|
||||
* @return {GridActor|null} The GridActor of the grid container of the given node.
|
||||
* Otherwise, returns null.
|
||||
*/
|
||||
getCurrentGrid(node) {
|
||||
|
@ -348,10 +357,16 @@ const LayoutActor = ActorClassWithSpec(layoutSpec, {
|
|||
*
|
||||
* @param {Node|NodeActor} node
|
||||
* The node to start iterating at.
|
||||
* @return {FlexboxActor|null} The FlexboxActor of the flex container of the give node.
|
||||
* @param {Boolean|null} onlyLookAtParents
|
||||
* Whether or not to only consider the parent node of the given node.
|
||||
* @return {FlexboxActor|null} The FlexboxActor of the flex container of the given node.
|
||||
* Otherwise, returns null.
|
||||
*/
|
||||
getCurrentFlexbox(node) {
|
||||
getCurrentFlexbox(node, onlyLookAtParents) {
|
||||
if (onlyLookAtParents) {
|
||||
node = node.rawNode.parentNode;
|
||||
}
|
||||
|
||||
return this.getCurrentDisplay(node, "flex");
|
||||
},
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ const layoutSpec = generateActorSpec({
|
|||
getCurrentFlexbox: {
|
||||
request: {
|
||||
node: Arg(0, "domnode"),
|
||||
onlyLookAtParents: Arg(1, "nullable:boolean"),
|
||||
},
|
||||
response: {
|
||||
flexbox: RetVal("nullable:flexbox")
|
||||
|
|
Загрузка…
Ссылка в новой задаче