2018-07-27 04:06:39 +02:00
|
|
|
// @flow
|
|
|
|
|
|
|
|
import React from 'react';
|
|
|
|
import mammoth from 'mammoth';
|
|
|
|
import LoadingScreen from 'component/common/loading-screen';
|
|
|
|
|
|
|
|
type Props = {
|
2018-08-02 02:53:38 +02:00
|
|
|
source: string,
|
2018-07-27 04:06:39 +02:00
|
|
|
};
|
|
|
|
|
2018-10-15 02:27:09 +02:00
|
|
|
type State = {
|
|
|
|
error: boolean,
|
|
|
|
loading: boolean,
|
|
|
|
content: ?string,
|
|
|
|
};
|
|
|
|
|
|
|
|
class DocxViewer extends React.PureComponent<Props, State> {
|
|
|
|
constructor(props: Props) {
|
2018-07-27 04:06:39 +02:00
|
|
|
super(props);
|
|
|
|
this.state = {
|
2018-10-15 02:27:09 +02:00
|
|
|
error: false,
|
2018-07-27 04:06:39 +02:00
|
|
|
content: null,
|
|
|
|
loading: true,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
componentDidMount() {
|
|
|
|
const { source } = this.props;
|
|
|
|
|
2018-08-02 02:53:38 +02:00
|
|
|
// Overwrite element and styles
|
2018-07-27 04:06:39 +02:00
|
|
|
const options = {
|
|
|
|
styleMap: [
|
2018-07-28 03:54:06 +02:00
|
|
|
"p[style-name='Title'] => h1:fresh",
|
2018-07-27 04:06:39 +02:00
|
|
|
"p[style-name='Heading 1'] => h1:fresh",
|
|
|
|
"p[style-name='Heading 2'] => h2:fresh",
|
|
|
|
"p[style-name='Heading 3'] => h3:fresh",
|
|
|
|
"p[style-name='Section Title'] => h1:fresh",
|
|
|
|
"p[style-name='Subsection Title'] => h2:fresh",
|
|
|
|
"p[style-name='Aside Heading'] => div.aside > h2:fresh",
|
|
|
|
"p[style-name='Aside Text'] => div.aside > p:fresh",
|
|
|
|
],
|
|
|
|
};
|
2018-08-02 02:53:38 +02:00
|
|
|
|
|
|
|
// Parse docx to html
|
2018-07-27 04:06:39 +02:00
|
|
|
mammoth
|
2018-08-02 02:53:38 +02:00
|
|
|
.convertToHtml({ path: source }, options)
|
2018-07-27 04:06:39 +02:00
|
|
|
.then(result => {
|
2019-03-05 05:46:57 +01:00
|
|
|
this.setState({ content: result.value, loading: false });
|
2018-07-27 04:06:39 +02:00
|
|
|
})
|
2018-10-15 02:27:09 +02:00
|
|
|
.catch(() => {
|
2018-08-02 02:53:38 +02:00
|
|
|
this.setState({ error: true, loading: false });
|
2018-07-27 04:06:39 +02:00
|
|
|
})
|
|
|
|
.done();
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const { content, error, loading } = this.state;
|
|
|
|
const loadingMessage = __('Rendering document.');
|
2018-08-02 02:53:38 +02:00
|
|
|
const errorMessage = __("Sorry, looks like we can't load the document.");
|
2018-07-27 04:06:39 +02:00
|
|
|
|
|
|
|
return (
|
2020-04-14 01:48:11 +02:00
|
|
|
<div className="file-viewer file-viewer--document">
|
2018-07-27 04:06:39 +02:00
|
|
|
{loading && <LoadingScreen status={loadingMessage} spinner />}
|
2018-08-02 02:53:38 +02:00
|
|
|
{error && <LoadingScreen status={errorMessage} spinner={false} />}
|
2019-08-13 07:35:13 +02:00
|
|
|
{content && <div className="file-render__content" dangerouslySetInnerHTML={{ __html: content }} />}
|
2018-07-27 04:06:39 +02:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default DocxViewer;
|