--- a/devtools/client/locales/en-US/performance.dtd
+++ b/devtools/client/locales/en-US/performance.dtd
@@ -6,21 +6,16 @@
<!-- LOCALIZATION NOTE : FILE Do not translate commandkey -->
<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
- keep it in English, or another language commonly spoken among web developers.
- You want to make that choice consistent across the developer tools.
- A good criteria is the language in which you'd find the best
- documentation on web development on the web. -->
-<!-- LOCALIZATION NOTE (performanceUI.startRecording/performanceUI.stopRecording): These are
- - the labels shown on the main recording buttons to start/stop recording. -->
-<!ENTITY performanceUI.startRecording "Start Recording Performance">
-<!ENTITY performanceUI.stopRecording "Stop Recording Performance">
-
<!-- LOCALIZATION NOTE (performanceUI.bufferStatusTooltip): This string
- is displayed as the tooltip for the buffer capacity during a recording. -->
<!ENTITY performanceUI.bufferStatusTooltip "The profiler stores samples in a circular buffer, and once the buffer reaches the limit for a recording, newer samples begin to overwrite samples at the beginning of the recording.">
<!-- LOCALIZATION NOTE (performanceUI.disabledRealTime.nonE10SBuild): This string
- is displayed as a message for why the real time overview graph is disabled
- when running on a non-multiprocess build. -->
<!ENTITY performanceUI.disabledRealTime.nonE10SBuild "Realtime recording data disabled on non-multiprocess Firefox.">
@@ -38,28 +33,16 @@
- in the details view while the profiler is unavailable, for example, while
- in Private Browsing mode. -->
<!ENTITY performanceUI.unavailableNoticePB "Recording a profile is currently unavailable. Please close all private browsing windows and try again.">
<!-- LOCALIZATION NOTE (performanceUI.loadingNotice): This is the label shown
- in the details view while loading a profile. -->
<!ENTITY performanceUI.loadingNotice "Loading…">
-<!-- LOCALIZATION NOTE (performanceUI.recordButton): This string is displayed
- - on a button that starts a new profile. -->
-<!ENTITY performanceUI.recordButton.tooltip "Toggle the recording state of a performance recording.">
-
-<!-- LOCALIZATION NOTE (performanceUI.importButton): This string is displayed
- - on a button that opens a dialog to import a saved profile data file. -->
-<!ENTITY performanceUI.importButton "Import…">
-
-<!-- LOCALIZATION NOTE (performanceUI.clearButton): This string is displayed
- - on a button that removes all the recordings. -->
-<!ENTITY performanceUI.clearButton "Clear">
-
<!-- LOCALIZATION NOTE (performanceUI.toolbar.*): These strings are displayed
- in the toolbar on buttons that select which view is currently shown. -->
<!ENTITY performanceUI.toolbar.waterfall "Waterfall">
<!ENTITY performanceUI.toolbar.waterfall.tooltiptext "Shows the different operations the browser is performing during the recording, laid out sequentially as a waterfall.">
<!ENTITY performanceUI.toolbar.js-calltree "Call Tree">
<!ENTITY performanceUI.toolbar.js-calltree.tooltiptext "Highlights JavaScript functions where the browser spent most time during the recording.">
<!ENTITY performanceUI.toolbar.memory-calltree "Allocations">
<!ENTITY performanceUI.toolbar.allocations.tooltiptext "Shows where memory was allocated during the recording.">
--- a/devtools/client/locales/en-US/performance.properties
+++ b/devtools/client/locales/en-US/performance.properties
@@ -152,8 +152,28 @@ timeline.records=RECORDS
# LOCALIZATION NOTE (profiler.bufferFull):
# This string is displayed when recording, indicating how much of the
# buffer is currently be used.
# %S is the percentage of the buffer used -- there are two "%"s after to escape
# the % that is actually displayed.
# Example: "Buffer 54% full"
profiler.bufferFull=Buffer %S%% full
+
+# LOCALIZATION NOTE (recordings.start):
+# The label shown on the main recording buttons to start recording.
+recordings.start=Start Recording Performance
+
+# LOCALIZATION NOTE (recordings.stop):
+# The label shown on the main recording buttons to stop recording.
+recordings.stop=Stop Recording Performance
+
+# LOCALIZATION NOTE (recordings.start.tooltip):
+# This string is displayed as a tooltip on a button that starts a new profile.
+recordings.start.tooltip=Toggle the recording state of a performance recording.
+
+# LOCALIZATION NOTE (recordings.import.tooltip):
+# This string is displayed on a button that opens a dialog to import a saved profile data file.
+recordings.import.tooltip=Import…
+
+# LOCALIZATION NOTE (recordings.clear.tooltip):
+# This string is displayed on a button that removes all the recordings.
+recordings.clear.tooltip=Clear
--- a/devtools/client/performance/components/moz.build
+++ b/devtools/client/performance/components/moz.build
@@ -1,11 +1,13 @@
# vim: set filetype=python:
# 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/.
DevToolsModules(
'jit-optimizations-item.js',
'jit-optimizations.js',
+ 'recording-button.js',
+ 'recording-controls.js',
)
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
new file mode 100644
--- /dev/null
+++ b/devtools/client/performance/components/recording-button.js
@@ -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/. */
+"use strict";
+
+const {L10N} = require("devtools/client/performance/modules/global");
+const {DOM, createClass} = require("devtools/client/shared/vendor/react");
+const {button} = DOM;
+
+module.exports = createClass({
+ displayName: "Recording Button",
+
+ render() {
+ let {
+ onRecordButtonClick,
+ isRecording
+ } = this.props;
+
+ return button(
+ {
+ className: "devtools-toolbarbutton record-button",
+ onClick: onRecordButtonClick,
+ "data-standalone": "true",
+ "data-text-only": "true",
+ },
+ isRecording ? L10N.getStr("recordings.stop") : L10N.getStr("recordings.start")
+ );
+ }
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/performance/components/recording-controls.js
@@ -0,0 +1,70 @@
+/* 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 {L10N} = require("devtools/client/performance/modules/global");
+const {DOM, createClass} = require("devtools/client/shared/vendor/react");
+const {div, button} = DOM;
+
+module.exports = createClass({
+ displayName: "Recording Controls",
+
+ /**
+ * Manually handle the "checked" and "locked" attributes, as the DOM element won't
+ * change by just by changing the checked attribute through React.
+ */
+ componentDidUpdate() {
+ if (this.props.isRecording) {
+ this._recordButton.setAttribute("checked", true);
+ } else {
+ this._recordButton.removeAttribute("checked");
+ }
+
+ if (this.props.isLocked) {
+ this._recordButton.setAttribute("locked", true);
+ } else {
+ this._recordButton.removeAttribute("locked");
+ }
+ },
+
+ render() {
+ let {
+ onClearButtonClick,
+ onRecordButtonClick,
+ onImportButtonClick,
+ isRecording,
+ isLocked
+ } = this.props;
+
+ return (
+ div({ className: "devtools-toolbar" },
+ div({ className: "toolbar-group" },
+ button({
+ id: "clear-button",
+ className: "devtools-button",
+ title: L10N.getStr("recordings.clear.tooltip"),
+ onClick: onClearButtonClick
+ }),
+ button({
+ id: "main-record-button",
+ className: "devtools-button record-button",
+ title: L10N.getStr("recordings.start.tooltip"),
+ onClick: onRecordButtonClick,
+ checked: isRecording,
+ ref: (el) => {
+ this._recordButton = el;
+ },
+ locked: isLocked
+ }),
+ button({
+ id: "import-button",
+ className: "devtools-button",
+ title: L10N.getStr("recordings.import.tooltip"),
+ onClick: onImportButtonClick
+ })
+ )
+ )
+ );
+ }
+});
--- a/devtools/client/performance/modules/moz.build
+++ b/devtools/client/performance/modules/moz.build
@@ -12,9 +12,10 @@ DevToolsModules(
'categories.js',
'constants.js',
'global.js',
'io.js',
'marker-blueprint-utils.js',
'marker-dom-utils.js',
'marker-formatters.js',
'markers.js',
+ 'utils.js',
)
new file mode 100644
--- /dev/null
+++ b/devtools/client/performance/modules/utils.js
@@ -0,0 +1,21 @@
+/* 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";
+
+/* globals document */
+
+/**
+ * React components grab the namespace of the element they are mounting to. This function
+ * takes a XUL element, and makes sure to create a properly namespaced HTML element to
+ * avoid React creating XUL elements.
+ *
+ * {XULElement} xulElement
+ * return {HTMLElement} div
+ */
+
+exports.createHtmlMount = function (xulElement) {
+ let htmlElement = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+ xulElement.appendChild(htmlElement);
+ return htmlElement;
+};
--- a/devtools/client/performance/performance-controller.js
+++ b/devtools/client/performance/performance-controller.js
@@ -21,36 +21,41 @@ var { gDevTools } = require("devtools/cl
// Events emitted by various objects in the panel.
var EVENTS = require("devtools/client/performance/events");
Object.defineProperty(this, "EVENTS", {
value: EVENTS,
enumerable: true,
writable: false
});
-/* exported React, ReactDOM, JITOptimizationsView, Services, promise, EventEmitter,
- DevToolsUtils, system */
+/* exported React, ReactDOM, JITOptimizationsView, RecordingControls, RecordingButton,
+ Services, promise, EventEmitter, DevToolsUtils, system */
var React = require("devtools/client/shared/vendor/react");
var ReactDOM = require("devtools/client/shared/vendor/react-dom");
var JITOptimizationsView = React.createFactory(require("devtools/client/performance/components/jit-optimizations"));
+var RecordingControls = React.createFactory(require("devtools/client/performance/components/recording-controls"));
+var RecordingButton = React.createFactory(require("devtools/client/performance/components/recording-button"));
+
var Services = require("Services");
var promise = require("promise");
var EventEmitter = require("devtools/shared/event-emitter");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var flags = require("devtools/shared/flags");
var system = require("devtools/shared/system");
// Logic modules
/* exported L10N, PerformanceTelemetry, TIMELINE_BLUEPRINT, RecordingUtils,
- OptimizationsGraph, GraphsController, WaterfallHeader, MarkerView, MarkerDetails,
- MarkerBlueprintUtils, WaterfallUtils, FrameUtils, CallView, ThreadNode, FrameNode */
+ PerformanceUtils, OptimizationsGraph, GraphsController, WaterfallHeader, MarkerView,
+ MarkerDetails, MarkerBlueprintUtils, WaterfallUtils, FrameUtils, CallView, ThreadNode,
+ FrameNode */
var { L10N } = require("devtools/client/performance/modules/global");
var { PerformanceTelemetry } = require("devtools/client/performance/modules/logic/telemetry");
var { TIMELINE_BLUEPRINT } = require("devtools/client/performance/modules/markers");
var RecordingUtils = require("devtools/shared/performance/recording-utils");
+var PerformanceUtils = require("devtools/client/performance/modules/utils");
var { OptimizationsGraph, GraphsController } = require("devtools/client/performance/modules/widgets/graphs");
var { WaterfallHeader } = require("devtools/client/performance/modules/widgets/waterfall-ticks");
var { MarkerView } = require("devtools/client/performance/modules/widgets/marker-view");
var { MarkerDetails } = require("devtools/client/performance/modules/widgets/marker-details");
var { MarkerBlueprintUtils } = require("devtools/client/performance/modules/marker-blueprint-utils");
var WaterfallUtils = require("devtools/client/performance/modules/logic/waterfall-utils");
var FrameUtils = require("devtools/client/performance/modules/logic/frame-utils");
var { CallView } = require("devtools/client/performance/modules/widgets/tree-view");
--- a/devtools/client/performance/performance-view.js
+++ b/devtools/client/performance/performance-view.js
@@ -111,34 +111,24 @@ var PerformanceView = {
},
]
},
/**
* Sets up the view with event binding and main subviews.
*/
initialize: Task.async(function* () {
- this._recordButton = $("#main-record-button");
- this._importButton = $("#import-button");
- this._clearButton = $("#clear-button");
-
this._onRecordButtonClick = this._onRecordButtonClick.bind(this);
this._onImportButtonClick = this._onImportButtonClick.bind(this);
this._onClearButtonClick = this._onClearButtonClick.bind(this);
this._onRecordingSelected = this._onRecordingSelected.bind(this);
this._onProfilerStatusUpdated = this._onProfilerStatusUpdated.bind(this);
this._onRecordingStateChange = this._onRecordingStateChange.bind(this);
this._onNewRecordingFailed = this._onNewRecordingFailed.bind(this);
- for (let button of $$(".record-button")) {
- button.addEventListener("click", this._onRecordButtonClick);
- }
- this._importButton.addEventListener("click", this._onImportButtonClick);
- this._clearButton.addEventListener("click", this._onClearButtonClick);
-
// Bind to controller events to unlock the record button
PerformanceController.on(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
PerformanceController.on(EVENTS.RECORDING_PROFILER_STATUS_UPDATE,
this._onProfilerStatusUpdated);
PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange);
PerformanceController.on(EVENTS.RECORDING_ADDED, this._onRecordingStateChange);
PerformanceController.on(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START,
this._onNewRecordingFailed);
@@ -150,28 +140,49 @@ var PerformanceView = {
}
// Initialize the ToolbarView first, because other views may need access
// to the OptionsView via the controller, to read prefs.
yield ToolbarView.initialize();
yield RecordingsView.initialize();
yield OverviewView.initialize();
yield DetailsView.initialize();
+
+ // DE-XUL: Begin migrating the toolbar to React. Temporarily hold state here.
+ this._recordingControlsState = {
+ onRecordButtonClick: this._onRecordButtonClick,
+ onImportButtonClick: this._onImportButtonClick,
+ onClearButtonClick: this._onClearButtonClick,
+ isRecording: false,
+ isDisabled: false
+ };
+ // Mount to an HTML element.
+ const {createHtmlMount} = PerformanceUtils;
+ this._recordingControlsMount = createHtmlMount($("#recording-controls-mount"));
+ this._recordingButtonsMounts = Array.from($$(".recording-button-mount"))
+ .map(createHtmlMount);
+
+ this._renderRecordingControls();
}),
/**
+ * DE-XUL: Render the recording controls and buttons using React.
+ */
+ _renderRecordingControls: function () {
+ ReactDOM.render(RecordingControls(this._recordingControlsState),
+ this._recordingControlsMount);
+ for (let button of this._recordingButtonsMounts) {
+ ReactDOM.render(RecordingButton(this._recordingControlsState), button);
+ }
+ },
+
+ /**
* Unbinds events and destroys subviews.
*/
destroy: Task.async(function* () {
- for (let button of $$(".record-button")) {
- button.removeEventListener("click", this._onRecordButtonClick);
- }
- this._importButton.removeEventListener("click", this._onImportButtonClick);
- this._clearButton.removeEventListener("click", this._onClearButtonClick);
-
PerformanceController.off(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
PerformanceController.off(EVENTS.RECORDING_PROFILER_STATUS_UPDATE,
this._onProfilerStatusUpdated);
PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE,
this._onRecordingStateChange);
PerformanceController.off(EVENTS.RECORDING_ADDED, this._onRecordingStateChange);
PerformanceController.off(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START,
this._onNewRecordingFailed);
@@ -269,39 +280,29 @@ var PerformanceView = {
/**
* Toggles the `locked` attribute on the record buttons based
* on `lock`.
*
* @param {boolean} lock
*/
_lockRecordButtons: function (lock) {
- for (let button of $$(".record-button")) {
- if (lock) {
- button.setAttribute("locked", "true");
- } else {
- button.removeAttribute("locked");
- }
- }
+ this._recordingControlsState.isLocked = lock;
+ this._renderRecordingControls();
},
/*
* Toggles the `checked` attribute on the record buttons based
* on `activate`.
*
* @param {boolean} activate
*/
_toggleRecordButtons: function (activate) {
- for (let button of $$(".record-button")) {
- if (activate) {
- button.setAttribute("checked", "true");
- } else {
- button.removeAttribute("checked");
- }
- }
+ this._recordingControlsState.isRecording = !!activate;
+ this._renderRecordingControls();
},
/**
* When a recording has started.
*/
_onRecordingStateChange: function () {
let currentRecording = PerformanceController.getCurrentRecording();
let recordings = PerformanceController.getRecordings();
@@ -334,17 +335,17 @@ var PerformanceView = {
_onClearButtonClick: function (e) {
this.emit(EVENTS.UI_CLEAR_RECORDINGS);
},
/**
* Handler for clicking the record button.
*/
_onRecordButtonClick: function (e) {
- if (this._recordButton.hasAttribute("checked")) {
+ if (this._recordingControlsState.isRecording) {
this.emit(EVENTS.UI_STOP_RECORDING);
} else {
this._lockRecordButtons(true);
this._toggleRecordButtons(true);
this.emit(EVENTS.UI_START_RECORDING);
}
},
--- a/devtools/client/performance/performance.xul
+++ b/devtools/client/performance/performance.xul
@@ -8,17 +8,18 @@
<?xml-stylesheet href="chrome://devtools/skin/performance.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/jit-optimizations.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/components-frame.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % performanceDTD SYSTEM "chrome://devtools/locale/performance.dtd">
%performanceDTD;
]>
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml">
<script src="chrome://devtools/content/shared/theme-switching.js"/>
<script type="application/javascript" src="performance-controller.js"/>
<script type="application/javascript" src="performance-view.js"/>
<script type="application/javascript" src="views/overview.js"/>
<script type="application/javascript" src="views/toolbar.js"/>
<script type="application/javascript" src="views/details-abstract-subview.js"/>
<script type="application/javascript" src="views/details-waterfall.js"/>
<script type="application/javascript" src="views/details-js-call-tree.js"/>
@@ -71,35 +72,23 @@
<menuitem id="option-flatten-tree-recursion"
type="checkbox"
data-pref="flatten-tree-recursion"
label="&performanceUI.flattenTreeRecursion;"
tooltiptext="&performanceUI.flattenTreeRecursion.tooltiptext;"/>
</menupopup>
</popupset>
- <hbox id="body" class="theme-body" flex="1">
+ <hbox id="body" class="theme-body performance-tool" flex="1">
<!-- Sidebar: controls and recording list -->
<vbox id="recordings-pane">
- <toolbar id="recordings-toolbar"
- class="devtools-toolbar">
- <hbox id="recordings-controls"
- class="devtools-toolbarbutton-group">
- <toolbarbutton id="clear-button"
- class="devtools-toolbarbutton devtools-clear-icon"
- tooltiptext="&performanceUI.clearButton;"/>
- <toolbarbutton id="main-record-button"
- class="devtools-toolbarbutton record-button"
- tooltiptext="&performanceUI.recordButton.tooltip;"/>
- <toolbarbutton id="import-button"
- class="devtools-toolbarbutton"
- tooltiptext="&performanceUI.importButton;"/>
- </hbox>
- </toolbar>
+ <hbox id="recordings-controls">
+ <html:div id='recording-controls-mount'/>
+ </hbox>
<vbox id="recordings-list" class="theme-sidebar" flex="1"/>
</vbox>
<!-- Main panel content -->
<vbox id="performance-pane" flex="1">
<!-- Top toolbar controls -->
<toolbar id="performance-toolbar"
@@ -165,38 +154,32 @@
<!-- "Unavailable" notice, shown when the entire tool is disabled,
for example, when in private browsing mode. -->
<vbox id="unavailable-notice"
class="notice-container"
align="center"
pack="center"
flex="1">
- <hbox class="devtools-toolbarbutton-group"
- pack="center">
- <toolbarbutton class="devtools-toolbarbutton record-button"
- label="&performanceUI.startRecording;"
- standalone="true"/>
+ <hbox pack="center">
+ <html:div class='recording-button-mount'/>
</hbox>
<description class="tool-disabled-message">
&performanceUI.unavailableNoticePB;
</description>
</vbox>
<!-- "Empty" notice, shown when there's no recordings available -->
<hbox id="empty-notice"
class="notice-container"
align="center"
pack="center"
flex="1">
- <hbox class="devtools-toolbarbutton-group"
- pack="center">
- <toolbarbutton class="devtools-toolbarbutton record-button"
- label="&performanceUI.startRecording;"
- standalone="true"/>
+ <hbox pack="center">
+ <html:div class='recording-button-mount'/>
</hbox>
</hbox>
<!-- Recording contents -->
<vbox id="performance-view-content" flex="1">
<!-- Overview graphs -->
<vbox id="overview-pane">
@@ -218,21 +201,18 @@
</hbox>
<!-- "Recording" notice, shown when a recording is in progress -->
<vbox id="recording-notice"
class="notice-container"
align="center"
pack="center"
flex="1">
- <hbox class="devtools-toolbarbutton-group"
- pack="center">
- <toolbarbutton class="devtools-toolbarbutton record-button"
- label="&performanceUI.stopRecording;"
- standalone="true"/>
+ <hbox pack="center">
+ <html:div class='recording-button-mount'/>
</hbox>
<label class="realtime-disabled-message"
value="&performanceUI.disabledRealTime.nonE10SBuild;"/>
<label class="realtime-disabled-on-e10s-message"
value="&performanceUI.disabledRealTime.disabledE10S;"/>
<label class="buffer-status-message"
tooltiptext="&performanceUI.bufferStatusTooltip;"/>
<label class="buffer-status-message-full"
--- a/devtools/client/themes/performance.css
+++ b/devtools/client/themes/performance.css
@@ -23,16 +23,24 @@
.theme-firebug {
--cell-border-color: rgba(0,0,0,0.15);
--cell-border-color-light: rgba(0,0,0,0.1);
--focus-cell-border-color: rgba(0,0,0,0.3);
--row-alt-background-color: rgba(76,158,217,0.1);
--row-hover-background-color: rgba(76,158,217,0.2);
}
+/*
+ * DE-XUL: Set a sidebar width because inline XUL components will cause the flex
+ * to overflow if dynamically sized.
+ */
+.performance-tool {
+ --sidebar-width: 185px;
+}
+
/**
* A generic class to hide elements, replacing the `element.hidden` attribute
* that we use to hide elements that can later be active
*/
.hidden {
display: none;
width: 0px;
height: 0px;
@@ -79,22 +87,26 @@
}
#select-optimizations-view {
list-style-image: url(images/profiler-stopwatch.svg);
}
/* Recording buttons */
-#main-record-button {
- list-style-image: url(images/profiler-stopwatch.svg);
+#clear-button::before {
+ background-image: var(--clear-icon-url);
}
-#import-button {
- list-style-image: url(images/import.svg);
+#main-record-button::before {
+ background-image: url(images/profiler-stopwatch.svg);
+}
+
+#import-button::before {
+ background-image: url(images/import.svg);
}
#main-record-button .button-icon, #import-button .button-icon {
margin: 0;
}
#main-record-button .button-text, #import-button .button-text {
display: none;
@@ -114,16 +126,32 @@
pointer-events: none;
opacity: 0.5;
}
/* Sidebar & recording items */
#recordings-pane {
border-inline-end: 1px solid var(--theme-splitter-color);
+ width: var(--sidebar-width);
+}
+
+#recording-controls-mount {
+ width: var(--sidebar-width);
+}
+
+#recording-controls-mount > div {
+ width: var(--sidebar-width);
+}
+
+/*
+ * DE-XUL: The height of the toolbar is not correct without tweaking the line-height.
+ */
+#recordings-pane .devtools-toolbar {
+ line-height: 0;
}
#recordings-list {
max-width: 300px;
}
.recording-item {
padding: 4px;