зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1580599 - Migrate DevTools toolbox meatball menu to fluent; r=devtools-reviewers,fluent-reviewers,nchevobbe,flod
Differential Revision: https://phabricator.services.mozilla.com/D134419
This commit is contained in:
Родитель
b732cde303
Коммит
c6eeab3adf
|
@ -80,7 +80,9 @@ class MeatballMenu extends PureComponent {
|
|||
// Function to turn the disable pop-up autohide behavior on / off.
|
||||
toggleNoAutohide: PropTypes.func,
|
||||
|
||||
// Localization interface.
|
||||
// Bug 1709191 - The help shortcut key is localized without Fluent, and still needs
|
||||
// to be migrated. This is the only remaining use of the legacy L10N object.
|
||||
// Everything else should prefer the Fluent API.
|
||||
L10N: PropTypes.object.isRequired,
|
||||
|
||||
// Callback function that will be invoked any time the component contents
|
||||
|
@ -122,22 +124,22 @@ class MeatballMenu extends PureComponent {
|
|||
for (const hostType of this.props.hostTypes) {
|
||||
// This is more verbose than it needs to be but lets us easily search for
|
||||
// l10n entities.
|
||||
let l10nkey;
|
||||
let l10nID;
|
||||
switch (hostType.position) {
|
||||
case "window":
|
||||
l10nkey = "toolbox.meatballMenu.dock.separateWindow.label";
|
||||
l10nID = "toolbox-meatball-menu-dock-separate-window-label";
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
l10nkey = "toolbox.meatballMenu.dock.bottom.label";
|
||||
l10nID = "toolbox-meatball-menu-dock-bottom-label";
|
||||
break;
|
||||
|
||||
case "left":
|
||||
l10nkey = "toolbox.meatballMenu.dock.left.label";
|
||||
l10nID = "toolbox-meatball-menu-dock-left-label";
|
||||
break;
|
||||
|
||||
case "right":
|
||||
l10nkey = "toolbox.meatballMenu.dock.right.label";
|
||||
l10nID = "toolbox-meatball-menu-dock-right-label";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -149,7 +151,7 @@ class MeatballMenu extends PureComponent {
|
|||
MenuItem({
|
||||
id: `toolbox-meatball-menu-dock-${hostType.position}`,
|
||||
key: `dock-${hostType.position}`,
|
||||
label: this.props.L10N.getStr(l10nkey),
|
||||
l10nID,
|
||||
onClick: hostType.switchHost,
|
||||
checked: hostType.position === this.props.currentHostType,
|
||||
className: "iconic",
|
||||
|
@ -163,14 +165,14 @@ class MeatballMenu extends PureComponent {
|
|||
|
||||
// Split console
|
||||
if (this.props.currentToolId !== "webconsole") {
|
||||
const l10nkey = this.props.isSplitConsoleActive
|
||||
? "toolbox.meatballMenu.hideconsole.label"
|
||||
: "toolbox.meatballMenu.splitconsole.label";
|
||||
const l10nID = this.props.isSplitConsoleActive
|
||||
? "toolbox-meatball-menu-hideconsole-label"
|
||||
: "toolbox-meatball-menu-splitconsole-label";
|
||||
items.push(
|
||||
MenuItem({
|
||||
id: "toolbox-meatball-menu-splitconsole",
|
||||
key: "splitconsole",
|
||||
label: this.props.L10N.getStr(l10nkey),
|
||||
l10nID,
|
||||
accelerator: "Esc",
|
||||
onClick: this.props.toggleSplitConsole,
|
||||
className: "iconic",
|
||||
|
@ -187,9 +189,7 @@ class MeatballMenu extends PureComponent {
|
|||
MenuItem({
|
||||
id: "toolbox-meatball-menu-noautohide",
|
||||
key: "noautohide",
|
||||
label: this.props.L10N.getStr(
|
||||
"toolbox.meatballMenu.noautohide.label"
|
||||
),
|
||||
l10nID: "toolbox-meatball-menu-noautohide-label",
|
||||
type: "checkbox",
|
||||
checked: this.props.disableAutohide,
|
||||
onClick: this.props.toggleNoAutohide,
|
||||
|
@ -203,7 +203,9 @@ class MeatballMenu extends PureComponent {
|
|||
MenuItem({
|
||||
id: "toolbox-meatball-menu-settings",
|
||||
key: "settings",
|
||||
label: this.props.L10N.getStr("toolbox.meatballMenu.settings.label"),
|
||||
l10nID: "toolbox-meatball-menu-settings-label",
|
||||
// Bug 1709191 - The help key is localized without Fluent, and still needs to
|
||||
// be migrated.
|
||||
accelerator: this.props.L10N.getStr("toolbox.help.key"),
|
||||
onClick: this.props.toggleOptions,
|
||||
className: "iconic",
|
||||
|
@ -217,9 +219,7 @@ class MeatballMenu extends PureComponent {
|
|||
MenuItem({
|
||||
id: "toolbox-meatball-menu-documentation",
|
||||
key: "documentation",
|
||||
label: this.props.L10N.getStr(
|
||||
"toolbox.meatballMenu.documentation.label"
|
||||
),
|
||||
l10nID: "toolbox-meatball-menu-documentation-label",
|
||||
onClick: openDevToolsDocsLink,
|
||||
})
|
||||
);
|
||||
|
@ -229,7 +229,7 @@ class MeatballMenu extends PureComponent {
|
|||
MenuItem({
|
||||
id: "toolbox-meatball-menu-community",
|
||||
key: "community",
|
||||
label: this.props.L10N.getStr("toolbox.meatballMenu.community.label"),
|
||||
l10nID: "toolbox-meatball-menu-community-label",
|
||||
onClick: openCommunityLink,
|
||||
})
|
||||
);
|
||||
|
|
|
@ -10,7 +10,6 @@ const {
|
|||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const { div, button } = dom;
|
||||
|
||||
const DebugTargetInfo = createFactory(
|
||||
require("devtools/client/framework/components/DebugTargetInfo")
|
||||
);
|
||||
|
@ -36,6 +35,11 @@ loader.lazyGetter(this, "MenuList", function() {
|
|||
require("devtools/client/shared/components/menu/MenuList")
|
||||
);
|
||||
});
|
||||
loader.lazyGetter(this, "LocalizationProvider", function() {
|
||||
return createFactory(
|
||||
require("devtools/client/shared/vendor/fluent-react").LocalizationProvider
|
||||
);
|
||||
});
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
|
@ -119,6 +123,8 @@ class ToolboxToolbar extends Component {
|
|||
runtimeInfo: PropTypes.object.isRequired,
|
||||
targetType: PropTypes.string.isRequired,
|
||||
}),
|
||||
// The loaded Fluent localization bundles.
|
||||
fluentBundles: PropTypes.array.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -466,7 +472,7 @@ class ToolboxToolbar extends Component {
|
|||
* render functions for how each of the sections is rendered.
|
||||
*/
|
||||
render() {
|
||||
const { L10N, debugTargetData, toolbox } = this.props;
|
||||
const { L10N, debugTargetData, toolbox, fluentBundles } = this.props;
|
||||
const classnames = ["devtools-tabbar"];
|
||||
const startButtons = this.renderToolboxButtonsStart();
|
||||
const endButtons = this.renderToolboxButtonsEnd();
|
||||
|
@ -494,7 +500,10 @@ class ToolboxToolbar extends Component {
|
|||
? DebugTargetInfo({ debugTargetData, L10N, toolbox })
|
||||
: null;
|
||||
|
||||
return div({}, debugTargetInfo, toolbar);
|
||||
return LocalizationProvider(
|
||||
{ bundles: fluentBundles },
|
||||
div({}, debugTargetInfo, toolbar)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ add_task(async function() {
|
|||
"resource://devtools/client/shared/vendor/react-dom-factories.js",
|
||||
"resource://devtools/client/shared/vendor/react-prop-types.js",
|
||||
"resource://devtools/client/shared/vendor/redux.js",
|
||||
"resource://devtools/client/shared/vendor/fluent-react.js",
|
||||
]);
|
||||
|
||||
runMetricsTest({
|
||||
|
|
|
@ -39,6 +39,7 @@ add_task(async function() {
|
|||
"resource://devtools/client/shared/components/menu/MenuButton.js",
|
||||
"resource://devtools/client/shared/components/menu/MenuItem.js",
|
||||
"resource://devtools/client/shared/components/menu/MenuList.js",
|
||||
"resource://devtools/client/shared/vendor/fluent-react.js",
|
||||
"resource://devtools/client/shared/vendor/react.js",
|
||||
"resource://devtools/client/shared/vendor/react-dom.js",
|
||||
"resource://devtools/client/shared/vendor/react-prop-types.js",
|
||||
|
|
|
@ -33,6 +33,10 @@ var Telemetry = require("devtools/client/shared/telemetry");
|
|||
const { getUnicodeUrl } = require("devtools/client/shared/unicode-url");
|
||||
var { DOMHelpers } = require("devtools/shared/dom-helpers");
|
||||
const { KeyCodes } = require("devtools/client/shared/keycodes");
|
||||
const {
|
||||
FluentL10n,
|
||||
} = require("devtools/client/shared/fluent-l10n/fluent-l10n");
|
||||
|
||||
var Startup = Cc["@mozilla.org/devtools/startup-clh;1"].getService(
|
||||
Ci.nsISupports
|
||||
).wrappedJSObject;
|
||||
|
@ -845,6 +849,12 @@ Toolbox.prototype = {
|
|||
*/
|
||||
open: function() {
|
||||
return async function() {
|
||||
// Kick off async loading the Fluent bundles.
|
||||
const fluentL10n = new FluentL10n();
|
||||
const fluentInitPromise = fluentL10n.init([
|
||||
"devtools/client/toolbox.ftl",
|
||||
]);
|
||||
|
||||
const isToolboxURL = this.win.location.href.startsWith(this._URL);
|
||||
if (isToolboxURL) {
|
||||
// Update the URL so that onceDOMReady watch for the right url.
|
||||
|
@ -944,7 +954,9 @@ Toolbox.prototype = {
|
|||
// Get the DOM element to mount the ToolboxController to.
|
||||
this._componentMount = this.doc.getElementById("toolbox-toolbar-mount");
|
||||
|
||||
this._mountReactComponent();
|
||||
await fluentInitPromise;
|
||||
|
||||
this._mountReactComponent(fluentL10n.getBundles());
|
||||
this._buildDockOptions();
|
||||
this._buildTabs();
|
||||
|
||||
|
@ -1889,10 +1901,11 @@ Toolbox.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
_mountReactComponent: function() {
|
||||
_mountReactComponent(fluentBundles) {
|
||||
// Ensure the toolbar doesn't try to render until the tool is ready.
|
||||
const element = this.React.createElement(this.ToolboxController, {
|
||||
L10N,
|
||||
fluentBundles,
|
||||
currentToolId: this.currentToolId,
|
||||
selectTool: this.selectTool,
|
||||
toggleOptions: this.toggleOptions,
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# 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/.
|
||||
|
||||
### These messages are used in the DevTools toolbox.
|
||||
|
||||
## These labels are shown in the "..." menu in the toolbox, and represent different
|
||||
## commands such as the docking of DevTools, toggling features, and viewing some
|
||||
## external links. Some of the commands have the keyboard shortcut shown next to
|
||||
## the label.
|
||||
|
||||
toolbox-meatball-menu-dock-bottom-label = Dock to Bottom
|
||||
toolbox-meatball-menu-dock-left-label = Dock to Left
|
||||
toolbox-meatball-menu-dock-right-label = Dock to Right
|
||||
toolbox-meatball-menu-dock-separate-window-label = Separate Window
|
||||
|
||||
toolbox-meatball-menu-splitconsole-label = Show Split Console
|
||||
toolbox-meatball-menu-hideconsole-label = Hide Split Console
|
||||
|
||||
toolbox-meatball-menu-settings-label = Settings
|
||||
toolbox-meatball-menu-documentation-label = Documentation…
|
||||
toolbox-meatball-menu-community-label = Community…
|
||||
|
||||
# This menu item is only available in the browser toolbox. It forces the popups/panels
|
||||
# to stay visible on blur, which is primarily useful for addon developers and Firefox
|
||||
# contributors.
|
||||
toolbox-meatball-menu-noautohide-label = Disable Popup Auto-Hide
|
||||
|
||||
##
|
|
@ -168,42 +168,6 @@ toolbox.showFrames.key=Alt+Down
|
|||
# for the "..." button on the developer tools toolbox.
|
||||
toolbox.meatballMenu.button.tooltip=Customize Developer Tools and Get Help
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.meatballMenu.dock.*.label): These labels are shown
|
||||
# in the "..." menu in the toolbox and represent the different arrangements for
|
||||
# docking (or undocking) the developer tools toolbox.
|
||||
toolbox.meatballMenu.dock.bottom.label=Dock to Bottom
|
||||
toolbox.meatballMenu.dock.left.label=Dock to Left
|
||||
toolbox.meatballMenu.dock.right.label=Dock to Right
|
||||
toolbox.meatballMenu.dock.separateWindow.label=Separate Window
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.meatballMenu.{splitconsole,hideconsole}.label):
|
||||
# These are the labels in the "..." menu in the toolbox for toggling the split
|
||||
# console window.
|
||||
# The keyboard shortcut will be shown to the side of the label.
|
||||
toolbox.meatballMenu.splitconsole.label=Show Split Console
|
||||
toolbox.meatballMenu.hideconsole.label=Hide Split Console
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.meatballMenu.noautohide.label): This is the label
|
||||
# in the "..." menu in the toolbox to force the popups/panels to stay visible on
|
||||
# blur.
|
||||
# This is only visible in the browser toolbox as it is meant for
|
||||
# addon developers and Firefox contributors.
|
||||
toolbox.meatballMenu.noautohide.label=Disable Popup Auto-Hide
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.meatballMenu.settings.label): This is the label for
|
||||
# the item in the "..." menu in the toolbox that brings up the Settings
|
||||
# (Options) panel.
|
||||
# The keyboard shortcut will be shown to the side of the label.
|
||||
toolbox.meatballMenu.settings.label=Settings
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.meatballMenu.documentation.label): This is the
|
||||
# label for the Documentation menu item.
|
||||
toolbox.meatballMenu.documentation.label=Documentation…
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.meatballMenu.community.label): This is the label
|
||||
# for the Community menu item.
|
||||
toolbox.meatballMenu.community.label=Community…
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.closebutton.tooltip): This is the tooltip for
|
||||
# the close button the developer tools toolbox.
|
||||
toolbox.closebutton.tooltip=Close Developer Tools
|
||||
|
|
|
@ -8,12 +8,16 @@
|
|||
// A command in a menu.
|
||||
|
||||
const {
|
||||
createFactory,
|
||||
createRef,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { button, li, span } = dom;
|
||||
loader.lazyGetter(this, "Localized", () =>
|
||||
createFactory(require("devtools/client/shared/vendor/fluent-react").Localized)
|
||||
);
|
||||
|
||||
class MenuItem extends PureComponent {
|
||||
static get propTypes() {
|
||||
|
@ -46,8 +50,11 @@ class MenuItem extends PureComponent {
|
|||
// An optional ID to be assigned to the item.
|
||||
id: PropTypes.string,
|
||||
|
||||
// The item label.
|
||||
label: PropTypes.string.isRequired,
|
||||
// The item label for use with legacy localization systems.
|
||||
label: PropTypes.string,
|
||||
|
||||
// The Fluent ID for localizing the label.
|
||||
l10nID: PropTypes.string,
|
||||
|
||||
// An optional callback to be invoked when the item is selected.
|
||||
onClick: PropTypes.func,
|
||||
|
@ -153,11 +160,32 @@ class MenuItem extends PureComponent {
|
|||
attr["aria-checked"] = true;
|
||||
}
|
||||
|
||||
const textLabel = span(
|
||||
{ key: "label", className: "label", ref: this.labelRef },
|
||||
this.props.label
|
||||
);
|
||||
const children = [textLabel];
|
||||
const children = [];
|
||||
const className = "label";
|
||||
|
||||
// Add the text label.
|
||||
if (this.props.l10nID) {
|
||||
// Fluent localized label.
|
||||
children.push(
|
||||
Localized(
|
||||
{ id: this.props.l10nID, key: "label" },
|
||||
span({ className, ref: this.labelRef })
|
||||
)
|
||||
);
|
||||
} else {
|
||||
children.push(
|
||||
span({ key: "label", className, ref: this.labelRef }, this.props.label)
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.l10nID && this.props.label) {
|
||||
console.warn(
|
||||
"<MenuItem> should only take either an l10nID or a label, not both"
|
||||
);
|
||||
}
|
||||
if (!this.props.l10nID && !this.props.label) {
|
||||
console.warn("<MenuItem> requires either an l10nID, or a label prop.");
|
||||
}
|
||||
|
||||
if (typeof this.props.accelerator !== "undefined") {
|
||||
const acceleratorLabel = span(
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
|
||||
const TEST_URI =
|
||||
"data:text/html;charset=utf-8,<!DOCTYPE html>Web Console test for splitting";
|
||||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
const L10N = new LocalizationHelper(
|
||||
"devtools/client/locales/toolbox.properties"
|
||||
);
|
||||
|
||||
// Test is slow on Linux EC2 instances - Bug 962931
|
||||
requestLongerTimeout(4);
|
||||
|
@ -122,8 +118,7 @@ add_task(async function() {
|
|||
let label;
|
||||
if (menuItem && menuItem.querySelector(".label")) {
|
||||
label =
|
||||
menuItem.querySelector(".label").textContent ===
|
||||
L10N.getStr("toolbox.meatballMenu.hideconsole.label")
|
||||
menuItem.querySelector(".label").textContent === "Hide Split Console"
|
||||
? "hide"
|
||||
: "split";
|
||||
}
|
||||
|
|
|
@ -5,11 +5,6 @@
|
|||
|
||||
// Test that the split console state is persisted.
|
||||
|
||||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
const L10N = new LocalizationHelper(
|
||||
"devtools/client/locales/toolbox.properties"
|
||||
);
|
||||
|
||||
const TEST_URI =
|
||||
"data:text/html;charset=utf-8,<!DOCTYPE html><p>Web Console test for splitting</p>";
|
||||
|
||||
|
@ -121,8 +116,7 @@ async function doesMenuSayHide(toolbox) {
|
|||
const result =
|
||||
menuItem &&
|
||||
menuItem.querySelector(".label") &&
|
||||
menuItem.querySelector(".label").textContent ===
|
||||
L10N.getStr("toolbox.meatballMenu.hideconsole.label");
|
||||
menuItem.querySelector(".label").textContent === "Hide Split Console";
|
||||
|
||||
toolbox.doc.addEventListener(
|
||||
"popuphidden",
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
import fluent.syntax.ast as FTL
|
||||
from fluent.migrate.transforms import COPY
|
||||
|
||||
|
||||
def migrate(ctx):
|
||||
"""Bug 1580599 - Convert toolbox.properties to Fluent, part {index}."""
|
||||
|
||||
source = "devtools/client/toolbox.properties"
|
||||
target = "devtools/client/toolbox.ftl"
|
||||
ctx.add_transforms(
|
||||
target,
|
||||
target,
|
||||
[
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-dock-bottom-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.dock.bottom.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-dock-left-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.dock.left.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-dock-right-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.dock.right.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-dock-separate-window-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.dock.separateWindow.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-splitconsole-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.splitconsole.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-hideconsole-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.hideconsole.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-noautohide-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.noautohide.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-settings-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.settings.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-documentation-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.documentation.label"),
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier("toolbox-meatball-menu-community-label"),
|
||||
value=COPY(source, "toolbox.meatballMenu.community.label"),
|
||||
),
|
||||
],
|
||||
)
|
Загрузка…
Ссылка в новой задаче