diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js
index 6ede36ee81..7fc6908caf 100644
--- a/src/HtmlUtils.js
+++ b/src/HtmlUtils.js
@@ -2,6 +2,7 @@
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017, 2018 New Vector Ltd
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
+Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -33,6 +34,7 @@ import url from 'url';
import EMOJIBASE from 'emojibase-data/en/compact.json';
import EMOJIBASE_REGEX from 'emojibase-regex';
+import {tryTransformPermalinkToLocalHref} from "./utils/permalinks/RoomPermalinkCreator";
linkifyMatrix(linkify);
@@ -158,30 +160,10 @@ const transformTags = { // custom to matrix
if (attribs.href) {
attribs.target = '_blank'; // by default
- let m;
- // FIXME: horrible duplication with linkify-matrix
- m = attribs.href.match(linkifyMatrix.VECTOR_URL_PATTERN);
- if (m) {
- attribs.href = m[1];
+ const transformed = tryTransformPermalinkToLocalHref(attribs.href);
+ if (transformed !== attribs.href || attribs.href.match(linkifyMatrix.VECTOR_URL_PATTERN)) {
+ attribs.href = transformed;
delete attribs.target;
- } else {
- m = attribs.href.match(linkifyMatrix.MATRIXTO_URL_PATTERN);
- if (m) {
- const entity = m[1];
- switch (entity[0]) {
- case '@':
- attribs.href = '#/user/' + entity;
- break;
- case '+':
- attribs.href = '#/group/' + entity;
- break;
- case '#':
- case '!':
- attribs.href = '#/room/' + entity;
- break;
- }
- delete attribs.target;
- }
}
}
attribs.rel = 'noopener'; // https://mathiasbynens.github.io/rel-noopener/
diff --git a/src/linkify-matrix.js b/src/linkify-matrix.js
index 2d72b7fb41..0bed83ce84 100644
--- a/src/linkify-matrix.js
+++ b/src/linkify-matrix.js
@@ -1,5 +1,6 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
+Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,6 +16,7 @@ limitations under the License.
*/
import {baseUrl} from "./utils/permalinks/SpecPermalinkConstructor";
+import {tryTransformPermalinkToLocalHref} from "./utils/permalinks/RoomPermalinkCreator";
function matrixLinkify(linkify) {
// Text tokens
@@ -225,20 +227,8 @@ matrixLinkify.options = {
case 'roomalias':
case 'userid':
case 'groupid':
- return matrixLinkify.MATRIXTO_BASE_URL + '/#/' + href;
default: {
- // FIXME: horrible duplication with HtmlUtils' transform tags
- let m = href.match(matrixLinkify.VECTOR_URL_PATTERN);
- if (m) {
- return m[1];
- }
- m = href.match(matrixLinkify.MATRIXTO_URL_PATTERN);
- if (m) {
- const entity = m[1];
- if (matrixToEntityMap[entity[0]]) return matrixToEntityMap[entity[0]] + entity;
- }
-
- return href;
+ return tryTransformPermalinkToLocalHref(href);
}
}
},
@@ -249,8 +239,8 @@ matrixLinkify.options = {
target: function(href, type) {
if (type === 'url') {
- if (href.match(matrixLinkify.VECTOR_URL_PATTERN) ||
- href.match(matrixLinkify.MATRIXTO_URL_PATTERN)) {
+ const transformed = tryTransformPermalinkToLocalHref(href);
+ if (transformed !== href || href.match(matrixLinkify.VECTOR_URL_PATTERN)) {
return null;
} else {
return '_blank';
diff --git a/src/utils/permalinks/RoomPermalinkCreator.js b/src/utils/permalinks/RoomPermalinkCreator.js
index 82f92c80c9..489a6c8b82 100644
--- a/src/utils/permalinks/RoomPermalinkCreator.js
+++ b/src/utils/permalinks/RoomPermalinkCreator.js
@@ -20,6 +20,7 @@ import utils from 'matrix-js-sdk/lib/utils';
import SpecPermalinkConstructor, {baseUrl as matrixtoBaseUrl} from "./SpecPermalinkConstructor";
import PermalinkConstructor, {PermalinkParts} from "./PermalinkConstructor";
import RiotPermalinkConstructor from "./RiotPermalinkConstructor";
+import * as matrixLinkify from "../../linkify-matrix";
const SdkConfig = require("../../SdkConfig");
@@ -286,6 +287,40 @@ export function isPermalinkHost(host: string): boolean {
return getPermalinkConstructor().isPermalinkHost(host);
}
+/**
+ * Transforms a permalink (or possible permalink) into a local URL if possible. If
+ * the given permalink is found to not be a permalink, it'll be returned unaltered.
+ */
+export function tryTransformPermalinkToLocalHref(permalink: string): string {
+ if (!permalink.startsWith("http:") && !permalink.startsWith("https:")) {
+ return permalink;
+ }
+
+ let m = permalink.match(matrixLinkify.VECTOR_URL_PATTERN);
+ if (m) {
+ return m[1];
+ }
+
+ // A bit of a hack to convert permalinks of unknown origin to Riot links
+ try {
+ const permalinkParts = parsePermalink(permalink);
+ if (permalinkParts) {
+ if (permalinkParts.roomIdOrAlias) {
+ const eventIdPart = permalinkParts.eventId ? `/${permalinkParts.eventId}` : '';
+ permalink = `#/room/${permalinkParts.roomIdOrAlias}${eventIdPart}`;
+ } else if (permalinkParts.groupId) {
+ permalink = `#/group/${permalinkParts.groupId}`;
+ } else if (permalinkParts.userId) {
+ permalink = `#/user/${permalinkParts.userId}`;
+ } // else not a valid permalink for our purposes - do not handle
+ }
+ } catch (e) {
+ // Not an href we need to care about
+ }
+
+ return permalink;
+}
+
function getPermalinkConstructor(): PermalinkConstructor {
const riotPrefix = SdkConfig.get()['permalinkPrefix'];
if (riotPrefix && riotPrefix !== matrixtoBaseUrl) {