Change ref handling in TextualBody to prevent it parsing generated nodes

Remove unused paths

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2019-12-08 01:01:19 +00:00
parent 89fdfd7a23
commit 702a8ff4a9
3 changed files with 19 additions and 17 deletions

View file

@ -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 ?
<span key="body" className={className} dangerouslySetInnerHTML={{ __html: safeBody }} dir="auto" /> :
<span key="body" className={className} dir="auto">{ strippedBody }</span>;
<span key="body" ref={opts.ref} className={className} dangerouslySetInnerHTML={{ __html: safeBody }} dir="auto" /> :
<span key="body" ref={opts.ref} className={className} dir="auto">{ strippedBody }</span>;
}
/**

View file

@ -422,7 +422,7 @@ module.exports = createReactClass({
</MenuItem>
);
if (this.props.eventTileOps && this.props.eventTileOps.getInnerText) {
if (this.props.eventTileOps) { // this event is rendered using TextuaLBody
quoteButton = (
<MenuItem className="mx_MessageContextMenu_field" onClick={this.onQuoteClick}>
{ _t('Quote') }

View file

@ -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 (
<span ref="content" className="mx_MEmoteBody mx_EventTile_content">
<span className="mx_MEmoteBody mx_EventTile_content">
*&nbsp;
<span
className="mx_MEmoteBody_sender"
onClick={this.onEmoteSenderClick}
>
{ name }
{ mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender() }
</span>
&nbsp;
{ body }
@ -467,14 +468,14 @@ module.exports = createReactClass({
);
case "m.notice":
return (
<span ref="content" className="mx_MNoticeBody mx_EventTile_content">
<span className="mx_MNoticeBody mx_EventTile_content">
{ body }
{ widgets }
</span>
);
default: // including "m.text"
return (
<span ref="content" className="mx_MTextBody mx_EventTile_content">
<span className="mx_MTextBody mx_EventTile_content">
{ body }
{ widgets }
</span>