зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1597385 - Create a stripped down version of the profiler front-end; r=julienw
Differential Revision: https://phabricator.services.mozilla.com/D65146 --HG-- rename : devtools/client/performance-new/components/DevToolsAndPopup.js => devtools/client/performance-new/components/DevToolsPanel.js extra : moz-landing-system : lando
This commit is contained in:
Родитель
6325813760
Коммит
c3340d41b3
|
@ -64,20 +64,10 @@ class Description extends PureComponent {
|
|||
{ className: "perf-description" },
|
||||
p(
|
||||
null,
|
||||
"This new recording panel is a bit different from the existing " +
|
||||
"performance panel. It records the entire browser, and then opens up " +
|
||||
"and shares the profile with ",
|
||||
"Recordings launch ",
|
||||
this.renderLink("https://profiler.firefox.com", "profiler.firefox.com"),
|
||||
", a Mozilla performance analysis tool."
|
||||
),
|
||||
p(
|
||||
null,
|
||||
"This is still a prototype. Join along or file bugs at: ",
|
||||
this.renderLink(
|
||||
"https://github.com/firefox-devtools/profiler",
|
||||
"github.com/firefox-devtools/profiler"
|
||||
),
|
||||
"."
|
||||
" in a new tab. All data is stored locally, but you can choose to upload it",
|
||||
" for sharing."
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
* @typedef {Object} StateProps
|
||||
* @property {boolean?} isSupportedPlatform
|
||||
* @property {PageContext} pageContext
|
||||
* @property {string | null} promptEnvRestart
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -31,22 +30,19 @@ const {
|
|||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
const {
|
||||
div,
|
||||
button,
|
||||
hr,
|
||||
} = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const RecordingButton = createFactory(
|
||||
require("devtools/client/performance-new/components/RecordingButton.js")
|
||||
);
|
||||
const Settings = createFactory(
|
||||
require("devtools/client/performance-new/components/Settings.js")
|
||||
require("devtools/client/performance-new/components/RecordingButton")
|
||||
);
|
||||
const Description = createFactory(
|
||||
require("devtools/client/performance-new/components/Description.js")
|
||||
require("devtools/client/performance-new/components/Description")
|
||||
);
|
||||
const DevToolsPresetSelection = createFactory(
|
||||
require("devtools/client/performance-new/components/DevToolsPresetSelection")
|
||||
);
|
||||
|
||||
const selectors = require("devtools/client/performance-new/store/selectors");
|
||||
const {
|
||||
restartBrowserWithEnvironmentVariable,
|
||||
} = require("devtools/client/performance-new/browser");
|
||||
|
||||
/**
|
||||
* This is the top level component for the DevTools panel and the profiler popup, but
|
||||
|
@ -55,25 +51,9 @@ const {
|
|||
*
|
||||
* @extends {React.PureComponent<Props>}
|
||||
*/
|
||||
class DevToolsAndPopup extends PureComponent {
|
||||
/** @param {Props} props */
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleRestart = this.handleRestart.bind(this);
|
||||
}
|
||||
|
||||
handleRestart() {
|
||||
const { promptEnvRestart } = this.props;
|
||||
if (!promptEnvRestart) {
|
||||
throw new Error(
|
||||
"handleRestart() should only be called when promptEnvRestart exists."
|
||||
);
|
||||
}
|
||||
restartBrowserWithEnvironmentVariable(promptEnvRestart, "1");
|
||||
}
|
||||
|
||||
class DevToolsPanel extends PureComponent {
|
||||
render() {
|
||||
const { isSupportedPlatform, pageContext, promptEnvRestart } = this.props;
|
||||
const { isSupportedPlatform, pageContext } = this.props;
|
||||
|
||||
if (isSupportedPlatform === null) {
|
||||
// We don't know yet if this is a supported platform, wait for a response.
|
||||
|
@ -82,30 +62,10 @@ class DevToolsAndPopup extends PureComponent {
|
|||
|
||||
return div(
|
||||
{ className: `perf perf-${pageContext}` },
|
||||
promptEnvRestart
|
||||
? div(
|
||||
{ className: "perf-env-restart" },
|
||||
div(
|
||||
{
|
||||
className:
|
||||
"perf-photon-message-bar perf-photon-message-bar-warning perf-env-restart-fixed",
|
||||
},
|
||||
div({ className: "perf-photon-message-bar-warning-icon" }),
|
||||
"The browser must be restarted to enable this feature.",
|
||||
button(
|
||||
{
|
||||
className: "perf-photon-button perf-photon-button-micro",
|
||||
type: "button",
|
||||
onClick: this.handleRestart,
|
||||
},
|
||||
"Restart"
|
||||
)
|
||||
)
|
||||
)
|
||||
: null,
|
||||
RecordingButton(),
|
||||
Settings(),
|
||||
pageContext === "devtools" ? Description() : null
|
||||
Description(),
|
||||
hr({ className: "perf-presets-hr" }),
|
||||
DevToolsPresetSelection()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -118,8 +78,7 @@ function mapStateToProps(state) {
|
|||
return {
|
||||
isSupportedPlatform: selectors.getIsSupportedPlatform(state),
|
||||
pageContext: selectors.getPageContext(state),
|
||||
promptEnvRestart: selectors.getPromptEnvRestart(state),
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = connect(mapStateToProps)(DevToolsAndPopup);
|
||||
module.exports = connect(mapStateToProps)(DevToolsPanel);
|
|
@ -0,0 +1,186 @@
|
|||
/* 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/. */
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @template P
|
||||
* @typedef {import("react-redux").ResolveThunks<P>} ResolveThunks<P>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} StateProps
|
||||
* @property {string} presetName
|
||||
* @property {number} interval
|
||||
* @property {string[]} threads
|
||||
* @property {string[]} features
|
||||
* @property {import("../@types/perf").Presets} presets
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ThunkDispatchProps
|
||||
* @property {typeof actions.changePreset} changePreset
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ResolveThunks<ThunkDispatchProps>} DispatchProps
|
||||
* @typedef {StateProps & DispatchProps} Props
|
||||
* @typedef {import("../@types/perf").State} StoreState
|
||||
* @typedef {import("../@types/perf").FeatureDescription} FeatureDescription
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
div,
|
||||
select,
|
||||
option,
|
||||
button,
|
||||
ul,
|
||||
li,
|
||||
span,
|
||||
} = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
const actions = require("devtools/client/performance-new/store/actions");
|
||||
const selectors = require("devtools/client/performance-new/store/selectors");
|
||||
const {
|
||||
featureDescriptions,
|
||||
} = require("devtools/client/performance-new/utils");
|
||||
|
||||
/**
|
||||
* This component displays the preset selection for the DevTools panel. It should be
|
||||
* basically the same implementation as the popup, but done in React. The popup
|
||||
* is written using vanilla JS and browser chrome elements in order to be more
|
||||
* performant.
|
||||
*
|
||||
* @extends {React.PureComponent<Props>}
|
||||
*/
|
||||
class DevToolsPresetSelection extends PureComponent {
|
||||
/** @param {Props} props */
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onPresetChange = this.onPresetChange.bind(this);
|
||||
this.handleLinkClick = this.handleLinkClick.bind(this);
|
||||
|
||||
/**
|
||||
* Create an object map to easily look up feature description.
|
||||
* @type {{[key: string]: FeatureDescription}}
|
||||
*/
|
||||
this.featureDescriptionMap = {};
|
||||
for (const feature of featureDescriptions) {
|
||||
this.featureDescriptionMap[feature.value] = feature;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the select change.
|
||||
* @param {React.ChangeEvent<HTMLSelectElement>} event
|
||||
*/
|
||||
onPresetChange(event) {
|
||||
const { presets } = this.props;
|
||||
this.props.changePreset(presets, event.target.value);
|
||||
}
|
||||
|
||||
handleLinkClick() {
|
||||
const { openTrustedLink } = require("devtools/client/shared/link");
|
||||
openTrustedLink("about:profiling", {});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { presetName, presets } = this.props;
|
||||
|
||||
let presetDescription;
|
||||
const currentPreset = presets[presetName];
|
||||
if (currentPreset) {
|
||||
presetDescription = currentPreset.description;
|
||||
} else {
|
||||
const { interval, threads, features } = this.props;
|
||||
presetDescription = div(
|
||||
null,
|
||||
ul(
|
||||
{ className: "perf-presets-custom" },
|
||||
li(
|
||||
null,
|
||||
span({ className: "perf-presets-custom-bold" }, "Interval: "),
|
||||
`${interval} ms`
|
||||
),
|
||||
li(
|
||||
null,
|
||||
span({ className: "perf-presets-custom-bold" }, "Threads: "),
|
||||
threads.join(", ")
|
||||
),
|
||||
features.map(feature => {
|
||||
const description = this.featureDescriptionMap[feature];
|
||||
if (!description) {
|
||||
throw new Error(
|
||||
"Could not find the feature description for " + feature
|
||||
);
|
||||
}
|
||||
return li(
|
||||
{ key: feature },
|
||||
description ? description.name : feature
|
||||
);
|
||||
})
|
||||
),
|
||||
button(
|
||||
{ className: "perf-external-link", onClick: this.handleLinkClick },
|
||||
"Edit Settings…"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return div(
|
||||
{ className: "perf-presets" },
|
||||
div({ className: "perf-presets-settings" }, "Settings"),
|
||||
div(
|
||||
{ className: "perf-presets-details" },
|
||||
div(
|
||||
{ className: "perf-presets-details-row" },
|
||||
select(
|
||||
{
|
||||
className: "perf-presets-select",
|
||||
onChange: this.onPresetChange,
|
||||
value: presetName,
|
||||
},
|
||||
Object.entries(presets).map(([name, preset]) =>
|
||||
option({ key: name, value: name }, preset.label)
|
||||
),
|
||||
option({ value: "custom" }, "Custom")
|
||||
)
|
||||
// The overhead component will go here.
|
||||
),
|
||||
div(
|
||||
{ className: "perf-presets-details-row perf-presets-description" },
|
||||
presetDescription
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {StoreState} state
|
||||
* @returns {StateProps}
|
||||
*/
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
presetName: selectors.getPresetName(state),
|
||||
presets: selectors.getPresets(state),
|
||||
interval: selectors.getInterval(state),
|
||||
threads: selectors.getThreads(state),
|
||||
features: selectors.getFeatures(state),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ThunkDispatchProps}
|
||||
*/
|
||||
const mapDispatchToProps = {
|
||||
changePreset: actions.changePreset,
|
||||
};
|
||||
|
||||
module.exports = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(DevToolsPresetSelection);
|
|
@ -60,68 +60,6 @@ class RecordingButton extends PureComponent {
|
|||
this.props.getProfileAndStopProfiler(window);
|
||||
}
|
||||
|
||||
/** @param {{
|
||||
* disabled?: boolean,
|
||||
* label?: React.ReactNode,
|
||||
* onClick?: any,
|
||||
* additionalMessage?: React.ReactNode,
|
||||
* isPrimary?: boolean,
|
||||
* pageContext?: PageContext,
|
||||
* additionalButton?: {
|
||||
* label: string,
|
||||
* onClick: any,
|
||||
* },
|
||||
* }} buttonSettings
|
||||
*/
|
||||
renderButton(buttonSettings) {
|
||||
const {
|
||||
disabled,
|
||||
label,
|
||||
onClick,
|
||||
additionalMessage,
|
||||
isPrimary,
|
||||
// pageContext,
|
||||
additionalButton,
|
||||
} = buttonSettings;
|
||||
|
||||
const nbsp = "\u00A0";
|
||||
const showAdditionalMessage = false;
|
||||
// TODO - Bug 1615431 - This feature needs to be migrated to about:profiling.
|
||||
// const showAdditionalMessage = pageContext === "aboutprofiling" && additionalMessage;
|
||||
const buttonClass = isPrimary ? "primary" : "default";
|
||||
|
||||
return div(
|
||||
{ className: "perf-button-container" },
|
||||
showAdditionalMessage
|
||||
? div(
|
||||
{ className: "perf-additional-message" },
|
||||
additionalMessage || nbsp
|
||||
)
|
||||
: null,
|
||||
div(
|
||||
null,
|
||||
button(
|
||||
{
|
||||
className: `perf-photon-button perf-photon-button-${buttonClass} perf-button`,
|
||||
disabled,
|
||||
onClick,
|
||||
},
|
||||
label
|
||||
),
|
||||
additionalButton
|
||||
? button(
|
||||
{
|
||||
className: `perf-photon-button perf-photon-button-default perf-button`,
|
||||
onClick: additionalButton.onClick,
|
||||
disabled,
|
||||
},
|
||||
additionalButton.label
|
||||
)
|
||||
: null
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
startRecording,
|
||||
|
@ -132,8 +70,9 @@ class RecordingButton extends PureComponent {
|
|||
} = this.props;
|
||||
|
||||
if (!isSupportedPlatform) {
|
||||
return this.renderButton({
|
||||
label: "Start recording",
|
||||
return renderButton({
|
||||
label: startRecordingLabel(),
|
||||
isPrimary: true,
|
||||
disabled: true,
|
||||
additionalMessage:
|
||||
"Your platform is not supported. The Gecko Profiler only " +
|
||||
|
@ -147,37 +86,40 @@ class RecordingButton extends PureComponent {
|
|||
return null;
|
||||
|
||||
case "available-to-record":
|
||||
return this.renderButton({
|
||||
return renderButton({
|
||||
onClick: startRecording,
|
||||
label: span(
|
||||
null,
|
||||
img({
|
||||
className: "perf-button-image",
|
||||
src: "chrome://devtools/skin/images/tool-profiler.svg",
|
||||
}),
|
||||
"Start recording"
|
||||
),
|
||||
isPrimary: true,
|
||||
label: startRecordingLabel(),
|
||||
additionalMessage: recordingUnexpectedlyStopped
|
||||
? div(null, "The recording was stopped by another tool.")
|
||||
: null,
|
||||
});
|
||||
|
||||
case "request-to-stop-profiler":
|
||||
return this.renderButton({
|
||||
return renderButton({
|
||||
label: "Stopping recording",
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
case "request-to-get-profile-and-stop-profiler":
|
||||
return this.renderButton({
|
||||
return renderButton({
|
||||
label: "Capturing profile",
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
case "request-to-start-recording":
|
||||
case "recording":
|
||||
return this.renderButton({
|
||||
label: "Capture recording",
|
||||
return renderButton({
|
||||
label: span(
|
||||
null,
|
||||
"Capture recording",
|
||||
img({
|
||||
className: "perf-button-image",
|
||||
alt: "",
|
||||
/* This icon is actually the "open in new page" icon. */
|
||||
src: "chrome://devtools/skin/images/dock-undock.svg",
|
||||
})
|
||||
),
|
||||
isPrimary: true,
|
||||
onClick: this._getProfileAndStopProfiler,
|
||||
disabled: recordingState === "request-to-start-recording",
|
||||
|
@ -188,15 +130,9 @@ class RecordingButton extends PureComponent {
|
|||
});
|
||||
|
||||
case "locked-by-private-browsing":
|
||||
return this.renderButton({
|
||||
label: span(
|
||||
null,
|
||||
img({
|
||||
className: "perf-button-image",
|
||||
src: "chrome://devtools/skin/images/tool-profiler.svg",
|
||||
}),
|
||||
"Start recording"
|
||||
),
|
||||
return renderButton({
|
||||
label: startRecordingLabel(),
|
||||
isPrimary: true,
|
||||
disabled: true,
|
||||
additionalMessage: `The profiler is disabled when Private Browsing is enabled.
|
||||
Close all Private Windows to re-enable the profiler`,
|
||||
|
@ -208,6 +144,75 @@ class RecordingButton extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* disabled?: boolean,
|
||||
* label?: React.ReactNode,
|
||||
* onClick?: any,
|
||||
* additionalMessage?: React.ReactNode,
|
||||
* isPrimary?: boolean,
|
||||
* pageContext?: PageContext,
|
||||
* additionalButton?: {
|
||||
* label: string,
|
||||
* onClick: any,
|
||||
* },
|
||||
* }} buttonSettings
|
||||
*/
|
||||
function renderButton(buttonSettings) {
|
||||
const {
|
||||
disabled,
|
||||
label,
|
||||
onClick,
|
||||
additionalMessage,
|
||||
isPrimary,
|
||||
// pageContext,
|
||||
additionalButton,
|
||||
} = buttonSettings;
|
||||
|
||||
const buttonClass = isPrimary ? "primary" : "default";
|
||||
|
||||
return div(
|
||||
{ className: "perf-button-container" },
|
||||
div(
|
||||
null,
|
||||
button(
|
||||
{
|
||||
className: `perf-photon-button perf-photon-button-${buttonClass} perf-button`,
|
||||
disabled,
|
||||
onClick,
|
||||
},
|
||||
label
|
||||
),
|
||||
additionalButton
|
||||
? button(
|
||||
{
|
||||
className: `perf-photon-button perf-photon-button-default perf-button`,
|
||||
onClick: additionalButton.onClick,
|
||||
disabled,
|
||||
},
|
||||
additionalButton.label
|
||||
)
|
||||
: null
|
||||
),
|
||||
additionalMessage
|
||||
? div({ className: "perf-additional-message" }, additionalMessage)
|
||||
: null
|
||||
);
|
||||
}
|
||||
|
||||
function startRecordingLabel() {
|
||||
return span(
|
||||
null,
|
||||
"Start recording",
|
||||
img({
|
||||
className: "perf-button-image",
|
||||
alt: "",
|
||||
/* This icon is actually the "open in new page" icon. */
|
||||
src: "chrome://devtools/skin/images/dock-undock.svg",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {StoreState} state
|
||||
* @returns {StateProps}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
DevToolsModules(
|
||||
'AboutProfiling.js',
|
||||
'Description.js',
|
||||
'DevToolsAndPopup.js',
|
||||
'DevToolsPanel.js',
|
||||
'DevToolsPresetSelection.js',
|
||||
'DirectoryPicker.js',
|
||||
'Presets.js',
|
||||
'ProfilerEventHandling.js',
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const DevToolsAndPopup = React.createFactory(
|
||||
require("devtools/client/performance-new/components/DevToolsAndPopup")
|
||||
const DevToolsPanel = React.createFactory(
|
||||
require("devtools/client/performance-new/components/DevToolsPanel")
|
||||
);
|
||||
const ProfilerEventHandling = React.createFactory(
|
||||
require("devtools/client/performance-new/components/ProfilerEventHandling")
|
||||
|
@ -93,9 +93,6 @@ async function gInit(perfFront, preferenceFront) {
|
|||
Promise.resolve(perfFront.getSupportedFeatures()).catch(() => null),
|
||||
]);
|
||||
|
||||
// This panel doesn't support presets yet, make sure it's always set to custom.
|
||||
recordingPreferences.presetName = "custom";
|
||||
|
||||
// Do some initialization, especially with privileged things that are part of the
|
||||
// the browser.
|
||||
store.dispatch(
|
||||
|
@ -139,7 +136,7 @@ async function gInit(perfFront, preferenceFront) {
|
|||
React.Fragment,
|
||||
null,
|
||||
ProfilerEventHandling(),
|
||||
DevToolsAndPopup()
|
||||
DevToolsPanel()
|
||||
)
|
||||
),
|
||||
document.querySelector("#root")
|
||||
|
|
|
@ -187,7 +187,7 @@ function createPerfComponent() {
|
|||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const ReactRedux = require("devtools/client/shared/vendor/react-redux");
|
||||
const DevToolsAndPopup = React.createFactory(
|
||||
require("devtools/client/performance-new/components/DevToolsAndPopup")
|
||||
require("devtools/client/performance-new/components/DevToolsPanel")
|
||||
);
|
||||
const ProfilerEventHandling = React.createFactory(
|
||||
require("devtools/client/performance-new/components/ProfilerEventHandling")
|
||||
|
|
|
@ -30,10 +30,11 @@
|
|||
}
|
||||
|
||||
.perf-button-image {
|
||||
vertical-align: text-top;
|
||||
padding-inline-end: 4px;
|
||||
vertical-align: middle;
|
||||
padding-inline-start: 8px;
|
||||
width: 13px;
|
||||
-moz-context-properties: fill;
|
||||
fill: var(--theme-icon-color);
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.perf-button-container {
|
||||
|
@ -47,7 +48,9 @@
|
|||
}
|
||||
|
||||
.perf-additional-message {
|
||||
margin: 10px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.perf > * {
|
||||
|
@ -55,6 +58,7 @@
|
|||
}
|
||||
|
||||
.perf-description {
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
|
@ -67,6 +71,7 @@
|
|||
text-decoration: underline;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
|
@ -328,7 +333,6 @@
|
|||
|
||||
/* See https://design.firefox.com/photon/components/buttons.html for the spec */
|
||||
.perf-photon-button {
|
||||
--blue-50-a30: rgba(10, 132, 255, 0.3);
|
||||
padding: 0 8px;
|
||||
border: none;
|
||||
margin: 0;
|
||||
|
@ -375,14 +379,15 @@
|
|||
}
|
||||
|
||||
.perf-photon-button[disabled] {
|
||||
opacity: 0.4;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.perf-photon-button.perf-button {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
button.perf-photon-button:focus {
|
||||
button.perf-photon-button:focus,
|
||||
.perf-presets-select:focus {
|
||||
box-shadow: 0 0 0 1px var(--blue-50) inset, 0 0 0 1px var(--blue-50),
|
||||
0 0 0 4px var(--blue-50-a30);
|
||||
outline: 0;
|
||||
|
@ -397,72 +402,70 @@ a.perf-photon-button:focus {
|
|||
height: 24px;
|
||||
}
|
||||
|
||||
/* Photon message bar - https://design.firefox.com/photon/components/message-bars.html */
|
||||
.perf-presets-hr {
|
||||
width: 100%;
|
||||
border: 1px solid var(--grey-30);
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.perf-photon-message-bar {
|
||||
.perf-presets {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 32px;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
padding: 0 4px;
|
||||
border-radius: 4px;
|
||||
margin-block: 12px;
|
||||
}
|
||||
|
||||
.perf-presets-settings {
|
||||
margin-inline-end: 17px;
|
||||
margin-block: 3px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.perf-presets-description {
|
||||
margin-block: 13px;
|
||||
}
|
||||
|
||||
.perf-presets-select {
|
||||
/* Layout */
|
||||
position: relative;
|
||||
min-width: 186px;
|
||||
padding-block: 3px;
|
||||
padding-inline: 5px;
|
||||
border: 1px solid transparent;
|
||||
|
||||
/* Presentational: */
|
||||
-moz-appearance: none;
|
||||
background-color: var(--grey-20);
|
||||
background-image: url('chrome://global/skin/icons/arrow-dropdown-12.svg');
|
||||
background-position: right 4px center;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 2px;
|
||||
border: 1px solid transparent;
|
||||
color: inherit !important;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.perf-photon-message-bar-warning {
|
||||
/* This should include an info icon, but it's left out since it's probably not worth
|
||||
* adding and maintaining an extra icon here. */
|
||||
padding: 4px 8px;
|
||||
background: var(--yellow-50);
|
||||
color: var(--yellow-90);
|
||||
fill: var(--yellow-90);
|
||||
.perf-presets-select:hover {
|
||||
border: 1px solid var(--grey-30);
|
||||
}
|
||||
|
||||
.perf-photon-message-bar-warning-icon {
|
||||
background: url("chrome://global/skin/icons/warning.svg");
|
||||
-moz-context-properties: fill;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 4px;
|
||||
.perf-presets-select:focus {
|
||||
box-shadow:
|
||||
0 0 0 2px var(--blue-50),
|
||||
0 0 0 6px var(--blue-50-a30);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.perf-photon-message-bar .perf-photon-button {
|
||||
margin-inline-start: 8px;
|
||||
.perf-presets-custom {
|
||||
padding-inline: 10px;
|
||||
margin-block: 13px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.perf-photon-message-bar-warning .perf-photon-button {
|
||||
background-color: var(--yellow-60);
|
||||
}
|
||||
|
||||
.perf-photon-message-bar-warning .perf-photon-button:hover {
|
||||
background-color: var(--yellow-70);
|
||||
}
|
||||
|
||||
.perf-photon-message-bar-warning .perf-photon-button:hover:active {
|
||||
background-color: var(--yellow-80);
|
||||
}
|
||||
|
||||
/* Restart prompt */
|
||||
|
||||
.perf-env-restart {
|
||||
/* Create an empty space at the top of the page. */
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
.perf-env-restart-fixed {
|
||||
/* This style is for the floating bar */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
/* Create a new stacking context, so that the fixed positioning will be over the
|
||||
* rest of the components */
|
||||
z-index: 1;
|
||||
|
||||
border-radius: 0;
|
||||
.perf-presets-custom-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
--blue-30: #75baff;
|
||||
--blue-40: #45a1ff;
|
||||
--blue-50: #0a84ff;
|
||||
--blue-50-a30: rgba(10, 132, 255, 0.3);
|
||||
--blue-55: #0074e8;
|
||||
--blue-60: #0060df;
|
||||
--blue-70: #003eaa;
|
||||
|
|
Загрузка…
Ссылка в новой задаче