diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index a72608d329..310da598fa 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -45,9 +45,9 @@ module.exports = React.createClass({ getInitialState: function() { return { - // the URL (if any) to be previewed with a LinkPreviewWidget + // the URLs (if any) to be previewed with a LinkPreviewWidget // inside this TextualBody. - link: null, + links: [], // track whether the preview widget is hidden widgetHidden: false, @@ -57,9 +57,11 @@ module.exports = React.createClass({ componentDidMount: function() { linkifyElement(this.refs.content, linkifyMatrix.options); - var link = this.findLink(this.refs.content.children); - if (link) { - this.setState({ link: link.getAttribute("href") }); + var links = this.findLinks(this.refs.content.children); + if (links.length) { + this.setState({ links: links.map((link)=>{ + return link.getAttribute("href"); + })}); // lazy-load the hidden state of the preview widget from localstorage if (global.localStorage) { @@ -74,27 +76,32 @@ module.exports = React.createClass({ shouldComponentUpdate: function(nextProps, nextState) { // exploit that events are immutable :) + // ...and that .links is only ever set in componentDidMount and never changes return (nextProps.mxEvent.getId() !== this.props.mxEvent.getId() || nextProps.highlights !== this.props.highlights || nextProps.highlightLink !== this.props.highlightLink || - nextState.link !== this.state.link || + nextState.links !== this.state.links || nextState.widgetHidden !== this.state.widgetHidden); }, - findLink: function(nodes) { + findLinks: function(nodes) { + var links = []; for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; if (node.tagName === "A" && node.getAttribute("href")) { - return this.isLinkPreviewable(node) ? node : undefined; + if (this.isLinkPreviewable(node)) { + links.push(node); + } } else if (node.tagName === "PRE" || node.tagName === "CODE") { - return; + continue; } else if (node.children && node.children.length) { - return this.findLink(node.children) + links = links.concat(this.findLinks(node.children)); } } + return links; }, isLinkPreviewable: function(node) { @@ -160,14 +167,17 @@ module.exports = React.createClass({ {highlightLink: this.props.highlightLink}); - var widget; - if (this.state.link && !this.state.widgetHidden) { + var widgets; + if (this.state.links.length && !this.state.widgetHidden) { var LinkPreviewWidget = sdk.getComponent('rooms.LinkPreviewWidget'); - widget = ; + widgets = this.state.links.map((link)=>{ + return ; + }); } switch (content.msgtype) { @@ -176,21 +186,21 @@ module.exports = React.createClass({ return ( * { name } { body } - { widget } + { widgets } ); case "m.notice": return ( { body } - { widget } + { widgets } ); default: // including "m.text" return ( { body } - { widget } + { widgets } ); }