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 }
);
}