aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/js/components/ContentView/ContentLoader.jsx
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2016-07-25 17:03:50 -0700
committerMaximilian Hils <git@maximilianhils.com>2016-07-25 17:03:50 -0700
commit70dbd1b32d13d30e15c03ee91b0fab7bfdf429b3 (patch)
tree8c15d471934ac4b2c898725a2929f30f8dc7f9dd /web/src/js/components/ContentView/ContentLoader.jsx
parent79ebcb046e8669f80357a6c3046ec76c6adf49be (diff)
downloadmitmproxy-70dbd1b32d13d30e15c03ee91b0fab7bfdf429b3.tar.gz
mitmproxy-70dbd1b32d13d30e15c03ee91b0fab7bfdf429b3.tar.bz2
mitmproxy-70dbd1b32d13d30e15c03ee91b0fab7bfdf429b3.zip
web: refactor ContentLoader
Diffstat (limited to 'web/src/js/components/ContentView/ContentLoader.jsx')
-rw-r--r--web/src/js/components/ContentView/ContentLoader.jsx97
1 files changed, 54 insertions, 43 deletions
diff --git a/web/src/js/components/ContentView/ContentLoader.jsx b/web/src/js/components/ContentView/ContentLoader.jsx
index eff82d05..fb022df6 100644
--- a/web/src/js/components/ContentView/ContentLoader.jsx
+++ b/web/src/js/components/ContentView/ContentLoader.jsx
@@ -1,58 +1,34 @@
import React, { Component, PropTypes } from 'react'
import { MessageUtils } from '../../flow/utils.js'
-// This is the only place where we use jQuery.
-// Remove when possible.
-import $ from "jquery"
-export default class ContentLoader extends Component {
+export default View => class extends React.Component {
+
+ static displayName = View.displayName || View.name
+ static matches = View.matches
static propTypes = {
+ ...View.propTypes,
+ content: PropTypes.string, // mark as non-required
flow: PropTypes.object.isRequired,
message: PropTypes.object.isRequired,
}
- constructor(props, context) {
- super(props, context)
- this.state = { content: null, request: null }
- }
-
- requestContent(nextProps) {
- if (this.state.request) {
- this.state.request.abort()
+ constructor(props) {
+ super(props)
+ this.state = {
+ content: undefined,
+ request: undefined,
}
-
- const requestUrl = MessageUtils.getContentURL(nextProps.flow, nextProps.message)
- const request = $.get(requestUrl)
-
- this.setState({ content: null, request })
-
- request
- .done(content => {
- this.setState({ content })
- })
- .fail((xhr, textStatus, errorThrown) => {
- if (textStatus === 'abort') {
- return
- }
- this.setState({ content: `AJAX Error: ${textStatus}\r\n${errorThrown}` })
- })
- .always(() => {
- this.setState({ request: null })
- })
}
componentWillMount() {
- this.requestContent(this.props)
+ this.startRequest(this.props)
}
componentWillReceiveProps(nextProps) {
- let reload = nextProps.message !== this.props.message
- let isUserEdit = !nextProps.readonly && nextProps.message.content
-
- if (isUserEdit)
- this.setState({content: nextProps.message.content})
- else if(reload)
- this.requestContent(nextProps)
+ if (nextProps.message.contentHash !== this.props.message.contentHash) {
+ this.startRequest(nextProps)
+ }
}
componentWillUnmount() {
@@ -61,15 +37,50 @@ export default class ContentLoader extends Component {
}
}
+ startRequest(props) {
+ if (this.state.request) {
+ this.state.request.abort()
+ }
+ let requestUrl = MessageUtils.getContentURL(props.flow, props.message)
+
+ // We use XMLHttpRequest instead of fetch() because fetch() is not (yet) abortable.
+ let request = new XMLHttpRequest();
+ request.addEventListener("load", this.requestComplete.bind(this, request));
+ request.addEventListener("error", this.requestFailed.bind(this, request));
+ request.open("GET", requestUrl);
+ request.send();
+ this.setState({ request, content: undefined })
+ }
+
+ requestComplete(request, e) {
+ if (request !== this.state.request) {
+ return // Stale request
+ }
+ this.setState({
+ content: request.responseText,
+ request: undefined
+ })
+ }
+
+ requestFailed(request, e) {
+ if (request !== this.state.request) {
+ return // Stale request
+ }
+ console.error(e)
+ // FIXME: Better error handling
+ this.setState({
+ content: "Error getting content.",
+ request: undefined
+ })
+ }
+
render() {
return this.state.content ? (
- React.cloneElement(this.props.children, {
- content: this.state.content
- })
+ <View content={this.state.content} {...this.props}/>
) : (
<div className="text-center">
<i className="fa fa-spinner fa-spin"></i>
</div>
)
}
-}
+};