2016-04-21 00:15:34 +03:00
|
|
|
/* 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/. */
|
|
|
|
|
2016-05-17 20:49:29 +03:00
|
|
|
/* eslint-env browser */
|
|
|
|
|
2016-04-21 00:15:34 +03:00
|
|
|
"use strict";
|
|
|
|
|
2017-01-31 03:26:12 +03:00
|
|
|
const { DOM: dom, createClass, createFactory, PropTypes, addons } =
|
2016-04-21 00:15:34 +03:00
|
|
|
require("devtools/client/shared/vendor/react");
|
2017-01-31 03:26:12 +03:00
|
|
|
|
2017-02-03 02:38:57 +03:00
|
|
|
const { getStr, getFormatStr } = require("../utils/l10n");
|
2016-04-21 00:15:34 +03:00
|
|
|
const Types = require("../types");
|
2017-01-31 03:26:12 +03:00
|
|
|
const DeviceAdder = createFactory(require("./device-adder"));
|
2016-04-21 00:15:34 +03:00
|
|
|
|
|
|
|
module.exports = createClass({
|
2016-05-17 21:55:49 +03:00
|
|
|
displayName: "DeviceModal",
|
|
|
|
|
2016-04-21 00:15:34 +03:00
|
|
|
propTypes: {
|
2017-01-31 03:26:12 +03:00
|
|
|
deviceAdderViewportTemplate: PropTypes.shape(Types.viewport).isRequired,
|
2016-04-21 00:15:34 +03:00
|
|
|
devices: PropTypes.shape(Types.devices).isRequired,
|
2017-02-04 02:09:01 +03:00
|
|
|
onAddCustomDevice: PropTypes.func.isRequired,
|
2016-04-21 00:15:34 +03:00
|
|
|
onDeviceListUpdate: PropTypes.func.isRequired,
|
2017-02-04 02:09:01 +03:00
|
|
|
onRemoveCustomDevice: PropTypes.func.isRequired,
|
2016-04-21 00:15:34 +03:00
|
|
|
onUpdateDeviceDisplayed: PropTypes.func.isRequired,
|
2017-01-31 03:26:12 +03:00
|
|
|
onUpdateDeviceModal: PropTypes.func.isRequired,
|
2016-04-21 00:15:34 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
mixins: [ addons.PureRenderMixin ],
|
|
|
|
|
|
|
|
getInitialState() {
|
|
|
|
return {};
|
|
|
|
},
|
|
|
|
|
2016-05-17 20:49:29 +03:00
|
|
|
componentDidMount() {
|
|
|
|
window.addEventListener("keydown", this.onKeyDown, true);
|
|
|
|
},
|
|
|
|
|
2016-04-21 00:15:34 +03:00
|
|
|
componentWillReceiveProps(nextProps) {
|
2017-03-02 02:57:24 +03:00
|
|
|
let {
|
|
|
|
devices: oldDevices,
|
|
|
|
} = this.props;
|
2016-04-21 00:15:34 +03:00
|
|
|
let {
|
|
|
|
devices,
|
|
|
|
} = nextProps;
|
|
|
|
|
2017-03-02 02:57:24 +03:00
|
|
|
// Refresh component state only when model transitions from closed to open
|
|
|
|
if (!oldDevices.isModalOpen && devices.isModalOpen) {
|
|
|
|
for (let type of devices.types) {
|
|
|
|
for (let device of devices[type]) {
|
|
|
|
this.setState({
|
|
|
|
[device.name]: device.displayed,
|
|
|
|
});
|
|
|
|
}
|
2016-04-21 00:15:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-05-17 20:49:29 +03:00
|
|
|
componentWillUnmount() {
|
|
|
|
window.removeEventListener("keydown", this.onKeyDown, true);
|
|
|
|
},
|
|
|
|
|
2017-03-02 02:57:24 +03:00
|
|
|
onAddCustomDevice(device) {
|
|
|
|
this.props.onAddCustomDevice(device);
|
|
|
|
// Default custom devices to enabled
|
|
|
|
this.setState({
|
|
|
|
[device.name]: true,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2017-01-04 18:34:37 +03:00
|
|
|
onDeviceCheckboxChange({ nativeEvent: { button }, target }) {
|
|
|
|
if (button !== 0) {
|
|
|
|
return;
|
|
|
|
}
|
2016-04-21 00:15:34 +03:00
|
|
|
this.setState({
|
|
|
|
[target.value]: !this.state[target.value]
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
onDeviceModalSubmit() {
|
|
|
|
let {
|
|
|
|
devices,
|
|
|
|
onDeviceListUpdate,
|
|
|
|
onUpdateDeviceDisplayed,
|
2017-01-31 03:26:12 +03:00
|
|
|
onUpdateDeviceModal,
|
2016-04-21 00:15:34 +03:00
|
|
|
} = this.props;
|
|
|
|
|
2016-06-22 16:41:00 +03:00
|
|
|
let preferredDevices = {
|
|
|
|
"added": new Set(),
|
|
|
|
"removed": new Set(),
|
|
|
|
};
|
2016-04-21 00:15:34 +03:00
|
|
|
|
|
|
|
for (let type of devices.types) {
|
|
|
|
for (let device of devices[type]) {
|
2016-06-22 16:41:00 +03:00
|
|
|
let newState = this.state[device.name];
|
|
|
|
|
|
|
|
if (device.featured && !newState) {
|
|
|
|
preferredDevices.removed.add(device.name);
|
|
|
|
} else if (!device.featured && newState) {
|
|
|
|
preferredDevices.added.add(device.name);
|
2016-04-21 00:15:34 +03:00
|
|
|
}
|
|
|
|
|
2016-06-22 16:41:00 +03:00
|
|
|
if (this.state[device.name] != device.displayed) {
|
|
|
|
onUpdateDeviceDisplayed(device, type, this.state[device.name]);
|
2016-04-21 00:15:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-22 16:41:00 +03:00
|
|
|
onDeviceListUpdate(preferredDevices);
|
2017-01-31 03:26:12 +03:00
|
|
|
onUpdateDeviceModal(false);
|
2016-04-21 00:15:34 +03:00
|
|
|
},
|
|
|
|
|
2016-05-17 20:49:29 +03:00
|
|
|
onKeyDown(event) {
|
|
|
|
if (!this.props.devices.isModalOpen) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Escape keycode
|
|
|
|
if (event.keyCode === 27) {
|
|
|
|
let {
|
2017-01-31 03:26:12 +03:00
|
|
|
onUpdateDeviceModal
|
2016-05-17 20:49:29 +03:00
|
|
|
} = this.props;
|
2017-01-31 03:26:12 +03:00
|
|
|
onUpdateDeviceModal(false);
|
2016-05-17 20:49:29 +03:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-04-21 00:15:34 +03:00
|
|
|
render() {
|
|
|
|
let {
|
2017-01-31 03:26:12 +03:00
|
|
|
deviceAdderViewportTemplate,
|
2016-04-21 00:15:34 +03:00
|
|
|
devices,
|
2017-02-04 02:09:01 +03:00
|
|
|
onRemoveCustomDevice,
|
2017-01-31 03:26:12 +03:00
|
|
|
onUpdateDeviceModal,
|
2016-04-21 00:15:34 +03:00
|
|
|
} = this.props;
|
|
|
|
|
2017-03-02 02:57:24 +03:00
|
|
|
let {
|
|
|
|
onAddCustomDevice,
|
|
|
|
} = this;
|
|
|
|
|
2016-06-02 18:41:00 +03:00
|
|
|
const sortedDevices = {};
|
|
|
|
for (let type of devices.types) {
|
|
|
|
sortedDevices[type] = Object.assign([], devices[type])
|
|
|
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
|
|
}
|
|
|
|
|
2016-04-21 00:15:34 +03:00
|
|
|
return dom.div(
|
|
|
|
{
|
2016-05-17 20:49:29 +03:00
|
|
|
id: "device-modal-wrapper",
|
|
|
|
className: this.props.devices.isModalOpen ? "opened" : "closed",
|
2016-04-21 00:15:34 +03:00
|
|
|
},
|
|
|
|
dom.div(
|
|
|
|
{
|
2016-05-17 20:49:29 +03:00
|
|
|
className: "device-modal container",
|
2016-04-21 00:15:34 +03:00
|
|
|
},
|
2016-05-17 20:49:29 +03:00
|
|
|
dom.button({
|
|
|
|
id: "device-close-button",
|
|
|
|
className: "toolbar-button devtools-button",
|
2017-01-31 03:26:12 +03:00
|
|
|
onClick: () => onUpdateDeviceModal(false),
|
2016-05-17 20:49:29 +03:00
|
|
|
}),
|
|
|
|
dom.div(
|
|
|
|
{
|
|
|
|
className: "device-modal-content",
|
|
|
|
},
|
|
|
|
devices.types.map(type => {
|
|
|
|
return dom.div(
|
2016-04-21 00:15:34 +03:00
|
|
|
{
|
2016-05-17 20:49:29 +03:00
|
|
|
className: "device-type",
|
|
|
|
key: type,
|
2016-04-21 00:15:34 +03:00
|
|
|
},
|
2016-05-17 20:49:29 +03:00
|
|
|
dom.header(
|
2016-04-21 00:15:34 +03:00
|
|
|
{
|
2016-05-17 20:49:29 +03:00
|
|
|
className: "device-header",
|
2016-04-21 00:15:34 +03:00
|
|
|
},
|
2016-05-17 20:49:29 +03:00
|
|
|
type
|
|
|
|
),
|
|
|
|
sortedDevices[type].map(device => {
|
2017-02-03 02:38:57 +03:00
|
|
|
let details = getFormatStr(
|
|
|
|
"responsive.deviceDetails", device.width, device.height,
|
|
|
|
device.pixelRatio, device.userAgent, device.touch
|
|
|
|
);
|
2017-02-04 02:09:01 +03:00
|
|
|
|
|
|
|
let removeDeviceButton;
|
|
|
|
if (type == "custom") {
|
|
|
|
removeDeviceButton = dom.button({
|
|
|
|
className: "device-remove-button toolbar-button devtools-button",
|
|
|
|
onClick: () => onRemoveCustomDevice(device),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-05-17 20:49:29 +03:00
|
|
|
return dom.label(
|
|
|
|
{
|
|
|
|
className: "device-label",
|
|
|
|
key: device.name,
|
2017-02-03 02:38:57 +03:00
|
|
|
title: details,
|
2016-05-17 20:49:29 +03:00
|
|
|
},
|
|
|
|
dom.input({
|
|
|
|
className: "device-input-checkbox",
|
|
|
|
type: "checkbox",
|
|
|
|
value: device.name,
|
|
|
|
checked: this.state[device.name],
|
2017-01-04 18:34:37 +03:00
|
|
|
onChange: this.onDeviceCheckboxChange,
|
2016-05-17 20:49:29 +03:00
|
|
|
}),
|
2017-02-04 02:09:01 +03:00
|
|
|
dom.span(
|
|
|
|
{
|
|
|
|
className: "device-name",
|
|
|
|
},
|
|
|
|
device.name
|
|
|
|
),
|
|
|
|
removeDeviceButton
|
2016-05-17 20:49:29 +03:00
|
|
|
);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
})
|
|
|
|
),
|
2017-02-08 01:57:03 +03:00
|
|
|
DeviceAdder({
|
|
|
|
devices,
|
|
|
|
viewportTemplate: deviceAdderViewportTemplate,
|
|
|
|
onAddCustomDevice,
|
|
|
|
}),
|
2016-05-17 20:49:29 +03:00
|
|
|
dom.button(
|
|
|
|
{
|
|
|
|
id: "device-submit-button",
|
|
|
|
onClick: this.onDeviceModalSubmit,
|
|
|
|
},
|
|
|
|
getStr("responsive.done")
|
|
|
|
)
|
2016-04-21 00:15:34 +03:00
|
|
|
),
|
2016-05-17 20:49:29 +03:00
|
|
|
dom.div(
|
2016-04-21 00:15:34 +03:00
|
|
|
{
|
2016-05-17 20:49:29 +03:00
|
|
|
className: "modal-overlay",
|
2017-01-31 03:26:12 +03:00
|
|
|
onClick: () => onUpdateDeviceModal(false),
|
2016-05-17 20:49:29 +03:00
|
|
|
}
|
2016-04-21 00:15:34 +03:00
|
|
|
)
|
|
|
|
);
|
|
|
|
},
|
|
|
|
});
|