diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 631caadac2..223eabdc36 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -84,11 +84,12 @@ module.exports = React.createClass({ findLink: function(nodes) { for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; - if (node.tagName === "A" && node.getAttribute("href") && - (node.getAttribute("href").startsWith("http://") || - node.getAttribute("href").startsWith("https://"))) + if (node.tagName === "A" && node.getAttribute("href")) { - return node; + return this.isLinkPreviewable(node) ? node : undefined; + } + else if (node.tagName === "PRE" || node.tagName === "CODE") { + return; } else if (node.children && node.children.length) { return this.findLink(node.children) @@ -96,6 +97,37 @@ module.exports = React.createClass({ } }, + isLinkPreviewable: function(node) { + // don't try to preview relative links + if (!node.getAttribute("href").startsWith("http://") && + !node.getAttribute("href").startsWith("https://")) + { + return false; + } + + // as a random heuristic to avoid highlighting things like "foo.pl" + // we require the linked text to either include a / (either from http:// + // or from a full foo.bar/baz style schemeless URL) - or be a markdown-style + // link, in which case we check the target text differs from the link value. + // TODO: make this configurable? + if (node.textContent.indexOf("/") > -1) + { + return node; + } + else { + var url = node.getAttribute("href"); + var host = url.match(/^https?:\/\/(.*?)(\/|$)/)[1]; + if (node.textContent.trim().startsWith(host)) { + // it's a "foo.pl" style link + return; + } + else { + // it's a [foo bar](http://foo.com) style link + return node; + } + } + }, + onCancelClick: function(event) { this.setState({ widgetHidden: true }); // FIXME: persist this somewhere smarter than local storage