diff --git a/web/src/js/__tests__/components/ContentView/ContentLoaderSpec.js b/web/src/js/__tests__/components/ContentView/ContentLoaderSpec.js index f5e184421..80b40c723 100644 --- a/web/src/js/__tests__/components/ContentView/ContentLoaderSpec.js +++ b/web/src/js/__tests__/components/ContentView/ContentLoaderSpec.js @@ -1,12 +1,11 @@ import React from 'react' import renderer from 'react-test-renderer' -import ContentLoaderGenerator from '../../../components/ContentView/ContentLoader' +import withContentLoader from '../../../components/ContentView/ContentLoader' import { TFlow } from '../../ducks/tutils' import TestUtils from 'react-dom/test-utils' import mockXMLHttpRequest from 'mock-xmlhttprequest' global.XMLHttpRequest = mockXMLHttpRequest - class tComponent extends React.Component { constructor(props, context){ super(props, context) @@ -17,7 +16,7 @@ class tComponent extends React.Component { } let tflow = new TFlow(), - ContentLoader = ContentLoaderGenerator(tComponent) + ContentLoader = withContentLoader(tComponent) describe('ContentLoader Component', () => { it('should render correctly', () => { diff --git a/web/src/js/components/ContentView/ContentLoader.jsx b/web/src/js/components/ContentView/ContentLoader.jsx index 4cafde28f..69e4a9884 100644 --- a/web/src/js/components/ContentView/ContentLoader.jsx +++ b/web/src/js/components/ContentView/ContentLoader.jsx @@ -2,98 +2,100 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { MessageUtils } from '../../flow/utils.js' -export default View => class extends React.Component { +export default function withContentLoader(View) { + + return class extends React.Component { + static displayName = View.displayName || View.name + static matches = View.matches - 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) { - super(props) - this.state = { - content: undefined, - request: undefined, - } - } - - componentWillMount() { - this.updateContent(this.props) - } - - componentWillReceiveProps(nextProps) { - if ( - nextProps.message.content !== this.props.message.content || - nextProps.message.contentHash !== this.props.message.contentHash || - nextProps.contentView !== this.props.contentView - ) { - this.updateContent(nextProps) - } - } - - componentWillUnmount() { - if (this.state.request) { - this.state.request.abort() - } - } - - updateContent(props) { - if (this.state.request) { - this.state.request.abort() - } - // We have a few special cases where we do not need to make an HTTP request. - if(props.message.content !== undefined) { - return this.setState({request: undefined, content: props.message.content}) - } - if(props.message.contentLength === 0 || props.message.contentLength === null){ - return this.setState({request: undefined, content: ""}) + static propTypes = { + ...View.propTypes, + content: PropTypes.string, // mark as non-required + flow: PropTypes.object.isRequired, + message: PropTypes.object.isRequired, } - let requestUrl = MessageUtils.getContentURL(props.flow, props.message, (View.name == 'ViewServer' ? props.contentView : undefined)) - - // 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 + constructor(props) { + super(props) + this.state = { + content: undefined, + request: undefined, + } } - this.setState({ - content: request.responseText, - request: undefined - }) - } - requestFailed(request, e) { - if (request !== this.state.request) { - return // Stale request + componentWillMount() { + this.updateContent(this.props) } - console.error(e) - // FIXME: Better error handling - this.setState({ - content: "Error getting content.", - request: undefined - }) - } - render() { - return this.state.content !== undefined ? ( - - ) : ( -
- -
- ) + componentWillReceiveProps(nextProps) { + if ( + nextProps.message.content !== this.props.message.content || + nextProps.message.contentHash !== this.props.message.contentHash || + nextProps.contentView !== this.props.contentView + ) { + this.updateContent(nextProps) + } + } + + componentWillUnmount() { + if (this.state.request) { + this.state.request.abort() + } + } + + updateContent(props) { + if (this.state.request) { + this.state.request.abort() + } + // We have a few special cases where we do not need to make an HTTP request. + if (props.message.content !== undefined) { + return this.setState({request: undefined, content: props.message.content}) + } + if (props.message.contentLength === 0 || props.message.contentLength === null) { + return this.setState({request: undefined, content: ""}) + } + + let requestUrl = MessageUtils.getContentURL(props.flow, props.message, (View.name == 'ViewServer' ? props.contentView : undefined)) + + // 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 !== undefined ? ( + + ) : ( +
+ +
+ ) + } } };