FIX: allows to have custom emoji translation without static file (#9893)
This commit is contained in:
@@ -483,8 +483,15 @@ export default Component.extend({
|
||||
}
|
||||
}
|
||||
|
||||
if (translations[full]) {
|
||||
return resolve([translations[full]]);
|
||||
// note this will only work for emojis starting with :
|
||||
// eg: :-)
|
||||
const allTranslations = Object.assign(
|
||||
{},
|
||||
translations,
|
||||
this.getWithDefault("site.custom_emoji_translation", {})
|
||||
);
|
||||
if (allTranslations[full]) {
|
||||
return resolve([allTranslations[full]]);
|
||||
}
|
||||
|
||||
const match = term.match(/^:?(.*?):t([2-6])?$/);
|
||||
|
||||
@@ -18,6 +18,7 @@ function getOpts(opts) {
|
||||
getURL: getURLWithCDN,
|
||||
currentUser: Discourse.__container__.lookup("current-user:main"),
|
||||
censoredRegexp: site.censored_regexp,
|
||||
customEmojiTranslation: site.custom_emoji_translation,
|
||||
siteSettings,
|
||||
formatUsername
|
||||
},
|
||||
|
||||
@@ -98,13 +98,18 @@ export function performEmojiUnescape(string, opts) {
|
||||
|
||||
const inlineEmoji = opts.inlineEmoji;
|
||||
const regexp = unicodeRegexp(inlineEmoji);
|
||||
const allTranslations = Object.assign(
|
||||
{},
|
||||
translations,
|
||||
opts.customEmojiTranslation || {}
|
||||
);
|
||||
|
||||
return string.replace(regexp, (m, index) => {
|
||||
const isEmoticon = opts.enableEmojiShortcuts && !!translations[m];
|
||||
const isEmoticon = opts.enableEmojiShortcuts && !!allTranslations[m];
|
||||
const isUnicodeEmoticon = !!replacements[m];
|
||||
let emojiVal;
|
||||
if (isEmoticon) {
|
||||
emojiVal = translations[m];
|
||||
emojiVal = allTranslations[m];
|
||||
} else if (isUnicodeEmoticon) {
|
||||
emojiVal = replacements[m];
|
||||
} else {
|
||||
@@ -131,11 +136,16 @@ export function performEmojiUnescape(string, opts) {
|
||||
export function performEmojiEscape(string, opts) {
|
||||
const inlineEmoji = opts.inlineEmoji;
|
||||
const regexp = unicodeRegexp(inlineEmoji);
|
||||
const allTranslations = Object.assign(
|
||||
{},
|
||||
translations,
|
||||
opts.customEmojiTranslation || {}
|
||||
);
|
||||
|
||||
return string.replace(regexp, (m, index) => {
|
||||
if (isReplacableInlineEmoji(string, index, inlineEmoji)) {
|
||||
if (!!translations[m]) {
|
||||
return opts.emojiShortcuts ? `:${translations[m]}:` : m;
|
||||
if (!!allTranslations[m]) {
|
||||
return opts.emojiShortcuts ? `:${allTranslations[m]}:` : m;
|
||||
} else if (!!replacements[m]) {
|
||||
return `:${replacements[m]}:`;
|
||||
}
|
||||
|
||||
@@ -5,15 +5,25 @@ const MAX_NAME_LENGTH = 60;
|
||||
|
||||
let translationTree = null;
|
||||
|
||||
export function resetTranslationTree() {
|
||||
translationTree = null;
|
||||
}
|
||||
|
||||
// This allows us to efficiently search for aliases
|
||||
// We build a data structure that allows us to quickly
|
||||
// search through our N next chars to see if any match
|
||||
// one of our alias emojis.
|
||||
function buildTranslationTree() {
|
||||
function buildTranslationTree(customEmojiTranslation) {
|
||||
let tree = [];
|
||||
let lastNode;
|
||||
|
||||
Object.keys(translations).forEach(key => {
|
||||
const allTranslations = Object.assign(
|
||||
{},
|
||||
translations,
|
||||
customEmojiTranslation || {}
|
||||
);
|
||||
|
||||
Object.keys(allTranslations).forEach(key => {
|
||||
let node = tree;
|
||||
|
||||
for (let i = 0; i < key.length; i++) {
|
||||
@@ -37,7 +47,7 @@ function buildTranslationTree() {
|
||||
}
|
||||
}
|
||||
|
||||
lastNode[2] = translations[key];
|
||||
lastNode[2] = allTranslations[key];
|
||||
});
|
||||
|
||||
return tree;
|
||||
@@ -114,8 +124,14 @@ function getEmojiTokenByName(name, state) {
|
||||
}
|
||||
}
|
||||
|
||||
function getEmojiTokenByTranslation(content, pos, state) {
|
||||
translationTree = translationTree || buildTranslationTree();
|
||||
function getEmojiTokenByTranslation(
|
||||
content,
|
||||
pos,
|
||||
state,
|
||||
customEmojiTranslation
|
||||
) {
|
||||
translationTree =
|
||||
translationTree || buildTranslationTree(customEmojiTranslation);
|
||||
|
||||
let t = translationTree;
|
||||
let start = pos;
|
||||
@@ -175,7 +191,8 @@ function applyEmoji(
|
||||
state,
|
||||
emojiUnicodeReplacer,
|
||||
enableShortcuts,
|
||||
inlineEmoji
|
||||
inlineEmoji,
|
||||
customEmojiTranslation
|
||||
) {
|
||||
let result = null;
|
||||
let start = 0;
|
||||
@@ -201,7 +218,12 @@ function applyEmoji(
|
||||
|
||||
if (enableShortcuts && !token) {
|
||||
// handle aliases (note: we can't do this in inline cause ; is not a split point)
|
||||
const info = getEmojiTokenByTranslation(content, i, state);
|
||||
const info = getEmojiTokenByTranslation(
|
||||
content,
|
||||
i,
|
||||
state,
|
||||
customEmojiTranslation
|
||||
);
|
||||
|
||||
if (info) {
|
||||
offset = info.pos - i;
|
||||
@@ -310,7 +332,8 @@ export function setup(helper) {
|
||||
s,
|
||||
md.options.discourse.emojiUnicodeReplacer,
|
||||
md.options.discourse.features.emojiShortcuts,
|
||||
md.options.discourse.features.inlineEmoji
|
||||
md.options.discourse.features.inlineEmoji,
|
||||
md.options.discourse.customEmojiTranslation
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -30,7 +30,8 @@ export function buildOptions(state) {
|
||||
previewing,
|
||||
linkify,
|
||||
censoredRegexp,
|
||||
disableEmojis
|
||||
disableEmojis,
|
||||
customEmojiTranslation
|
||||
} = state;
|
||||
|
||||
let features = {
|
||||
@@ -68,6 +69,7 @@ export function buildOptions(state) {
|
||||
emojiUnicodeReplacer,
|
||||
lookupUploadUrls,
|
||||
censoredRegexp,
|
||||
customEmojiTranslation,
|
||||
allowedHrefSchemes: siteSettings.allowed_href_schemes
|
||||
? siteSettings.allowed_href_schemes.split("|")
|
||||
: null,
|
||||
|
||||
Reference in New Issue
Block a user