Add unicode emoji to frontend markdown parser.

Fixes 2nd half of #1011.
This commit is contained in:
Alex Wilson 2016-06-24 16:39:44 -04:00 committed by Tim Abbott
parent 5ec29101eb
commit b040839c76
5 changed files with 58 additions and 1 deletions

View File

@ -123,6 +123,8 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
expected: '<p>mmm...<img alt=\":burrito:\" class=\"emoji\" src=\"/static/third/gemoji/images/emoji/burrito.png\" title=\":burrito:\">s</p>'},
{input: 'This is an :poop: message',
expected: '<p>This is an <img alt=":poop:" class="emoji" src="/static/third/gemoji/images/emoji/poop.png" title=":poop:"> message</p>'},
{input: "\ud83d\udca9",
expected: '<p><img alt="\ud83d\udca9" class="emoji" src="/static/third/gemoji/images/emoji/unicode/1f4a9.png" title="\ud83d\udca9"></p>'},
{input: 'This is a realm filter #1234 with text after it',
expected: '<p>This is a realm filter <a href="https://trac.zulip.net/ticket/1234" target="_blank" title="https://trac.zulip.net/ticket/1234">#1234</a> with text after it</p>'},
{input: 'This is a realm filter with ZGROUP_123:45 groups',

View File

@ -300,6 +300,18 @@ function escape(html, encode) {
.replace(/'/g, '&#39;');
}
function handleUnicodeEmoji(unicode_emoji) {
var hex_value = unicode_emoji.codePointAt(0).toString(16);
if (emoji.emojis_by_name.hasOwnProperty(hex_value)) {
var emoji_url = emoji.emojis_by_name[hex_value];
return '<img alt="' + unicode_emoji + '"' +
' class="emoji" src="' + emoji_url + '"' +
' title="' + unicode_emoji + '">';
} else {
return unicode_emoji;
}
}
function handleEmoji(emoji_name) {
var input_emoji = ':' + emoji_name + ":";
if (emoji.emojis_by_name.hasOwnProperty(emoji_name)) {
@ -470,6 +482,7 @@ $(function () {
smartypants: false,
zulip: true,
emojiHandler: handleEmoji,
unicodeEmojiHandler: handleUnicodeEmoji,
userMentionHandler: handleUserMentions,
realmFilterHandler: handleRealmFilter,
renderer: r,

File diff suppressed because one or more lines are too long

View File

@ -468,6 +468,7 @@ var inline = {
br: /^ {2,}\n(?!\s*$)/,
del: noop,
emoji: noop,
unicodeemoji: noop,
usermention: noop,
realm_filters: [],
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
@ -525,9 +526,11 @@ inline.breaks = merge({}, inline.gfm, {
inline.zulip = merge({}, inline.breaks, {
emoji: /^:([A-Za-z0-9_\-\+]+?):/,
unicodeemoji: /^(\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff])/,
usermention: /^(@\*\*([^\*]+)?\*\*)/m,
realm_filters: [],
text: replace(inline.breaks.text)
('|', '|(\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff])|')
(']|', '@:]|')
()
});
@ -742,6 +745,13 @@ InlineLexer.prototype.output = function(src) {
continue;
}
// unicode emoji
if (cap = this.rules.unicodeemoji.exec(src)) {
src = src.substring(cap[0].length);
out += this.unicodeEmoji(cap[1]);
continue;
}
// text
if (cap = this.rules.text.exec(src)) {
src = src.substring(cap[0].length);
@ -780,6 +790,12 @@ InlineLexer.prototype.emoji = function (name) {
return this.options.emojiHandler(name);
};
InlineLexer.prototype.unicodeEmoji = function (name) {
if (typeof this.options.unicodeEmojiHandler !== 'function')
return name;
return this.options.unicodeEmojiHandler(name);
};
InlineLexer.prototype.realm_filter = function (filter, matches, orig) {
if (typeof this.options.realmFilterHandler !== 'function')
return;
@ -1352,6 +1368,7 @@ marked.setOptions = function(opt) {
marked.defaults = {
gfm: true,
emoji: false,
unicodeemoji: false,
tables: true,
breaks: false,
pedantic: false,

View File

@ -192,6 +192,24 @@
"expected_output": "<p>:not_an_emoji:</p>",
"bugdown_matches_marked": true
},
{
"name": "unicode_emoji",
"input": "\ud83d\udca9",
"expected_output":"<p><img alt=\"\ud83d\udca9\" class=\"emoji\" src=\"\/static\/third\/gemoji\/images\/emoji\/unicode\/1f4a9.png\" title=\"\ud83d\udca9\"><\/p>",
"bugdown_matches_marked": true
},
{
"name": "two_unicode_emoji",
"input": "\ud83d\udca9\ud83d\udca9",
"expected_output":"<p><img alt=\"\ud83d\udca9\" class=\"emoji\" src=\"\/static\/third\/gemoji\/images\/emoji\/unicode\/1f4a9.png\" title=\"\ud83d\udca9\"><img alt=\"\ud83d\udca9\" class=\"emoji\" src=\"\/static\/third\/gemoji\/images\/emoji\/unicode\/1f4a9.png\" title=\"\ud83d\udca9\"><\/p>",
"bugdown_matches_marked": true
},
{
"name": "two_unicode_emoji_separated_by_text",
"input": "\ud83d\udca9 word \ud83d\udca9",
"expected_output":"<p><img alt=\"\ud83d\udca9\" class=\"emoji\" src=\"\/static\/third\/gemoji\/images\/emoji\/unicode\/1f4a9.png\" title=\"\ud83d\udca9\"> word <img alt=\"\ud83d\udca9\" class=\"emoji\" src=\"\/static\/third\/gemoji\/images\/emoji\/unicode\/1f4a9.png\" title=\"\ud83d\udca9\"><\/p>",
"bugdown_matches_marked": true
},
{
"name": "emoji_alongside_punctuation",
"input": ":smile:, :smile:; :smile:",