Bug 1467572 - Part 9: Use native context menu instead of select elements in the reload condition menu of RDM. r=Honza

- Converts the reload condition <select> to use native context menu
- Converts the showMenu util to be reusable by both RDM and the Network Monitor
- Renames getToplevelWindow to getTopLevelWindow
- Renames the reload condition menu to be a setting menu in RDM according to the designs
- Uses the new photon setting icon in RDM

--HG--
rename : devtools/client/responsive.html/components/ReloadConditions.js => devtools/client/responsive.html/components/SettingsMenu.js
rename : devtools/client/netmonitor/src/utils/menu.js => devtools/client/shared/components/menu/utils.js
This commit is contained in:
Gabriel Luong 2018-08-15 17:27:41 -04:00
Родитель 0cf08baeef
Коммит 8112f73aed
19 изменённых файлов: 123 добавлений и 242 удалений

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

@ -265,6 +265,7 @@ devtools.jar:
skin/images/read-only.svg (themes/images/read-only.svg)
skin/images/reveal.svg (themes/images/reveal.svg)
skin/images/select-arrow.svg (themes/images/select-arrow.svg)
skin/images/settings.svg (themes/images/settings.svg)
# Debugger
skin/images/debugger/angular.svg (themes/images/debugger/angular.svg)

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

@ -124,14 +124,6 @@ responsive.deviceDetails=Size: %1$S x %2$S\nDPR: %3$S\nUA: %4$S\nTouch: %5$S
# the device pixel ratio. %1$S is the devicePixelRatio value of the device.
responsive.devicePixelRatioOption=DPR: %1$S
# LOCALIZATION NOTE (responsive.reloadConditions.label): Label on button to open a menu
# used to choose whether to reload the page automatically when certain actions occur.
responsive.reloadConditions.label=Reload when…
# LOCALIZATION NOTE (responsive.reloadConditions.title): Title on button to open a menu
# used to choose whether to reload the page automatically when certain actions occur.
responsive.reloadConditions.title=Choose whether to reload the page automatically when certain actions occur
# LOCALIZATION NOTE (responsive.reloadConditions.touchSimulation): Label on checkbox used
# to select whether to reload when touch simulation is toggled.
responsive.reloadConditions.touchSimulation=Reload when touch simulation is toggled

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

@ -56,7 +56,7 @@ const NO_THROTTLING_LABEL = new LocalizationHelper(
).getStr("responsive.noThrottling");
// Menu
loader.lazyRequireGetter(this, "showMenu", "devtools/client/netmonitor/src/utils/menu", true);
loader.lazyRequireGetter(this, "showMenu", "devtools/client/shared/components/menu/utils", true);
loader.lazyRequireGetter(this, "HarMenuUtils", "devtools/client/netmonitor/src/har/har-menu-utils", true);
// Throttling

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

