DEV: replaces huge generated emoji list by a simpler regex (#11053)

Note that this commit is also fixing various mistakes in emojis.

Some of them have been fixed manually in db.json/data.js/groups.json and will need to be fixed in emoji-db gem.
This commit is contained in:
Joffrey JAFFEUX authored and GitHub committed 2021-04-22 08:43:06 +02:00
1 parent e0d17c8d19
commit 0eeedf307a
7 files changed
+86 -90

No files matched your search

@@ -8,7 +8,7 @@
<div class="section-group"> <div class="section-group">
{{replace-emoji ":grinning:" (hash lazy=true)}} {{replace-emoji ":grinning:" (hash lazy=true)}}
{{replace-emoji ":smiley:" (hash lazy=true)}} {{replace-emoji ":smiley:" (hash lazy=true)}}
{{replace-emoji ":smile:" (hash lazy=true)}} {{replace-emoji ":grinning_face_with_smiling_eyes:" (hash lazy=true)}}
{{replace-emoji ":grin:" (hash lazy=true)}} {{replace-emoji ":grin:" (hash lazy=true)}}
{{replace-emoji ":laughing:" (hash lazy=true)}} {{replace-emoji ":laughing:" (hash lazy=true)}}
{{replace-emoji ":sweat_smile:" (hash lazy=true)}} {{replace-emoji ":sweat_smile:" (hash lazy=true)}}
@@ -78,6 +78,7 @@
{{replace-emoji ":flushed:" (hash lazy=true)}} {{replace-emoji ":flushed:" (hash lazy=true)}}
{{replace-emoji ":pleading_face:" (hash lazy=true)}} {{replace-emoji ":pleading_face:" (hash lazy=true)}}
{{replace-emoji ":frowning:" (hash lazy=true)}} {{replace-emoji ":frowning:" (hash lazy=true)}}
{{replace-emoji ":frowning_face_with_open_mouth:" (hash lazy=true)}}
{{replace-emoji ":anguished:" (hash lazy=true)}} {{replace-emoji ":anguished:" (hash lazy=true)}}
{{replace-emoji ":fearful:" (hash lazy=true)}} {{replace-emoji ":fearful:" (hash lazy=true)}}
{{replace-emoji ":cold_sweat:" (hash lazy=true)}} {{replace-emoji ":cold_sweat:" (hash lazy=true)}}
@@ -21,45 +21,12 @@ export function extendedEmojiList() {
const emojiHash = {}; const emojiHash = {};
export function buildReplacementsList(emojiReplacements) { // https://github.com/mathiasbynens/emoji-regex/blob/main/text.js
return Object.keys(emojiReplacements) export const emojiReplacementRegex =
.sort() "\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uLine truncated
.reverse()
.map((emoji) => {
return emoji
.split("")
.map((chr) => {
return "\\u" + chr.charCodeAt(0).toString(16).padStart(4, "0");
})
.join("");
})
.join("|");
}
let replacementListCache; function textEmojiRegex(inlineEmoji) {
const unicodeRegexpCache = {}; return inlineEmoji ? /:[^\s:]+(?::t\d)?:?/g : /\B:[^\s:]+(?::t\d)?:?\B/g;
function replacementList() {
if (replacementListCache === undefined) {
replacementListCache = buildReplacementsList(replacements);
}
return replacementListCache;
}
function unicodeRegexp(inlineEmoji) {
if (unicodeRegexpCache[inlineEmoji] === undefined) {
const emojiExpression = inlineEmoji
? "|:[^\\s:]+(?::t\\d)?:?"
: "|\\B:[^\\s:]+(?::t\\d)?:?\\B";
unicodeRegexpCache[inlineEmoji] = new RegExp(
replacementList() + emojiExpression,
"g"
);
}
return unicodeRegexpCache[inlineEmoji];
} }
// add all default emojis // add all default emojis
@@ -83,7 +50,7 @@ function isReplacableInlineEmoji(string, index, inlineEmoji) {
return ( return (
beforeEmoji.length === 0 || beforeEmoji.length === 0 ||
/(?:\s|[>.,\/#!$%^&*;:{}=\-_`~()])$/.test(beforeEmoji) || /(?:\s|[>.,\/#!$%^&*;:{}=\-_`~()])$/.test(beforeEmoji) ||
new RegExp(`(?:${replacementList()})$`).test(beforeEmoji) new RegExp(`(?:${emojiReplacementRegex})$`, "g").test(beforeEmoji)
); );
} }
@@ -92,18 +59,17 @@ export function performEmojiUnescape(string, opts) {
return; return;
} }
const inlineEmoji = opts.inlineEmoji;
const regexp = unicodeRegexp(inlineEmoji);
const allTranslations = Object.assign( const allTranslations = Object.assign(
{}, {},
translations, translations,
opts.customEmojiTranslation || {} opts.customEmojiTranslation || {}
); );
return string.replace(regexp, (m, index) => { const replacementFunction = (m, index) => {
const isEmoticon = opts.enableEmojiShortcuts && !!allTranslations[m]; const isEmoticon = opts.enableEmojiShortcuts && !!allTranslations[m];
const isUnicodeEmoticon = !!replacements[m]; const isUnicodeEmoticon = !!replacements[m];
let emojiVal; let emojiVal;
if (isEmoticon) { if (isEmoticon) {
emojiVal = allTranslations[m]; emojiVal = allTranslations[m];
} else if (isUnicodeEmoticon) { } else if (isUnicodeEmoticon) {
@@ -123,7 +89,7 @@ export function performEmojiUnescape(string, opts) {
const isReplacable = const isReplacable =
(isEmoticon || hasEndingColon || isUnicodeEmoticon) && (isEmoticon || hasEndingColon || isUnicodeEmoticon) &&
isReplacableInlineEmoji(string, index, inlineEmoji); isReplacableInlineEmoji(string, index, opts.inlineEmoji);
return url && isReplacable return url && isReplacable
? `<img width="20" height="20" src='${url}' ${ ? `<img width="20" height="20" src='${url}' ${
@@ -132,20 +98,22 @@ export function performEmojiUnescape(string, opts) {
opts.lazy ? "loading='lazy' " : "" opts.lazy ? "loading='lazy' " : ""
}alt='${emojiVal}' class='${classes}'>` }alt='${emojiVal}' class='${classes}'>`
: m; : m;
}); };
return string
.replace(new RegExp(emojiReplacementRegex, "g"), replacementFunction)
.replace(textEmojiRegex(opts.inlineEmoji), replacementFunction);
} }
export function performEmojiEscape(string, opts) { export function performEmojiEscape(string, opts) {
const inlineEmoji = opts.inlineEmoji;
const regexp = unicodeRegexp(inlineEmoji);
const allTranslations = Object.assign( const allTranslations = Object.assign(
{}, {},
translations, translations,
opts.customEmojiTranslation || {} opts.customEmojiTranslation || {}
); );
return string.replace(regexp, (m, index) => { const replacementFunction = (m, index) => {
if (isReplacableInlineEmoji(string, index, inlineEmoji)) { if (isReplacableInlineEmoji(string, index, opts.inlineEmoji)) {
if (!!allTranslations[m]) { if (!!allTranslations[m]) {
return opts.emojiShortcuts ? `:${allTranslations[m]}:` : m; return opts.emojiShortcuts ? `:${allTranslations[m]}:` : m;
} else if (!!replacements[m]) { } else if (!!replacements[m]) {
@@ -154,7 +122,11 @@ export function performEmojiEscape(string, opts) {
} }
return m; return m;
}); };
return string
.replace(new RegExp(emojiReplacementRegex, "g"), replacementFunction)
.replace(textEmojiRegex(opts.inlineEmoji), replacementFunction);
} }
export function isCustomEmoji(code, opts) { export function isCustomEmoji(code, opts) {
@@ -48,8 +48,7 @@ export const emojis = [
"rage", "rage",
"pensive", "pensive",
"confused", "confused",
"slightly_frowning_face", "frowning",
"frowning_face",
"persevere", "persevere",
"confounded", "confounded",
"tired_face", "tired_face",
@@ -60,7 +59,7 @@ export const emojis = [
"fearful", "fearful",
"cold_sweat", "cold_sweat",
"hushed", "hushed",
"frowning", "slightly_frowning_face",
"frowning_face_with_open_mouth", "frowning_face_with_open_mouth",
"anguished", "anguished",
"cry", "cry",
@@ -1829,6 +1828,7 @@ export const tonableEmojis = [
"palms_up_together", "palms_up_together",
]; ];
export const aliases = { export const aliases = {
grinning_face_with_smiling_eyes: ["smile"],
right_anger_bubble: ["anger_right"], right_anger_bubble: ["anger_right"],
ballot_box: ["ballot_box_with_ballot"], ballot_box: ["ballot_box_with_ballot"],
basketball_man: ["basketball_player", "person_with_ball"], basketball_man: ["basketball_player", "person_with_ball"],
@@ -1920,7 +1920,6 @@ export const aliases = {
"white_sun_rain_cloud", "white_sun_rain_cloud",
"white_sun_behind_cloud_with_rain", "white_sun_behind_cloud_with_rain",
], ],
grinning_face_with_smiling_eyes: ["smile"],
partly_sunny: ["white_sun_small_cloud", "white_sun_with_small_cloud"], partly_sunny: ["white_sun_small_cloud", "white_sun_with_small_cloud"],
open_umbrella: ["umbrella2"], open_umbrella: ["umbrella2"],
hammer_and_wrench: ["tools"], hammer_and_wrench: ["tools"],
@@ -1936,8 +1935,8 @@ export const aliases = {
nerd_face: ["nerd"], nerd_face: ["nerd"],
hugs: ["hugging", "hugging_face"], hugs: ["hugging", "hugging_face"],
roll_eyes: ["rolling_eyes", "face_with_rolling_eyes"], roll_eyes: ["rolling_eyes", "face_with_rolling_eyes"],
slightly_frowning_face: ["slight_frown"], slightly_frowning_face: ["slight_frown", "slightly_frowning"],
frowning_face: ["frowning2", "white_frowning_face"], frowning: ["frowning2", "white_frowning_face", "frowning_face"],
zipper_mouth_face: ["zipper_mouth"], zipper_mouth_face: ["zipper_mouth"],
face_with_head_bandage: ["head_bandage"], face_with_head_bandage: ["head_bandage"],
raised_hand_with_fingers_splayed: ["hand_splayed"], raised_hand_with_fingers_splayed: ["hand_splayed"],
@@ -2083,7 +2082,7 @@ export const replacements = {
"😊": "blush", "😊": "blush",
"🙂": "slightly_smiling_face", "🙂": "slightly_smiling_face",
"🙃": "upside_down_face", "🙃": "upside_down_face",
"☺": "slight_smile", "☺": "relaxed",
"😋": "yum", "😋": "yum",
"😌": "relieved", "😌": "relieved",
"😍": "heart_eyes", "😍": "heart_eyes",
@@ -2115,8 +2114,7 @@ export const replacements = {
"😡": "rage", "😡": "rage",
"😔": "pensive", "😔": "pensive",
"😕": "confused", "😕": "confused",
"☹️": "slightly_frowning_face", "🙁": "slightly_frowning_face",
"🙁": "frowning",
"😣": "persevere", "😣": "persevere",
"😖": "confounded", "😖": "confounded",
"😫": "tired_face", "😫": "tired_face",
@@ -3708,7 +3706,7 @@ export const replacements = {
"🖌": "paintbrush", "🖌": "paintbrush",
"🔍": "mag", "🔍": "mag",
"🔎": "mag_right", "🔎": "mag_right",
"❤": "heart", "❤️": "heart",
"💛": "yellow_heart", "💛": "yellow_heart",
"💚": "green_heart", "💚": "green_heart",
"💙": "blue_heart", "💙": "blue_heart",
@@ -3944,7 +3942,6 @@ export const replacements = {
"🀄": "mahjong", "🀄": "mahjong",
"♠": "spades", "♠": "spades",
"♣": "clubs", "♣": "clubs",
"♥": "heart",
"♦": "diamonds", "♦": "diamonds",
"🎴": "flower_playing_cards", "🎴": "flower_playing_cards",
"💭": "thought_balloon", "💭": "thought_balloon",
@@ -4539,19 +4536,18 @@ export const replacements = {
"👨‍🦼": "man_in_motorized_wheelchair", "👨‍🦼": "man_in_motorized_wheelchair",
"👩‍🦯": "woman_with_probing_cane", "👩‍🦯": "woman_with_probing_cane",
"👨‍🦯": "man_with_probing_cane", "👨‍🦯": "man_with_probing_cane",
"🧎‍♀": "woman_kneeling", "🧎‍♀️": "woman_kneeling",
"🧎‍♂": "man_kneeling", "🧎‍♂️": "man_kneeling",
"🧍‍♂": "man_standing", "🧍‍♂️": "man_standing",
"🧍‍♀": "woman_standing", "🧍‍♀️": "woman_standing",
"🧏‍♀": "deaf_woman", "🧏‍♀️": "deaf_woman",
"🧏‍♂": "deaf_man", "🧏‍♂️": "deaf_man",
"🦻": "hear_with_hearing_aid", "🦻": "hear_with_hearing_aid",
"🦿": "mechanical_leg", "🦿": "mechanical_leg",
"🦾": "mechanical_arm", "🦾": "mechanical_arm",
"🤍": "white_heart", "🤍": "white_heart",
"🤎": "brown_heart", "🤎": "brown_heart",
"🏳️‍⚧": "transgender_flag", "🏳️‍⚧️": "transgender_flag",
"☹": "frowning", "☹️": "frowning",
"☻": "slight_smile", "☻": "slight_smile",
"♡": "heart",
}; };
+11 -7
View File
@@ -60,6 +60,10 @@
"code": "263a", "code": "263a",
"name": "relaxed" "name": "relaxed"
}, },
{
"code": "263b",
"name": "slight_smile"
},
{ {
"code": "1f60b", "code": "1f60b",
"name": "yum" "name": "yum"
@@ -185,12 +189,12 @@
"name": "confused" "name": "confused"
}, },
{ {
"code": "2639-fe0f", "code": "2639",
"name": "slightly_frowning_face" "name": "frowning"
}, },
{ {
"code": "1f641", "code": "1f641",
"name": "frowning_face" "name": "slightly_frowning_face"
}, },
{ {
"code": "1f623", "code": "1f623",
@@ -232,10 +236,6 @@
"code": "1f62f", "code": "1f62f",
"name": "hushed" "name": "hushed"
}, },
{
"code": "1f641",
"name": "frowning"
},
{ {
"code": "1f626", "code": "1f626",
"name": "frowning_face_with_open_mouth" "name": "frowning_face_with_open_mouth"
@@ -3664,6 +3664,10 @@
"code": "2764", "code": "2764",
"name": "heart" "name": "heart"
}, },
{
"code": "2661",
"name": "white_heart_suit"
},
{ {
"code": "1f49b", "code": "1f49b",
"name": "yellow_heart" "name": "yellow_heart"
-4
View File
@@ -263,10 +263,6 @@
"name": "slightly_frowning_face", "name": "slightly_frowning_face",
"diversity": false "diversity": false
}, },
{
"name": "frowning_face",
"diversity": false
},
{ {
"name": "open_mouth", "name": "open_mouth",
"diversity": false "diversity": false
+28 -8
View File
@@ -1,7 +1,7 @@
__PrettyText = require("pretty-text/pretty-text").default; __PrettyText = require("pretty-text/pretty-text").default;
__buildOptions = require("pretty-text/pretty-text").buildOptions; __buildOptions = require("pretty-text/pretty-text").buildOptions;
__performEmojiUnescape = require("pretty-text/emoji").performEmojiUnescape; __performEmojiUnescape = require("pretty-text/emoji").performEmojiUnescape;
__buildReplacementsList = require("pretty-text/emoji").buildReplacementsList; __emojiReplacementRegex = require("pretty-text/emoji").emojiReplacementRegex;
__performEmojiEscape = require("pretty-text/emoji").performEmojiEscape; __performEmojiEscape = require("pretty-text/emoji").performEmojiEscape;
__resetTranslationTree = require("pretty-text/engines/discourse-markdown/emoji") __resetTranslationTree = require("pretty-text/engines/discourse-markdown/emoji")
.resetTranslationTree; .resetTranslationTree;
@@ -28,18 +28,34 @@ __utils = require("discourse/lib/utilities");
__emojiUnicodeReplacer = null; __emojiUnicodeReplacer = null;
__setUnicode = function (replacements) { __setUnicode = function (replacements) {
let unicodeRegexp = new RegExp(__buildReplacementsList(replacements), "g"); const regexp = new RegExp(__emojiReplacementRegex, "g");
__emojiUnicodeReplacer = function (text) { __emojiUnicodeReplacer = function (text) {
unicodeRegexp.lastIndex = 0; regexp.lastIndex = 0;
let m; let m;
while ((m = unicodeRegexp.exec(text)) !== null) { while ((m = regexp.exec(text)) !== null) {
let replacement = ":" + replacements[m[0]] + ":"; let match = m[0];
let replacement = replacements[match];
if (!replacement) {
// if we can't find replacement for an emoji match
// attempts to look for the same without trailing variation selector
match = match.replace(/\ufe0f$/g, "");
replacement = replacements[match];
}
if (!replacement) {
continue;
}
replacement = ":" + replacement + ":";
const before = text.charAt(m.index - 1); const before = text.charAt(m.index - 1);
if (!/\B/.test(before)) { if (!/\B/.test(before)) {
replacement = "\u200b" + replacement; replacement = "\u200b" + replacement;
} }
text = text.replace(m[0], replacement); text = text.replace(match, replacement);
} }
// fixes Safari VARIATION SELECTOR-16 issue with some emojis // fixes Safari VARIATION SELECTOR-16 issue with some emojis
@@ -53,7 +69,9 @@ __setUnicode = function (replacements) {
__paths = {}; __paths = {};
function __getURLNoCDN(url) { function __getURLNoCDN(url) {
if (!url) return url; if (!url) {
return url;
}
// if it's a non relative URL, return it. // if it's a non relative URL, return it.
if (url !== "/" && !/^\/[^\/]/.test(url)) { if (url !== "/" && !/^\/[^\/]/.test(url)) {
@@ -63,7 +81,9 @@ function __getURLNoCDN(url) {
if (url.indexOf(__paths.baseUri) !== -1) { if (url.indexOf(__paths.baseUri) !== -1) {
return url; return url;
} }
if (url[0] !== "/") url = "/" + url; if (url[0] !== "/") {
url = "/" + url;
}
return __paths.baseUri + url; return __paths.baseUri + url;
} }
+8 -1
View File
@@ -112,6 +112,7 @@ describe PrettyText do
it "adds an only-emoji class when a line has only one emoji" do it "adds an only-emoji class when a line has only one emoji" do
md = <<~MD md = <<~MD
☹️
foo 😀 foo 😀
foo 😀 bar foo 😀 bar
:smile_cat: :smile_cat:
@@ -131,7 +132,8 @@ describe PrettyText do
MD MD
html = <<~HTML html = <<~HTML
<p>foo <img src="/images/emoji/twitter/grinning.png?v=#{Emoji::EMOJI_VERSION}" title=":grinning:" class="emoji" alt=":grinning:"><br> <p><img src="/images/emoji/twitter/frowning.png?v=#{Emoji::EMOJI_VERSION}" title=":frowning:" class="emoji only-emoji" alt=":frowning:"><br>
foo <img src="/images/emoji/twitter/grinning.png?v=#{Emoji::EMOJI_VERSION}" title=":grinning:" class="emoji" alt=":grinning:"><br>
foo <img src="/images/emoji/twitter/grinning.png?v=#{Emoji::EMOJI_VERSION}" title=":grinning:" class="emoji" alt=":grinning:"> bar<br> foo <img src="/images/emoji/twitter/grinning.png?v=#{Emoji::EMOJI_VERSION}" title=":grinning:" class="emoji" alt=":grinning:"> bar<br>
<img src="/images/emoji/twitter/smile_cat.png?v=#{Emoji::EMOJI_VERSION}" title=":smile_cat:" class="emoji only-emoji" alt=":smile_cat:"><br> <img src="/images/emoji/twitter/smile_cat.png?v=#{Emoji::EMOJI_VERSION}" title=":smile_cat:" class="emoji only-emoji" alt=":smile_cat:"><br>
<img src="/images/emoji/twitter/smile_cat.png?v=#{Emoji::EMOJI_VERSION}" title=":smile_cat:" class="emoji only-emoji" alt=":smile_cat:"> <img src="/images/emoji/twitter/smile_cat.png?v=#{Emoji::EMOJI_VERSION}" title=":smile_cat:" class="emoji only-emoji" alt=":smile_cat:"><br> <img src="/images/emoji/twitter/smile_cat.png?v=#{Emoji::EMOJI_VERSION}" title=":smile_cat:" class="emoji only-emoji" alt=":smile_cat:"> <img src="/images/emoji/twitter/smile_cat.png?v=#{Emoji::EMOJI_VERSION}" title=":smile_cat:" class="emoji only-emoji" alt=":smile_cat:"><br>
@@ -1109,7 +1111,12 @@ describe PrettyText do
end end
it "replaces some glyphs that are not in the emoji range" do it "replaces some glyphs that are not in the emoji range" do
expect(PrettyText.cook("☹")).to match(/\:frowning\:/)
expect(PrettyText.cook("☺")).to match(/\:relaxed\:/) expect(PrettyText.cook("☺")).to match(/\:relaxed\:/)
expect(PrettyText.cook("☻")).to match(/\:slight_smile\:/)
expect(PrettyText.cook("♡")).to match(/\:heart\:/)
expect(PrettyText.cook("❤")).to match(/\:heart\:/)
expect(PrettyText.cook("❤️")).to match(/\:heart\:/) # in emoji range but ensure it works along others
end end
it "replaces digits" do it "replaces digits" do