Bug 1338300 - part3: add colorpicker to update grid overlay color;r=gl

MozReview-Commit-ID: 5wgZCgx8J3u

--HG--
extra : rebase_source : 88ffb25a7737d4ea44911a7d6101454298387824
This commit is contained in:
Julian Descottes 2017-02-22 12:39:04 +01:00
Родитель 2b9ac413d6
Коммит 5551adf76e
10 изменённых файлов: 231 добавлений и 9 удалений

Просмотреть файл

@ -5,12 +5,29 @@
"use strict";
const {
UPDATE_GRID_COLOR,
UPDATE_GRID_HIGHLIGHTED,
UPDATE_GRIDS,
} = require("./index");
module.exports = {
/**
* Update the color used for the grid's highlighter.
*
* @param {NodeFront} nodeFront
* The NodeFront of the DOM node to toggle the grid highlighter.
* @param {String} color
* The color to use for thie nodeFront's grid highlighter.
*/
updateGridColor(nodeFront, color) {
return {
type: UPDATE_GRID_COLOR,
color,
nodeFront,
};
},
/**
* Update the grid highlighted state.
*
@ -22,8 +39,8 @@ module.exports = {
updateGridHighlighted(nodeFront, highlighted) {
return {
type: UPDATE_GRID_HIGHLIGHTED,
nodeFront,
highlighted,
nodeFront,
};
},

Просмотреть файл

@ -8,6 +8,9 @@ const { createEnum } = require("devtools/client/shared/enum");
createEnum([
// Update the color used for the overlay of a grid.
"UPDATE_GRID_COLOR",
// Update the grid highlighted state.
"UPDATE_GRID_HIGHLIGHTED",

Просмотреть файл

@ -26,11 +26,13 @@ const App = createClass({
propTypes: {
boxModel: PropTypes.shape(Types.boxModel).isRequired,
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
showBoxModelProperties: PropTypes.bool.isRequired,
onShowBoxModelEditor: PropTypes.func.isRequired,
onHideBoxModelHighlighter: PropTypes.func.isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onShowBoxModelEditor: PropTypes.func.isRequired,
onShowBoxModelHighlighter: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
onToggleShowGridLineNumbers: PropTypes.func.isRequired,

Просмотреть файл

@ -18,8 +18,10 @@ module.exports = createClass({
displayName: "Grid",
propTypes: {
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
onToggleShowGridLineNumbers: PropTypes.func.isRequired,
onToggleShowInfiniteLines: PropTypes.func.isRequired,
@ -29,8 +31,10 @@ module.exports = createClass({
render() {
let {
getSwatchColorPickerTooltip,
grids,
highlighterSettings,
onSetGridOverlayColor,
onToggleGridHighlighter,
onToggleShowGridLineNumbers,
onToggleShowInfiniteLines,
@ -42,7 +46,9 @@ module.exports = createClass({
id: "layout-grid-container",
},
GridList({
getSwatchColorPickerTooltip,
grids,
onSetGridOverlayColor,
onToggleGridHighlighter,
}),
GridDisplaySettings({

Просмотреть файл

@ -4,8 +4,8 @@
"use strict";
const { addons, createClass, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { addons, createClass, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react");
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
const Types = require("../types");
@ -14,6 +14,7 @@ module.exports = createClass({
displayName: "GridItem",
propTypes: {
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grid: PropTypes.shape(Types.grid).isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
@ -21,6 +22,34 @@ module.exports = createClass({
mixins: [ addons.PureRenderMixin ],
componentDidMount() {
let tooltip = this.props.getSwatchColorPickerTooltip();
let swatchEl = findDOMNode(this).querySelector(".grid-color-swatch");
let previousColor;
tooltip.addSwatch(swatchEl, {
onCommit: this.setGridColor,
onPreview: this.setGridColor,
onRevert: () => {
this.props.onSetGridOverlayColor(this.props.grid.nodeFront, previousColor);
},
onShow: () => {
previousColor = this.props.grid.color;
},
});
},
componentWillUnmount() {
let tooltip = this.props.getSwatchColorPickerTooltip();
let swatchEl = findDOMNode(this).querySelector(".grid-color-swatch");
tooltip.removeSwatch(swatchEl);
},
setGridColor() {
let color = findDOMNode(this).querySelector(".grid-color-value").textContent;
this.props.onSetGridOverlayColor(this.props.grid.nodeFront, color);
},
onGridCheckboxClick() {
let {
grid,
@ -50,6 +79,7 @@ module.exports = createClass({
return dom.li(
{
key: grid.id,
className: "grid-item",
},
dom.label(
{},
@ -62,6 +92,25 @@ module.exports = createClass({
}
),
gridName
),
dom.div(
{
className: "grid-color-swatch",
style: {
backgroundColor: grid.color,
},
title: grid.color,
}
),
// The SwatchColorPicker relies on the nextSibling of the swatch element to apply
// the selected color. This is why we use a span in display: none for now.
// Ideally we should modify the SwatchColorPickerTooltip to bypass this requirement.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1341578
dom.span(
{
className: "grid-color-value"
},
grid.color
)
);
},

Просмотреть файл

@ -17,7 +17,9 @@ module.exports = createClass({
displayName: "GridList",
propTypes: {
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
},
@ -25,7 +27,9 @@ module.exports = createClass({
render() {
let {
getSwatchColorPickerTooltip,
grids,
onSetGridOverlayColor,
onToggleGridHighlighter,
} = this.props;
@ -40,7 +44,9 @@ module.exports = createClass({
dom.ul(
{},
grids.map(grid => GridItem({
getSwatchColorPickerTooltip,
grid,
onSetGridOverlayColor,
onToggleGridHighlighter,
}))
)

Просмотреть файл

@ -13,10 +13,13 @@ const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
const { Provider } = require("devtools/client/shared/vendor/react-redux");
const SwatchColorPickerTooltip = require("devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip");
const {
updateLayout,
} = require("./actions/box-model");
const {
updateGridColor,
updateGridHighlighted,
updateGrids,
} = require("./actions/grids");
@ -37,6 +40,18 @@ const NUMERIC = /^-?[\d\.]+$/;
const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers";
const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
// Default grid colors.
const GRID_COLORS = [
"#05E4EE",
"#BB9DFF",
"#FFB53B",
"#71F362",
"#FF90FF",
"#FF90FF",
"#1B80FF",
"#FF2647"
];
function LayoutView(inspector, window) {
this.document = window.document;
this.highlighters = inspector.highlighters;
@ -74,7 +89,23 @@ LayoutView.prototype = {
this.loadHighlighterSettings();
// Create a shared SwatchColorPicker instance to be reused by all GridItem components.
this.swatchColorPickerTooltip = new SwatchColorPickerTooltip(
this.inspector.toolbox.doc,
this.inspector,
{
supportsCssColor4ColorFunction: () => false
}
);
let app = App({
/**
* Retrieve the shared SwatchColorPicker instance.
*/
getSwatchColorPickerTooltip: () => {
return this.swatchColorPickerTooltip;
},
/**
* Shows the box model properties under the box model if true, otherwise, hidden by
* default.
@ -89,6 +120,29 @@ LayoutView.prototype = {
toolbox.highlighterUtils.unhighlight();
},
/**
* Handler for a change in the grid overlay color picker for a grid container.
*
* @param {NodeFront} node
* The NodeFront of the grid container element for which the grid color is
* being updated.
* @param {String} color
* A hex string representing the color to use.
*/
onSetGridOverlayColor: (node, color) => {
this.store.dispatch(updateGridColor(node, color));
let { grids } = this.store.getState();
// If the grid for which the color was updated currently has a highlighter, update
// the color.
for (let grid of grids) {
if (grid.nodeFront === node && grid.highlighted) {
let highlighterSettings = this.getGridHighlighterSettings(node);
this.highlighters.showGridHighlighter(node, highlighterSettings);
}
}
},
/**
* Shows the inplace editor when a box model editable value is clicked on the
* box model panel.
@ -180,13 +234,13 @@ LayoutView.prototype = {
* highlighter is toggled on/off for.
*/
onToggleGridHighlighter: node => {
let { highlighterSettings } = this.store.getState();
let highlighterSettings = this.getGridHighlighterSettings(node);
this.highlighters.toggleGridHighlighter(node, highlighterSettings);
},
/**
* Handler for a change in the show grid line numbers checkbox in the
* GridDisplaySettings component. TOggles on/off the option to show the grid line
* GridDisplaySettings component. Toggles on/off the option to show the grid line
* numbers in the grid highlighter. Refreshes the shown grid highlighter for the
* grids currently highlighted.
*
@ -197,10 +251,11 @@ LayoutView.prototype = {
this.store.dispatch(updateShowGridLineNumbers(enabled));
Services.prefs.setBoolPref(SHOW_GRID_LINE_NUMBERS, enabled);
let { grids, highlighterSettings } = this.store.getState();
let { grids } = this.store.getState();
for (let grid of grids) {
if (grid.highlighted) {
let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront);
this.highlighters.showGridHighlighter(grid.nodeFront, highlighterSettings);
}
}
@ -219,14 +274,15 @@ LayoutView.prototype = {
this.store.dispatch(updateShowInfiniteLines(enabled));
Services.prefs.setBoolPref(SHOW_INFINITE_LINES_PREF, enabled);
let { grids, highlighterSettings } = this.store.getState();
let { grids } = this.store.getState();
for (let grid of grids) {
if (grid.highlighted) {
let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront);
this.highlighters.showGridHighlighter(grid.nodeFront, highlighterSettings);
}
}
},
}
});
let provider = createElement(Provider, {
@ -270,6 +326,43 @@ LayoutView.prototype = {
this.walker = null;
},
/**
* Returns the color set for the grid highlighter associated with the provided
* nodeFront.
*
* @param {NodeFront} nodeFront
* The NodeFront for which we need the color.
*/
getGridColorForNodeFront(nodeFront) {
let { grids } = this.store.getState();
for (let grid of grids) {
if (grid.nodeFront === nodeFront) {
return grid.color;
}
}
return null;
},
/**
* Create a highlighter settings object for the provided nodeFront.
*
* @param {NodeFront} nodeFront
* The NodeFront for which we need highlighter settings.
*/
getGridHighlighterSettings(nodeFront) {
let { highlighterSettings } = this.store.getState();
// Get the grid color for the provided nodeFront.
let color = this.getGridColorForNodeFront(nodeFront);
// Merge the grid color to the generic highlighter settings.
return Object.assign({}, highlighterSettings, {
color
});
},
/**
* Returns true if the layout panel is visible, and false otherwise.
*/
@ -391,8 +484,12 @@ LayoutView.prototype = {
let grid = gridFronts[i];
let nodeFront = yield this.walker.getNodeFromActor(grid.actorID, ["containerEl"]);
let fallbackColor = GRID_COLORS[i % GRID_COLORS.length];
let color = this.getGridColorForNodeFront(nodeFront) || fallbackColor;
grids.push({
id: i,
color,
gridFragments: grid.gridFragments,
highlighted: nodeFront == this.highlighters.gridHighlighterShown,
nodeFront,

Просмотреть файл

@ -5,6 +5,7 @@
"use strict";
const {
UPDATE_GRID_COLOR,
UPDATE_GRID_HIGHLIGHTED,
UPDATE_GRIDS,
} = require("../actions/index");
@ -13,6 +14,18 @@ const INITIAL_GRIDS = [];
let reducers = {
[UPDATE_GRID_COLOR](grids, { nodeFront, color }) {
let newGrids = grids.map(g => {
if (g.nodeFront == nodeFront) {
g.color = color;
}
return g;
});
return newGrids;
},
[UPDATE_GRID_HIGHLIGHTED](grids, { nodeFront, highlighted }) {
return grids.map(g => {
return Object.assign({}, g, {

Просмотреть файл

@ -24,6 +24,9 @@ exports.grid = {
// The id of the grid
id: PropTypes.number,
// The color for the grid overlay highlighter
color: PropTypes.string,
// The grid fragment object of the grid container
gridFragments: PropTypes.array,

Просмотреть файл

@ -52,3 +52,29 @@
text-align: center;
padding: 0.5em;
}
/**
* Grid Item
*/
.grid-item {
display: flex;
align-items: center;
}
.grid-item input {
margin: 0 5px;
}
.grid-color-swatch {
width: 12px;
height: 12px;
margin-left: 5px;
border: 1px solid var(--theme-highlight-gray);
border-radius: 50%;
cursor: pointer;
}
.grid-color-value {
display: none;
}