diff options
Diffstat (limited to 'client/components/main/editor.js')
-rw-r--r-- | client/components/main/editor.js | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/client/components/main/editor.js b/client/components/main/editor.js index c34539b3..1d88fe74 100644 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -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'); + } }, }); |