Bug 1241720 - Modal to promote devices from larger DB r=jyrans
This commit is contained in:
@@ -142,7 +142,7 @@
|
||||
|
||||
.theme-dark .tabs .tabs-menu-item:hover,
|
||||
.theme-light .tabs .tabs-menu-item:hover {
|
||||
background-color: rgba(170,170,170,.2);
|
||||
background-color: var(--toolbar-tab-hover);
|
||||
}
|
||||
|
||||
.theme-dark .tabs .tabs-menu-item.is-active,
|
||||
@@ -161,7 +161,7 @@
|
||||
|
||||
.theme-dark .tabs .tabs-menu-item:active:hover,
|
||||
.theme-light .tabs .tabs-menu-item:active:hover {
|
||||
background-color: rgba(170,170,170,.4);
|
||||
background-color: var(--toolbar-tab-hover-active);
|
||||
}
|
||||
|
||||
.theme-dark .tabs .tabs-menu-item.is-active,
|
||||
@@ -190,7 +190,7 @@
|
||||
}
|
||||
|
||||
.theme-dark .tabs .tabs-menu-item:active:hover {
|
||||
background-color: hsla(206,37%,4%,.4);
|
||||
background-color: hsla(206, 37%, 4%, .4); /* --toolbar-tab-hover-active */
|
||||
}
|
||||
|
||||
.theme-dark .tabs .tabs-menu-item.is-active {
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
margin: 1px 2px 1px 2px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: rgba(170, 170, 170, .2); /* Splitter */
|
||||
background-color: rgba(170, 170, 170, .2); /* --toolbar-tab-hover */
|
||||
transition: background 0.05s ease-in-out;
|
||||
}
|
||||
|
||||
@@ -90,5 +90,5 @@
|
||||
|
||||
.theme-dark .toolbar .btn:not([disabled]):hover:active,
|
||||
.theme-light .toolbar .btn:not([disabled]):hover:active {
|
||||
background: rgba(170, 170, 170, .4); /* Splitters */
|
||||
background: rgba(170, 170, 170, .4); /* --toolbar-tab-hover-active */
|
||||
}
|
||||
|
||||
@@ -11,17 +11,24 @@
|
||||
# A good criteria is the language in which you'd find the best
|
||||
# documentation on web development on the web.
|
||||
|
||||
# LOCALIZATION NOTE (responsive.title): the title displayed in the global
|
||||
# toolbar
|
||||
responsive.title=Responsive Design Mode
|
||||
# LOCALIZATION NOTE (responsive.editDeviceList): option displayed in the device
|
||||
# selector
|
||||
responsive.editDeviceList=Edit list…
|
||||
|
||||
# LOCALIZATION NOTE (responsive.exit): tooltip text of the exit button.
|
||||
responsive.exit=Close Responsive Design Mode
|
||||
|
||||
# LOCALIZATION NOTE (responsive.done): button text in the device list modal
|
||||
responsive.done=Done
|
||||
|
||||
# LOCALIZATION NOTE (responsive.noDeviceSelected): placeholder text for the
|
||||
# device selector
|
||||
responsive.noDeviceSelected=no device selected
|
||||
|
||||
# LOCALIZATION NOTE (responsive.title): the title displayed in the global
|
||||
# toolbar
|
||||
responsive.title=Responsive Design Mode
|
||||
|
||||
# LOCALIZATION NOTE (responsive.screenshot): tooltip of the screenshot button.
|
||||
responsive.screenshot=Take a screenshot of the viewport
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
const {
|
||||
ADD_DEVICE,
|
||||
ADD_DEVICE_TYPE,
|
||||
UPDATE_DEVICE_DISPLAYED,
|
||||
UPDATE_DEVICE_MODAL_OPEN,
|
||||
} = require("./index");
|
||||
|
||||
module.exports = {
|
||||
@@ -26,4 +28,20 @@ module.exports = {
|
||||
};
|
||||
},
|
||||
|
||||
updateDeviceDisplayed(device, deviceType, displayed) {
|
||||
return {
|
||||
type: UPDATE_DEVICE_DISPLAYED,
|
||||
device,
|
||||
deviceType,
|
||||
displayed,
|
||||
};
|
||||
},
|
||||
|
||||
updateDeviceModalOpen(isOpen) {
|
||||
return {
|
||||
type: UPDATE_DEVICE_MODAL_OPEN,
|
||||
isOpen,
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
@@ -38,6 +38,12 @@ createEnum([
|
||||
// Indicates when the screenshot action ends.
|
||||
"TAKE_SCREENSHOT_END",
|
||||
|
||||
// Update the device display state in the device selector.
|
||||
"UPDATE_DEVICE_DISPLAYED",
|
||||
|
||||
// Update the device modal open state.
|
||||
"UPDATE_DEVICE_MODAL_OPEN",
|
||||
|
||||
], module.exports);
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,15 +10,21 @@ const { createClass, createFactory, PropTypes, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const {
|
||||
updateDeviceDisplayed,
|
||||
updateDeviceModalOpen,
|
||||
} = require("./actions/devices");
|
||||
const {
|
||||
changeDevice,
|
||||
resizeViewport,
|
||||
rotateViewport
|
||||
} = require("./actions/viewports");
|
||||
const { takeScreenshot } = require("./actions/screenshot");
|
||||
const Types = require("./types");
|
||||
const Viewports = createFactory(require("./components/viewports"));
|
||||
const DeviceModal = createFactory(require("./components/device-modal"));
|
||||
const GlobalToolbar = createFactory(require("./components/global-toolbar"));
|
||||
const Viewports = createFactory(require("./components/viewports"));
|
||||
const { updateDeviceList } = require("./devices");
|
||||
const Types = require("./types");
|
||||
|
||||
let App = createClass({
|
||||
propTypes: {
|
||||
@@ -46,6 +52,10 @@ let App = createClass({
|
||||
}, "*");
|
||||
},
|
||||
|
||||
onDeviceListUpdate(devices) {
|
||||
updateDeviceList(devices);
|
||||
},
|
||||
|
||||
onExit() {
|
||||
window.postMessage({ type: "exit" }, "*");
|
||||
},
|
||||
@@ -62,6 +72,14 @@ let App = createClass({
|
||||
this.props.dispatch(takeScreenshot());
|
||||
},
|
||||
|
||||
onUpdateDeviceDisplayed(device, deviceType, displayed) {
|
||||
this.props.dispatch(updateDeviceDisplayed(device, deviceType, displayed));
|
||||
},
|
||||
|
||||
onUpdateDeviceModalOpen(isOpen) {
|
||||
this.props.dispatch(updateDeviceModalOpen(isOpen));
|
||||
},
|
||||
|
||||
render() {
|
||||
let {
|
||||
devices,
|
||||
@@ -74,10 +92,13 @@ let App = createClass({
|
||||
onBrowserMounted,
|
||||
onChangeViewportDevice,
|
||||
onContentResize,
|
||||
onDeviceListUpdate,
|
||||
onExit,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
onScreenshot,
|
||||
onUpdateDeviceDisplayed,
|
||||
onUpdateDeviceModalOpen,
|
||||
} = this;
|
||||
|
||||
return dom.div(
|
||||
@@ -99,6 +120,13 @@ let App = createClass({
|
||||
onContentResize,
|
||||
onRotateViewport,
|
||||
onResizeViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
}),
|
||||
DeviceModal({
|
||||
devices,
|
||||
onDeviceListUpdate,
|
||||
onUpdateDeviceDisplayed,
|
||||
onUpdateDeviceModalOpen,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
139
devtools/client/responsive.html/components/device-modal.js
Normal file
139
devtools/client/responsive.html/components/device-modal.js
Normal file
@@ -0,0 +1,139 @@
|
||||
/* 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 { DOM: dom, createClass, PropTypes, addons } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
const { getStr } = require("../utils/l10n");
|
||||
const Types = require("../types");
|
||||
|
||||
module.exports = createClass({
|
||||
propTypes: {
|
||||
devices: PropTypes.shape(Types.devices).isRequired,
|
||||
onDeviceListUpdate: PropTypes.func.isRequired,
|
||||
onUpdateDeviceDisplayed: PropTypes.func.isRequired,
|
||||
onUpdateDeviceModalOpen: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
displayName: "DeviceModal",
|
||||
|
||||
mixins: [ addons.PureRenderMixin ],
|
||||
|
||||
getInitialState() {
|
||||
return {};
|
||||
},
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
let {
|
||||
devices,
|
||||
} = nextProps;
|
||||
|
||||
for (let type of devices.types) {
|
||||
for (let device of devices[type]) {
|
||||
this.setState({
|
||||
[device.name]: device.displayed,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onDeviceCheckboxClick({ target }) {
|
||||
this.setState({
|
||||
[target.value]: !this.state[target.value]
|
||||
});
|
||||
},
|
||||
|
||||
onDeviceModalSubmit() {
|
||||
let {
|
||||
devices,
|
||||
onDeviceListUpdate,
|
||||
onUpdateDeviceDisplayed,
|
||||
onUpdateDeviceModalOpen,
|
||||
} = this.props;
|
||||
|
||||
let displayedDeviceList = [];
|
||||
|
||||
for (let type of devices.types) {
|
||||
for (let device of devices[type]) {
|
||||
if (this.state[device.name] != device.displayed) {
|
||||
onUpdateDeviceDisplayed(device, type, this.state[device.name]);
|
||||
}
|
||||
|
||||
if (this.state[device.name]) {
|
||||
displayedDeviceList.push(device.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDeviceListUpdate(displayedDeviceList);
|
||||
onUpdateDeviceModalOpen(false);
|
||||
},
|
||||
|
||||
render() {
|
||||
let {
|
||||
devices,
|
||||
onUpdateDeviceModalOpen,
|
||||
} = this.props;
|
||||
|
||||
let modalClass = "device-modal container";
|
||||
|
||||
if (!devices.isModalOpen) {
|
||||
modalClass += " hidden";
|
||||
}
|
||||
|
||||
return dom.div(
|
||||
{
|
||||
className: modalClass,
|
||||
},
|
||||
dom.button({
|
||||
id: "device-close-button",
|
||||
className: "toolbar-button devtools-button",
|
||||
onClick: () => onUpdateDeviceModalOpen(false),
|
||||
}),
|
||||
dom.div(
|
||||
{
|
||||
className: "device-modal-content",
|
||||
},
|
||||
devices.types.map(type => {
|
||||
return dom.div(
|
||||
{
|
||||
className: "device-type",
|
||||
key: type,
|
||||
},
|
||||
dom.header(
|
||||
{
|
||||
className: "device-header",
|
||||
},
|
||||
type
|
||||
),
|
||||
devices[type].map(device => {
|
||||
return dom.label(
|
||||
{
|
||||
className: "device-label",
|
||||
key: device.name,
|
||||
},
|
||||
dom.input({
|
||||
className: "device-input-checkbox",
|
||||
type: "checkbox",
|
||||
value: device.name,
|
||||
checked: this.state[device.name],
|
||||
onChange: this.onDeviceCheckboxClick,
|
||||
}),
|
||||
device.name
|
||||
);
|
||||
})
|
||||
);
|
||||
})
|
||||
),
|
||||
dom.button(
|
||||
{
|
||||
id: "device-submit-button",
|
||||
onClick: this.onDeviceModalSubmit,
|
||||
},
|
||||
getStr("responsive.done")
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -9,6 +9,7 @@ const { DOM: dom, createClass, PropTypes, addons } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
const Types = require("../types");
|
||||
const OPEN_DEVICE_MODAL_VALUE = "OPEN_DEVICE_MODAL";
|
||||
|
||||
module.exports = createClass({
|
||||
propTypes: {
|
||||
@@ -16,6 +17,7 @@ module.exports = createClass({
|
||||
selectedDevice: PropTypes.string.isRequired,
|
||||
onChangeViewportDevice: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
onUpdateDeviceModalOpen: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
displayName: "DeviceSelector",
|
||||
@@ -27,8 +29,14 @@ module.exports = createClass({
|
||||
devices,
|
||||
onChangeViewportDevice,
|
||||
onResizeViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
} = this.props;
|
||||
|
||||
if (target.value === OPEN_DEVICE_MODAL_VALUE) {
|
||||
onUpdateDeviceModalOpen(true);
|
||||
return;
|
||||
}
|
||||
|
||||
for (let type of devices.types) {
|
||||
for (let device of devices[type]) {
|
||||
if (device.name === target.value) {
|
||||
@@ -50,7 +58,9 @@ module.exports = createClass({
|
||||
let options = [];
|
||||
for (let type of devices.types) {
|
||||
for (let device of devices[type]) {
|
||||
options.push(device);
|
||||
if (device.displayed) {
|
||||
options.push(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +85,10 @@ module.exports = createClass({
|
||||
key: device.name,
|
||||
value: device.name,
|
||||
}, device.name);
|
||||
})
|
||||
}),
|
||||
dom.option({
|
||||
value: OPEN_DEVICE_MODAL_VALUE,
|
||||
}, getStr("responsive.editDeviceList"))
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ module.exports = createClass({
|
||||
return dom.header(
|
||||
{
|
||||
id: "global-toolbar",
|
||||
className: "toolbar",
|
||||
className: "container",
|
||||
},
|
||||
dom.span(
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
DevToolsModules(
|
||||
'browser.js',
|
||||
'device-modal.js',
|
||||
'device-selector.js',
|
||||
'global-toolbar.js',
|
||||
'resizable-viewport.js',
|
||||
|
||||
@@ -28,6 +28,7 @@ module.exports = createClass({
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
onUpdateDeviceModalOpen: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
displayName: "ResizableViewport",
|
||||
@@ -123,6 +124,7 @@ module.exports = createClass({
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
} = this.props;
|
||||
|
||||
let resizeHandleClass = "viewport-resize-handle";
|
||||
@@ -145,6 +147,7 @@ module.exports = createClass({
|
||||
onChangeViewportDevice,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
}),
|
||||
dom.div(
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ module.exports = createClass({
|
||||
onChangeViewportDevice: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
onUpdateDeviceModalOpen: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
displayName: "ViewportToolbar",
|
||||
@@ -30,17 +31,19 @@ module.exports = createClass({
|
||||
onChangeViewportDevice,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
} = this.props;
|
||||
|
||||
return dom.div(
|
||||
{
|
||||
className: "toolbar viewport-toolbar",
|
||||
className: "viewport-toolbar container",
|
||||
},
|
||||
DeviceSelector({
|
||||
devices,
|
||||
selectedDevice,
|
||||
onChangeViewportDevice,
|
||||
onResizeViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
}),
|
||||
dom.button({
|
||||
className: "viewport-rotate-button toolbar-button devtools-button",
|
||||
|
||||
@@ -22,6 +22,7 @@ module.exports = createClass({
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
onUpdateDeviceModalOpen: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
displayName: "Viewport",
|
||||
@@ -59,8 +60,9 @@ module.exports = createClass({
|
||||
location,
|
||||
screenshot,
|
||||
viewport,
|
||||
onContentResize,
|
||||
onBrowserMounted,
|
||||
onContentResize,
|
||||
onUpdateDeviceModalOpen,
|
||||
} = this.props;
|
||||
|
||||
let {
|
||||
@@ -83,6 +85,7 @@ module.exports = createClass({
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
}),
|
||||
ViewportDimension({
|
||||
viewport,
|
||||
|
||||
@@ -21,6 +21,7 @@ module.exports = createClass({
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
onUpdateDeviceModalOpen: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
displayName: "Viewports",
|
||||
@@ -36,6 +37,7 @@ module.exports = createClass({
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
} = this.props;
|
||||
|
||||
return dom.div(
|
||||
@@ -54,6 +56,7 @@ module.exports = createClass({
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
onUpdateDeviceModalOpen,
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
81
devtools/client/responsive.html/devices.js
Normal file
81
devtools/client/responsive.html/devices.js
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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 Services = require("Services");
|
||||
const { Task } = require("resource://gre/modules/Task.jsm");
|
||||
const { GetDevices } = require("devtools/client/shared/devices");
|
||||
const { addDevice, addDeviceType } = require("./actions/devices");
|
||||
|
||||
const DISPLAYED_DEVICES_PREF = "devtools.responsive.html.displayedDeviceList";
|
||||
|
||||
/**
|
||||
* Get the device catalog and load the devices onto the store.
|
||||
*
|
||||
* @param {Function} dispatch
|
||||
* Action dispatch function
|
||||
*/
|
||||
let initDevices = Task.async(function*(dispatch) {
|
||||
let deviceList = loadDeviceList();
|
||||
let devices = yield GetDevices();
|
||||
|
||||
for (let type of devices.TYPES) {
|
||||
dispatch(addDeviceType(type));
|
||||
for (let device of devices[type]) {
|
||||
if (device.os == "fxos") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let newDevice = Object.assign({}, device, {
|
||||
displayed: deviceList.includes(device.name) ?
|
||||
true :
|
||||
!!device.featured,
|
||||
});
|
||||
|
||||
if (newDevice.displayed) {
|
||||
deviceList.push(newDevice.name);
|
||||
}
|
||||
|
||||
dispatch(addDevice(newDevice, type));
|
||||
}
|
||||
}
|
||||
|
||||
updateDeviceList(deviceList);
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns an array containing the user preference of displayed devices.
|
||||
*
|
||||
* @return {Array} containing the device names that are to be displayed in the
|
||||
* device catalog.
|
||||
*/
|
||||
function loadDeviceList() {
|
||||
let deviceList = [];
|
||||
|
||||
if (Services.prefs.prefHasUserValue(DISPLAYED_DEVICES_PREF)) {
|
||||
try {
|
||||
deviceList = JSON.parse(Services.prefs.getCharPref(
|
||||
DISPLAYED_DEVICES_PREF));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the displayed device list preference with the given device list.
|
||||
*
|
||||
* @param {Array} devices
|
||||
* Array of device names that are displayed in the device catalog.
|
||||
*/
|
||||
function updateDeviceList(devices) {
|
||||
Services.prefs.setCharPref(DISPLAYED_DEVICES_PREF, JSON.stringify(devices));
|
||||
}
|
||||
|
||||
exports.initDevices = initDevices;
|
||||
exports.loadDeviceList = loadDeviceList;
|
||||
exports.updateDeviceList = updateDeviceList;
|
||||
@@ -6,7 +6,9 @@
|
||||
*/
|
||||
|
||||
.theme-light {
|
||||
--box-shadow: 0 4px 4px 0 rgba(155, 155, 155, 0.26);
|
||||
--rdm-box-shadow: 0 4px 4px 0 rgba(155, 155, 155, 0.26);
|
||||
--submit-button-active-background-color: rgba(0,0,0,0.12);
|
||||
--submit-button-active-color: var(--theme-body-color);
|
||||
--viewport-active-color: var(--theme-body-color);
|
||||
--viewport-selection-arrow: url("./images/select-arrow.svg#light");
|
||||
--viewport-selection-arrow-selected:
|
||||
@@ -14,7 +16,9 @@
|
||||
}
|
||||
|
||||
.theme-dark {
|
||||
--box-shadow: 0 4px 4px 0 rgba(105, 105, 105, 0.26);
|
||||
--rdm-box-shadow: 0 4px 4px 0 rgba(105, 105, 105, 0.26);
|
||||
--submit-button-active-background-color: var(--toolbar-tab-hover-active);
|
||||
--submit-button-active-color: var(--theme-selection-color);
|
||||
--viewport-active-color: var(--theme-selection-color);
|
||||
--viewport-selection-arrow: url("./images/select-arrow.svg#dark");
|
||||
--viewport-selection-arrow-selected:
|
||||
@@ -51,10 +55,10 @@ html, body {
|
||||
}
|
||||
|
||||
/**
|
||||
* Common style for toolbars and toolbar buttons
|
||||
* Common style for containers and toolbar buttons
|
||||
*/
|
||||
|
||||
.toolbar {
|
||||
.container {
|
||||
background-color: var(--theme-toolbar-background);
|
||||
border: 1px solid var(--theme-splitter-color);
|
||||
}
|
||||
@@ -80,7 +84,7 @@ html, body {
|
||||
#global-toolbar {
|
||||
color: var(--theme-body-color-alt);
|
||||
border-radius: 2px;
|
||||
box-shadow: var(--box-shadow);
|
||||
box-shadow: var(--rdm-box-shadow);
|
||||
margin: 30px 0;
|
||||
padding: 4px 5px;
|
||||
display: inline-flex;
|
||||
@@ -142,7 +146,7 @@ html, body {
|
||||
|
||||
.resizable-viewport {
|
||||
border: 1px solid var(--theme-splitter-color);
|
||||
box-shadow: var(--box-shadow);
|
||||
box-shadow: var(--rdm-box-shadow);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -308,3 +312,88 @@ html, body {
|
||||
.viewport-dimension-separator {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Device Modal
|
||||
*/
|
||||
|
||||
.device-modal {
|
||||
border-radius: 2px;
|
||||
box-shadow: var(--rdm-box-shadow);
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 642px;
|
||||
height: 612px;
|
||||
}
|
||||
|
||||
.device-modal.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.device-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
overflow: auto;
|
||||
height: 550px;
|
||||
width: 600px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
#device-close-button,
|
||||
#device-close-button::before {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 2px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
#device-close-button::before {
|
||||
background-image: url("./images/close.svg");
|
||||
margin: -6px 0 0 -6px;
|
||||
}
|
||||
|
||||
.device-type {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.device-header {
|
||||
font-weight: bold;
|
||||
text-transform: capitalize;
|
||||
padding: 0 0 3px 23px;
|
||||
}
|
||||
|
||||
.device-label {
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
.device-input-checkbox {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#device-submit-button {
|
||||
background-color: var(--theme-tab-toolbar-background);
|
||||
border-width: 1px 0 0 0;
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid;
|
||||
border-top-color: var(--theme-splitter-color);
|
||||
color: var(--theme-body-color);
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#device-submit-button:hover {
|
||||
background-color: var(--toolbar-tab-hover);
|
||||
}
|
||||
|
||||
#device-submit-button:hover:active {
|
||||
background-color: var(--submit-button-active-background-color);
|
||||
color: var(--submit-button-active-color);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ const { require } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/responsive.html/",
|
||||
window: this
|
||||
});
|
||||
const { GetDevices } = require("devtools/client/shared/devices");
|
||||
const { Task } = require("resource://gre/modules/Task.jsm");
|
||||
const Telemetry = require("devtools/client/shared/telemetry");
|
||||
const { loadSheet } = require("sdk/stylesheet/utils");
|
||||
|
||||
@@ -22,9 +22,9 @@ const { createFactory, createElement } =
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const { initDevices } = require("./devices");
|
||||
const App = createFactory(require("./app"));
|
||||
const Store = require("./store");
|
||||
const { addDevice, addDeviceType } = require("./actions/devices");
|
||||
const { changeLocation } = require("./actions/location");
|
||||
const { addViewport, resizeViewport } = require("./actions/viewports");
|
||||
|
||||
@@ -34,7 +34,7 @@ let bootstrap = {
|
||||
|
||||
store: null,
|
||||
|
||||
init() {
|
||||
init: Task.async(function*() {
|
||||
// Load a special UA stylesheet to reset certain styles such as dropdown
|
||||
// lists.
|
||||
loadSheet(window,
|
||||
@@ -42,11 +42,11 @@ let bootstrap = {
|
||||
"agent");
|
||||
this.telemetry.toolOpened("responsive");
|
||||
let store = this.store = Store();
|
||||
yield initDevices(this.dispatch.bind(this));
|
||||
let provider = createElement(Provider, { store }, App());
|
||||
ReactDOM.render(provider, document.querySelector("#root"));
|
||||
this.initDevices();
|
||||
window.postMessage({ type: "init" }, "*");
|
||||
},
|
||||
}),
|
||||
|
||||
destroy() {
|
||||
this.store = null;
|
||||
@@ -69,19 +69,6 @@ let bootstrap = {
|
||||
this.store.dispatch(action);
|
||||
},
|
||||
|
||||
initDevices() {
|
||||
GetDevices().then(devices => {
|
||||
for (let type of devices.TYPES) {
|
||||
this.dispatch(addDeviceType(type));
|
||||
for (let device of devices[type]) {
|
||||
if (device.os != "fxos") {
|
||||
this.dispatch(addDevice(device, type));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
window.addEventListener("load", function onLoad() {
|
||||
|
||||
@@ -16,6 +16,7 @@ DIRS += [
|
||||
DevToolsModules(
|
||||
'app.js',
|
||||
'constants.js',
|
||||
'devices.js',
|
||||
'index.css',
|
||||
'manager.js',
|
||||
'reducers.js',
|
||||
|
||||
@@ -7,10 +7,13 @@
|
||||
const {
|
||||
ADD_DEVICE,
|
||||
ADD_DEVICE_TYPE,
|
||||
UPDATE_DEVICE_DISPLAYED,
|
||||
UPDATE_DEVICE_MODAL_OPEN,
|
||||
} = require("../actions/index");
|
||||
|
||||
const INITIAL_DEVICES = {
|
||||
types: [],
|
||||
isModalOpen: false,
|
||||
};
|
||||
|
||||
let reducers = {
|
||||
@@ -28,6 +31,26 @@ let reducers = {
|
||||
});
|
||||
},
|
||||
|
||||
[UPDATE_DEVICE_DISPLAYED](devices, { device, deviceType, displayed }) {
|
||||
let newDevices = devices[deviceType].map(d => {
|
||||
if (d == device) {
|
||||
d.displayed = displayed;
|
||||
}
|
||||
|
||||
return d;
|
||||
});
|
||||
|
||||
return Object.assign({}, devices, {
|
||||
[deviceType]: newDevices,
|
||||
});
|
||||
},
|
||||
|
||||
[UPDATE_DEVICE_MODAL_OPEN](devices, { isOpen }) {
|
||||
return Object.assign({}, devices, {
|
||||
isModalOpen: isOpen,
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
module.exports = function(devices = INITIAL_DEVICES, action) {
|
||||
|
||||
@@ -9,6 +9,8 @@ support-files =
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
!/devtools/client/framework/test/shared-redux-head.js
|
||||
|
||||
[browser_device_modal_exit.js]
|
||||
[browser_device_modal_submit.js]
|
||||
[browser_device_width.js]
|
||||
[browser_exit_button.js]
|
||||
[browser_mouse_resize.js]
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test submitting display device changes on the device modal
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8,";
|
||||
|
||||
addRDMTask(TEST_URL, function* ({ ui }) {
|
||||
let { store, document } = ui.toolWindow;
|
||||
let modal = document.querySelector(".device-modal");
|
||||
let closeButton = document.querySelector("#device-close-button");
|
||||
|
||||
// Wait until the viewport has been added
|
||||
yield waitUntilState(store, state => state.viewports.length == 1);
|
||||
|
||||
openDeviceModal(ui);
|
||||
|
||||
let deviceListBefore = loadDeviceList();
|
||||
|
||||
info("Check the first unchecked device and exit the modal.");
|
||||
let uncheckedCb = [...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => !cb.checked)[0];
|
||||
let value = uncheckedCb.value;
|
||||
uncheckedCb.click();
|
||||
closeButton.click();
|
||||
|
||||
ok(modal.classList.contains("hidden"),
|
||||
"The device modal is hidden on exit.");
|
||||
|
||||
info("Check that the device list remains unchanged after exitting.");
|
||||
let deviceListAfter = loadDeviceList();
|
||||
is(deviceListBefore.length, deviceListAfter.length,
|
||||
"Got expected number of displayed devices.");
|
||||
ok(!deviceListAfter.includes(value),
|
||||
value + " was not added to displayed device list.");
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test submitting display device changes on the device modal
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8,";
|
||||
|
||||
addRDMTask(TEST_URL, function* ({ ui }) {
|
||||
let { store, document } = ui.toolWindow;
|
||||
let modal = document.querySelector(".device-modal");
|
||||
let select = document.querySelector(".viewport-device-selector");
|
||||
let submitButton = document.querySelector("#device-submit-button");
|
||||
|
||||
// Wait until the viewport has been added
|
||||
yield waitUntilState(store, state => state.viewports.length == 1);
|
||||
|
||||
openDeviceModal(ui);
|
||||
|
||||
info("Checking displayed device checkboxes are checked in the device modal.");
|
||||
let checkedCbs = [...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => cb.checked);
|
||||
let deviceList = loadDeviceList();
|
||||
|
||||
is(deviceList.length, checkedCbs.length,
|
||||
"Got expected number of displayed devices.");
|
||||
|
||||
for (let cb of checkedCbs) {
|
||||
ok(deviceList.includes(cb.value), cb.value + " is correctly checked.");
|
||||
}
|
||||
|
||||
info("Check the first unchecked device and submit new device list.");
|
||||
let uncheckedCb = [...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => !cb.checked)[0];
|
||||
let value = uncheckedCb.value;
|
||||
uncheckedCb.click();
|
||||
submitButton.click();
|
||||
|
||||
ok(modal.classList.contains("hidden"),
|
||||
"The device modal is hidden on submit.");
|
||||
|
||||
info("Checking new device is added to the displayed device list.");
|
||||
deviceList = loadDeviceList();
|
||||
ok(deviceList.includes(value), value + " added to displayed device list.");
|
||||
|
||||
info("Checking new device is added to the device selector.");
|
||||
let options = [...select.options];
|
||||
is(options.length - 2, deviceList.length,
|
||||
"Got expected number of devices in device selector.");
|
||||
ok(options.filter(o => o.value === value)[0],
|
||||
value + " added to the device selector.");
|
||||
|
||||
info("Reopen device modal and check new device is correctly checked");
|
||||
openDeviceModal(ui);
|
||||
ok([...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => cb.checked && cb.value === value)[0],
|
||||
value + " is checked in the device modal.");
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"TYPES": [ "phones" ],
|
||||
"TYPES": [ "phones", "tablets", "laptops", "televisions", "consoles", "watches" ],
|
||||
"phones": [
|
||||
{
|
||||
"name": "Firefox OS Flame",
|
||||
@@ -20,6 +20,632 @@
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "Alcatel One Touch Fire C",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; ALCATELOneTouch4019X; rv:28.0) Gecko/28.0 Firefox/28.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "Alcatel One Touch Fire E",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; ALCATELOneTouch6015X; rv:32.0) Gecko/32.0 Firefox/32.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "Apple iPhone 4",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios"
|
||||
},
|
||||
{
|
||||
"name": "Apple iPhone 5",
|
||||
"width": 320,
|
||||
"height": 568,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios"
|
||||
},
|
||||
{
|
||||
"name": "Apple iPhone 5s",
|
||||
"width": 320,
|
||||
"height": 568,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13D15 Safari/601.1",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Apple iPhone 6",
|
||||
"width": 375,
|
||||
"height": 667,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios"
|
||||
},
|
||||
{
|
||||
"name": "Apple iPhone 6 Plus",
|
||||
"width": 414,
|
||||
"height": 736,
|
||||
"pixelRatio": 3,
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Apple iPhone 6s",
|
||||
"width": 375,
|
||||
"height": 667,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Apple iPhone 6s Plus",
|
||||
"width": 414,
|
||||
"height": 736,
|
||||
"pixelRatio": 3,
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios"
|
||||
},
|
||||
{
|
||||
"name": "BlackBerry Z30",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "blackberryos"
|
||||
},
|
||||
{
|
||||
"name": "Geeksphone Keon",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Geeksphone Peak, Revolution",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Google Nexus S",
|
||||
"width": 320,
|
||||
"height": 533,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Nexus S Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Google Nexus 4",
|
||||
"width": 384,
|
||||
"height": 640,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.4; en-us; Nexus 4 Build/JOP40D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Google Nexus 5",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 3,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.4; en-us; Nexus 5 Build/JOP40D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Google Nexus 6",
|
||||
"width": 412,
|
||||
"height": 732,
|
||||
"pixelRatio": 3.5,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Intex Cloud Fx",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:32.0) Gecko/32.0 Firefox/32.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "KDDI Fx0",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; LGL25; rv:32.0) Gecko/32.0 Firefox/32.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "LG Fireweb",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; LG-D300; rv:18.1) Gecko/18.1 Firefox/18.1",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "LG Optimus L70",
|
||||
"width": 384,
|
||||
"height": 640,
|
||||
"pixelRatio": 1.25,
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.1599.103 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Nokia Lumia 520",
|
||||
"width": 320,
|
||||
"height": 533,
|
||||
"pixelRatio": 1.4,
|
||||
"userAgent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Nokia N9",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "OnePlus One",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 3,
|
||||
"userAgent": "Mozilla/5.0 (Android 5.1.1; Mobile; rv:43.0) Gecko/43.0 Firefox/43.0",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Samsung Galaxy S3",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Samsung Galaxy S4",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 3,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Samsung Galaxy S5",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 3,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Samsung Galaxy S6",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 4,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Sony Xperia Z3",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 3,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Spice Fire One Mi-FX1",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:28.0) Gecko/28.0 Firefox/28.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "Symphony GoFox F15",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:30.0) Gecko/30.0 Firefox/30.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "ZTE Open",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; ZTEOPEN; rv:18.1) Gecko/18.0 Firefox/18.1",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "ZTE Open II",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; OPEN2; rv:28.0) Gecko/28.0 Firefox/28.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "ZTE Open C",
|
||||
"width": 320,
|
||||
"height": 450,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; OPENC; rv:32.0) Gecko/32.0 Firefox/32.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
},
|
||||
{
|
||||
"name": "Zen Fire 105",
|
||||
"width": 320,
|
||||
"height": 480,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:28.0) Gecko/28.0 Firefox/28.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
}
|
||||
],
|
||||
"tablets": [
|
||||
{
|
||||
"name": "Amazon Kindle Fire HDX 8.9",
|
||||
"width": 1280,
|
||||
"height": 800,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "fireos",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Apple iPad",
|
||||
"width": 1024,
|
||||
"height": 768,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios"
|
||||
},
|
||||
{
|
||||
"name": "Apple iPad Air 2",
|
||||
"width": 1024,
|
||||
"height": 768,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Apple iPad Mini",
|
||||
"width": 1024,
|
||||
"height": 768,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios"
|
||||
},
|
||||
{
|
||||
"name": "Apple iPad Mini 2",
|
||||
"width": 1024,
|
||||
"height": 768,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "BlackBerry PlayBook",
|
||||
"width": 1024,
|
||||
"height": 600,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "blackberryos"
|
||||
},
|
||||
{
|
||||
"name": "Foxconn InFocus",
|
||||
"width": 1280,
|
||||
"height": 800,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Tablet; rv:32.0) Gecko/32.0 Firefox/32.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Google Nexus 7",
|
||||
"width": 960,
|
||||
"height": 600,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Google Nexus 10",
|
||||
"width": 1280,
|
||||
"height": 800,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Samsung Galaxy Note 2",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Samsung Galaxy Note 3",
|
||||
"width": 360,
|
||||
"height": 640,
|
||||
"pixelRatio": 3,
|
||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "android",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Tesla Model S",
|
||||
"width": 1200,
|
||||
"height": 1920,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (X11; Linux) AppleWebKit/534.34 (KHTML, like Gecko) QtCarBrowser Safari/534.34",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "linux"
|
||||
},
|
||||
{
|
||||
"name": "VIA Vixen",
|
||||
"width": 1024,
|
||||
"height": 600,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Tablet; rv:32.0) Gecko/32.0 Firefox/32.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
}
|
||||
],
|
||||
"laptops": [
|
||||
{
|
||||
"name": "Laptop (1366 x 768)",
|
||||
"width": 1366,
|
||||
"height": 768,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "",
|
||||
"touch": false,
|
||||
"firefoxOS": false,
|
||||
"os": "windows",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Laptop (1920 x 1080)",
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "",
|
||||
"touch": false,
|
||||
"firefoxOS": false,
|
||||
"os": "windows",
|
||||
"featured": true
|
||||
},
|
||||
{
|
||||
"name": "Laptop (1920 x 1080) with touch",
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "windows"
|
||||
}
|
||||
],
|
||||
"televisions": [
|
||||
{
|
||||
"name": "720p HD Television",
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "",
|
||||
"touch": false,
|
||||
"firefoxOS": true,
|
||||
"os": "custom"
|
||||
},
|
||||
{
|
||||
"name": "1080p Full HD Television",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "",
|
||||
"touch": false,
|
||||
"firefoxOS": true,
|
||||
"os": "custom"
|
||||
},
|
||||
{
|
||||
"name": "4K Ultra HD Television",
|
||||
"width": 3840,
|
||||
"height": 2160,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "",
|
||||
"touch": false,
|
||||
"firefoxOS": true,
|
||||
"os": "custom"
|
||||
}
|
||||
],
|
||||
"consoles": [
|
||||
{
|
||||
"name": "Nintendo 3DS",
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7585.EU",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "nintendo"
|
||||
},
|
||||
{
|
||||
"name": "Nintendo Wii U Gamepad",
|
||||
"width": 854,
|
||||
"height": 480,
|
||||
"pixelRatio": 0.87,
|
||||
"userAgent": "Mozilla/5.0 (Nintendo WiiU) AppleWebKit/536.28 (KHTML, like Gecko) NX/3.0.3.12.15 NintendoBrowser/4.1.1.9601.EU",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "nintendo"
|
||||
},
|
||||
{
|
||||
"name": "Sony PlayStation Vita",
|
||||
"width": 960,
|
||||
"height": 544,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Playstation Vita 1.61) AppleWebKit/531.22.8 (KHTML, like Gecko) Silk/3.2",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "playstation"
|
||||
}
|
||||
],
|
||||
"watches": [
|
||||
{
|
||||
"name": "LG G Watch",
|
||||
"width": 280,
|
||||
"height": 280,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "LG G Watch R",
|
||||
"width": 320,
|
||||
"height": 320,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Motorola Moto 360",
|
||||
"width": 320,
|
||||
"height": 290,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0.1; Moto 360 Build/LWX48T) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/19.77.34.5 Mobile Safari/537.36",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
},
|
||||
{
|
||||
"name": "Samsung Gear Live",
|
||||
"width": 320,
|
||||
"height": 320,
|
||||
"pixelRatio": 1,
|
||||
"userAgent": "",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "android"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ SimpleTest.requestCompleteLog();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
DevToolsUtils.testing = true;
|
||||
Services.prefs.clearUserPref("devtools.responsive.html.displayedDeviceList");
|
||||
Services.prefs.setCharPref("devtools.devices.url",
|
||||
TEST_URI_ROOT + "devices.json");
|
||||
Services.prefs.setBoolPref("devtools.responsive.html.enabled", true);
|
||||
@@ -34,8 +35,12 @@ registerCleanupFunction(() => {
|
||||
DevToolsUtils.testing = false;
|
||||
Services.prefs.clearUserPref("devtools.devices.url");
|
||||
Services.prefs.clearUserPref("devtools.responsive.html.enabled");
|
||||
Services.prefs.clearUserPref("devtools.responsive.html.displayedDeviceList");
|
||||
});
|
||||
const { ResponsiveUIManager } = Cu.import("resource://devtools/client/responsivedesign/responsivedesign.jsm", {});
|
||||
const { loadDeviceList } = require("devtools/client/responsive.html/devices");
|
||||
|
||||
const OPEN_DEVICE_MODAL_VALUE = "OPEN_DEVICE_MODAL";
|
||||
|
||||
/**
|
||||
* Open responsive design mode for the given tab.
|
||||
@@ -125,3 +130,25 @@ var setViewportSize = Task.async(function* (ui, manager, width, height) {
|
||||
yield resized;
|
||||
}
|
||||
});
|
||||
|
||||
function openDeviceModal(ui) {
|
||||
let { document } = ui.toolWindow;
|
||||
let select = document.querySelector(".viewport-device-selector");
|
||||
let modal = document.querySelector(".device-modal");
|
||||
let editDeviceOption = [...select.options].filter(o => {
|
||||
return o.value === OPEN_DEVICE_MODAL_VALUE;
|
||||
})[0];
|
||||
|
||||
info("Checking initial device modal state");
|
||||
ok(modal.classList.contains("hidden"),
|
||||
"The device modal is hidden by default.");
|
||||
|
||||
info("Opening device modal through device selector.");
|
||||
EventUtils.synthesizeMouseAtCenter(select, {type: "mousedown"},
|
||||
ui.toolWindow);
|
||||
EventUtils.synthesizeMouseAtCenter(editDeviceOption, {type: "mouseup"},
|
||||
ui.toolWindow);
|
||||
|
||||
ok(!modal.classList.contains("hidden"),
|
||||
"The device modal is displayed.");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test updating the device `displayed` property
|
||||
|
||||
const {
|
||||
addDevice,
|
||||
addDeviceType,
|
||||
updateDeviceDisplayed,
|
||||
} = require("devtools/client/responsive.html/actions/devices");
|
||||
|
||||
add_task(function*() {
|
||||
let store = Store();
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
let device = {
|
||||
"name": "Firefox OS Flame",
|
||||
"width": 320,
|
||||
"height": 570,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos"
|
||||
};
|
||||
|
||||
dispatch(addDeviceType("phones"));
|
||||
dispatch(addDevice(device, "phones"));
|
||||
dispatch(updateDeviceDisplayed(device, "phones", true));
|
||||
|
||||
equal(getState().devices.phones.length, 1,
|
||||
"Correct number of phones");
|
||||
ok(getState().devices.phones[0].displayed,
|
||||
"Device phone list contains enabled Firefox OS Flame");
|
||||
});
|
||||
@@ -11,3 +11,4 @@ firefox-appdir = browser
|
||||
[test_change_viewport_device.js]
|
||||
[test_resize_viewport.js]
|
||||
[test_rotate_viewport.js]
|
||||
[test_update_device_displayed.js]
|
||||
|
||||
@@ -32,9 +32,12 @@ const device = {
|
||||
// Whether or not it is a touch device
|
||||
touch: PropTypes.bool,
|
||||
|
||||
// The operating system of the device
|
||||
// The operating system of the device
|
||||
os: PropTypes.String,
|
||||
|
||||
// Whether or not the device is displayed in the device selector
|
||||
displayed: PropTypes.bool,
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -63,6 +66,9 @@ exports.devices = {
|
||||
// An array of watch devices
|
||||
watches: PropTypes.arrayOf(PropTypes.shape(device)),
|
||||
|
||||
// Whether or not the device modal is open
|
||||
isModalOpen: PropTypes.bool,
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@ xul|scrollbar[orient="horizontal"] {
|
||||
}
|
||||
|
||||
xul|scrollbar xul|thumb {
|
||||
background-color: rgba(170,170,170,0.2) !important;
|
||||
background-color: rgba(170, 170, 170, .2) !important; /* --toolbar-tab-hover */
|
||||
-moz-appearance: none !important;
|
||||
border-width: 0px !important;
|
||||
border-radius: 3px !important;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
/* CSS Variables specific to the devtools toolbar that aren't defined by the themes */
|
||||
.theme-light {
|
||||
--toolbar-tab-hover: rgba(170, 170, 170, .2);
|
||||
--toolbar-tab-hover-active: rgba(170, 170, 170, .4);
|
||||
--searchbox-background-color: #ffee99;
|
||||
--searchbox-border-color: #ffbf00;
|
||||
--searcbox-no-match-background-color: #ffe5e5;
|
||||
@@ -22,6 +24,8 @@
|
||||
}
|
||||
|
||||
.theme-dark {
|
||||
--toolbar-tab-hover: hsla(206, 37%, 4%, .2);
|
||||
--toolbar-tab-hover-active: hsla(206, 37%, 4%, .4);
|
||||
--searchbox-background-color: #4d4222;
|
||||
--searchbox-border-color: #d99f2b;
|
||||
--searcbox-no-match-background-color: #402325;
|
||||
@@ -271,7 +275,7 @@
|
||||
.theme-light .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]),
|
||||
.theme-light .devtools-toolbarbutton[data-text-only],
|
||||
.theme-light #toolbox-buttons .devtools-toolbarbutton[text-as-image] {
|
||||
background-color: rgba(170, 170, 170, .2); /* Splitter */
|
||||
background-color: var(--toolbar-tab-hover);
|
||||
}
|
||||
.theme-dark .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]),
|
||||
.theme-dark .devtools-toolbarbutton[data-text-only],
|
||||
@@ -299,7 +303,7 @@
|
||||
.theme-light .devtools-button:not(:empty):not([disabled]):hover:active,
|
||||
.theme-light #toolbox-buttons .devtools-toolbarbutton:not([disabled])[text-as-image]:hover:active,
|
||||
.theme-light .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover:active {
|
||||
background: rgba(170, 170, 170, .4); /* Splitters */
|
||||
background: var(--toolbar-tab-hover-active);
|
||||
}
|
||||
|
||||
.theme-dark .devtools-toolbarbutton:not([disabled])[label][checked=true],
|
||||
@@ -729,10 +733,10 @@
|
||||
}
|
||||
|
||||
.command-button:hover {
|
||||
background-color: hsla(206,37%,4%,.2);
|
||||
background-color: var(--toolbar-tab-hover);
|
||||
}
|
||||
.command-button:hover:active, .command-button[checked=true]:not(:hover) {
|
||||
background-color: hsla(206,37%,4%,.4);
|
||||
background-color: var(--toolbar-tab-hover-active)
|
||||
}
|
||||
|
||||
.command-button > image {
|
||||
@@ -867,21 +871,19 @@
|
||||
}
|
||||
|
||||
.theme-dark .devtools-tab:hover {
|
||||
background-color: hsla(206,37%,4%,.2);
|
||||
color: #ced3d9;
|
||||
}
|
||||
|
||||
.theme-light .devtools-tab:hover {
|
||||
background-color: rgba(170,170,170,.2);
|
||||
.devtools-tab:hover {
|
||||
background-color: var(--toolbar-tab-hover);
|
||||
}
|
||||
|
||||
.theme-dark .devtools-tab:hover:active {
|
||||
background-color: hsla(206,37%,4%,.4);
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
.theme-light .devtools-tab:hover:active {
|
||||
background-color: rgba(170,170,170,.4);
|
||||
.devtools-tab:hover:active {
|
||||
background-color: var(--toolbar-tab-hover-active);
|
||||
}
|
||||
|
||||
.devtools-tab:not([selected])[highlighted] {
|
||||
|
||||
Reference in New Issue
Block a user