@ -15,7 +15,6 @@ DevToolsModules(
'headers-provider.js',
'l10n.js',
'mdn-utils.js',
'menu.js',
'open-request-in-tab.js',
'prefs.js',
'request-utils.js',

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

@ -17,7 +17,7 @@ const {
loader.lazyRequireGetter(this, "Curl", "devtools/client/shared/curl", true);
loader.lazyRequireGetter(this, "saveAs", "devtools/client/shared/file-saver", true);
loader.lazyRequireGetter(this, "copyString", "devtools/shared/platform/clipboard", true);
loader.lazyRequireGetter(this, "showMenu", "devtools/client/netmonitor/src/utils/menu", true);
loader.lazyRequireGetter(this, "showMenu", "devtools/client/shared/components/menu/utils", true);
loader.lazyRequireGetter(this, "openRequestInTab", "devtools/client/netmonitor/src/utils/firefox/open-request-in-tab", true);
loader.lazyRequireGetter(this, "HarMenuUtils", "devtools/client/netmonitor/src/har/har-menu-utils", true);

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

@ -4,7 +4,7 @@
"use strict";
const { showMenu } = require("devtools/client/netmonitor/src/utils/menu");
const { showMenu } = require("devtools/client/shared/components/menu/utils");
const { HEADERS } = require("../constants");
const { L10N } = require("../utils/l10n");

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

@ -73,7 +73,8 @@ const webpackConfig = {
"devtools/client/framework/devtools": path.join(__dirname, "../../client/shared/webpack/shims/framework-devtools-shim"),
"devtools/client/framework/menu": "devtools-modules/src/menu",
"devtools/client/netmonitor/src/utils/menu": "devtools-contextmenu",
"devtools/client/shared/components/menu/utils": "devtools-contextmenu",
"devtools/client/shared/vendor/react": "react",
"devtools/client/shared/vendor/react-dom": "react-dom",

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

@ -12,7 +12,7 @@ const {
} = require("./index");
const { getFormatStr } = require("../utils/l10n");
const { getToplevelWindow } = require("../utils/window");
const { getTopLevelWindow } = require("../utils/window");
const e10s = require("../utils/e10s");
const Services = require("Services");
@ -40,7 +40,7 @@ function createScreenshotFor(node) {
}
function saveToFile(data, filename) {
const chromeWindow = getToplevelWindow(window);
const chromeWindow = getTopLevelWindow(window);
const chromeDocument = chromeWindow.document;
// append .png extension to filename if it doesn't exist

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

@ -14,7 +14,7 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const e10s = require("../utils/e10s");
const message = require("../utils/message");
const { getToplevelWindow } = require("../utils/window");
const { getTopLevelWindow } = require("../utils/window");
const FRAME_SCRIPT = "resource://devtools/client/responsive.html/browser/content.js";
@ -114,7 +114,7 @@ class Browser extends PureComponent {
mm.loadFrameScript(FRAME_SCRIPT, true);
await ready;
const browserWindow = getToplevelWindow(window);
const browserWindow = getTopLevelWindow(window);
const requiresFloatingScrollbars =
!browserWindow.matchMedia("(-moz-overlay-scrollbars)").matches;

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

@ -1,50 +0,0 @@
/* 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, PureComponent } = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const ToggleMenu = createFactory(require("./ToggleMenu"));
const { getStr } = require("../utils/l10n");
const Types = require("../types");
class ReloadConditions extends PureComponent {
static get propTypes() {
return {
reloadConditions: PropTypes.shape(Types.reloadConditions).isRequired,
onChangeReloadCondition: PropTypes.func.isRequired,
};
}
render() {
const {
reloadConditions,
onChangeReloadCondition,
} = this.props;
return ToggleMenu({
id: "reload-conditions-menu",
items: [
{
id: "touchSimulation",
label: getStr("responsive.reloadConditions.touchSimulation"),
checked: reloadConditions.touchSimulation,
},
{
id: "userAgent",
label: getStr("responsive.reloadConditions.userAgent"),
checked: reloadConditions.userAgent,
},
],
label: getStr("responsive.reloadConditions.label"),
title: getStr("responsive.reloadConditions.title"),
onChange: onChangeReloadCondition,
});
}
}
module.exports = ReloadConditions;

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

@ -0,0 +1,73 @@
/* 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 { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { getStr } = require("../utils/l10n");
const Types = require("../types");
loader.lazyRequireGetter(this, "showMenu", "devtools/client/shared/components/menu/utils", true);
class SettingsMenu extends PureComponent {
static get propTypes() {
return {
reloadConditions: PropTypes.shape(Types.reloadConditions).isRequired,
onChangeReloadCondition: PropTypes.func.isRequired,
};
}
constructor(props) {
super(props);
this.onToggleSettingMenu = this.onToggleSettingMenu.bind(this);
}
onToggleSettingMenu(event) {
const {
reloadConditions,
onChangeReloadCondition,
} = this.props;
const menuItems = [
{
id: "touchSimulation",
checked: reloadConditions.touchSimulation,
label: getStr("responsive.reloadConditions.touchSimulation"),
type: "checkbox",
click: () => {
onChangeReloadCondition("touchSimulation", !reloadConditions.touchSimulation);
},
},
{
id: "userAgent",
checked: reloadConditions.userAgent,
label: getStr("responsive.reloadConditions.userAgent"),
type: "checkbox",
click: () => {
onChangeReloadCondition("userAgent", !reloadConditions.userAgent);
},
},
];
showMenu(menuItems, {
button: event.target,
useTopLevelWindow: true,
});
}
render() {
return (
dom.button({
id: "settings-button",
className: "devtools-button",
onClick: this.onToggleSettingMenu,
})
);
}
}
module.exports = SettingsMenu;

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

@ -1,130 +0,0 @@
/* 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 { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const MenuItem = {
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
checked: PropTypes.bool,
};
class ToggleMenu extends PureComponent {
static get propTypes() {
return {
id: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.shape(MenuItem)).isRequired,
label: PropTypes.string,
title: PropTypes.string,
onChange: PropTypes.func.isRequired,
};
}
constructor(props) {
super(props);
this.state = {
isOpen: false,
};
this.onItemChange = this.onItemChange.bind(this);
this.onToggleOpen = this.onToggleOpen.bind(this);
}
onItemChange({ target }) {
const {
onChange,
} = this.props;
// Close menu after changing an item
this.setState({
isOpen: false,
});
const id = target.name;
onChange(id, target.checked);
}
onToggleOpen() {
const {
isOpen,
} = this.state;
this.setState({
isOpen: !isOpen,
});
}
render() {
const {
id: menuID,
items,
label: toggleLabel,
title,
} = this.props;
const {
isOpen,
} = this.state;
const {
onItemChange,
onToggleOpen,
} = this;
const menuItems = items.map(({ id, label, checked }) => {
const inputID = `devtools-menu-item-${id}`;
return dom.div(
{
className: "devtools-menu-item",
key: id,
},
dom.input({
type: "checkbox",
id: inputID,
name: id,
checked,
onChange: onItemChange,
}),
dom.label({
htmlFor: inputID,
}, label)
);
});
let menuClass = "devtools-menu";
if (isOpen) {
menuClass += " opened";
}
const menu = dom.div(
{
className: menuClass,
},
menuItems
);
let buttonClass = "devtools-toggle-menu";
buttonClass += " toolbar-dropdown toolbar-button devtools-button";
if (isOpen || items.some(({ checked }) => checked)) {
buttonClass += " selected";
}
return dom.div(
{
id: menuID,
className: buttonClass,
title,
onClick: onToggleOpen,
},
toggleLabel,
menu
);
}
}
module.exports = ToggleMenu;

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

@ -11,7 +11,7 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const DevicePixelRatioSelector = createFactory(require("./DevicePixelRatioSelector"));
const DeviceSelector = createFactory(require("./DeviceSelector"));
const NetworkThrottlingSelector = createFactory(require("devtools/client/shared/components/throttling/NetworkThrottlingSelector"));
const ReloadConditions = createFactory(require("./ReloadConditions"));
const SettingsMenu = createFactory(require("./SettingsMenu"));
const ViewportDimension = createFactory(require("./ViewportDimension"));
const { getStr } = require("../utils/l10n");
@ -126,7 +126,7 @@ class Toolbar extends PureComponent {
onClick: onScreenshot,
disabled: screenshot.isCapturing,
}),
ReloadConditions({
SettingsMenu({
reloadConditions,
onChangeReloadCondition,
}),

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

@ -11,9 +11,8 @@ DevToolsModules(
'DeviceModal.js',
'DevicePixelRatioSelector.js',
'DeviceSelector.js',
'ReloadConditions.js',
'ResizableViewport.js',
'ToggleMenu.js',
'SettingsMenu.js',
'Toolbar.js',
'ViewportDimension.js',
'Viewports.js',

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

@ -132,37 +132,6 @@ select > option.divider {
font-size: 0px;
}
/**
* Toggle Menu
*/
.devtools-toggle-menu {
position: relative;
}
.devtools-toggle-menu .devtools-menu {
display: none;
flex-direction: column;
align-items: start;
position: absolute;
right: 0;
top: 100%;
z-index: 1;
padding: 5px;
border-radius: 2px;
background-color: var(--theme-toolbar-background);
box-shadow: var(--rdm-box-shadow);
}
.devtools-toggle-menu .devtools-menu.opened {
display: flex;
}
.devtools-toggle-menu .devtools-menu-item {
display: flex;
align-items: center;
}
/**
* Common background for dropdowns like select and toggle menu
*/
@ -230,6 +199,10 @@ select > option.divider {
background-image: url("./images/screenshot.svg");
}
#settings-button::before {
background-image: url("chrome://devtools/skin/images/settings.svg");
}
#exit-button::before {
background-image: url("chrome://devtools/skin/images/close.svg");
}

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

@ -9,10 +9,10 @@ const Services = require("Services");
/**
* Returns the `nsIDOMWindow` toplevel window for any child/inner window
*/
function getToplevelWindow(window) {
function getTopLevelWindow(window) {
return window.docShell.rootTreeItem.domWindow;
}
exports.getToplevelWindow = getToplevelWindow;
exports.getTopLevelWindow = getTopLevelWindow;
function getDOMWindowUtils(window) {
return window.windowUtils;

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

@ -5,7 +5,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'MenuButton.js',
'MenuItem.js',
'MenuList.js',
'MenuButton.js',
'MenuItem.js',
'MenuList.js',
'utils.js',
)

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

@ -7,14 +7,23 @@
const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");
loader.lazyRequireGetter(this, "getTopLevelWindow", "devtools/client/responsive.html/utils/window", true);
/**
* Helper function for opening context menu.
*
* @param {Array} items List of menu items.
* @param {Array} items
* List of menu items.
* @param {Object} options:
* @property {Number} screenX coordinate of the menu on the screen
* @property {Number} screenY coordinate of the menu on the screen
* @property {Object} button parent used to open the menu
* @property {Element} button
* Button element used to open the menu.
* @property {Number} screenX
* Screen x coordinate of the menu on the screen.
* @property {Number} screenY
* Screen y coordinate of the menu on the screen.
* @property {Boolean} useTopLevelWindow
* Whether or not the top level window needs to be fetched. This option is used
* by RDM.
*/
function showMenu(items, options) {
if (items.length === 0) {
@ -55,7 +64,14 @@ function showMenu(items, options) {
screenY = rect.bottom + defaultView.mozInnerScreenY;
}
menu.popup(screenX, screenY, { doc: window.parent.document });
let doc;
if (options.useTopLevelWindow) {
doc = getTopLevelWindow(window).document;
} else {
doc = window.parent.document;
}
menu.popup(screenX, screenY, { doc });
}
module.exports = {

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

@ -0,0 +1,6 @@
<!-- 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/. -->
<svg width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="context-fill" fill-rule="evenodd" clip-rule="evenodd" d="M12 22a1 1 0 0 1-1-1v-3.083a5.966 5.966 0 0 1-2.477-1.026l-2.18 2.18a1 1 0 0 1-1.414-1.414l2.18-2.18A5.967 5.967 0 0 1 6.083 13H3a1 1 0 1 1 0-2h3.083a5.968 5.968 0 0 1 1.026-2.477l-2.18-2.18A1 1 0 0 1 6.343 4.93l2.18 2.18A5.968 5.968 0 0 1 11 6.083V3a1 1 0 1 1 2 0v3.083a5.967 5.967 0 0 1 2.476 1.026l2.18-2.18a1 1 0 1 1 1.415 1.414l-2.18 2.18A5.966 5.966 0 0 1 17.917 11H21a1 1 0 1 1 0 2h-3.083a5.966 5.966 0 0 1-1.026 2.476l2.18 2.18a1 1 0 0 1-1.414 1.415l-2.18-2.18A5.966 5.966 0 0 1 13 17.917V21a1 1 0 0 1-1 1zM8 12a4 4 0 1 1 8 0 4 4 0 0 1-8 0z"></path>
</svg>

После

Ширина:  |  Высота:  |  Размер: 932 B