@ -68,7 +68,55 @@ EscapeActions.register('textcomplete',
( ) => dropdownMenuIsOpened
) ;
// XXX I believe we should compute a HTML rendered field on the server that
// would handle markdown, emojies and user mentions. We can simply have two
// fields, one source, and one compiled version (in HTML) and send only the
// compiled version to most users -- who don't need to edit.
// In the meantime, all the transformation are done on the client using the
// Blaze API.
const at = HTML . CharRef ( { html : '@' , str : '@' } ) ;
Blaze . Template . registerHelper ( 'mentions' , new Template ( 'mentions' , function ( ) {
const view = this ;
const currentBoard = Boards . findOne ( Session . get ( 'currentBoard' ) ) ;
const knowedUsers = _ . map ( currentBoard . members , ( member ) => {
member . username = Users . findOne ( member . userId ) . username ;
return member ;
} ) ;
const mentionRegex = /\B@(\w*)/gi ;
let content = Blaze . toHTML ( view . templateContentBlock ) ;
let currentMention , knowedUser , linkClass , linkValue , link ;
while ( Boolean ( currentMention = mentionRegex . exec ( content ) ) ) {
knowedUser = _ . findWhere ( knowedUsers , { username : currentMention [ 1 ] } ) ;
if ( ! knowedUser )
continue ;
linkValue = [ ' ' , at , knowedUser . username ] ;
linkClass = 'atMention js-open-member' ;
if ( knowedUser . userId === Meteor . userId ( ) )
linkClass += ' me' ;
link = HTML . A ( {
'class' : linkClass ,
// XXX Hack. Since we stringify this render function result below with
// `Blaze.toHTML` we can't rely on blaze data contexts to pass the
// `userId` to the popup as usual, and we need to store it in the DOM
// using a data attribute.
'data-userId' : knowedUser . userId ,
} , linkValue ) ;
content = content . replace ( currentMention [ 0 ] , Blaze . toHTML ( link ) ) ;
}
return HTML . Raw ( content ) ;
} ) ) ;
Template . viewer . events ( {
'click .js-open-member' ( evt , tpl ) {
const userId = evt . currentTarget . dataset . userid ;
Popup . open ( 'member' ) . call ( { userId } , evt , tpl ) ;
} ,
// Viewer sometimes have click-able wrapper around them (for instance to edit
// the corresponding text). Clicking a link shouldn't fire these actions, stop
// we stop these event at the viewer component level.
@ -81,6 +129,8 @@ Template.viewer.events({
// by using directly `_blank` attribute in the rendered HTML.
evt . preventDefault ( ) ;
const href = evt . currentTarget . href ;
window . open ( href , '_blank' ) ;
if ( href ) {
window . open ( href , '_blank' ) ;
}
} ,
} ) ;