--- a/devtools/client/dom/content/components/dom-tree.js
+++ b/devtools/client/dom/content/components/dom-tree.js
@@ -1,63 +1,67 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* 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";
// React & Redux
-const React = require("devtools/client/shared/vendor/react");
+const { Component, createFactory } = require("devtools/client/shared/vendor/react");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+
const { connect } = require("devtools/client/shared/vendor/react-redux");
-const TreeView = React.createFactory(require("devtools/client/shared/components/tree/TreeView"));
-
+const TreeView = createFactory(require("devtools/client/shared/components/tree/TreeView"));
// Reps
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
const { Rep } = REPS;
+
const Grip = REPS.Grip;
-
// DOM Panel
const { GripProvider } = require("../grip-provider");
+
const { DomDecorator } = require("../dom-decorator");
-// Shortcuts
-const PropTypes = React.PropTypes;
-
/**
* Renders DOM panel tree.
*/
-var DomTree = React.createClass({
- displayName: "DomTree",
+class DomTree extends Component {
+ static get propTypes() {
+ return {
+ dispatch: PropTypes.func.isRequired,
+ filter: PropTypes.string,
+ grips: PropTypes.object,
+ object: PropTypes.any,
+ openLink: PropTypes.func,
+ };
+ }
- propTypes: {
- dispatch: PropTypes.func.isRequired,
- filter: PropTypes.string,
- grips: PropTypes.object,
- object: PropTypes.any,
- openLink: PropTypes.func,
- },
+ constructor(props) {
+ super(props);
+ this.onFilter = this.onFilter.bind(this);
+ }
/**
* Filter DOM properties. Return true if the object
* should be visible in the tree.
*/
- onFilter: function (object) {
+ onFilter(object) {
if (!this.props.filter) {
return true;
}
return (object.name && object.name.indexOf(this.props.filter) > -1);
- },
+ }
/**
* Render DOM panel content
*/
- render: function () {
+ render() {
let {
dispatch,
grips,
object,
openLink,
} = this.props;
let columns = [{
@@ -82,17 +86,17 @@ var DomTree = React.createClass({
object,
onFilter: this.onFilter,
openLink,
provider: new GripProvider(grips, dispatch),
renderValue,
})
);
}
-});
+}
const mapStateToProps = (state) => {
return {
grips: state.grips,
filter: state.filter
};
};
--- a/devtools/client/dom/content/components/main-frame.js
+++ b/devtools/client/dom/content/components/main-frame.js
@@ -1,46 +1,47 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* 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/. */
- /* globals DomProvider */
+/* globals DomProvider */
"use strict";
// React & Redux
-const React = require("devtools/client/shared/vendor/react");
+const { Component, createFactory } = require("devtools/client/shared/vendor/react");
+const dom = 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");
-
// DOM Panel
-const DomTree = React.createFactory(require("./dom-tree"));
-const MainToolbar = React.createFactory(require("./main-toolbar"));
+const DomTree = createFactory(require("./dom-tree"));
+const MainToolbar = createFactory(require("./main-toolbar"));
// Shortcuts
-const { div } = React.DOM;
-const PropTypes = React.PropTypes;
+const { div } = dom;
/**
* Renders basic layout of the DOM panel. The DOM panel content consists
* from two main parts: toolbar and tree.
*/
-var MainFrame = React.createClass({
- displayName: "MainFrame",
-
- propTypes: {
- dispatch: PropTypes.func.isRequired,
- filter: PropTypes.string,
- object: PropTypes.any,
- },
+class MainFrame extends Component {
+ static get propTypes() {
+ return {
+ dispatch: PropTypes.func.isRequired,
+ filter: PropTypes.string,
+ object: PropTypes.any,
+ };
+ }
/**
* Render DOM panel content
*/
- render: function () {
+ render() {
let {
filter,
object,
} = this.props;
return (
div({className: "mainFrame"},
MainToolbar({
@@ -52,17 +53,17 @@ var MainFrame = React.createClass({
filter,
object,
openLink: url => DomProvider.openLink(url),
})
)
)
);
}
-});
+}
// Transform state into props
// Note: use https://github.com/faassen/reselect for better performance.
const mapStateToProps = (state) => {
return {
filter: state.filter
};
};
--- a/devtools/client/dom/content/components/main-toolbar.js
+++ b/devtools/client/dom/content/components/main-toolbar.js
@@ -1,54 +1,59 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* 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";
// React
-const React = require("devtools/client/shared/vendor/react");
+const { Component, createFactory } = require("devtools/client/shared/vendor/react");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+
const { l10n } = require("../utils");
-
// Reps
const { createFactories } = require("devtools/client/shared/react-utils");
+
const { Toolbar, ToolbarButton } = createFactories(require("devtools/client/jsonview/components/reps/Toolbar"));
// DOM Panel
-const SearchBox = React.createFactory(require("devtools/client/shared/components/SearchBox"));
-
+const SearchBox = createFactory(require("devtools/client/shared/components/SearchBox"));
// Actions
const { fetchProperties } = require("../actions/grips");
+
const { setVisibilityFilter } = require("../actions/filter");
-// Shortcuts
-const PropTypes = React.PropTypes;
-
/**
* This template is responsible for rendering a toolbar
* within the 'Headers' panel.
*/
-var MainToolbar = React.createClass({
- displayName: "MainToolbar",
-
- propTypes: {
- object: PropTypes.any.isRequired,
- dispatch: PropTypes.func.isRequired,
- },
+class MainToolbar extends Component {
+ static get propTypes() {
+ return {
+ object: PropTypes.any.isRequired,
+ dispatch: PropTypes.func.isRequired,
+ };
+ }
- onRefresh: function () {
- this.props.dispatch(fetchProperties(this.props.object));
- },
+ constructor(props) {
+ super(props);
+ this.onRefresh = this.onRefresh.bind(this);
+ this.onSearch = this.onSearch.bind(this);
+ }
- onSearch: function (value) {
+ onRefresh() {
+ this.props.dispatch(fetchProperties(this.props.object));
+ }
+
+ onSearch(value) {
this.props.dispatch(setVisibilityFilter(value));
- },
+ }
- render: function () {
+ render() {
return (
Toolbar({},
ToolbarButton({
className: "refresh devtools-button",
id: "dom-refresh-button",
title: l10n.getStr("dom.refresh"),
onClick: this.onRefresh
}),
@@ -56,12 +61,12 @@ var MainToolbar = React.createClass({
delay: 250,
onChange: this.onSearch,
placeholder: l10n.getStr("dom.filterDOMPanel"),
type: "filter"
})
)
);
}
-});
+}
// Exports from this module
module.exports = MainToolbar;
--- a/devtools/client/performance/components/jit-optimizations-item.js
+++ b/devtools/client/performance/components/jit-optimizations-item.js
@@ -2,18 +2,20 @@
* 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 { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "devtools/client/locales/jit-optimizations.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
-const {PluralForm} = require("devtools/shared/plural-form");
-const { DOM: dom, PropTypes, createClass, createFactory } = require("devtools/client/shared/vendor/react");
+const { PluralForm } = require("devtools/shared/plural-form");
+const { Component, createFactory } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const Frame = createFactory(require("devtools/client/shared/components/Frame"));
const PROPNAME_MAX_LENGTH = 4;
// If TREE_ROW_HEIGHT changes, be sure to change `var(--jit-tree-row-height)`
// in `devtools/client/themes/jit-optimizations.css`
const TREE_ROW_HEIGHT = 14;
const OPTIMIZATION_ITEM_TYPES = ["site", "attempts", "types", "attempt", "type",
"observedtype"];
@@ -25,30 +27,41 @@ const OPTIMIZATION_ITEM_TYPES = ["site",
*/
const {
JITOptimizations, hasSuccessfulOutcome, isSuccessfulOutcome
} = require("devtools/client/performance/modules/logic/jit");
const OPTIMIZATION_FAILURE = L10N.getStr("jit.optimizationFailure");
const JIT_SAMPLES = L10N.getStr("jit.samples");
const JIT_TYPES = L10N.getStr("jit.types");
const JIT_ATTEMPTS = L10N.getStr("jit.attempts");
+
/* eslint-enable no-unused-vars */
-const JITOptimizationsItem = createClass({
- displayName: "JITOptimizationsItem",
+class JITOptimizationsItem extends Component {
+ static get propTypes() {
+ return {
+ onViewSourceInDebugger: PropTypes.func.isRequired,
+ frameData: PropTypes.object.isRequired,
+ type: PropTypes.oneOf(OPTIMIZATION_ITEM_TYPES).isRequired,
+ depth: PropTypes.number.isRequired,
+ arrow: PropTypes.element.isRequired,
+ item: PropTypes.object,
+ focused: PropTypes.bool
+ };
+ }
- propTypes: {
- onViewSourceInDebugger: PropTypes.func.isRequired,
- frameData: PropTypes.object.isRequired,
- type: PropTypes.oneOf(OPTIMIZATION_ITEM_TYPES).isRequired,
- depth: PropTypes.number.isRequired,
- arrow: PropTypes.element.isRequired,
- item: PropTypes.object,
- focused: PropTypes.bool
- },
+ constructor(props) {
+ super(props);
+ this._renderSite = this._renderSite.bind(this);
+ this._renderAttempts = this._renderAttempts.bind(this);
+ this._renderTypes = this._renderTypes.bind(this);
+ this._renderAttempt = this._renderAttempt.bind(this);
+ this._renderType = this._renderType.bind(this);
+ this._renderObservedType = this._renderObservedType.bind(this);
+ }
_renderSite({ item: site, onViewSourceInDebugger, frameData }) {
let attempts = site.data.attempts;
let lastStrategy = attempts[attempts.length - 1].strategy;
let propString = "";
let propertyName = site.data.propertyName;
// Display property name if it exists
@@ -76,45 +89,45 @@ const JITOptimizationsItem = createClass
});
let children = [text, frame];
if (!hasSuccessfulOutcome(site)) {
children.unshift(dom.span({ className: "opt-icon warning" }));
}
return dom.span({ className: "optimization-site" }, ...children);
- },
+ }
_renderAttempts({ item: attempts }) {
return dom.span({ className: "optimization-attempts" },
`${JIT_ATTEMPTS} (${attempts.length})`
);
- },
+ }
_renderTypes({ item: types }) {
return dom.span({ className: "optimization-types" },
`${JIT_TYPES} (${types.length})`
);
- },
+ }
_renderAttempt({ item: attempt }) {
let success = isSuccessfulOutcome(attempt.outcome);
let { strategy, outcome } = attempt;
return dom.span({ className: "optimization-attempt" },
dom.span({ className: "optimization-strategy" }, strategy),
" → ",
dom.span({ className: `optimization-outcome ${success ? "success" : "failure"}` },
outcome)
);
- },
+ }
_renderType({ item: type }) {
return dom.span({ className: "optimization-ion-type" },
`${type.site}:${type.mirType}`);
- },
+ }
_renderObservedType({ onViewSourceInDebugger, item: type }) {
let children = [
dom.span({ className: "optimization-observed-type-keyed" },
`${type.keyedBy}${type.name ? ` → ${type.name}` : ""}`)
];
// If we have a line and location, make a link to the debugger
@@ -130,17 +143,17 @@ const JITOptimizationsItem = createClass
})
);
// Otherwise if we just have a location, it's probably just a memory location.
} else if (type.location) {
children.push(`@${type.location}`);
}
return dom.span({ className: "optimization-observed-type" }, ...children);
- },
+ }
render() {
/* eslint-disable no-unused-vars */
/**
* TODO - Re-enable this eslint rule. The JIT tool is a work in progress, and these
* undefined variables may represent intended functionality.
*/
let {
@@ -168,12 +181,12 @@ const JITOptimizationsItem = createClass
return dom.div(
{
className: `optimization-tree-item optimization-tree-item-${type}`,
style: { marginInlineStart: depth * TREE_ROW_HEIGHT }
},
arrow,
content
);
- },
-});
+ }
+}
module.exports = JITOptimizationsItem;
--- a/devtools/client/performance/components/jit-optimizations.js
+++ b/devtools/client/performance/components/jit-optimizations.js
@@ -3,17 +3,19 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "devtools/client/locales/jit-optimizations.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const { assert } = require("devtools/shared/DevToolsUtils");
-const { DOM: dom, createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react");
+const { Component, createFactory } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const Tree = createFactory(require("../../shared/components/Tree"));
const OptimizationsItem = createFactory(require("./jit-optimizations-item"));
const FrameView = createFactory(require("../../shared/components/Frame"));
const JIT_TITLE = L10N.getStr("jit.title");
// If TREE_ROW_HEIGHT changes, be sure to change `var(--jit-tree-row-height)`
// in `devtools/client/themes/jit-optimizations.css`
const TREE_ROW_HEIGHT = 14;
@@ -53,47 +55,52 @@ const optimizationSiteModel = {
line: PropTypes.number.isRequired,
column: PropTypes.number.isRequired,
data: PropTypes.shape({
attempts: PropTypes.arrayOf(optimizationAttemptModel).isRequired,
types: PropTypes.arrayOf(optimizationIonTypeModel).isRequired,
}).isRequired,
};
-const JITOptimizations = createClass({
- displayName: "JITOptimizations",
+class JITOptimizations extends Component {
+ static get propTypes() {
+ return {
+ onViewSourceInDebugger: PropTypes.func.isRequired,
+ frameData: PropTypes.object.isRequired,
+ optimizationSites: PropTypes.arrayOf(optimizationSiteModel).isRequired,
+ autoExpandDepth: PropTypes.number,
+ };
+ }
- propTypes: {
- onViewSourceInDebugger: PropTypes.func.isRequired,
- frameData: PropTypes.object.isRequired,
- optimizationSites: PropTypes.arrayOf(optimizationSiteModel).isRequired,
- autoExpandDepth: PropTypes.number,
- },
-
- getDefaultProps() {
+ static get defaultProps() {
return {
autoExpandDepth: 0
};
- },
+ }
- getInitialState() {
- return {
+ constructor(props) {
+ super(props);
+
+ this.state = {
expanded: new Set()
};
- },
+
+ this._createHeader = this._createHeader.bind(this);
+ this._createTree = this._createTree.bind(this);
+ }
/**
* Frame data generated from `frameNode.getInfo()`, or an empty
* object, as well as a handler for clicking on the frame component.
*
* @param {?Object} .frameData
* @param {Function} .onViewSourceInDebugger
* @return {ReactElement}
*/
- _createHeader: function ({ frameData, onViewSourceInDebugger }) {
+ _createHeader({ frameData, onViewSourceInDebugger }) {
let { isMetaCategory, url, line } = frameData;
let name = isMetaCategory ? frameData.categoryData.label :
frameData.functionName || "";
// Simulate `SavedFrame`s interface
let frame = { source: url, line: +line, functionDisplayName: name };
// Neither Meta Category nodes, or the lack of a selected frame node,
@@ -109,17 +116,17 @@ const JITOptimizations = createClass({
});
}
return dom.div({ className: "optimization-header" },
dom.span({ className: "header-title" }, JIT_TITLE),
dom.span({ className: "header-function-name" }, name),
frameComponent
);
- },
+ }
_createTree(props) {
let {
autoExpandDepth,
frameData,
onViewSourceInDebugger,
optimizationSites: sites
} = this.props;
@@ -230,19 +237,19 @@ const JITOptimizations = createClass({
depth,
focused,
arrow,
expanded,
type: getRowType(item),
frameData,
}),
});
- },
+ }
render() {
let header = this._createHeader(this.props);
let tree = this._createTree(this.props);
return dom.div({}, header, tree);
}
-});
+}
module.exports = JITOptimizations;
--- a/devtools/client/performance/components/recording-button.js
+++ b/devtools/client/performance/components/recording-button.js
@@ -1,25 +1,27 @@
/* 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, PropTypes} = require("devtools/client/shared/vendor/react");
-const {button} = DOM;
+const { L10N } = require("devtools/client/performance/modules/global");
+const { Component } = 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 } = dom;
-module.exports = createClass({
- displayName: "Recording Button",
-
- propTypes: {
- onRecordButtonClick: PropTypes.func.isRequired,
- isRecording: PropTypes.bool,
- isLocked: PropTypes.bool
- },
+class RecordingButton extends Component {
+ static get propTypes() {
+ return {
+ onRecordButtonClick: PropTypes.func.isRequired,
+ isRecording: PropTypes.bool,
+ isLocked: PropTypes.bool
+ };
+ }
render() {
let {
onRecordButtonClick,
isRecording,
isLocked
} = this.props;
@@ -35,9 +37,11 @@ module.exports = createClass({
onClick: onRecordButtonClick,
"data-standalone": "true",
"data-text-only": "true",
disabled: isLocked
},
isRecording ? L10N.getStr("recordings.stop") : L10N.getStr("recordings.start")
);
}
-});
+}
+
+module.exports = RecordingButton;
--- a/devtools/client/performance/components/recording-controls.js
+++ b/devtools/client/performance/components/recording-controls.js
@@ -1,27 +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, PropTypes} = require("devtools/client/shared/vendor/react");
-const {div, button} = DOM;
-
-module.exports = createClass({
- displayName: "Recording Controls",
+const { L10N } = require("devtools/client/performance/modules/global");
+const { Component } = 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 { div, button } = dom;
- propTypes: {
- onClearButtonClick: PropTypes.func.isRequired,
- onRecordButtonClick: PropTypes.func.isRequired,
- onImportButtonClick: PropTypes.func.isRequired,
- isRecording: PropTypes.bool,
- isLocked: PropTypes.bool
- },
+class RecordingControls extends Component {
+ static get propTypes() {
+ return {
+ onClearButtonClick: PropTypes.func.isRequired,
+ onRecordButtonClick: PropTypes.func.isRequired,
+ onImportButtonClick: PropTypes.func.isRequired,
+ isRecording: PropTypes.bool,
+ isLocked: PropTypes.bool
+ };
+ }
render() {
let {
onClearButtonClick,
onRecordButtonClick,
onImportButtonClick,
isRecording,
isLocked
@@ -54,9 +56,11 @@ module.exports = createClass({
className: "devtools-button",
title: L10N.getStr("recordings.import.tooltip"),
onClick: onImportButtonClick
})
)
)
);
}
-});
+}
+
+module.exports = RecordingControls;
--- a/devtools/client/performance/components/recording-list-item.js
+++ b/devtools/client/performance/components/recording-list-item.js
@@ -1,29 +1,31 @@
/* 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 {DOM, createClass, PropTypes} = require("devtools/client/shared/vendor/react");
-const {div, li, span, button} = DOM;
-const {L10N} = require("devtools/client/performance/modules/global");
-
-module.exports = createClass({
- displayName: "Recording List Item",
+const { Component } = 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 { div, li, span, button } = dom;
+const { L10N } = require("devtools/client/performance/modules/global");
- propTypes: {
- label: PropTypes.string.isRequired,
- duration: PropTypes.string,
- onSelect: PropTypes.func.isRequired,
- onSave: PropTypes.func.isRequired,
- isLoading: PropTypes.bool,
- isSelected: PropTypes.bool,
- isRecording: PropTypes.bool
- },
+class RecordingListItem extends Component {
+ static get propTypes() {
+ return {
+ label: PropTypes.string.isRequired,
+ duration: PropTypes.string,
+ onSelect: PropTypes.func.isRequired,
+ onSave: PropTypes.func.isRequired,
+ isLoading: PropTypes.bool,
+ isSelected: PropTypes.bool,
+ isRecording: PropTypes.bool
+ };
+ }
render() {
const {
label,
duration,
onSelect,
onSave,
isLoading,
@@ -51,9 +53,11 @@ module.exports = createClass({
span({ className: "recording-list-item-duration" }, durationText),
button({ className: "recording-list-item-save", onClick: onSave },
L10N.getStr("recordingsList.saveLabel")
)
)
)
);
}
-});
+}
+
+module.exports = RecordingListItem;
--- a/devtools/client/performance/components/recording-list.js
+++ b/devtools/client/performance/components/recording-list.js
@@ -1,28 +1,32 @@
/* 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 {DOM, createClass, PropTypes} = require("devtools/client/shared/vendor/react");
-const {L10N} = require("devtools/client/performance/modules/global");
-const {ul, div} = DOM;
+const { Component } = 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 { L10N } = require("devtools/client/performance/modules/global");
+const { ul, div } = dom;
-module.exports = createClass({
- displayName: "Recording List",
-
- propTypes: {
- items: PropTypes.arrayOf(PropTypes.object).isRequired,
- itemComponent: PropTypes.func.isRequired
- },
+class RecordingList extends Component {
+ static get propTypes() {
+ return {
+ items: PropTypes.arrayOf(PropTypes.object).isRequired,
+ itemComponent: PropTypes.func.isRequired
+ };
+ }
render() {
const {
items,
itemComponent: Item,
} = this.props;
return items.length > 0
? ul({ className: "recording-list" }, ...items.map(Item))
: div({ className: "recording-list-empty" }, L10N.getStr("noRecordingsText"));
}
-});
+}
+
+module.exports = RecordingList;
--- a/devtools/client/performance/components/waterfall-header.js
+++ b/devtools/client/performance/components/waterfall-header.js
@@ -3,17 +3,18 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* The "waterfall ticks" view, a header for the markers displayed in the waterfall.
*/
-const { DOM: dom, PropTypes } = 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 { L10N } = require("../modules/global");
const { TickUtils } = require("../modules/waterfall-ticks");
const WATERFALL_HEADER_TICKS_MULTIPLE = 5; // ms
const WATERFALL_HEADER_TICKS_SPACING_MIN = 50; // px
const WATERFALL_HEADER_TEXT_PADDING = 3; // px
function WaterfallHeader(props) {
--- a/devtools/client/performance/components/waterfall-tree-row.js
+++ b/devtools/client/performance/components/waterfall-tree-row.js
@@ -3,17 +3,18 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* A single row (node) in the waterfall tree
*/
-const { DOM: dom, PropTypes } = 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 { MarkerBlueprintUtils } = require("../modules/marker-blueprint-utils");
const LEVEL_INDENT = 10; // px
const ARROW_NODE_OFFSET = -14; // px
const WATERFALL_MARKER_TIMEBAR_WIDTH_MIN = 5; // px
function buildMarkerSidebar(blueprint, props) {
const { marker, level, sidebarWidth } = props;
--- a/devtools/client/performance/components/waterfall-tree.js
+++ b/devtools/client/performance/components/waterfall-tree.js
@@ -1,14 +1,15 @@
/* 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 { createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react");
+const { Component, createFactory } = require("devtools/client/shared/vendor/react");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const Tree = createFactory(require("devtools/client/shared/components/Tree"));
const WaterfallTreeRow = createFactory(require("./waterfall-tree-row"));
// Keep in sync with var(--waterfall-tree-row-height) in performance.css
const WATERFALL_TREE_ROW_HEIGHT = 15; // px
/**
* Checks if a given marker is in the specified time range.
@@ -33,40 +34,53 @@ function isMarkerInRange(e, start, end)
(mStart < start && mEnd > end) ||
// overlap start
(mStart < start && mEnd >= start && mEnd <= end) ||
// overlap end
(mEnd > end && mStart >= start && mStart <= end)
);
}
-const WaterfallTree = createClass({
- displayName: "WaterfallTree",
+class WaterfallTree extends Component {
+ static get propTypes() {
+ return {
+ marker: PropTypes.object.isRequired,
+ startTime: PropTypes.number.isRequired,
+ endTime: PropTypes.number.isRequired,
+ dataScale: PropTypes.number.isRequired,
+ sidebarWidth: PropTypes.number.isRequired,
+ waterfallWidth: PropTypes.number.isRequired,
+ onFocus: PropTypes.func,
+ };
+ }
- propTypes: {
- marker: PropTypes.object.isRequired,
- startTime: PropTypes.number.isRequired,
- endTime: PropTypes.number.isRequired,
- dataScale: PropTypes.number.isRequired,
- sidebarWidth: PropTypes.number.isRequired,
- waterfallWidth: PropTypes.number.isRequired,
- onFocus: PropTypes.func,
- },
+ constructor(props) {
+ super(props);
- getInitialState() {
- return {
+ this.state = {
focused: null,
expanded: new Set()
};
- },
+
+ this._getRoots = this._getRoots.bind(this);
+ this._getParent = this._getParent.bind(this);
+ this._getChildren = this._getChildren.bind(this);
+ this._getKey = this._getKey.bind(this);
+ this._isExpanded = this._isExpanded.bind(this);
+ this._onExpand = this._onExpand.bind(this);
+ this._onCollapse = this._onCollapse.bind(this);
+ this._onFocus = this._onFocus.bind(this);
+ this._filter = this._filter.bind(this);
+ this._renderItem = this._renderItem.bind(this);
+ }
_getRoots(node) {
let roots = this.props.marker.submarkers || [];
return roots.filter(this._filter);
- },
+ }
/**
* Find the parent node of 'node' with a depth-first search of the marker tree
*/
_getParent(node) {
function findParent(marker) {
if (marker.submarkers) {
for (let submarker of marker.submarkers) {
@@ -85,83 +99,83 @@ const WaterfallTree = createClass({
}
let rootMarker = this.props.marker;
let parent = findParent(rootMarker);
// We are interested only in parent markers that are rendered,
// which rootMarker is not. Return null if the parent is rootMarker.
return parent !== rootMarker ? parent : null;
- },
+ }
_getChildren(node) {
let submarkers = node.submarkers || [];
return submarkers.filter(this._filter);
- },
+ }
_getKey(node) {
return `marker-${node.index}`;
- },
+ }
_isExpanded(node) {
return this.state.expanded.has(node);
- },
+ }
_onExpand(node) {
this.setState(state => {
let expanded = new Set(state.expanded);
expanded.add(node);
return { expanded };
});
- },
+ }
_onCollapse(node) {
this.setState(state => {
let expanded = new Set(state.expanded);
expanded.delete(node);
return { expanded };
});
- },
+ }
_onFocus(node) {
this.setState({ focused: node });
if (this.props.onFocus) {
this.props.onFocus(node);
}
- },
+ }
_filter(node) {
let { startTime, endTime } = this.props;
return isMarkerInRange(node, startTime, endTime);
- },
+ }
_renderItem(marker, level, focused, arrow, expanded) {
let { startTime, dataScale, sidebarWidth } = this.props;
return WaterfallTreeRow({
marker,
level,
arrow,
expanded,
focused,
startTime,
dataScale,
sidebarWidth
});
- },
+ }
render() {
return Tree({
getRoots: this._getRoots,
getParent: this._getParent,
getChildren: this._getChildren,
getKey: this._getKey,
isExpanded: this._isExpanded,
onExpand: this._onExpand,
onCollapse: this._onCollapse,
onFocus: this._onFocus,
renderItem: this._renderItem,
focused: this.state.focused,
itemHeight: WATERFALL_TREE_ROW_HEIGHT
});
}
-});
+}
module.exports = WaterfallTree;
--- a/devtools/client/performance/components/waterfall.js
+++ b/devtools/client/performance/components/waterfall.js
@@ -3,17 +3,19 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* This file contains the "waterfall" view, essentially a detailed list
* of all the markers in the timeline data.
*/
-const { DOM: dom, createFactory, PropTypes } = require("devtools/client/shared/vendor/react");
+const { createFactory } = 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 WaterfallHeader = createFactory(require("./waterfall-header"));
const WaterfallTree = createFactory(require("./waterfall-tree"));
function Waterfall(props) {
return dom.div(
{ className: "waterfall-markers" },
WaterfallHeader(props),
WaterfallTree(props)