diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 2b7384a5aa..9cf3994ff4 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -394,6 +394,7 @@ class TextHighlighter extends BaseHighlighter { * opts.stripReplyFallback: optional argument specifying the event is a reply and so fallback needs removing * opts.returnString: return an HTML string rather than JSX elements * opts.forComposerQuote: optional param to lessen the url rewriting done by sanitization, for quoting into composer + * opts.ref: React ref to attach to any React components returned (not compatible with opts.returnString) */ export function bodyToHtml(content, highlights, opts={}) { const isHtmlMessage = content.format === "org.matrix.custom.html" && content.formatted_body; @@ -476,8 +477,8 @@ export function bodyToHtml(content, highlights, opts={}) { }); return isDisplayedWithHtml ? - : - { strippedBody }; + : + { strippedBody }; } /** diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index efbfc4322f..2084a67cdc 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -422,7 +422,7 @@ module.exports = createReactClass({ ); - if (this.props.eventTileOps && this.props.eventTileOps.getInnerText) { + if (this.props.eventTileOps) { // this event is rendered using TextuaLBody quoteButton = ( { _t('Quote') } diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 2680c13512..fdfa351df3 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React from 'react'; +import React, {createRef} from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import createReactClass from 'create-react-class'; @@ -86,6 +86,10 @@ module.exports = createReactClass({ return successful; }, + componentWillMount: function() { + this._content = createRef(); + }, + componentDidMount: function() { this._unmounted = false; if (!this.props.editState) { @@ -94,13 +98,13 @@ module.exports = createReactClass({ }, _applyFormatting() { - this.activateSpoilers(this.refs.content.children); + this.activateSpoilers([this._content.current]); // pillifyLinks BEFORE linkifyElement because plain room/user URLs in the composer // are still sent as plaintext URLs. If these are ever pillified in the composer, // we should be pillify them here by doing the linkifying BEFORE the pillifying. - pillifyLinks(this.refs.content.children, this.props.mxEvent); - HtmlUtils.linkifyElement(this.refs.content); + pillifyLinks([this._content.current], this.props.mxEvent); + HtmlUtils.linkifyElement(this._content.current); this.calculateUrlPreview(); if (this.props.mxEvent.getContent().format === "org.matrix.custom.html") { @@ -163,7 +167,8 @@ module.exports = createReactClass({ //console.info("calculateUrlPreview: ShowUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview); if (this.props.showUrlPreview) { - let links = this.findLinks(this.refs.content.children); + // pass only the first child which is the event tile otherwise this recurses on edited events + let links = this.findLinks([this._content.current]); if (links.length) { // de-dup the links (but preserve ordering) const seen = new Set(); @@ -325,10 +330,6 @@ module.exports = createReactClass({ global.localStorage.removeItem("hide_preview_" + this.props.mxEvent.getId()); } }, - - getInnerText: () => { - return this.refs.content.innerText; - }, }; }, @@ -424,6 +425,7 @@ module.exports = createReactClass({ disableBigEmoji: content.msgtype === "m.emote" || !SettingsStore.getValue('TextualBody.enableBigEmoji'), // Part of Replies fallback support stripReplyFallback: stripReply, + ref: this._content, }); if (this.props.replacingEventId) { body = [body, this._renderEditedMarker()]; @@ -450,15 +452,14 @@ module.exports = createReactClass({ switch (content.msgtype) { case "m.emote": - const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); return ( - + - { name } + { mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender() }   { body } @@ -467,14 +468,14 @@ module.exports = createReactClass({ ); case "m.notice": return ( - + { body } { widgets } ); default: // including "m.text" return ( - + { body } { widgets }