Bug 1406287 - Part 3: Correspond for changing size of sidebar. r?gl
MozReview-Commit-ID: 9ndHImmpM9c
--- a/devtools/client/inspector/animation/actions/index.js
+++ b/devtools/client/inspector/animation/actions/index.js
@@ -2,13 +2,19 @@
* 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 { createEnum } = require("devtools/client/shared/enum");
createEnum([
+
// Update the list of animation.
"UPDATE_ANIMATIONS",
+
// Update state of the picker enabled.
"UPDATE_ELEMENT_PICKER_ENABLED",
+
+ // Update sidebar size.
+ "UPDATE_SIDEBAR_SIZE",
+
], module.exports);
--- a/devtools/client/inspector/animation/actions/moz.build
+++ b/devtools/client/inspector/animation/actions/moz.build
@@ -1,9 +1,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(
'animations.js',
'element-picker.js',
- 'index.js'
+ 'index.js',
+ 'sidebar.js',
)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/animation/actions/sidebar.js
@@ -0,0 +1,19 @@
+/* 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 { UPDATE_SIDEBAR_SIZE } = require("./index");
+
+module.exports = {
+ /**
+ * Update the sidebar size.
+ */
+ updateSidebarSize(size) {
+ return {
+ type: UPDATE_SIDEBAR_SIZE,
+ size,
+ };
+ }
+};
--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -5,27 +5,31 @@
"use strict";
const { AnimationsFront } = require("devtools/shared/fronts/animation");
const { createElement, createFactory } = require("devtools/client/shared/vendor/react");
const { Provider } = require("devtools/client/shared/vendor/react-redux");
const App = createFactory(require("./components/App"));
const { isAllTimingEffectEqual } = require("./utils/utils");
+
const { updateAnimations } = require("./actions/animations");
const { updateElementPickerEnabled } = require("./actions/element-picker");
+const { updateSidebarSize } = require("./actions/sidebar");
class AnimationInspector {
constructor(inspector) {
this.inspector = inspector;
this.toggleElementPicker = this.toggleElementPicker.bind(this);
this.update = this.update.bind(this);
this.onElementPickerStarted = this.onElementPickerStarted.bind(this);
this.onElementPickerStopped = this.onElementPickerStopped.bind(this);
+ this.onSidebarResized = this.onSidebarResized.bind(this);
+ this.onSidebarSelect = this.onSidebarSelect.bind(this);
this.init();
}
init() {
const target = this.inspector.target;
this.animationsFront = new AnimationsFront(target.client, target.form);
@@ -39,24 +43,26 @@ class AnimationInspector {
{
toggleElementPicker: this.toggleElementPicker
}
)
);
this.provider = provider;
this.inspector.selection.on("new-node-front", this.update);
- this.inspector.sidebar.on("newanimationinspector-selected", this.update);
+ this.inspector.sidebar.on("newanimationinspector-selected", this.onSidebarSelect);
+ this.inspector.toolbox.on("inspector-sidebar-resized", this.onSidebarResized);
this.inspector.toolbox.on("picker-started", this.onElementPickerStarted);
this.inspector.toolbox.on("picker-stopped", this.onElementPickerStopped);
}
destroy() {
this.inspector.selection.off("new-node-front", this.update);
- this.inspector.sidebar.off("newanimationinspector-selected", this.update);
+ this.inspector.sidebar.off("newanimationinspector-selected", this.onSidebarSelect);
+ this.inspector.toolbox.off("inspector-sidebar-resized", this.onSidebarResized);
this.inspector.toolbox.off("picker-started", this.onElementPickerStarted);
this.inspector.toolbox.off("picker-stopped", this.onElementPickerStopped);
this.inspector = null;
}
async update() {
if (!this.inspector || !this.isPanelVisible()) {
@@ -92,11 +98,24 @@ class AnimationInspector {
onElementPickerStarted() {
this.inspector.store.dispatch(updateElementPickerEnabled(true));
}
onElementPickerStopped() {
this.inspector.store.dispatch(updateElementPickerEnabled(false));
}
+
+ onSidebarSelect() {
+ this.update();
+ this.onSidebarResized(null, this.inspector.getSidebarSize());
+ }
+
+ onSidebarResized(type, size) {
+ if (!this.isPanelVisible()) {
+ return;
+ }
+
+ this.inspector.store.dispatch(updateSidebarSize(size));
+ }
}
module.exports = AnimationInspector;
--- a/devtools/client/inspector/animation/components/AnimationTimelineTickList.js
+++ b/devtools/client/inspector/animation/components/AnimationTimelineTickList.js
@@ -1,45 +1,68 @@
/* 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, DOM: dom, PropTypes, PureComponent } =
require("devtools/client/shared/vendor/react");
+const { connect } = require("devtools/client/shared/vendor/react-redux");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const AnimationTimelineTickItem = createFactory(require("./AnimationTimelineTickItem"));
const TimeScale = require("../utils/timescale");
const { findOptimalTimeInterval } = require("../utils/utils");
// The minimum spacing between 2 time graduation headers in the timeline (px).
const TIME_GRADUATION_MIN_SPACING = 40;
class AnimationTimelineTickList extends PureComponent {
static get propTypes() {
return {
animations: PropTypes.arrayOf(PropTypes.object).isRequired,
+ sidebarWidth: PropTypes.number.isRequired,
};
}
constructor(props) {
super(props);
this.state = {
tickList: [],
};
}
componentDidMount() {
this.updateTickList();
}
+ componentWillReceiveProps(nextProps) {
+ this.updateTickList();
+ }
+
+ shouldComponentUpdate(nextProps, nextState) {
+ if (this.state.tickList.length !== nextState.tickList.length) {
+ return true;
+ }
+
+ for (let i = 0; i < this.state.tickList.length; i++) {
+ const currentTickItem = this.state.tickList[i];
+ const nextTickItem = nextState.tickList[i];
+
+ if (currentTickItem.text !== nextTickItem.text) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
updateTickList() {
const { animations } = this.props;
const timeScale = new TimeScale(animations);
const tickListEl = ReactDOM.findDOMNode(this);
const width = tickListEl.offsetWidth;
const animationDuration = timeScale.getDuration();
const minTimeInterval = TIME_GRADUATION_MIN_SPACING * animationDuration / width;
const intervalLength = findOptimalTimeInterval(minTimeInterval);
@@ -65,9 +88,15 @@ class AnimationTimelineTickList extends
{
className: "animation-timeline-tick-list"
},
tickList.map(tickItem => AnimationTimelineTickItem(tickItem))
);
}
}
-module.exports = AnimationTimelineTickList;
+const mapStateToProps = state => {
+ return {
+ sidebarWidth: state.animationSidebar.width
+ };
+};
+
+module.exports = connect(mapStateToProps)(AnimationTimelineTickList);
--- a/devtools/client/inspector/animation/reducers/moz.build
+++ b/devtools/client/inspector/animation/reducers/moz.build
@@ -1,8 +1,9 @@
# 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(
'animations.js',
'element-picker.js',
+ 'sidebar.js',
)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/animation/reducers/sidebar.js
@@ -0,0 +1,23 @@
+/* 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 { UPDATE_SIDEBAR_SIZE } = require("../actions/index");
+
+const INITIAL_SIZE = {
+ width: 0,
+ height: 0
+};
+
+const reducers = {
+ [UPDATE_SIDEBAR_SIZE](_, { size }) {
+ return size;
+ }
+};
+
+module.exports = function (size = INITIAL_SIZE, action) {
+ const reducer = reducers[action.type];
+ return reducer ? reducer(size, action) : size;
+};
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -121,16 +121,17 @@ function Inspector(toolbox) {
this.onDetached = this.onDetached.bind(this);
this.onMarkupLoaded = this.onMarkupLoaded.bind(this);
this.onNewSelection = this.onNewSelection.bind(this);
this.onNewRoot = this.onNewRoot.bind(this);
this.onPanelWindowResize = this.onPanelWindowResize.bind(this);
this.onShowBoxModelHighlighterForNode =
this.onShowBoxModelHighlighterForNode.bind(this);
this.onSidebarHidden = this.onSidebarHidden.bind(this);
+ this.onSidebarResized = this.onSidebarResized.bind(this);
this.onSidebarSelect = this.onSidebarSelect.bind(this);
this.onSidebarShown = this.onSidebarShown.bind(this);
this._target.on("will-navigate", this._onBeforeNavigate);
this._detectingActorFeatures = this._detectActorFeatures();
}
Inspector.prototype = {
@@ -498,16 +499,17 @@ Inspector.prototype = {
endPanelControl: true,
startPanel: this.InspectorTabPanel({
id: "inspector-main-content"
}),
endPanel: this.InspectorTabPanel({
id: "inspector-sidebar-container"
}),
vert: this.useLandscapeMode(),
+ onControlledPanelResized: this.onSidebarResized,
});
this._splitter = this.ReactDOM.render(splitter,
this.panelDoc.getElementById("inspector-splitter-box"));
this.panelWin.addEventListener("resize", this.onPanelWindowResize, true);
},
@@ -568,16 +570,20 @@ Inspector.prototype = {
// Then forces the panel creation by calling getPanel
// (This allows lazy loading the panels only once we select them)
this.getPanel(toolId);
this.toolbox.emit("inspector-sidebar-select", toolId);
},
+ onSidebarResized: function (width, height) {
+ this.toolbox.emit("inspector-sidebar-resized", { width, height });
+ },
+
/**
* Lazily get and create panel instances displayed in the sidebar
*/
getPanel: function (id) {
if (this._panels.has(id)) {
return this._panels.get(id);
}
let panel;
--- a/devtools/client/inspector/reducers.js
+++ b/devtools/client/inspector/reducers.js
@@ -5,16 +5,18 @@
"use strict";
// This file exposes the Redux reducers of the box model, grid and grid highlighter
// settings.
exports.animations = require("devtools/client/inspector/animation/reducers/animations");
exports.animationElementPicker =
require("devtools/client/inspector/animation/reducers/element-picker");
+exports.animationSidebar =
+ require("devtools/client/inspector/animation/reducers/sidebar");
exports.boxModel = require("devtools/client/inspector/boxmodel/reducers/box-model");
exports.changes = require("devtools/client/inspector/changes/reducers/changes");
exports.events = require("devtools/client/inspector/events/reducers/events");
exports.extensionsSidebar = require("devtools/client/inspector/extensions/reducers/sidebar");
exports.flexboxes = require("devtools/client/inspector/flexbox/reducers/flexboxes");
exports.fontOptions = require("devtools/client/inspector/fonts/reducers/font-options");
exports.fonts = require("devtools/client/inspector/fonts/reducers/fonts");
exports.grids = require("devtools/client/inspector/grids/reducers/grids");
--- a/devtools/client/shared/components/splitter/SplitBox.js
+++ b/devtools/client/shared/components/splitter/SplitBox.js
@@ -35,16 +35,18 @@ class SplitBox extends Component {
// True if the right/bottom panel should be controlled.
endPanelControl: PropTypes.bool,
// Size of the splitter handle bar.
splitterSize: PropTypes.string,
// True if the splitter bar is vertical (default is vertical).
vert: PropTypes.bool,
// Style object.
style: PropTypes.object,
+ // Call when controlled panel was resized.
+ onControlledPanelResized: PropTypes.func,
};
}
static get defaultProps() {
return {
splitterSize: 5,
vert: true,
endPanelControl: false
@@ -85,16 +87,23 @@ class SplitBox extends Component {
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 ||
nextProps.splitterSize != this.props.splitterSize;
}
+ 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);
+ }
+ }
+
// Dragging Events
/**
* Set 'resizing' cursor on entire document during splitter dragging.
* This avoids cursor-flickering that happens when the mouse leaves
* the splitter bar area (happens frequently).
*/
onStartMove() {