DEV: Use `Map()` to store emoji groups (#16065)
This commit is contained in:
parent
b135961b56
commit
b9c90d6a06
|
@ -17,14 +17,13 @@ import { underscore } from "@ember/string";
|
||||||
function customEmojis() {
|
function customEmojis() {
|
||||||
const list = extendedEmojiList();
|
const list = extendedEmojiList();
|
||||||
const groups = [];
|
const groups = [];
|
||||||
Object.keys(list).forEach((code) => {
|
for (const [code, emoji] of list.entries()) {
|
||||||
const emoji = list[code];
|
|
||||||
groups[emoji.group] = groups[emoji.group] || [];
|
groups[emoji.group] = groups[emoji.group] || [];
|
||||||
groups[emoji.group].push({
|
groups[emoji.group].push({
|
||||||
code,
|
code,
|
||||||
src: emojiUrlFor(code),
|
src: emojiUrlFor(code),
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,18 @@ import {
|
||||||
} from "pretty-text/emoji/data";
|
} from "pretty-text/emoji/data";
|
||||||
import { IMAGE_VERSION } from "pretty-text/emoji/version";
|
import { IMAGE_VERSION } from "pretty-text/emoji/version";
|
||||||
|
|
||||||
const extendedEmoji = {};
|
const extendedEmojiMap = new Map();
|
||||||
|
|
||||||
export function registerEmoji(code, url, group) {
|
export function registerEmoji(code, url, group) {
|
||||||
code = code.toLowerCase();
|
code = code.toLowerCase();
|
||||||
extendedEmoji[code] = { url, group };
|
extendedEmojiMap.set(code, { url, group });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extendedEmojiList() {
|
export function extendedEmojiList() {
|
||||||
return extendedEmoji;
|
return extendedEmojiMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
const emojiHash = {};
|
const emojiMap = new Map();
|
||||||
|
|
||||||
// https://github.com/mathiasbynens/emoji-regex/blob/main/text.js
|
// https://github.com/mathiasbynens/emoji-regex/blob/main/text.js
|
||||||
export const emojiReplacementRegex =
|
export const emojiReplacementRegex =
|
||||||
|
@ -30,12 +30,12 @@ function textEmojiRegex(inlineEmoji) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all default emojis
|
// add all default emojis
|
||||||
emojis.forEach((code) => (emojiHash[code] = true));
|
emojis.forEach((code) => emojiMap.set(code, true));
|
||||||
|
|
||||||
// and their aliases
|
// and their aliases
|
||||||
const aliasHash = {};
|
const aliasMap = new Map();
|
||||||
Object.keys(aliases).forEach((name) => {
|
Object.entries(aliases).forEach(([name, list]) => {
|
||||||
aliases[name].forEach((alias) => (aliasHash[alias] = name));
|
list.forEach((alias) => aliasMap.set(alias, name));
|
||||||
});
|
});
|
||||||
|
|
||||||
function isReplacableInlineEmoji(string, index, inlineEmoji) {
|
function isReplacableInlineEmoji(string, index, inlineEmoji) {
|
||||||
|
@ -84,7 +84,7 @@ export function performEmojiUnescape(string, opts) {
|
||||||
: "emoji";
|
: "emoji";
|
||||||
|
|
||||||
if (opts.class) {
|
if (opts.class) {
|
||||||
classes = `${classes} ${opts.class}`;
|
classes += ` ${opts.class}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isReplacable =
|
const isReplacable =
|
||||||
|
@ -131,23 +131,18 @@ export function performEmojiEscape(string, opts) {
|
||||||
|
|
||||||
export function isCustomEmoji(code, opts) {
|
export function isCustomEmoji(code, opts) {
|
||||||
code = code.toLowerCase();
|
code = code.toLowerCase();
|
||||||
if (extendedEmoji.hasOwnProperty(code)) {
|
return extendedEmojiMap.has(code) || opts?.customEmoji?.hasOwnProperty(code);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (opts && opts.customEmoji && opts.customEmoji.hasOwnProperty(code)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildEmojiUrl(code, opts) {
|
export function buildEmojiUrl(code, opts) {
|
||||||
let url;
|
let url;
|
||||||
code = String(code).toLowerCase();
|
code = String(code).toLowerCase();
|
||||||
if (extendedEmoji.hasOwnProperty(code)) {
|
|
||||||
url = extendedEmoji[code].url;
|
if (extendedEmojiMap.has(code)) {
|
||||||
|
url = extendedEmojiMap.get(code).url;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts && opts.customEmoji && opts.customEmoji[code]) {
|
if (opts.customEmoji?.[code]) {
|
||||||
url = opts.customEmoji[code].url || opts.customEmoji[code];
|
url = opts.customEmoji[code].url || opts.customEmoji[code];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,10 +154,11 @@ export function buildEmojiUrl(code, opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
opts.getURL &&
|
||||||
|
opts.emojiSet &&
|
||||||
noToneMatch &&
|
noToneMatch &&
|
||||||
!url &&
|
!url &&
|
||||||
(emojiHash.hasOwnProperty(noToneMatch[1]) ||
|
(emojiMap.has(noToneMatch[1]) || aliasMap.has(noToneMatch[1]))
|
||||||
aliasHash.hasOwnProperty(noToneMatch[1]))
|
|
||||||
) {
|
) {
|
||||||
url = opts.getURL(
|
url = opts.getURL(
|
||||||
`${emojiBasePath}/${opts.emojiSet}/${code.replace(/:t/, "/")}.png`
|
`${emojiBasePath}/${opts.emojiSet}/${code.replace(/:t/, "/")}.png`
|
||||||
|
@ -170,7 +166,7 @@ export function buildEmojiUrl(code, opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
url = url + "?v=" + IMAGE_VERSION;
|
url = `${url}?v=${IMAGE_VERSION}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
|
@ -178,34 +174,30 @@ export function buildEmojiUrl(code, opts) {
|
||||||
|
|
||||||
export function emojiExists(code) {
|
export function emojiExists(code) {
|
||||||
code = code.toLowerCase();
|
code = code.toLowerCase();
|
||||||
return !!(
|
return extendedEmojiMap.has(code) || emojiMap.has(code) || aliasMap.has(code);
|
||||||
extendedEmoji.hasOwnProperty(code) ||
|
|
||||||
emojiHash.hasOwnProperty(code) ||
|
|
||||||
aliasHash.hasOwnProperty(code)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let toSearch;
|
let toSearch;
|
||||||
export function emojiSearch(term, options) {
|
export function emojiSearch(term, options) {
|
||||||
const maxResults = (options && options["maxResults"]) || -1;
|
const maxResults = options?.maxResults;
|
||||||
const diversity = options && options.diversity;
|
const diversity = options?.diversity;
|
||||||
if (maxResults === 0) {
|
if (maxResults === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
toSearch =
|
if (!toSearch) {
|
||||||
toSearch ||
|
toSearch = [
|
||||||
[
|
...emojiMap.keys(),
|
||||||
...Object.keys(emojiHash),
|
...extendedEmojiMap.keys(),
|
||||||
...Object.keys(extendedEmoji),
|
...aliasMap.keys(),
|
||||||
...Object.keys(aliasHash),
|
|
||||||
].sort();
|
].sort();
|
||||||
|
}
|
||||||
|
|
||||||
const results = [];
|
const results = [];
|
||||||
|
|
||||||
function addResult(t) {
|
function addResult(t) {
|
||||||
const val = aliasHash[t] || t;
|
const val = aliasMap.get(t) || t;
|
||||||
if (results.indexOf(val) === -1) {
|
if (!results.includes(val)) {
|
||||||
if (diversity && diversity > 1 && isSkinTonableEmoji(val)) {
|
if (diversity && diversity > 1 && isSkinTonableEmoji(val)) {
|
||||||
results.push(`${val}:t${diversity}`);
|
results.push(`${val}:t${diversity}`);
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,8 +207,7 @@ export function emojiSearch(term, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if term matches from beginning
|
// if term matches from beginning
|
||||||
for (let i = 0; i < toSearch.length; i++) {
|
for (const item of toSearch) {
|
||||||
const item = toSearch[i];
|
|
||||||
if (item.indexOf(term) === 0) {
|
if (item.indexOf(term) === 0) {
|
||||||
addResult(item);
|
addResult(item);
|
||||||
}
|
}
|
||||||
|
@ -230,24 +221,23 @@ export function emojiSearch(term, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < toSearch.length; i++) {
|
for (const item of toSearch) {
|
||||||
const item = toSearch[i];
|
|
||||||
if (item.indexOf(term) > 0) {
|
if (item.indexOf(term) > 0) {
|
||||||
addResult(item);
|
addResult(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxResults === -1) {
|
if (maxResults) {
|
||||||
return results;
|
|
||||||
} else {
|
|
||||||
return results.slice(0, maxResults);
|
return results.slice(0, maxResults);
|
||||||
|
} else {
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isSkinTonableEmoji(term) {
|
export function isSkinTonableEmoji(term) {
|
||||||
const match = term.split(":").filter(Boolean)[0];
|
const match = term.split(":").filter(Boolean)[0];
|
||||||
if (match) {
|
if (match) {
|
||||||
return tonableEmojis.indexOf(match) !== -1;
|
return tonableEmojis.includes(match);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue