From 8cf273a460fb0f18a322fc47cdd5f659a863b5dd Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Oct 2016 18:41:28 +0100 Subject: [PATCH] Run highlight.js asynchronously Move the very minimal logic of highlightDOM into TextualBody because then we can avoid scheduling a lot of timeouts which would ultimately do nothing (ie. any messages that don't have code blocks). --- src/HtmlUtils.js | 7 ------- src/components/views/messages/TextualBody.js | 22 ++++++++++++++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 01ae50cf68..fc1630b6fb 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -302,13 +302,6 @@ export function bodyToHtml(content, highlights, opts) { return ; } -export function highlightDom(element) { - var blocks = element.getElementsByTagName("code"); - for (var i = 0; i < blocks.length; i++) { - highlight.highlightBlock(blocks[i]); - } -} - export function emojifyText(text) { return { __html: unicodeToImage(escape(text)), diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 9ce4aa1e84..04a3a83fd7 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -18,6 +18,7 @@ limitations under the License. var React = require('react'); var ReactDOM = require('react-dom'); +var highlight = require('highlight.js'); var HtmlUtils = require('../../../HtmlUtils'); var linkify = require('linkifyjs'); var linkifyElement = require('linkifyjs/element'); @@ -62,17 +63,34 @@ module.exports = React.createClass({ }, componentDidMount: function() { + this._unmounted = false; + linkifyElement(this.refs.content, linkifyMatrix.options); this.calculateUrlPreview(); - if (this.props.mxEvent.getContent().format === "org.matrix.custom.html") - HtmlUtils.highlightDom(ReactDOM.findDOMNode(this)); + if (this.props.mxEvent.getContent().format === "org.matrix.custom.html") { + const blocks = ReactDOM.findDOMNode(this).getElementsByTagName("code"); + if (blocks.length > 0) { + // Do this asynchronously: parsing code takes time and we don't + // need to block the DOM update on it. + setTimeout(() => { + if (this._unmounted) return; + for (let i = 0; i < blocks.length; i++) { + highlight.highlightBlock(blocks[i]); + } + }, 10); + } + } }, componentDidUpdate: function() { this.calculateUrlPreview(); }, + componentWillUnmount: function() { + this._unmounted = true; + }, + shouldComponentUpdate: function(nextProps, nextState) { //console.log("shouldComponentUpdate: ShowUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);