Skip to content

Commit

Permalink
markdown: Inject emoji helpers.
Browse files Browse the repository at this point in the history
Note that we try to avoid the helpers global, but we
still need a future commit to further clean things up.
  • Loading branch information
showell authored and timabbott committed Apr 4, 2022
1 parent 94f1fe6 commit 1156001
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 10 deletions.
2 changes: 2 additions & 0 deletions frontend_tests/node_tests/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,8 @@ test("missing unicode emojis", ({override_rewire}) => {
assert.equal(codepoint, "1f6b2");
// return undefined
});

markdown.initialize(markdown_config.get_helpers());
markdown.apply_markdown(message);
assert.equal(message.content, "<p>\u{1F6B2}</p>");
});
Expand Down
55 changes: 54 additions & 1 deletion frontend_tests/node_tests/markdown_parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,38 @@ function stream_topic_hash(stream_id, topic) {
return `stream-${stream_id}-topic-${topic}`;
}

function get_emoticon_translations() {
return [
{regex: /(:\))/g, replacement_text: ":smile:"},
{regex: /(<3)/g, replacement_text: ":heart:"},
];
}

const emoji_map = new Map();
emoji_map.set("smile", "1f642");
emoji_map.set("alien", "1f47d");

function get_emoji_codepoint(emoji_name) {
return emoji_map.get(emoji_name);
}

function get_emoji_name(codepoint) {
for (const [emoji_name, _codepoint] of emoji_map.entries()) {
if (codepoint === _codepoint) {
return emoji_name;
}
}

return undefined;
}

const realm_emoji_map = new Map();
realm_emoji_map.set("heart", "/images/emoji/heart.bmp");

function get_realm_emoji_url(emoji_name) {
return realm_emoji_map.get(emoji_name);
}

const helper_config = {
// user stuff
get_actual_name_from_user_id,
Expand All @@ -95,7 +127,13 @@ const helper_config = {
stream_topic_hash,

// settings
should_translate_emoticons: () => false,
should_translate_emoticons: () => true,

// emojis
get_emoji_codepoint,
get_emoji_name,
get_emoticon_translations,
get_realm_emoji_url,
};

function assert_parse(raw_content, expected_content) {
Expand Down Expand Up @@ -147,3 +185,18 @@ test("stream links", () => {
'<p><a class="stream-topic" data-stream-id="301" href="/stream-301-topic-lunch">#social &gt; lunch</a></p>',
);
});

test("emojis", () => {
assert_parse(
"yup :)",
'<p>yup <span aria-label="smile" class="emoji emoji-1f642" role="img" title="smile">:smile:</span></p>',
);
assert_parse(
"I <3 JavaScript",
'<p>I <img alt=":heart:" class="emoji" src="/images/emoji/heart.bmp" title="heart"> JavaScript</p>',
);
assert_parse(
"Mars Attacks! \uD83D\uDC7D",
'<p>Mars Attacks! <span aria-label="alien" class="emoji emoji-1f47d" role="img" title="alien">:alien:</span></p>',
);
});
32 changes: 23 additions & 9 deletions static/js/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import * as fenced_code from "../shared/js/fenced_code";
import marked from "../third/marked/lib/marked";

import * as blueslip from "./blueslip";
import * as emoji from "./emoji";
import * as linkifiers from "./linkifiers";

// This contains zulip's frontend Markdown implementation; see
Expand Down Expand Up @@ -69,7 +68,7 @@ export function translate_emoticons_to_names(text) {
return match;
};

for (const translation of emoji.get_emoticon_translations()) {
for (const translation of helpers.get_emoticon_translations()) {
// We can't pass replacement_text directly into
// emoticon_replacer, because emoticon_replacer is
// a callback for `replace()`. Instead we just mutate
Expand Down Expand Up @@ -337,9 +336,9 @@ function make_emoji_span(codepoint, title, alt_text) {
)}" role="img" title="${_.escape(title)}">${_.escape(alt_text)}</span>`;
}

function handleUnicodeEmoji(unicode_emoji) {
function handleUnicodeEmoji({unicode_emoji, get_emoji_name}) {
const codepoint = unicode_emoji.codePointAt(0).toString(16);
const emoji_name = emoji.get_emoji_name(codepoint);
const emoji_name = get_emoji_name(codepoint);

if (emoji_name) {
const alt_text = ":" + emoji_name + ":";
Expand All @@ -350,7 +349,7 @@ function handleUnicodeEmoji(unicode_emoji) {
return unicode_emoji;
}

function handleEmoji(emoji_name) {
function handleEmoji({emoji_name, get_realm_emoji_url, get_emoji_codepoint}) {
const alt_text = ":" + emoji_name + ":";
const title = emoji_name.replace(/_/g, " ");

Expand All @@ -361,15 +360,15 @@ function handleEmoji(emoji_name) {
// Otherwise we'll look at Unicode emoji to render with an emoji
// span using the spritesheet; and if it isn't one of those
// either, we pass through the plain text syntax unmodified.
const emoji_url = emoji.get_realm_emoji_url(emoji_name);
const emoji_url = get_realm_emoji_url(emoji_name);

if (emoji_url) {
return `<img alt="${_.escape(alt_text)}" class="emoji" src="${_.escape(
emoji_url,
)}" title="${_.escape(title)}">`;
}

const codepoint = emoji.get_emoji_codepoint(emoji_name);
const codepoint = get_emoji_codepoint(emoji_name);
if (codepoint) {
return make_emoji_span(codepoint, title, alt_text);
}
Expand Down Expand Up @@ -555,10 +554,25 @@ export function parse({raw_content, helper_config}) {
});
}

function emojiHandler(emoji_name) {
return handleEmoji({
emoji_name,
get_realm_emoji_url: helper_config.get_realm_emoji_url,
get_emoji_codepoint: helper_config.get_emoji_codepoint,
});
}

function unicodeEmojiHandler(unicode_emoji) {
return handleUnicodeEmoji({
unicode_emoji,
get_emoji_name: helper_config.get_emoji_name,
});
}

const options = {
emojiHandler: handleEmoji,
emojiHandler,
linkifierHandler: handleLinkifier,
unicodeEmojiHandler: handleUnicodeEmoji,
unicodeEmojiHandler,
streamHandler,
streamTopicHandler,
texHandler: handleTex,
Expand Down
7 changes: 7 additions & 0 deletions static/js/markdown_config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as emoji from "./emoji";
import * as hash_util from "./hash_util";
import * as people from "./people";
import * as stream_data from "./stream_data";
Expand Down Expand Up @@ -45,4 +46,10 @@ export const get_helpers = () => ({

// settings
should_translate_emoticons: () => user_settings.translate_emoticons,

// emojis
get_emoji_name: emoji.get_emoji_name,
get_emoji_codepoint: emoji.get_emoji_codepoint,
get_emoticon_translations: emoji.get_emoticon_translations,
get_realm_emoji_url: emoji.get_realm_emoji_url,
});

0 comments on commit 1156001

Please sign in to comment.