handle matrix.to links correctly. add partial support for #/user URLs

pull/21833/head
Matthew Hodgson 2016-08-28 01:55:42 +01:00
parent 50d09f73f5
commit ad873c2b60
3 changed files with 92 additions and 44 deletions

View File

@ -85,12 +85,28 @@ var sanitizeHtmlParams = {
transformTags: { // custom to matrix
// add blank targets to all hyperlinks except vector URLs
'a': function(tagName, attribs) {
var m = attribs.href ? attribs.href.match(linkifyMatrix.VECTOR_URL_PATTERN) : null;
if (m) {
delete attribs.target;
}
else {
attribs.target = '_blank';
if (attribs.href) {
attribs.target = '_blank'; // by default
var m;
// FIXME: horrible duplication with linkify-matrix
m = attribs.href.match(linkifyMatrix.VECTOR_URL_PATTERN);
if (m) {
attribs.href = m[1];
delete attribs.target;
}
m = attribs.href.match(linkifyMatrix.MATRIXTO_URL_PATTERN);
if (m) {
var entity = m[1];
if (entity[0] === '@') {
attribs.href = '#'; // TODO
}
else if (entity[0] === '#') {
attribs.href = '#/room/' + entity;
}
delete attribs.target;
}
}
attribs.rel = 'noopener'; // https://mathiasbynens.github.io/rel-noopener/
return { tagName: tagName, attribs : attribs };

View File

@ -176,12 +176,12 @@ module.exports = React.createClass({
// this can technically be done anywhere but doing this here keeps all
// the routing url path logic together.
if (this.onAliasClick) {
linkifyMatrix.onAliasClick = this.onAliasClick;
}
if (this.onUserClick) {
linkifyMatrix.onUserClick = this.onUserClick;
}
// if (this.onAliasClick) {
// linkifyMatrix.onAliasClick = this.onAliasClick;
// }
// if (this.onUserClick) {
// linkifyMatrix.onUserClick = this.onUserClick;
// }
window.addEventListener('resize', this.handleResize);
this.handleResize();
@ -739,6 +739,16 @@ module.exports = React.createClass({
} else {
dis.dispatch(payload);
}
} else if (screen.indexOf('user/') == 0) {
var userId = screen.substring(5);
var member = new Matrix.RoomMember(null, userId);
if (member) {
// FIXME: this doesn't work yet
dis.dispatch({
action: 'view_user',
member: member,
});
}
}
else {
console.info("Ignoring showScreen for '%s'", screen);
@ -751,31 +761,29 @@ module.exports = React.createClass({
}
},
onAliasClick: function(event, alias) {
event.preventDefault();
dis.dispatch({action: 'view_room', room_alias: alias});
},
// onAliasClick: function(event, alias) {
// event.preventDefault();
// dis.dispatch({action: 'view_room', room_alias: alias});
// },
onUserClick: function(event, userId) {
event.preventDefault();
// onUserClick: function(event, userId) {
// event.preventDefault();
/*
var MemberInfo = sdk.getComponent('rooms.MemberInfo');
var member = new Matrix.RoomMember(null, userId);
ContextualMenu.createMenu(MemberInfo, {
member: member,
right: window.innerWidth - event.pageX,
top: event.pageY
});
*/
// // var MemberInfo = sdk.getComponent('rooms.MemberInfo');
// // var member = new Matrix.RoomMember(null, userId);
// // ContextualMenu.createMenu(MemberInfo, {
// // member: member,
// // right: window.innerWidth - event.pageX,
// // top: event.pageY
// // });
var member = new Matrix.RoomMember(null, userId);
if (!member) { return; }
dis.dispatch({
action: 'view_user',
member: member,
});
},
// var member = new Matrix.RoomMember(null, userId);
// if (!member) { return; }
// dis.dispatch({
// action: 'view_user',
// member: member,
// });
// },
onLogoutClick: function(event) {
dis.dispatch({

View File

@ -95,20 +95,25 @@ function matrixLinkify(linkify) {
S_AT_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_USERID);
}
matrixLinkify.onUserClick = function(e, userId) { e.preventDefault(); };
matrixLinkify.onAliasClick = function(e, roomAlias) { e.preventDefault(); };
// stubs, overwritten in MatrixChat's componentDidMount
// matrixLinkify.onUserClick = function(e, userId) { e.preventDefault(); };
// matrixLinkify.onAliasClick = function(e, roomAlias) { e.preventDefault(); };
var escapeRegExp = function(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
};
// we only recognise URLs which match our current URL as being the same app
// as if someone explicitly links to vector.im/develop and we're on vector.im/beta
// they may well be trying to get us to explicitly go to develop.
// FIXME: intercept matrix.to URLs as well.
matrixLinkify.VECTOR_URL_PATTERN = "^(https?:\/\/)?" + escapeRegExp(window.location.host + window.location.pathname);
// Recognise URLs from both our local vector and official vector as vector.
// anyone else really should be using matrix.to.
matrixLinkify.VECTOR_URL_PATTERN = "^(?:https?:\/\/)?(?:"
+ escapeRegExp(window.location.host + window.location.pathname) + "|"
+ "(?:www\\.)?vector\\.im/(?:beta|staging|develop)/"
+ ")(#.*)";
matrixLinkify.MATRIXTO_URL_PATTERN = "^(?:https?:\/\/)?(?:www\\.)?matrix\\.to/#/((#|@).*)";
matrixLinkify.options = {
/*
events: function (href, type) {
switch (type) {
case "userid":
@ -125,14 +130,31 @@ matrixLinkify.options = {
};
}
},
*/
formatHref: function (href, type) {
switch (type) {
case 'roomalias':
return '#/room/' + href;
case 'userid':
return '#';
return '#/user/' + href;
default:
var m;
// FIXME: horrible duplication with HtmlUtils' transform tags
m = href.match(matrixLinkify.VECTOR_URL_PATTERN);
if (m) {
return m[1];
}
m = href.match(matrixLinkify.MATRIXTO_URL_PATTERN);
if (m) {
var entity = m[1];
if (entity[0] === '@') {
return '#'; // TODO
}
else if (entity[0] === '#') {
return '#/room/' + entity;
}
}
return href;
}
},
@ -143,7 +165,9 @@ matrixLinkify.options = {
target: function(href, type) {
if (type === 'url') {
if (href.match(matrixLinkify.VECTOR_URL_PATTERN)) {
if (href.match(matrixLinkify.VECTOR_URL_PATTERN) ||
href.match(matrixLinkify.MATRIXTO_URL_PATTERN))
{
return null;
}
else {