|
Packit |
f0b94e |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
f0b94e |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
f0b94e |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/* global window */
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
"use strict";
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
|
Packit |
f0b94e |
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|
Packit |
f0b94e |
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const Constants = require("../constants");
|
|
Packit |
f0b94e |
const Types = require("../types");
|
|
Packit |
f0b94e |
const Browser = createFactory(require("./Browser"));
|
|
Packit |
f0b94e |
const ViewportToolbar = createFactory(require("./ViewportToolbar"));
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const VIEWPORT_MIN_WIDTH = Constants.MIN_VIEWPORT_DIMENSION;
|
|
Packit |
f0b94e |
const VIEWPORT_MIN_HEIGHT = Constants.MIN_VIEWPORT_DIMENSION;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
class ResizableViewport extends Component {
|
|
Packit |
f0b94e |
static get propTypes() {
|
|
Packit |
f0b94e |
return {
|
|
Packit |
f0b94e |
devices: PropTypes.shape(Types.devices).isRequired,
|
|
Packit |
f0b94e |
screenshot: PropTypes.shape(Types.screenshot).isRequired,
|
|
Packit |
f0b94e |
swapAfterMount: PropTypes.bool.isRequired,
|
|
Packit |
f0b94e |
viewport: PropTypes.shape(Types.viewport).isRequired,
|
|
Packit |
f0b94e |
onBrowserMounted: PropTypes.func.isRequired,
|
|
Packit |
f0b94e |
onChangeDevice: PropTypes.func.isRequired,
|
|
Packit |
f0b94e |
onContentResize: PropTypes.func.isRequired,
|
|
Packit |
f0b94e |
onRemoveDeviceAssociation: PropTypes.func.isRequired,
|
|
Packit |
f0b94e |
onResizeViewport: PropTypes.func.isRequired,
|
|
Packit |
f0b94e |
onRotateViewport: PropTypes.func.isRequired,
|
|
Packit |
f0b94e |
onUpdateDeviceModal: PropTypes.func.isRequired,
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
constructor(props) {
|
|
Packit |
f0b94e |
super(props);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
this.state = {
|
|
Packit |
f0b94e |
isResizing: false,
|
|
Packit |
f0b94e |
lastClientX: 0,
|
|
Packit |
f0b94e |
lastClientY: 0,
|
|
Packit |
f0b94e |
ignoreX: false,
|
|
Packit |
f0b94e |
ignoreY: false,
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
this.onResizeStart = this.onResizeStart.bind(this);
|
|
Packit |
f0b94e |
this.onResizeStop = this.onResizeStop.bind(this);
|
|
Packit |
f0b94e |
this.onResizeDrag = this.onResizeDrag.bind(this);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
onResizeStart({ target, clientX, clientY }) {
|
|
Packit |
f0b94e |
window.addEventListener("mousemove", this.onResizeDrag, true);
|
|
Packit |
f0b94e |
window.addEventListener("mouseup", this.onResizeStop, true);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
this.setState({
|
|
Packit |
f0b94e |
isResizing: true,
|
|
Packit |
f0b94e |
lastClientX: clientX,
|
|
Packit |
f0b94e |
lastClientY: clientY,
|
|
Packit |
f0b94e |
ignoreX: target === this.refs.resizeBarY,
|
|
Packit |
f0b94e |
ignoreY: target === this.refs.resizeBarX,
|
|
Packit |
f0b94e |
});
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
onResizeStop() {
|
|
Packit |
f0b94e |
window.removeEventListener("mousemove", this.onResizeDrag, true);
|
|
Packit |
f0b94e |
window.removeEventListener("mouseup", this.onResizeStop, true);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
this.setState({
|
|
Packit |
f0b94e |
isResizing: false,
|
|
Packit |
f0b94e |
lastClientX: 0,
|
|
Packit |
f0b94e |
lastClientY: 0,
|
|
Packit |
f0b94e |
ignoreX: false,
|
|
Packit |
f0b94e |
ignoreY: false,
|
|
Packit |
f0b94e |
});
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
onResizeDrag({ clientX, clientY }) {
|
|
Packit |
f0b94e |
if (!this.state.isResizing) {
|
|
Packit |
f0b94e |
return;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let { lastClientX, lastClientY, ignoreX, ignoreY } = this.state;
|
|
Packit |
f0b94e |
// the viewport is centered horizontally, so horizontal resize resizes
|
|
Packit |
f0b94e |
// by twice the distance the mouse was dragged - on left and right side.
|
|
Packit |
f0b94e |
let deltaX = 2 * (clientX - lastClientX);
|
|
Packit |
f0b94e |
let deltaY = (clientY - lastClientY);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (ignoreX) {
|
|
Packit |
f0b94e |
deltaX = 0;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
if (ignoreY) {
|
|
Packit |
f0b94e |
deltaY = 0;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let width = this.props.viewport.width + deltaX;
|
|
Packit |
f0b94e |
let height = this.props.viewport.height + deltaY;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (width < VIEWPORT_MIN_WIDTH) {
|
|
Packit |
f0b94e |
width = VIEWPORT_MIN_WIDTH;
|
|
Packit |
f0b94e |
} else {
|
|
Packit |
f0b94e |
lastClientX = clientX;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (height < VIEWPORT_MIN_HEIGHT) {
|
|
Packit |
f0b94e |
height = VIEWPORT_MIN_HEIGHT;
|
|
Packit |
f0b94e |
} else {
|
|
Packit |
f0b94e |
lastClientY = clientY;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Update the viewport store with the new width and height.
|
|
Packit |
f0b94e |
this.props.onResizeViewport(width, height);
|
|
Packit |
f0b94e |
// Change the device selector back to an unselected device
|
|
Packit |
f0b94e |
// TODO: Bug 1332754: Logic like this probably belongs in the action creator.
|
|
Packit |
f0b94e |
if (this.props.viewport.device) {
|
|
Packit |
f0b94e |
// In bug 1329843 and others, we may eventually stop this approach of removing the
|
|
Packit |
f0b94e |
// the properties of the device on resize. However, at the moment, there is no
|
|
Packit |
f0b94e |
// way to edit dPR when a device is selected, and there is no UI at all for editing
|
|
Packit |
f0b94e |
// UA, so it's important to keep doing this for now.
|
|
Packit |
f0b94e |
this.props.onRemoveDeviceAssociation();
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
this.setState({
|
|
Packit |
f0b94e |
lastClientX,
|
|
Packit |
f0b94e |
lastClientY
|
|
Packit |
f0b94e |
});
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
render() {
|
|
Packit |
f0b94e |
let {
|
|
Packit |
f0b94e |
devices,
|
|
Packit |
f0b94e |
screenshot,
|
|
Packit |
f0b94e |
swapAfterMount,
|
|
Packit |
f0b94e |
viewport,
|
|
Packit |
f0b94e |
onBrowserMounted,
|
|
Packit |
f0b94e |
onChangeDevice,
|
|
Packit |
f0b94e |
onContentResize,
|
|
Packit |
f0b94e |
onResizeViewport,
|
|
Packit |
f0b94e |
onRotateViewport,
|
|
Packit |
f0b94e |
onUpdateDeviceModal,
|
|
Packit |
f0b94e |
} = this.props;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let resizeHandleClass = "viewport-resize-handle";
|
|
Packit |
f0b94e |
if (screenshot.isCapturing) {
|
|
Packit |
f0b94e |
resizeHandleClass += " hidden";
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let contentClass = "viewport-content";
|
|
Packit |
f0b94e |
if (this.state.isResizing) {
|
|
Packit |
f0b94e |
contentClass += " resizing";
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return dom.div(
|
|
Packit |
f0b94e |
{
|
|
Packit |
f0b94e |
className: "resizable-viewport",
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
ViewportToolbar({
|
|
Packit |
f0b94e |
devices,
|
|
Packit |
f0b94e |
viewport,
|
|
Packit |
f0b94e |
onChangeDevice,
|
|
Packit |
f0b94e |
onResizeViewport,
|
|
Packit |
f0b94e |
onRotateViewport,
|
|
Packit |
f0b94e |
onUpdateDeviceModal,
|
|
Packit |
f0b94e |
}),
|
|
Packit |
f0b94e |
dom.div(
|
|
Packit |
f0b94e |
{
|
|
Packit |
f0b94e |
className: contentClass,
|
|
Packit |
f0b94e |
style: {
|
|
Packit |
f0b94e |
width: viewport.width + "px",
|
|
Packit |
f0b94e |
height: viewport.height + "px",
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
Browser({
|
|
Packit |
f0b94e |
swapAfterMount,
|
|
Packit |
f0b94e |
onBrowserMounted,
|
|
Packit |
f0b94e |
onContentResize,
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
),
|
|
Packit |
f0b94e |
dom.div({
|
|
Packit |
f0b94e |
className: resizeHandleClass,
|
|
Packit |
f0b94e |
onMouseDown: this.onResizeStart,
|
|
Packit |
f0b94e |
}),
|
|
Packit |
f0b94e |
dom.div({
|
|
Packit |
f0b94e |
ref: "resizeBarX",
|
|
Packit |
f0b94e |
className: "viewport-horizontal-resize-handle",
|
|
Packit |
f0b94e |
onMouseDown: this.onResizeStart,
|
|
Packit |
f0b94e |
}),
|
|
Packit |
f0b94e |
dom.div({
|
|
Packit |
f0b94e |
ref: "resizeBarY",
|
|
Packit |
f0b94e |
className: "viewport-vertical-resize-handle",
|
|
Packit |
f0b94e |
onMouseDown: this.onResizeStart,
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
module.exports = ResizableViewport;
|