diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /devtools/client/performance/panel.js | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | devtools/client/performance/panel.js | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/devtools/client/performance/panel.js b/devtools/client/performance/panel.js new file mode 100644 index 0000000000..28fef793f0 --- /dev/null +++ b/devtools/client/performance/panel.js @@ -0,0 +1,162 @@ +/* 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"; + +loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter"); + +function PerformancePanel(iframeWindow, toolbox) { + this.panelWin = iframeWindow; + this.toolbox = toolbox; + this._targetAvailablePromise = Promise.resolve(); + + this._onTargetAvailable = this._onTargetAvailable.bind(this); + + EventEmitter.decorate(this); +} + +exports.PerformancePanel = PerformancePanel; + +PerformancePanel.prototype = { + /** + * Open is effectively an asynchronous constructor. + * + * @return object + * A promise that is resolved when the Performance tool + * completes opening. + */ + async open() { + if (this._opening) { + return this._opening; + } + + this._checkRecordingStatus = this._checkRecordingStatus.bind(this); + + const { PerformanceController, EVENTS } = this.panelWin; + PerformanceController.on( + EVENTS.RECORDING_ADDED, + this._checkRecordingStatus + ); + PerformanceController.on( + EVENTS.RECORDING_STATE_CHANGE, + this._checkRecordingStatus + ); + + // In case that the target is switched across process, the corresponding front also + // will be changed. In order to detect that, watch the change. + // Also, we wait for `watchTargets` to end. Indeed the function `_onTargetAvailable + // will be called synchronously with current target as a parameter by + // the `watchTargets` function. + // So this `await` waits for initialization with current target, happening + // in `_onTargetAvailable`. + await this.toolbox.targetList.watchTargets( + [this.toolbox.targetList.TYPES.FRAME], + this._onTargetAvailable + ); + + // Fire this once incase we have an in-progress recording (console profile) + // that caused this start up, and no state change yet, so we can highlight the + // tab if we need. + this._checkRecordingStatus(); + + this.isReady = true; + this.emit("ready"); + + this._opening = new Promise(resolve => { + resolve(this); + }); + return this._opening; + }, + + // DevToolPanel API + + get target() { + return this.toolbox.target; + }, + + async destroy() { + // Make sure this panel is not already destroyed. + if (this._destroyed) { + return; + } + + const { PerformanceController, PerformanceView, EVENTS } = this.panelWin; + PerformanceController.off( + EVENTS.RECORDING_ADDED, + this._checkRecordingStatus + ); + PerformanceController.off( + EVENTS.RECORDING_STATE_CHANGE, + this._checkRecordingStatus + ); + + this.toolbox.targetList.unwatchTargets( + [this.toolbox.targetList.TYPES.FRAME], + this._onTargetAvailable + ); + await PerformanceController.destroy(); + await PerformanceView.destroy(); + PerformanceController.disableFrontEventListeners(); + + this.emit("destroyed"); + this._destroyed = true; + }, + + _checkRecordingStatus: function() { + if (this.panelWin.PerformanceController.isRecording()) { + this.toolbox.highlightTool("performance"); + } else { + this.toolbox.unhighlightTool("performance"); + } + }, + + /** + * This function executes actual logic for the target-switching. + * + * @param {TargetFront} - targetFront + * As we are watching only FRAME type for this panel, + * the target should be a instance of BrowsingContextTarget. + */ + async _handleTargetAvailable({ targetFront }) { + if (targetFront.isTopLevel) { + const { PerformanceController, PerformanceView } = this.panelWin; + const performanceFront = await targetFront.getFront("performance"); + + if (!this._isPanelInitialized) { + await PerformanceController.initialize( + this.toolbox, + targetFront, + performanceFront + ); + await PerformanceView.initialize(); + PerformanceController.enableFrontEventListeners(); + this._isPanelInitialized = true; + } else { + const isRecording = PerformanceController.isRecording(); + if (isRecording) { + await PerformanceController.stopRecording(); + } + + PerformanceView.resetBufferStatus(); + PerformanceController.updateFronts(targetFront, performanceFront); + + if (isRecording) { + await PerformanceController.startRecording(); + } + } + } + }, + + /** + * This function is called for every target is available. + */ + _onTargetAvailable(parameters) { + // As this function is called asynchronous, while previous processing, this might be + // called. Thus, we wait until finishing previous one before starting next. + this._targetAvailablePromise = this._targetAvailablePromise.then(() => + this._handleTargetAvailable(parameters) + ); + + return this._targetAvailablePromise; + }, +}; |