--- a/devtools/client/webconsole/net/components/cookies-tab.js
+++ b/devtools/client/webconsole/net/components/cookies-tab.js
@@ -1,50 +1,47 @@
/* 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 React = require("devtools/client/shared/vendor/react");
-const NetInfoGroupList = React.createFactory(require("./net-info-group-list"));
-const Spinner = React.createFactory(require("./spinner"));
-
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
+const { Component, createFactory, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
+const NetInfoGroupList = createFactory(require("./net-info-group-list"));
+const Spinner = createFactory(require("./spinner"));
/**
* This template represents 'Cookies' tab displayed when the user
* expands network log in the Console panel. It's responsible for rendering
* sent and received cookies.
*/
-var CookiesTab = React.createClass({
- propTypes: {
- actions: PropTypes.shape({
- requestData: PropTypes.func.isRequired
- }),
- data: PropTypes.object.isRequired,
- },
-
- displayName: "CookiesTab",
+class CookiesTab extends Component {
+ static get propTypes() {
+ return {
+ actions: PropTypes.shape({
+ requestData: PropTypes.func.isRequired
+ }),
+ data: PropTypes.object.isRequired,
+ };
+ }
componentDidMount() {
let { actions, data } = this.props;
let requestCookies = data.request.cookies;
let responseCookies = data.response.cookies;
// TODO: use async action objects as soon as Redux is in place
if (!requestCookies || !requestCookies.length) {
actions.requestData("requestCookies");
}
if (!responseCookies || !responseCookies.length) {
actions.requestData("responseCookies");
}
- },
+ }
render() {
let { actions, data: file } = this.props;
let requestCookies = file.request.cookies;
let responseCookies = file.response.cookies;
// The cookie panel displays two groups of cookies:
// 1) Response Cookies
@@ -64,12 +61,12 @@ var CookiesTab = React.createClass({
DOM.div({className: "panelContent"},
NetInfoGroupList({
groups: groups
})
)
)
);
}
-});
+}
// Exports from this module
module.exports = CookiesTab;
--- a/devtools/client/webconsole/net/components/headers-tab.js
+++ b/devtools/client/webconsole/net/components/headers-tab.js
@@ -1,51 +1,48 @@
/* 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 React = require("devtools/client/shared/vendor/react");
-const NetInfoGroupList = React.createFactory(require("./net-info-group-list"));
-const Spinner = React.createFactory(require("./spinner"));
-
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
+const { Component, createFactory, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
+const NetInfoGroupList = createFactory(require("./net-info-group-list"));
+const Spinner = createFactory(require("./spinner"));
/**
* This template represents 'Headers' tab displayed when the user
* expands network log in the Console panel. It's responsible for rendering
* request and response HTTP headers.
*/
-var HeadersTab = React.createClass({
- propTypes: {
- actions: PropTypes.shape({
- requestData: PropTypes.func.isRequired
- }),
- data: PropTypes.object.isRequired,
- },
-
- displayName: "HeadersTab",
+class HeadersTab extends Component {
+ static get propTypes() {
+ return {
+ actions: PropTypes.shape({
+ requestData: PropTypes.func.isRequired
+ }),
+ data: PropTypes.object.isRequired,
+ };
+ }
componentDidMount() {
let { actions, data } = this.props;
let requestHeaders = data.request.headers;
let responseHeaders = data.response.headers;
// Request headers if they are not available yet.
// TODO: use async action objects as soon as Redux is in place
if (!requestHeaders) {
actions.requestData("requestHeaders");
}
if (!responseHeaders) {
actions.requestData("responseHeaders");
}
- },
+ }
render() {
let { data } = this.props;
let requestHeaders = data.request.headers;
let responseHeaders = data.response.headers;
// TODO: Another groups to implement:
// 1) Cached Headers
@@ -68,12 +65,12 @@ var HeadersTab = React.createClass({
return (
DOM.div({className: "headersTabBox"},
DOM.div({className: "panelContent"},
NetInfoGroupList({groups: groups})
)
)
);
}
-});
+}
// Exports from this module
module.exports = HeadersTab;
--- a/devtools/client/webconsole/net/components/net-info-body.js
+++ b/devtools/client/webconsole/net/components/net-info-body.js
@@ -1,86 +1,92 @@
/* 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 React = require("devtools/client/shared/vendor/react");
+const { Component, createFactory, PropTypes } =
+ require("devtools/client/shared/vendor/react");
const { createFactories } = require("devtools/client/shared/react-utils");
const { Tabs, TabPanel } = createFactories(require("devtools/client/shared/components/tabs/Tabs"));
// Network
-const HeadersTab = React.createFactory(require("./headers-tab"));
-const ResponseTab = React.createFactory(require("./response-tab"));
-const ParamsTab = React.createFactory(require("./params-tab"));
-const CookiesTab = React.createFactory(require("./cookies-tab"));
-const PostTab = React.createFactory(require("./post-tab"));
-const StackTraceTab = React.createFactory(require("./stacktrace-tab"));
+const HeadersTab = createFactory(require("./headers-tab"));
+const ResponseTab = createFactory(require("./response-tab"));
+const ParamsTab = createFactory(require("./params-tab"));
+const CookiesTab = createFactory(require("./cookies-tab"));
+const PostTab = createFactory(require("./post-tab"));
+const StackTraceTab = createFactory(require("./stacktrace-tab"));
const NetUtils = require("../utils/net");
-// Shortcuts
-const PropTypes = React.PropTypes;
/**
* This template renders the basic Network log info body. It's not
* visible by default, the user needs to expand the network log
* to see it.
*
* This is the set of tabs displaying details about network events:
* 1) Headers - request and response headers
* 2) Params - URL parameters
* 3) Response - response body
* 4) Cookies - request and response cookies
* 5) Post - posted data
*/
-var NetInfoBody = React.createClass({
- propTypes: {
- tabActive: PropTypes.number.isRequired,
- actions: PropTypes.object.isRequired,
- data: PropTypes.shape({
- request: PropTypes.object.isRequired,
- response: PropTypes.object.isRequired
- }),
- // Service to enable the source map feature.
- sourceMapService: PropTypes.object,
- },
+class NetInfoBody extends Component {
+ static get propTypes() {
+ return {
+ tabActive: PropTypes.number.isRequired,
+ actions: PropTypes.object.isRequired,
+ data: PropTypes.shape({
+ request: PropTypes.object.isRequired,
+ response: PropTypes.object.isRequired
+ }),
+ // Service to enable the source map feature.
+ sourceMapService: PropTypes.object,
+ };
+ }
- displayName: "NetInfoBody",
-
- getDefaultProps() {
+ static get defaultProps() {
return {
tabActive: 0
};
- },
+ }
- getInitialState() {
- return {
+ constructor(props) {
+ super(props);
+
+ this.state = {
data: {
request: {},
response: {}
},
- tabActive: this.props.tabActive,
+ tabActive: props.tabActive,
};
- },
+
+ this.onTabChanged = this.onTabChanged.bind(this);
+ this.hasCookies = this.hasCookies.bind(this);
+ this.hasStackTrace = this.hasStackTrace.bind(this);
+ this.getTabPanels = this.getTabPanels.bind(this);
+ }
onTabChanged(index) {
this.setState({tabActive: index});
- },
+ }
hasCookies() {
let {request, response} = this.state.data;
return this.state.hasCookies ||
NetUtils.getHeaderValue(request.headers, "Cookie") ||
NetUtils.getHeaderValue(response.headers, "Set-Cookie");
- },
+ }
hasStackTrace() {
let {cause} = this.state.data;
return cause && cause.stacktrace && cause.stacktrace.length > 0;
- },
+ }
getTabPanels() {
let { actions, sourceMapService } = this.props;
let data = this.state.data;
let {request} = data;
// Flags for optional tabs. Some tabs are visible only if there
// are data to display.
@@ -158,25 +164,25 @@ var NetInfoBody = React.createClass({
actions: actions,
sourceMapService: sourceMapService,
})
)
);
}
return panels;
- },
+ }
render() {
let tabActive = this.state.tabActive;
let tabPanels = this.getTabPanels();
return (
Tabs({
tabActive: tabActive,
onAfterChange: this.onTabChanged},
tabPanels
)
);
}
-});
+}
// Exports from this module
module.exports = NetInfoBody;
--- a/devtools/client/webconsole/net/components/net-info-group-list.js
+++ b/devtools/client/webconsole/net/components/net-info-group-list.js
@@ -1,30 +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 React = require("devtools/client/shared/vendor/react");
-const NetInfoGroup = React.createFactory(require("./net-info-group"));
-
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
+const { Component, createFactory, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
+const NetInfoGroup = createFactory(require("./net-info-group"));
/**
* This template is responsible for rendering sections/groups inside tabs.
* It's used e.g to display Response and Request headers as separate groups.
*/
-var NetInfoGroupList = React.createClass({
- propTypes: {
- groups: PropTypes.array.isRequired,
- },
-
- displayName: "NetInfoGroupList",
+class NetInfoGroupList extends Component {
+ static get propTypes() {
+ return {
+ groups: PropTypes.array.isRequired,
+ };
+ }
render() {
let groups = this.props.groups;
// Filter out empty groups.
groups = groups.filter(group => {
return group && ((group.params && group.params.length) || group.content);
});
@@ -36,12 +33,12 @@ var NetInfoGroupList = React.createClass
});
return (
DOM.div({className: "netInfoGroupList"},
groups
)
);
}
-});
+}
// Exports from this module
module.exports = NetInfoGroupList;
--- a/devtools/client/webconsole/net/components/net-info-group.js
+++ b/devtools/client/webconsole/net/components/net-info-group.js
@@ -1,53 +1,54 @@
/* 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 React = require("devtools/client/shared/vendor/react");
-const NetInfoParams = React.createFactory(require("./net-info-params"));
-
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
+const { Component, createFactory, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
+const NetInfoParams = createFactory(require("./net-info-params"));
/**
* This template represents a group of data within a tab. For example,
* Headers tab has two groups 'Request Headers' and 'Response Headers'
* The Response tab can also have two groups 'Raw Data' and 'JSON'
*/
-var NetInfoGroup = React.createClass({
- propTypes: {
- type: PropTypes.string.isRequired,
- name: PropTypes.string.isRequired,
- params: PropTypes.array,
- content: PropTypes.element,
- open: PropTypes.bool
- },
+class NetInfoGroup extends Component {
+ static get propTypes() {
+ return {
+ type: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ params: PropTypes.array,
+ content: PropTypes.element,
+ open: PropTypes.bool
+ };
+ }
- displayName: "NetInfoGroup",
-
- getDefaultProps() {
+ static get defaultProps() {
return {
open: true,
};
- },
+ }
+
+ constructor(props) {
+ super(props);
- getInitialState() {
- return {
- open: this.props.open,
+ this.state = {
+ open: props.open,
};
- },
+
+ this.onToggle = this.onToggle.bind(this);
+ }
onToggle(event) {
this.setState({
open: !this.state.open
});
- },
+ }
render() {
let content = this.props.content;
if (!content && this.props.params) {
content = NetInfoParams({
params: this.props.params
});
@@ -69,12 +70,12 @@ var NetInfoGroup = React.createClass({
this.props.name
),
DOM.div({className: "netInfoGroupContent"},
content
)
)
);
}
-});
+}
// Exports from this module
module.exports = NetInfoGroup;
--- a/devtools/client/webconsole/net/components/net-info-params.js
+++ b/devtools/client/webconsole/net/components/net-info-params.js
@@ -1,32 +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 React = require("devtools/client/shared/vendor/react");
-
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
+const { Component, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
/**
* This template renders list of parameters within a group.
* It's essentially a list of name + value pairs.
*/
-var NetInfoParams = React.createClass({
- displayName: "NetInfoParams",
-
- propTypes: {
- params: PropTypes.arrayOf(PropTypes.shape({
- name: PropTypes.string.isRequired,
- value: PropTypes.string.isRequired
- })).isRequired,
- },
+class NetInfoParams extends Component {
+ static get propTypes() {
+ return {
+ params: PropTypes.arrayOf(PropTypes.shape({
+ name: PropTypes.string.isRequired,
+ value: PropTypes.string.isRequired
+ })).isRequired,
+ };
+ }
render() {
let params = this.props.params || [];
params.sort(function (a, b) {
return a.name > b.name ? 1 : -1;
});
@@ -47,12 +44,12 @@ var NetInfoParams = React.createClass({
return (
DOM.table({cellPadding: 0, cellSpacing: 0},
DOM.tbody({},
rows
)
)
);
}
-});
+}
// Exports from this module
module.exports = NetInfoParams;
--- a/devtools/client/webconsole/net/components/params-tab.js
+++ b/devtools/client/webconsole/net/components/params-tab.js
@@ -1,41 +1,38 @@
/* 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 React = require("devtools/client/shared/vendor/react");
-const NetInfoParams = React.createFactory(require("./net-info-params"));
-
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
+const { Component, createFactory, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
+const NetInfoParams = createFactory(require("./net-info-params"));
/**
* This template represents 'Params' tab displayed when the user
* expands network log in the Console panel. It's responsible for
* displaying URL parameters (query string).
*/
-var ParamsTab = React.createClass({
- propTypes: {
- data: PropTypes.shape({
- request: PropTypes.object.isRequired
- })
- },
-
- displayName: "ParamsTab",
+class ParamsTab extends Component {
+ static get propTypes() {
+ return {
+ data: PropTypes.shape({
+ request: PropTypes.object.isRequired
+ })
+ };
+ }
render() {
let data = this.props.data;
return (
DOM.div({className: "paramsTabBox"},
DOM.div({className: "panelContent"},
NetInfoParams({params: data.request.queryString})
)
)
);
}
-});
+}
// Exports from this module
module.exports = ParamsTab;
--- a/devtools/client/webconsole/net/components/post-tab.js
+++ b/devtools/client/webconsole/net/components/post-tab.js
@@ -1,62 +1,74 @@
/* 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 React = require("devtools/client/shared/vendor/react");
+const { Component, createFactory, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
-const TreeView = React.createFactory(require("devtools/client/shared/components/tree/TreeView"));
+const TreeView =
+ createFactory(require("devtools/client/shared/components/tree/TreeView"));
-const { REPS, MODE, parseURLEncodedText } = require("devtools/client/shared/components/reps/reps");
+const { REPS, MODE, parseURLEncodedText } =
+ require("devtools/client/shared/components/reps/reps");
const { Rep } = REPS;
// Network
-const NetInfoParams = React.createFactory(require("./net-info-params"));
-const NetInfoGroupList = React.createFactory(require("./net-info-group-list"));
-const Spinner = React.createFactory(require("./spinner"));
-const SizeLimit = React.createFactory(require("./size-limit"));
+const NetInfoParams = createFactory(require("./net-info-params"));
+const NetInfoGroupList = createFactory(require("./net-info-group-list"));
+const Spinner = createFactory(require("./spinner"));
+const SizeLimit = createFactory(require("./size-limit"));
const NetUtils = require("../utils/net");
const Json = require("../utils/json");
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
-
/**
* This template represents 'Post' tab displayed when the user
* expands network log in the Console panel. It's responsible for
* displaying posted data (HTTP post body).
*/
-var PostTab = React.createClass({
- propTypes: {
- data: PropTypes.shape({
- request: PropTypes.object.isRequired
- }),
- actions: PropTypes.object.isRequired
- },
+class PostTab extends Component {
+ static get propTypes() {
+ return {
+ data: PropTypes.shape({
+ request: PropTypes.object.isRequired
+ }),
+ actions: PropTypes.object.isRequired
+ };
+ }
- displayName: "PostTab",
+ constructor(props) {
+ super(props);
+ this.isJson = this.isJson.bind(this);
+ this.parseJson = this.parseJson.bind(this);
+ this.renderJson = this.renderJson.bind(this);
+ this.parseXml = this.parseXml.bind(this);
+ this.isXml = this.isXml.bind(this);
+ this.renderXml = this.renderXml.bind(this);
+ this.renderMultiPart = this.renderMultiPart.bind(this);
+ this.renderUrlEncoded = this.renderUrlEncoded.bind(this);
+ this.renderRawData = this.renderRawData.bind(this);
+ }
isJson(file) {
let text = file.request.postData.text;
let value = NetUtils.getHeaderValue(file.request.headers, "content-type");
return Json.isJSON(value, text);
- },
+ }
parseJson(file) {
let postData = file.request.postData;
if (!postData) {
return null;
}
let jsonString = new String(postData.text);
return Json.parseJSONString(jsonString);
- },
+ }
/**
* Render JSON post data as an expandable tree.
*/
renderJson(file) {
let text = file.request.postData.text;
if (!text || isLongString(text)) {
return null;
@@ -78,42 +90,42 @@ var PostTab = React.createClass({
object: json,
mode: MODE.TINY,
renderValue: props => Rep(Object.assign({}, props, {
cropLimit: 50,
})),
}),
name: Locale.$STR("jsonScopeName")
};
- },
+ }
parseXml(file) {
let text = file.request.postData.text;
if (isLongString(text)) {
return null;
}
return NetUtils.parseXml({
mimeType: NetUtils.getHeaderValue(file.request.headers, "content-type"),
text: text,
});
- },
+ }
isXml(file) {
if (isLongString(file.request.postData.text)) {
return false;
}
let value = NetUtils.getHeaderValue(file.request.headers, "content-type");
if (!value) {
return false;
}
return NetUtils.isHTML(value);
- },
+ }
renderXml(file) {
let text = file.request.postData.text;
if (!text || isLongString(text)) {
return null;
}
if (!this.isXml(file)) {
@@ -122,34 +134,34 @@ var PostTab = React.createClass({
let doc = this.parseXml(file);
if (!doc) {
return null;
}
// Proper component for rendering XML should be used (see bug 1247392)
return null;
- },
+ }
/**
* Multipart post data are parsed and nicely rendered
* as an expandable tree of individual parts.
*/
renderMultiPart(file) {
let text = file.request.postData.text;
if (!text || isLongString(text)) {
return;
}
if (NetUtils.isMultiPartRequest(file)) {
// TODO: render multi part request (bug: 1247423)
}
return;
- },
+ }
/**
* URL encoded post data are nicely rendered as a list
* of parameters.
*/
renderUrlEncoded(file) {
let text = file.request.postData.text;
if (!text || isLongString(text)) {
@@ -163,17 +175,17 @@ var PostTab = React.createClass({
let lines = text.split("\n");
let params = parseURLEncodedText(lines[lines.length - 1]);
return {
key: "url-encoded",
content: NetInfoParams({params: params}),
name: Locale.$STR("netRequest.params")
};
- },
+ }
renderRawData(file) {
let text = file.request.postData.text;
let group;
// The post body might reached the limit, so check if we are
// dealing with a long string.
@@ -197,26 +209,26 @@ var PostTab = React.createClass({
name: Locale.$STR("netRequest.rawData"),
content: DOM.div({className: "netInfoResponseContent"},
sanitize(text)
)
};
}
return group;
- },
+ }
componentDidMount() {
let { actions, data: file } = this.props;
if (!file.request.postData) {
// TODO: use async action objects as soon as Redux is in place
actions.requestData("requestPostData");
}
- },
+ }
render() {
let { actions, data: file } = this.props;
if (file.discardRequestBody) {
return DOM.span({className: "netInfoBodiesDiscarded"},
Locale.$STR("netRequest.requestBodyDiscarded")
);
@@ -252,17 +264,17 @@ var PostTab = React.createClass({
DOM.div({className: "panelContent"},
NetInfoGroupList({
groups: groups
})
)
)
);
}
-});
+}
// Helpers
/**
* Workaround for a "not well-formed" error that react
* reports when there's multipart data passed to render.
*/
function sanitize(text) {
--- a/devtools/client/webconsole/net/components/response-tab.js
+++ b/devtools/client/webconsole/net/components/response-tab.js
@@ -1,95 +1,106 @@
/* 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 React = require("devtools/client/shared/vendor/react");
+const { Component, createFactory, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
// Reps
-const TreeView = React.createFactory(require("devtools/client/shared/components/tree/TreeView"));
+const TreeView = createFactory(require("devtools/client/shared/components/tree/TreeView"));
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
const { Rep } = REPS;
// Network
-const SizeLimit = React.createFactory(require("./size-limit"));
-const NetInfoGroupList = React.createFactory(require("./net-info-group-list"));
-const Spinner = React.createFactory(require("./spinner"));
+const SizeLimit = createFactory(require("./size-limit"));
+const NetInfoGroupList = createFactory(require("./net-info-group-list"));
+const Spinner = createFactory(require("./spinner"));
const Json = require("../utils/json");
const NetUtils = require("../utils/net");
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
-
/**
* This template represents 'Response' tab displayed when the user
* expands network log in the Console panel. It's responsible for
* rendering HTTP response body.
*
* In case of supported response mime-type (e.g. application/json,
* text/xml, etc.), the response is parsed using appropriate parser
* and rendered accordingly.
*/
-var ResponseTab = React.createClass({
- propTypes: {
- data: PropTypes.shape({
- request: PropTypes.object.isRequired,
- response: PropTypes.object.isRequired
- }),
- actions: PropTypes.object.isRequired
- },
+class ResponseTab extends Component {
+ static get propTypes() {
+ return {
+ data: PropTypes.shape({
+ request: PropTypes.object.isRequired,
+ response: PropTypes.object.isRequired
+ }),
+ actions: PropTypes.object.isRequired
+ };
+ }
- displayName: "ResponseTab",
+ constructor(props) {
+ super(props);
+ this.isJson = this.isJson.bind(this);
+ this.parseJson = this.parseJson.bind(this);
+ this.isImage = this.isImage.bind(this);
+ this.isXml = this.isXml.bind(this);
+ this.parseXml = this.parseXml.bind(this);
+ this.renderJson = this.renderJson.bind(this);
+ this.renderImage = this.renderImage.bind(this);
+ this.renderXml = this.renderXml.bind(this);
+ this.renderFormattedResponse = this.renderFormattedResponse.bind(this);
+ this.renderRawResponse = this.renderRawResponse.bind(this);
+ }
// Response Types
isJson(content) {
if (isLongString(content.text)) {
return false;
}
return Json.isJSON(content.mimeType, content.text);
- },
+ }
parseJson(file) {
let content = file.response.content;
if (isLongString(content.text)) {
return null;
}
let jsonString = new String(content.text);
return Json.parseJSONString(jsonString);
- },
+ }
isImage(content) {
if (isLongString(content.text)) {
return false;
}
return NetUtils.isImage(content.mimeType);
- },
+ }
isXml(content) {
if (isLongString(content.text)) {
return false;
}
return NetUtils.isHTML(content.mimeType);
- },
+ }
parseXml(file) {
let content = file.response.content;
if (isLongString(content.text)) {
return null;
}
return NetUtils.parseXml(content);
- },
+ }
// Rendering
renderJson(file) {
let content = file.response.content;
if (!this.isJson(content)) {
return null;
}
@@ -106,46 +117,46 @@ var ResponseTab = React.createClass({
object: json,
mode: MODE.TINY,
renderValue: props => Rep(Object.assign({}, props, {
cropLimit: 50,
})),
}),
name: Locale.$STR("jsonScopeName")
};
- },
+ }
renderImage(file) {
let content = file.response.content;
if (!this.isImage(content)) {
return null;
}
let dataUri = "data:" + content.mimeType + ";base64," + content.text;
return {
key: "image",
content: DOM.img({src: dataUri}),
name: Locale.$STR("netRequest.image")
};
- },
+ }
renderXml(file) {
let content = file.response.content;
if (!this.isXml(content)) {
return null;
}
let doc = this.parseXml(file);
if (!doc) {
return null;
}
// Proper component for rendering XML should be used (see bug 1247392)
return null;
- },
+ }
/**
* If full response text is available, let's try to parse and
* present nicely according to the underlying format.
*/
renderFormattedResponse(file) {
let content = file.response.content;
if (typeof content.text == "object") {
@@ -161,17 +172,17 @@ var ResponseTab = React.createClass({
if (group) {
return group;
}
group = this.renderXml(file);
if (group) {
return group;
}
- },
+ }
renderRawResponse(file) {
let group;
let content = file.response.content;
// The response might reached the limit, so check if we are
// dealing with a long string.
if (typeof content.text == "object") {
@@ -194,27 +205,27 @@ var ResponseTab = React.createClass({
name: Locale.$STR("netRequest.rawData"),
content: DOM.div({className: "netInfoResponseContent"},
content.text
)
};
}
return group;
- },
+ }
componentDidMount() {
let { actions, data: file } = this.props;
let content = file.response.content;
if (!content || typeof (content.text) == "undefined") {
// TODO: use async action objects as soon as Redux is in place
actions.requestData("responseContent");
}
- },
+ }
/**
* The response panel displays two groups:
*
* 1) Formatted response (in case of supported format, e.g. JSON, XML, etc.)
* 2) Raw response data (always displayed if not discarded)
*/
render() {
@@ -260,17 +271,17 @@ var ResponseTab = React.createClass({
DOM.div({className: "panelContent"},
NetInfoGroupList({
groups: groups
})
)
)
);
}
-});
+}
// Helpers
function isLongString(text) {
return typeof text == "object";
}
// Exports from this module
--- a/devtools/client/webconsole/net/components/size-limit.js
+++ b/devtools/client/webconsole/net/components/size-limit.js
@@ -1,45 +1,47 @@
/* 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 React = require("devtools/client/shared/vendor/react");
-
-// Shortcuts
-const DOM = React.DOM;
-const PropTypes = React.PropTypes;
+const { Component, DOM, PropTypes } =
+ require("devtools/client/shared/vendor/react");
/**
* This template represents a size limit notification message
* used e.g. in the Response tab when response body exceeds
* size limit. The message contains a link allowing the user
* to fetch the rest of the data from the backend (debugger server).
*/
-var SizeLimit = React.createClass({
- propTypes: {
- data: PropTypes.object.isRequired,
- message: PropTypes.string.isRequired,
- link: PropTypes.string.isRequired,
- actions: PropTypes.shape({
- resolveString: PropTypes.func.isRequired
- }),
- },
+class SizeLimit extends Component {
+ static get propTypes() {
+ return {
+ data: PropTypes.object.isRequired,
+ message: PropTypes.string.isRequired,
+ link: PropTypes.string.isRequired,
+ actions: PropTypes.shape({
+ resolveString: PropTypes.func.isRequired
+ }),
+ };
+ }
- displayName: "SizeLimit",
+ constructor(props) {
+ super(props);
+ this.onClickLimit = this.onClickLimit.bind(this);
+ }
// Event Handlers
onClickLimit(event) {
let actions = this.props.actions;
let content = this.props.data;
actions.resolveString(content, "text");
- },
+ }
// Rendering
render() {
let message = this.props.message;
let link = this.props.link;
let reLink = /^(.*)\{\{link\}\}(.*$)/;
let m = message.match(reLink);
@@ -51,12 +53,12 @@ var SizeLimit = React.createClass({
className: "objectLink",
onClick: this.onClickLimit},
link
),
DOM.span({}, m[2])
)
);
}
-});
+}
// Exports from this module
module.exports = SizeLimit;
--- a/devtools/client/webconsole/net/components/spinner.js
+++ b/devtools/client/webconsole/net/components/spinner.js
@@ -1,26 +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";
-const React = require("devtools/client/shared/vendor/react");
-
-// Shortcuts
-const DOM = React.DOM;
+const { Component, DOM } = require("devtools/client/shared/vendor/react");
/**
* This template represents a throbber displayed when the UI
* is waiting for data coming from the backend (debugging server).
*/
-var Spinner = React.createClass({
- displayName: "Spinner",
-
+class Spinner extends Component {
render() {
return (
DOM.div({className: "devtools-throbber"})
);
}
-});
+}
// Exports from this module
module.exports = Spinner;
--- a/devtools/client/webconsole/net/components/stacktrace-tab.js
+++ b/devtools/client/webconsole/net/components/stacktrace-tab.js
@@ -1,31 +1,33 @@
/* 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 { PropTypes, createClass, createFactory } = require("devtools/client/shared/vendor/react");
-const StackTrace = createFactory(require("devtools/client/shared/components/StackTrace"));
-
-const StackTraceTab = createClass({
- displayName: "StackTraceTab",
+const { PropTypes, Component, createFactory } =
+ require("devtools/client/shared/vendor/react");
+const StackTrace =
+ createFactory(require("devtools/client/shared/components/StackTrace"));
- propTypes: {
- data: PropTypes.object.isRequired,
- actions: PropTypes.shape({
- onViewSourceInDebugger: PropTypes.func.isRequired
- }),
- // Service to enable the source map feature.
- sourceMapService: PropTypes.object,
- },
+class StackTraceTab extends Component {
+ static get propTypes() {
+ return {
+ data: PropTypes.object.isRequired,
+ actions: PropTypes.shape({
+ onViewSourceInDebugger: PropTypes.func.isRequired
+ }),
+ // Service to enable the source map feature.
+ sourceMapService: PropTypes.object,
+ };
+ }
render() {
let { stacktrace } = this.props.data.cause;
let { actions, sourceMapService } = this.props;
let onViewSourceInDebugger = actions.onViewSourceInDebugger.bind(actions);
return StackTrace({ stacktrace, onViewSourceInDebugger, sourceMapService });
}
-});
+}
// Exports from this module
module.exports = StackTraceTab;
--- a/devtools/client/webconsole/new-console-output/components/ConsoleOutput.js
+++ b/devtools/client/webconsole/new-console-output/components/ConsoleOutput.js
@@ -1,15 +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,
+ Component,
createFactory,
DOM: dom,
PropTypes
} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const {
getAllMessagesById,
@@ -19,45 +19,49 @@ const {
getVisibleMessages,
getAllRepeatById,
} = require("devtools/client/webconsole/new-console-output/selectors/messages");
const MessageContainer = createFactory(require("devtools/client/webconsole/new-console-output/components/MessageContainer").MessageContainer);
const {
MESSAGE_TYPE,
} = require("devtools/client/webconsole/new-console-output/constants");
-const ConsoleOutput = createClass({
-
- displayName: "ConsoleOutput",
+class ConsoleOutput extends Component {
+ static get propTypes() {
+ return {
+ messages: PropTypes.object.isRequired,
+ messagesUi: PropTypes.object.isRequired,
+ serviceContainer: PropTypes.shape({
+ attachRefToHud: PropTypes.func.isRequired,
+ openContextMenu: PropTypes.func.isRequired,
+ sourceMapService: PropTypes.object,
+ }),
+ dispatch: PropTypes.func.isRequired,
+ timestampsVisible: PropTypes.bool,
+ messagesTableData: PropTypes.object.isRequired,
+ messagesRepeat: PropTypes.object.isRequired,
+ networkMessagesUpdate: PropTypes.object.isRequired,
+ visibleMessages: PropTypes.array.isRequired,
+ networkMessageActiveTabId: PropTypes.string.isRequired,
+ };
+ }
- propTypes: {
- messages: PropTypes.object.isRequired,
- messagesUi: PropTypes.object.isRequired,
- serviceContainer: PropTypes.shape({
- attachRefToHud: PropTypes.func.isRequired,
- openContextMenu: PropTypes.func.isRequired,
- sourceMapService: PropTypes.object,
- }),
- dispatch: PropTypes.func.isRequired,
- timestampsVisible: PropTypes.bool,
- messagesTableData: PropTypes.object.isRequired,
- messagesRepeat: PropTypes.object.isRequired,
- networkMessagesUpdate: PropTypes.object.isRequired,
- visibleMessages: PropTypes.array.isRequired,
- networkMessageActiveTabId: PropTypes.string.isRequired,
- },
+ constructor(props) {
+ super(props);
+ this.onContextMenu = this.onContextMenu.bind(this);
+ }
componentDidMount() {
// Do the scrolling in the nextTick since this could hit console startup performances.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1355869
setTimeout(() => {
scrollToBottom(this.outputNode);
}, 0);
this.props.serviceContainer.attachRefToHud("outputScroller", this.outputNode);
- },
+ }
componentWillUpdate(nextProps, nextState) {
const outputNode = this.outputNode;
if (!outputNode || !outputNode.lastChild) {
// Force a scroll to bottom when messages are added to an empty console.
// This makes the console stay pinned to the bottom if a batch of messages
// are added after a page refresh (Bug 1402237).
this.shouldScrollBottom = true;
@@ -73,29 +77,29 @@ const ConsoleOutput = createClass({
// We need to scroll to the bottom if:
// - the number of messages displayed changed
// and we are already scrolled to the bottom
// - the number of messages in the store changed
// and the new message is an evaluation result.
this.shouldScrollBottom =
(messagesDelta > 0 && nextProps.messages.last().type === MESSAGE_TYPE.RESULT) ||
(visibleMessagesDelta > 0 && isScrolledToBottom(lastChild, outputNode));
- },
+ }
componentDidUpdate() {
if (this.shouldScrollBottom) {
scrollToBottom(this.outputNode);
}
- },
+ }
onContextMenu(e) {
this.props.serviceContainer.openContextMenu(e);
e.stopPropagation();
e.preventDefault();
- },
+ }
render() {
let {
dispatch,
visibleMessages,
messages,
messagesUi,
messagesTableData,
@@ -126,17 +130,17 @@ const ConsoleOutput = createClass({
onContextMenu: this.onContextMenu,
ref: node => {
this.outputNode = node;
},
}, messageNodes
)
);
}
-});
+}
function scrollToBottom(node) {
node.scrollTop = node.scrollHeight;
}
function isScrolledToBottom(outputNode, scrollNode) {
let lastNodeHeight = outputNode.lastChild ?
outputNode.lastChild.clientHeight : 0;
--- a/devtools/client/webconsole/new-console-output/components/ConsoleTable.js
+++ b/devtools/client/webconsole/new-console-output/components/ConsoleTable.js
@@ -1,63 +1,68 @@
/* 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,
+ Component,
createFactory,
DOM: dom,
PropTypes
} = require("devtools/client/shared/vendor/react");
const ObjectClient = require("devtools/shared/client/object-client");
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
const { MODE } = require("devtools/client/shared/components/reps/reps");
const GripMessageBody = createFactory(require("devtools/client/webconsole/new-console-output/components/GripMessageBody"));
const TABLE_ROW_MAX_ITEMS = 1000;
const TABLE_COLUMN_MAX_ITEMS = 10;
-const ConsoleTable = createClass({
-
- displayName: "ConsoleTable",
+class ConsoleTable extends Component {
+ static get propTypes() {
+ return {
+ dispatch: PropTypes.func.isRequired,
+ parameters: PropTypes.array.isRequired,
+ serviceContainer: PropTypes.shape({
+ hudProxy: PropTypes.object.isRequired,
+ }),
+ id: PropTypes.string.isRequired,
+ tableData: PropTypes.object,
+ };
+ }
- propTypes: {
- dispatch: PropTypes.func.isRequired,
- parameters: PropTypes.array.isRequired,
- serviceContainer: PropTypes.shape({
- hudProxy: PropTypes.object.isRequired,
- }),
- id: PropTypes.string.isRequired,
- tableData: PropTypes.object,
- },
+ constructor(props) {
+ super(props);
+ this.getHeaders = this.getHeaders.bind(this);
+ this.getRows = this.getRows.bind(this);
+ }
- componentWillMount: function () {
+ componentWillMount() {
const {id, dispatch, serviceContainer, parameters} = this.props;
if (!Array.isArray(parameters) || parameters.length === 0) {
return;
}
const client = new ObjectClient(serviceContainer.hudProxy.client, parameters[0]);
let dataType = getParametersDataType(parameters);
// Get all the object properties.
dispatch(actions.messageTableDataGet(id, client, dataType));
- },
+ }
- getHeaders: function (columns) {
+ getHeaders(columns) {
let headerItems = [];
columns.forEach((value, key) => headerItems.push(dom.th({}, value)));
return headerItems;
- },
+ }
- getRows: function (columns, items) {
+ getRows(columns, items) {
const {
dispatch,
serviceContainer,
} = this.props;
return items.map(item => {
let cells = [];
columns.forEach((value, key) => {
@@ -71,19 +76,19 @@ const ConsoleTable = createClass({
serviceContainer,
dispatch,
})
)
);
});
return dom.tr({}, cells);
});
- },
+ }
- render: function () {
+ render() {
const {parameters, tableData} = this.props;
const headersGrip = parameters[1];
const headers = headersGrip && headersGrip.preview ? headersGrip.preview.items : null;
// if tableData is nullable, we don't show anything.
if (!tableData) {
return null;
}
@@ -96,17 +101,17 @@ const ConsoleTable = createClass({
return (
dom.table({className: "new-consoletable devtools-monospace"},
dom.thead({}, this.getHeaders(columns)),
dom.tbody({}, this.getRows(columns, items))
)
);
}
-});
+}
function getParametersDataType(parameters = null) {
if (!Array.isArray(parameters) || parameters.length === 0) {
return null;
}
return parameters[0].class;
}
--- a/devtools/client/webconsole/new-console-output/components/FilterBar.js
+++ b/devtools/client/webconsole/new-console-output/components/FilterBar.js
@@ -1,15 +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,
+ Component,
DOM: dom,
PropTypes
} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters");
const { getFilteredMessagesCount } = require("devtools/client/webconsole/new-console-output/selectors/messages");
const { getAllUi } = require("devtools/client/webconsole/new-console-output/selectors/ui");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
@@ -18,30 +18,48 @@ const { PluralForm } = require("devtools
const {
DEFAULT_FILTERS,
FILTERS,
} = require("../constants");
const FilterButton = require("devtools/client/webconsole/new-console-output/components/FilterButton");
const FilterCheckbox = require("devtools/client/webconsole/new-console-output/components/FilterCheckbox");
-const FilterBar = createClass({
-
- displayName: "FilterBar",
+class FilterBar extends Component {
+ static get propTypes() {
+ return {
+ dispatch: PropTypes.func.isRequired,
+ filter: PropTypes.object.isRequired,
+ serviceContainer: PropTypes.shape({
+ attachRefToHud: PropTypes.func.isRequired,
+ }).isRequired,
+ filterBarVisible: PropTypes.bool.isRequired,
+ persistLogs: PropTypes.bool.isRequired,
+ filteredMessagesCount: PropTypes.object.isRequired,
+ };
+ }
- propTypes: {
- dispatch: PropTypes.func.isRequired,
- filter: PropTypes.object.isRequired,
- serviceContainer: PropTypes.shape({
- attachRefToHud: PropTypes.func.isRequired,
- }).isRequired,
- filterBarVisible: PropTypes.bool.isRequired,
- persistLogs: PropTypes.bool.isRequired,
- filteredMessagesCount: PropTypes.object.isRequired,
- },
+ constructor(props) {
+ super(props);
+ this.onClickMessagesClear = this.onClickMessagesClear.bind(this);
+ this.onClickFilterBarToggle = this.onClickFilterBarToggle.bind(this);
+ this.onClickRemoveAllFilters = this.onClickRemoveAllFilters.bind(this);
+ this.onClickRemoveTextFilter = this.onClickRemoveTextFilter.bind(this);
+ this.onSearchInput = this.onSearchInput.bind(this);
+ this.onChangePersistToggle = this.onChangePersistToggle.bind(this);
+ this.renderFiltersConfigBar = this.renderFiltersConfigBar.bind(this);
+ this.renderFilteredMessagesBar = this.renderFilteredMessagesBar.bind(this);
+ }
+
+ componentDidMount() {
+ this.props.serviceContainer.attachRefToHud(
+ "filterBox",
+ this.wrapperNode.querySelector(".text-filter")
+ );
+ }
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.filter !== this.props.filter) {
return true;
}
if (nextProps.filterBarVisible !== this.props.filterBarVisible) {
return true;
@@ -54,46 +72,41 @@ const FilterBar = createClass({
if (
JSON.stringify(nextProps.filteredMessagesCount)
!== JSON.stringify(this.props.filteredMessagesCount)
) {
return true;
}
return false;
- },
-
- componentDidMount() {
- this.props.serviceContainer.attachRefToHud("filterBox",
- this.wrapperNode.querySelector(".text-filter"));
- },
+ }
- onClickMessagesClear: function () {
+ onClickMessagesClear() {
this.props.dispatch(actions.messagesClear());
- },
+ }
- onClickFilterBarToggle: function () {
+ onClickFilterBarToggle() {
this.props.dispatch(actions.filterBarToggle());
- },
+ }
- onClickRemoveAllFilters: function () {
+ onClickRemoveAllFilters() {
this.props.dispatch(actions.defaultFiltersReset());
- },
+ }
- onClickRemoveTextFilter: function () {
+ onClickRemoveTextFilter() {
this.props.dispatch(actions.filterTextSet(""));
- },
+ }
- onSearchInput: function (e) {
+ onSearchInput(e) {
this.props.dispatch(actions.filterTextSet(e.target.value));
- },
+ }
- onChangePersistToggle: function () {
+ onChangePersistToggle() {
this.props.dispatch(actions.persistToggle());
- },
+ }
renderFiltersConfigBar() {
const {
dispatch,
filter,
filteredMessagesCount,
} = this.props;
@@ -162,17 +175,17 @@ const FilterBar = createClass({
}),
FilterButton({
active: filter[FILTERS.NET],
label: l10n.getStr("webconsole.requestsFilterButton.label"),
filterKey: FILTERS.NET,
dispatch
}),
);
- },
+ }
renderFilteredMessagesBar() {
const {
filteredMessagesCount
} = this.props;
const {
global,
} = filteredMessagesCount;
@@ -196,17 +209,17 @@ const FilterBar = createClass({
className: "filter-message-text",
title,
}, label),
dom.button({
className: "devtools-button reset-filters-button",
onClick: this.onClickRemoveAllFilters
}, l10n.getStr("webconsole.resetFiltersButton.label"))
);
- },
+ }
render() {
const {
filter,
filterBarVisible,
persistLogs,
filteredMessagesCount,
} = this.props;
@@ -259,17 +272,17 @@ const FilterBar = createClass({
className: "webconsole-filteringbar-wrapper",
ref: node => {
this.wrapperNode = node;
}
}, ...children
)
);
}
-});
+}
function mapStateToProps(state) {
let uiState = getAllUi(state);
return {
filter: getAllFilters(state),
filterBarVisible: uiState.filterBarVisible,
persistLogs: uiState.persistLogs,
filteredMessagesCount: getFilteredMessagesCount(state),
--- a/devtools/client/webconsole/new-console-output/components/Message.js
+++ b/devtools/client/webconsole/new-console-output/components/Message.js
@@ -3,107 +3,113 @@
/* 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 {
- createClass,
+ Component,
createFactory,
DOM: dom,
PropTypes
} = require("devtools/client/shared/vendor/react");
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
const {MESSAGE_SOURCE} = require("devtools/client/webconsole/new-console-output/constants");
const CollapseButton = require("devtools/client/webconsole/new-console-output/components/CollapseButton");
const MessageIndent = require("devtools/client/webconsole/new-console-output/components/MessageIndent").MessageIndent;
const MessageIcon = require("devtools/client/webconsole/new-console-output/components/MessageIcon");
const MessageRepeat = require("devtools/client/webconsole/new-console-output/components/MessageRepeat");
const FrameView = createFactory(require("devtools/client/shared/components/Frame"));
const StackTrace = createFactory(require("devtools/client/shared/components/StackTrace"));
-const Message = createClass({
- displayName: "Message",
+class Message extends Component {
+ static get propTypes() {
+ return {
+ open: PropTypes.bool,
+ collapsible: PropTypes.bool,
+ collapseTitle: PropTypes.string,
+ source: PropTypes.string.isRequired,
+ type: PropTypes.string.isRequired,
+ level: PropTypes.string.isRequired,
+ indent: PropTypes.number.isRequired,
+ topLevelClasses: PropTypes.array.isRequired,
+ messageBody: PropTypes.any.isRequired,
+ repeat: PropTypes.any,
+ frame: PropTypes.any,
+ attachment: PropTypes.any,
+ stacktrace: PropTypes.any,
+ messageId: PropTypes.string,
+ scrollToMessage: PropTypes.bool,
+ exceptionDocURL: PropTypes.string,
+ parameters: PropTypes.object,
+ request: PropTypes.object,
+ dispatch: PropTypes.func,
+ timeStamp: PropTypes.number,
+ timestampsVisible: PropTypes.bool.isRequired,
+ serviceContainer: PropTypes.shape({
+ emitNewMessage: PropTypes.func.isRequired,
+ onViewSourceInDebugger: PropTypes.func,
+ onViewSourceInScratchpad: PropTypes.func,
+ onViewSourceInStyleEditor: PropTypes.func,
+ openContextMenu: PropTypes.func.isRequired,
+ openLink: PropTypes.func.isRequired,
+ sourceMapService: PropTypes.any,
+ }),
+ notes: PropTypes.arrayOf(PropTypes.shape({
+ messageBody: PropTypes.string.isRequired,
+ frame: PropTypes.any,
+ })),
+ };
+ }
- propTypes: {
- open: PropTypes.bool,
- collapsible: PropTypes.bool,
- collapseTitle: PropTypes.string,
- source: PropTypes.string.isRequired,
- type: PropTypes.string.isRequired,
- level: PropTypes.string.isRequired,
- indent: PropTypes.number.isRequired,
- topLevelClasses: PropTypes.array.isRequired,
- messageBody: PropTypes.any.isRequired,
- repeat: PropTypes.any,
- frame: PropTypes.any,
- attachment: PropTypes.any,
- stacktrace: PropTypes.any,
- messageId: PropTypes.string,
- scrollToMessage: PropTypes.bool,
- exceptionDocURL: PropTypes.string,
- parameters: PropTypes.object,
- request: PropTypes.object,
- dispatch: PropTypes.func,
- timeStamp: PropTypes.number,
- timestampsVisible: PropTypes.bool.isRequired,
- serviceContainer: PropTypes.shape({
- emitNewMessage: PropTypes.func.isRequired,
- onViewSourceInDebugger: PropTypes.func,
- onViewSourceInScratchpad: PropTypes.func,
- onViewSourceInStyleEditor: PropTypes.func,
- openContextMenu: PropTypes.func.isRequired,
- openLink: PropTypes.func.isRequired,
- sourceMapService: PropTypes.any,
- }),
- notes: PropTypes.arrayOf(PropTypes.shape({
- messageBody: PropTypes.string.isRequired,
- frame: PropTypes.any,
- })),
- },
-
- getDefaultProps: function () {
+ static get defaultProps() {
return {
indent: 0
};
- },
+ }
+
+ constructor(props) {
+ super(props);
+ this.onLearnMoreClick = this.onLearnMoreClick.bind(this);
+ this.onContextMenu = this.onContextMenu.bind(this);
+ }
componentDidMount() {
if (this.messageNode) {
if (this.props.scrollToMessage) {
this.messageNode.scrollIntoView();
}
// Event used in tests. Some message types don't pass it in because existing tests
// did not emit for them.
if (this.props.serviceContainer) {
this.props.serviceContainer.emitNewMessage(
this.messageNode, this.props.messageId, this.props.timeStamp);
}
}
- },
+ }
- onLearnMoreClick: function () {
+ onLearnMoreClick() {
let {exceptionDocURL} = this.props;
this.props.serviceContainer.openLink(exceptionDocURL);
- },
+ }
onContextMenu(e) {
let { serviceContainer, source, request, messageId } = this.props;
let messageInfo = {
source,
request,
messageId,
};
serviceContainer.openContextMenu(e, messageInfo);
e.stopPropagation();
e.preventDefault();
- },
+ }
render() {
const {
messageId,
open,
collapsible,
collapseTitle,
source,
@@ -256,11 +262,11 @@ const Message = createClass({
// Add a newline for formatting when copying to the clipboard.
"\n",
// If an attachment is displayed, the final newline is handled by the attachment.
attachment,
...notesNodes
)
);
}
-});
+}
module.exports = Message;
--- a/devtools/client/webconsole/new-console-output/components/MessageContainer.js
+++ b/devtools/client/webconsole/new-console-output/components/MessageContainer.js
@@ -3,17 +3,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/. */
"use strict";
// React & Redux
const {
- createClass,
+ Component,
PropTypes
} = require("devtools/client/shared/vendor/react");
const {
MESSAGE_SOURCE,
MESSAGE_TYPE
} = require("devtools/client/webconsole/new-console-output/constants");
@@ -21,59 +21,59 @@ const componentMap = new Map([
["ConsoleApiCall", require("./message-types/ConsoleApiCall")],
["ConsoleCommand", require("./message-types/ConsoleCommand")],
["DefaultRenderer", require("./message-types/DefaultRenderer")],
["EvaluationResult", require("./message-types/EvaluationResult")],
["NetworkEventMessage", require("./message-types/NetworkEventMessage")],
["PageError", require("./message-types/PageError")]
]);
-const MessageContainer = createClass({
- displayName: "MessageContainer",
+class MessageContainer extends Component {
+ static get propTypes() {
+ return {
+ messageId: PropTypes.string.isRequired,
+ open: PropTypes.bool.isRequired,
+ serviceContainer: PropTypes.object.isRequired,
+ tableData: PropTypes.object,
+ timestampsVisible: PropTypes.bool.isRequired,
+ repeat: PropTypes.number,
+ networkMessageUpdate: PropTypes.object,
+ getMessage: PropTypes.func.isRequired,
+ };
+ }
- propTypes: {
- messageId: PropTypes.string.isRequired,
- open: PropTypes.bool.isRequired,
- serviceContainer: PropTypes.object.isRequired,
- tableData: PropTypes.object,
- timestampsVisible: PropTypes.bool.isRequired,
- repeat: PropTypes.number,
- networkMessageUpdate: PropTypes.object,
- getMessage: PropTypes.func.isRequired,
- },
-
- getDefaultProps: function () {
+ static get defaultProps() {
return {
open: false,
};
- },
+ }
shouldComponentUpdate(nextProps, nextState) {
const repeatChanged = this.props.repeat !== nextProps.repeat;
const openChanged = this.props.open !== nextProps.open;
const tableDataChanged = this.props.tableData !== nextProps.tableData;
const timestampVisibleChanged =
this.props.timestampsVisible !== nextProps.timestampsVisible;
const networkMessageUpdateChanged =
this.props.networkMessageUpdate !== nextProps.networkMessageUpdate;
return repeatChanged
|| openChanged
|| tableDataChanged
|| timestampVisibleChanged
|| networkMessageUpdateChanged;
- },
+ }
render() {
const message = this.props.getMessage();
let MessageComponent = getMessageComponent(message);
return MessageComponent(Object.assign({message}, this.props));
}
-});
+}
function getMessageComponent(message) {
if (!message) {
return componentMap.get("DefaultRenderer");
}
switch (message.source) {
case MESSAGE_SOURCE.CONSOLE_API: