зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1598320 - Add types to the performance-new components; r=julienw
Differential Revision: https://phabricator.services.mozilla.com/D54771 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
246f170a3d
Коммит
086d2b5725
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
// Props are checked by TypeScript, so we don't need dynamic type checking here.
|
||||
"react/prop-types": "off"
|
||||
}
|
||||
};
|
|
@ -16,6 +16,7 @@ export interface PanelWindow {
|
|||
gTarget?: any;
|
||||
gInit(perfFront: any, preferenceFront: any): void;
|
||||
gDestroy(): void;
|
||||
gReportReady?(): void
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,6 +56,8 @@ export interface PerfFront {
|
|||
isActive: () => MaybePromise<boolean>;
|
||||
isSupportedPlatform: () => MaybePromise<boolean>;
|
||||
isLockedForPrivateBrowsing: () => MaybePromise<boolean>;
|
||||
on: (type: string, listener: () => void) => void;
|
||||
off: (type: string, listener: () => void) => void;
|
||||
/**
|
||||
* This method was was added in Firefox 72.
|
||||
*/
|
||||
|
@ -356,3 +359,17 @@ export interface PerformancePref {
|
|||
export interface PopupWindow extends Window {
|
||||
gResizePopup?: (height: number) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale a number value.
|
||||
*/
|
||||
export type NumberScaler = (value: number) => number;
|
||||
|
||||
/**
|
||||
* A collection of functions to scale numbers.
|
||||
*/
|
||||
export interface ScaleFunctions {
|
||||
fromFractionToValue: NumberScaler,
|
||||
fromValueToFraction: NumberScaler,
|
||||
fromFractionToSingleDigitValue: NumberScaler,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
/* 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
|
||||
|
||||
/**
|
||||
* @typedef {{}} Props - This is an empty object.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
|
@ -13,25 +19,34 @@ const {
|
|||
/**
|
||||
* This component provides a helpful description for what is going on in the component
|
||||
* and provides some external links.
|
||||
* @extends {React.PureComponent<Props>}
|
||||
*/
|
||||
class Description extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Props} props
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleLinkClick = this.handleLinkClick.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {React.MouseEvent<HTMLButtonElement>} event
|
||||
*/
|
||||
handleLinkClick(event) {
|
||||
const { openDocLink } = require("devtools/client/shared/link");
|
||||
openDocLink(event.target.value);
|
||||
|
||||
/** @type HTMLButtonElement */
|
||||
const target = /** @type {any} */ (event.target);
|
||||
|
||||
openDocLink(target.value, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement links as buttons to avoid any risk of loading the link in the
|
||||
* the panel.
|
||||
* @param {string} href
|
||||
* @param {string} text
|
||||
*/
|
||||
renderLink(href, text) {
|
||||
return button(
|
||||
|
|
|
@ -1,7 +1,17 @@
|
|||
/* 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
|
||||
|
||||
/**
|
||||
* @typedef {Object} Props
|
||||
* @property {string[]} dirs
|
||||
* @property {() => void} onAdd
|
||||
* @property {(index: number) => void} onRemove
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
div,
|
||||
|
@ -12,29 +22,24 @@ const {
|
|||
const {
|
||||
withCommonPathPrefixRemoved,
|
||||
} = require("devtools/client/performance-new/utils");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
// A list of directories with add and remove buttons.
|
||||
// Looks like this:
|
||||
//
|
||||
// +---------------------------------------------+
|
||||
// | code/obj-m-android-opt |
|
||||
// | code/obj-m-android-debug |
|
||||
// | test/obj-m-test |
|
||||
// | |
|
||||
// +---------------------------------------------+
|
||||
//
|
||||
// [+] [-]
|
||||
|
||||
/**
|
||||
* A list of directories with add and remove buttons.
|
||||
* Looks like this:
|
||||
*
|
||||
* +---------------------------------------------+
|
||||
* | code/obj-m-android-opt |
|
||||
* | code/obj-m-android-debug |
|
||||
* | test/obj-m-test |
|
||||
* | |
|
||||
* +---------------------------------------------+
|
||||
*
|
||||
* [+] [-]
|
||||
*
|
||||
* @extends {React.PureComponent<Props>}
|
||||
*/
|
||||
class DirectoryPicker extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
dirs: PropTypes.array.isRequired,
|
||||
onAdd: PropTypes.func.isRequired,
|
||||
onRemove: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
/** @param {Props} props */
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._listBox = null;
|
||||
|
@ -43,6 +48,9 @@ class DirectoryPicker extends PureComponent {
|
|||
this._handleRemoveButtonClick = this._handleRemoveButtonClick.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLSelectElement} element
|
||||
*/
|
||||
_takeListBoxRef(element) {
|
||||
this._listBox = element;
|
||||
}
|
||||
|
@ -64,7 +72,7 @@ class DirectoryPicker extends PureComponent {
|
|||
select(
|
||||
{
|
||||
className: "perf-settings-dir-list",
|
||||
size: "4",
|
||||
size: 4,
|
||||
ref: this._takeListBoxRef,
|
||||
},
|
||||
dirs.map((fullPath, i) =>
|
||||
|
|
|
@ -1,6 +1,40 @@
|
|||
/* 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 {PerfFront} perfFront
|
||||
* @property {RecordingState} recordingState
|
||||
* @property {boolean?} isSupportedPlatform
|
||||
* @property {boolean?} isPopup
|
||||
* @property {string | null} promptEnvRestart
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ThunkDispatchProps
|
||||
* @property {typeof actions.changeRecordingState} changeRecordingState
|
||||
* @property {typeof actions.reportProfilerReady} reportProfilerReady
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ResolveThunks<ThunkDispatchProps>} DispatchProps
|
||||
* @typedef {StateProps & DispatchProps} Props
|
||||
* @typedef {import("../@types/perf").PerfFront} PerfFront
|
||||
* @typedef {import("../@types/perf").RecordingState} RecordingState
|
||||
* @typedef {import("../@types/perf").State} StoreState
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import("../@types/perf").PanelWindow} PanelWindow
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
|
@ -12,7 +46,6 @@ const {
|
|||
div,
|
||||
button,
|
||||
} = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const RecordingButton = createFactory(
|
||||
require("devtools/client/performance-new/components/RecordingButton.js")
|
||||
);
|
||||
|
@ -38,23 +71,11 @@ const {
|
|||
*
|
||||
* 2) It mounts all of the sub components, but is itself very light on actual
|
||||
* markup for presentation.
|
||||
*
|
||||
* @extends {React.PureComponent<Props>}
|
||||
*/
|
||||
class Perf extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
// StateProps:
|
||||
perfFront: PropTypes.object.isRequired,
|
||||
recordingState: PropTypes.string.isRequired,
|
||||
isSupportedPlatform: PropTypes.bool,
|
||||
isPopup: PropTypes.bool,
|
||||
promptEnvRestart: PropTypes.string,
|
||||
|
||||
// DispatchProps:
|
||||
changeRecordingState: PropTypes.func.isRequired,
|
||||
reportProfilerReady: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
/** @param {Props} props */
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleProfilerStarting = this.handleProfilerStarting.bind(this);
|
||||
|
@ -103,8 +124,12 @@ class Perf extends PureComponent {
|
|||
// it will show. This defers the initial visibility of the popup until the
|
||||
// React components have fully rendered, and thus there is no annoying "blip"
|
||||
// to the screen when the page goes from fully blank, to showing the content.
|
||||
if (window.gReportReady) {
|
||||
window.gReportReady();
|
||||
/** @type {any} */
|
||||
const anyWindow = window;
|
||||
/** @type {PanelWindow} - Coerce the window into the PanelWindow. */
|
||||
const { gReportReady } = anyWindow;
|
||||
if (gReportReady) {
|
||||
gReportReady();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -302,6 +327,10 @@ class Perf extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {StoreState} state
|
||||
* @returns {StateProps}
|
||||
*/
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
perfFront: selectors.getPerfFront(state),
|
||||
|
@ -312,6 +341,7 @@ function mapStateToProps(state) {
|
|||
};
|
||||
}
|
||||
|
||||
/** @type {ThunkDispatchProps} */
|
||||
const mapDispatchToProps = {
|
||||
changeRecordingState: actions.changeRecordingState,
|
||||
reportProfilerReady: actions.reportProfilerReady,
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
/* 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
|
||||
|
||||
/**
|
||||
* @typedef {import("../@types/perf").ScaleFunctions} ScaleFunctions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Props
|
||||
* @property {number} value
|
||||
* @property {string} label
|
||||
* @property {string} id
|
||||
* @property {ScaleFunctions} scale
|
||||
* @property {(value: number) => unknown} onChange
|
||||
* @property {(value: number) => React.ReactNode} display
|
||||
*/
|
||||
"use strict";
|
||||
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const {
|
||||
div,
|
||||
input,
|
||||
|
@ -12,28 +26,22 @@ const {
|
|||
|
||||
/**
|
||||
* Provide a numeric range slider UI that works off of custom numeric scales.
|
||||
* @extends React.PureComponent<Props>
|
||||
*/
|
||||
class Range extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
value: PropTypes.number.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
scale: PropTypes.object.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
display: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
/** @param {Props} props */
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleInput = this.handleInput.bind(this);
|
||||
}
|
||||
|
||||
handleInput(e) {
|
||||
e.preventDefault();
|
||||
/**
|
||||
* @param {React.ChangeEvent<HTMLInputElement>} event
|
||||
*/
|
||||
handleInput(event) {
|
||||
event.preventDefault();
|
||||
const { scale, onChange } = this.props;
|
||||
const frac = e.target.value / 100;
|
||||
const frac = Number(event.target.value) / 100;
|
||||
onChange(scale.fromFractionToSingleDigitValue(frac));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,36 @@
|
|||
/* 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 {RecordingState} recordingState
|
||||
* @property {boolean} isSupportedPlatform
|
||||
* @property {boolean} recordingUnexpectedlyStopped
|
||||
* @property {boolean} isPopup
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ThunkDispatchProps
|
||||
* @property {typeof actions.startRecording} startRecording
|
||||
* @property {typeof actions.getProfileAndStopProfiler} getProfileAndStopProfiler
|
||||
* @property {typeof actions.stopProfilerAndDiscardProfile} stopProfilerAndDiscardProfile
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ResolveThunks<ThunkDispatchProps>} DispatchProps
|
||||
* @typedef {StateProps & DispatchProps} Props
|
||||
* @typedef {import("../@types/perf").RecordingState} RecordingState
|
||||
* @typedef {import("../@types/perf").State} StoreState
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
|
@ -10,7 +40,6 @@ const {
|
|||
span,
|
||||
img,
|
||||
} = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
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");
|
||||
|
@ -19,29 +48,30 @@ const selectors = require("devtools/client/performance-new/store/selectors");
|
|||
* This component is not responsible for the full life cycle of recording a profile. It
|
||||
* is only responsible for the actual act of stopping and starting recordings. It
|
||||
* also reacts to the changes of the recording state from external changes.
|
||||
*
|
||||
* @extends {React.PureComponent<Props>}
|
||||
*/
|
||||
class RecordingButton extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
// StateProps
|
||||
recordingState: PropTypes.string.isRequired,
|
||||
isSupportedPlatform: PropTypes.bool,
|
||||
recordingUnexpectedlyStopped: PropTypes.bool.isRequired,
|
||||
isPopup: PropTypes.bool.isRequired,
|
||||
|
||||
// DispatchProps
|
||||
startRecording: PropTypes.func.isRequired,
|
||||
getProfileAndStopProfiler: PropTypes.func.isRequired,
|
||||
stopProfilerAndDiscardProfile: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
/** @param {Props} props */
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._getProfileAndStopProfiler = () =>
|
||||
this.props.getProfileAndStopProfiler(window);
|
||||
}
|
||||
|
||||
/** @param {{
|
||||
* disabled?: boolean,
|
||||
* label?: React.ReactNode,
|
||||
* onClick?: any,
|
||||
* additionalMessage?: React.ReactNode,
|
||||
* isPrimary?: boolean,
|
||||
* isPopup?: boolean,
|
||||
* additionalButton?: {
|
||||
* label: string,
|
||||
* onClick: any,
|
||||
* },
|
||||
* }} buttonSettings
|
||||
*/
|
||||
renderButton(buttonSettings) {
|
||||
const {
|
||||
disabled,
|
||||
|
@ -70,7 +100,6 @@ class RecordingButton extends PureComponent {
|
|||
button(
|
||||
{
|
||||
className: `perf-photon-button perf-photon-button-${buttonClass} perf-button`,
|
||||
"data-standalone": true,
|
||||
disabled,
|
||||
onClick,
|
||||
},
|
||||
|
@ -80,7 +109,6 @@ class RecordingButton extends PureComponent {
|
|||
? button(
|
||||
{
|
||||
className: `perf-photon-button perf-photon-button-default perf-button`,
|
||||
"data-standalone": true,
|
||||
onClick: additionalButton.onClick,
|
||||
disabled,
|
||||
},
|
||||
|
@ -184,6 +212,10 @@ class RecordingButton extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {StoreState} state
|
||||
* @returns {StateProps}
|
||||
*/
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
recordingState: selectors.getRecordingState(state),
|
||||
|
@ -195,6 +227,7 @@ function mapStateToProps(state) {
|
|||
};
|
||||
}
|
||||
|
||||
/** @type {ThunkDispatchProps} */
|
||||
const mapDispatchToProps = {
|
||||
startRecording: actions.startRecording,
|
||||
stopProfilerAndDiscardProfile: actions.stopProfilerAndDiscardProfile,
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* 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
|
||||
/* eslint-disable react/prop-types */
|
||||
|
||||
/**
|
||||
* @typedef {Object} StateProps
|
||||
|
@ -34,7 +33,6 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import("react")} React
|
||||
* @typedef {import("../@types/perf").PopupWindow} PopupWindow
|
||||
* @typedef {import("../@types/perf").State} StoreState
|
||||
* @typedef {StateProps & DispatchProps} Props
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
* 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
|
||||
/**
|
||||
* @typedef {import("./@types/perf").NumberScaler} NumberScaler
|
||||
* @typedef {import("./@types/perf").ScaleFunctions} ScaleFunctions
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -64,25 +68,13 @@ function formatFileSize(num) {
|
|||
return (neg ? "-" : "") + numStr + " " + unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale a number value.
|
||||
*
|
||||
* @callback NumberScaler
|
||||
* @param {number} value
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates numbers that scale exponentially.
|
||||
*
|
||||
* @param {number} rangeStart
|
||||
* @param {number} rangeEnd
|
||||
*
|
||||
* @returns {{
|
||||
* fromFractionToValue: NumberScaler,
|
||||
* fromValueToFraction: NumberScaler,
|
||||
* fromFractionToSingleDigitValue: NumberScaler,
|
||||
* }}
|
||||
* @returns {ScaleFunctions}
|
||||
*/
|
||||
function makeExponentialScale(rangeStart, rangeEnd) {
|
||||
const startExp = Math.log(rangeStart);
|
||||
|
|
|
@ -244,6 +244,24 @@ class ActorReadyGeckoProfilerInterface {
|
|||
}
|
||||
return Services.profiler.GetFeatures();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} type
|
||||
* @param {() => void} listener
|
||||
*/
|
||||
on(type, listener) {
|
||||
// This is a stub for TypeScript. This function is assigned by the EventEmitter
|
||||
// decorator.
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} type
|
||||
* @param {() => void} listener
|
||||
*/
|
||||
off(type, listener) {
|
||||
// This is a stub for TypeScript. This function is assigned by the EventEmitter
|
||||
// decorator.
|
||||
}
|
||||
}
|
||||
|
||||
exports.ActorReadyGeckoProfilerInterface = ActorReadyGeckoProfilerInterface;
|
||||
|
|
Загрузка…
Ссылка в новой задаче