[build] upgrade eslint to 9.37.0 (#88)

Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/88
Co-authored-by: Zoë Bijl <moiety@noreply.codeberg.org>
Co-committed-by: Zoë Bijl <moiety@noreply.codeberg.org>
This commit is contained in:
Zoë Bijl
2025-10-12 13:42:02 +02:00
committed by tobi
parent 75d7a62693
commit 1ff70886a1
975 changed files with 22196 additions and 21964 deletions
@@ -1,97 +1,97 @@
import emojify from '../emoji';
import emojify from "../emoji";
describe('emoji', () => {
describe('.emojify', () => {
it('ignores unknown shortcodes', () => {
expect(emojify(':foobarbazfake:')).toEqual(':foobarbazfake:');
describe("emoji", () => {
describe(".emojify", () => {
it("ignores unknown shortcodes", () => {
expect(emojify(":foobarbazfake:")).toEqual(":foobarbazfake:");
});
it('ignores shortcodes inside of tags', () => {
expect(emojify('<p data-foo=":smile:"></p>')).toEqual('<p data-foo=":smile:"></p>');
it("ignores shortcodes inside of tags", () => {
expect(emojify("<p data-foo=\":smile:\"></p>")).toEqual("<p data-foo=\":smile:\"></p>");
});
it('works with unclosed tags', () => {
expect(emojify('hello>')).toEqual('hello&gt;');
expect(emojify('<hello')).toEqual('');
it("works with unclosed tags", () => {
expect(emojify("hello>")).toEqual("hello&gt;");
expect(emojify("<hello")).toEqual("");
});
it('works with unclosed shortcodes', () => {
expect(emojify('smile:')).toEqual('smile:');
expect(emojify(':smile')).toEqual(':smile');
it("works with unclosed shortcodes", () => {
expect(emojify("smile:")).toEqual("smile:");
expect(emojify(":smile")).toEqual(":smile");
});
it('does unicode', () => {
expect(emojify('\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66')).toEqual(
'<img draggable="false" class="emojione" alt="👩‍👩‍👦‍👦" title=":woman-woman-boy-boy:" src="/emoji/1f469-200d-1f469-200d-1f466-200d-1f466.svg">');
expect(emojify('👨‍👩‍👧‍👧')).toEqual(
'<img draggable="false" class="emojione" alt="👨‍👩‍👧‍👧" title=":man-woman-girl-girl:" src="/emoji/1f468-200d-1f469-200d-1f467-200d-1f467.svg">');
expect(emojify('👩‍👩‍👦')).toEqual('<img draggable="false" class="emojione" alt="👩‍👩‍👦" title=":woman-woman-boy:" src="/emoji/1f469-200d-1f469-200d-1f466.svg">');
expect(emojify('\u2757')).toEqual(
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg">');
it("does unicode", () => {
expect(emojify("\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66")).toEqual(
"<img draggable=\"false\" class=\"emojione\" alt=\"👩‍👩‍👦‍👦\" title=\":woman-woman-boy-boy:\" src=\"/emoji/1f469-200d-1f469-200d-1f466-200d-1f466.svg\">");
expect(emojify("👨‍👩‍👧‍👧")).toEqual(
"<img draggable=\"false\" class=\"emojione\" alt=\"👨‍👩‍👧‍👧\" title=\":man-woman-girl-girl:\" src=\"/emoji/1f468-200d-1f469-200d-1f467-200d-1f467.svg\">");
expect(emojify("👩‍👩‍👦")).toEqual("<img draggable=\"false\" class=\"emojione\" alt=\"👩‍👩‍👦\" title=\":woman-woman-boy:\" src=\"/emoji/1f469-200d-1f469-200d-1f466.svg\">");
expect(emojify("\u2757")).toEqual(
"<img draggable=\"false\" class=\"emojione\" alt=\"❗\" title=\":exclamation:\" src=\"/emoji/2757.svg\">");
});
it('does multiple unicode', () => {
expect(emojify('\u2757 #\uFE0F\u20E3')).toEqual(
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg"> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg">');
expect(emojify('\u2757#\uFE0F\u20E3')).toEqual(
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg"><img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg">');
expect(emojify('\u2757 #\uFE0F\u20E3 \u2757')).toEqual(
'<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg"> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg"> <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg">');
expect(emojify('foo \u2757 #\uFE0F\u20E3 bar')).toEqual(
'foo <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg"> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg"> bar');
it("does multiple unicode", () => {
expect(emojify("\u2757 #\uFE0F\u20E3")).toEqual(
"<img draggable=\"false\" class=\"emojione\" alt=\"❗\" title=\":exclamation:\" src=\"/emoji/2757.svg\"> <img draggable=\"false\" class=\"emojione\" alt=\"#️⃣\" title=\":hash:\" src=\"/emoji/23-20e3.svg\">");
expect(emojify("\u2757#\uFE0F\u20E3")).toEqual(
"<img draggable=\"false\" class=\"emojione\" alt=\"❗\" title=\":exclamation:\" src=\"/emoji/2757.svg\"><img draggable=\"false\" class=\"emojione\" alt=\"#️⃣\" title=\":hash:\" src=\"/emoji/23-20e3.svg\">");
expect(emojify("\u2757 #\uFE0F\u20E3 \u2757")).toEqual(
"<img draggable=\"false\" class=\"emojione\" alt=\"❗\" title=\":exclamation:\" src=\"/emoji/2757.svg\"> <img draggable=\"false\" class=\"emojione\" alt=\"#️⃣\" title=\":hash:\" src=\"/emoji/23-20e3.svg\"> <img draggable=\"false\" class=\"emojione\" alt=\"❗\" title=\":exclamation:\" src=\"/emoji/2757.svg\">");
expect(emojify("foo \u2757 #\uFE0F\u20E3 bar")).toEqual(
"foo <img draggable=\"false\" class=\"emojione\" alt=\"❗\" title=\":exclamation:\" src=\"/emoji/2757.svg\"> <img draggable=\"false\" class=\"emojione\" alt=\"#️⃣\" title=\":hash:\" src=\"/emoji/23-20e3.svg\"> bar");
});
it('ignores unicode inside of tags', () => {
expect(emojify('<p data-foo="\uD83D\uDC69\uD83D\uDC69\uD83D\uDC66"></p>')).toEqual('<p data-foo="\uD83D\uDC69\uD83D\uDC69\uD83D\uDC66"></p>');
it("ignores unicode inside of tags", () => {
expect(emojify("<p data-foo=\"\uD83D\uDC69\uD83D\uDC69\uD83D\uDC66\"></p>")).toEqual("<p data-foo=\"\uD83D\uDC69\uD83D\uDC69\uD83D\uDC66\"></p>");
});
it('does multiple emoji properly (issue 5188)', () => {
expect(emojify('👌🌈💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg"><img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg"><img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg">');
expect(emojify('👌 🌈 💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg"> <img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg"> <img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg">');
it("does multiple emoji properly (issue 5188)", () => {
expect(emojify("👌🌈💕")).toEqual("<img draggable=\"false\" class=\"emojione\" alt=\"👌\" title=\":ok_hand:\" src=\"/emoji/1f44c.svg\"><img draggable=\"false\" class=\"emojione\" alt=\"🌈\" title=\":rainbow:\" src=\"/emoji/1f308.svg\"><img draggable=\"false\" class=\"emojione\" alt=\"💕\" title=\":two_hearts:\" src=\"/emoji/1f495.svg\">");
expect(emojify("👌 🌈 💕")).toEqual("<img draggable=\"false\" class=\"emojione\" alt=\"👌\" title=\":ok_hand:\" src=\"/emoji/1f44c.svg\"> <img draggable=\"false\" class=\"emojione\" alt=\"🌈\" title=\":rainbow:\" src=\"/emoji/1f308.svg\"> <img draggable=\"false\" class=\"emojione\" alt=\"💕\" title=\":two_hearts:\" src=\"/emoji/1f495.svg\">");
});
it('does an emoji that has no shortcode', () => {
expect(emojify('👁‍🗨')).toEqual('<img draggable="false" class="emojione" alt="👁‍🗨" title="" src="/emoji/1f441-200d-1f5e8.svg">');
it("does an emoji that has no shortcode", () => {
expect(emojify("👁‍🗨")).toEqual("<img draggable=\"false\" class=\"emojione\" alt=\"👁‍🗨\" title=\"\" src=\"/emoji/1f441-200d-1f5e8.svg\">");
});
it('does an emoji whose filename is irregular', () => {
expect(emojify('↙️')).toEqual('<img draggable="false" class="emojione" alt="↙️" title=":arrow_lower_left:" src="/emoji/2199.svg">');
it("does an emoji whose filename is irregular", () => {
expect(emojify("↙️")).toEqual("<img draggable=\"false\" class=\"emojione\" alt=\"↙️\" title=\":arrow_lower_left:\" src=\"/emoji/2199.svg\">");
});
it('avoid emojifying on invisible text', () => {
expect(emojify('<a href="http://example.com/test%F0%9F%98%84"><span class="invisible">http://</span><span class="ellipsis">example.com/te</span><span class="invisible">st😄</span></a>'))
.toEqual('<a href="http://example.com/test%F0%9F%98%84"><span class="invisible">http://</span><span class="ellipsis">example.com/te</span><span class="invisible">st😄</span></a>');
expect(emojify('<span class="invisible">:luigi:</span>', { ':luigi:': { static_url: 'luigi.exe' } }))
.toEqual('<span class="invisible">:luigi:</span>');
it("avoid emojifying on invisible text", () => {
expect(emojify("<a href=\"http://example.com/test%F0%9F%98%84\"><span class=\"invisible\">http://</span><span class=\"ellipsis\">example.com/te</span><span class=\"invisible\">st😄</span></a>"))
.toEqual("<a href=\"http://example.com/test%F0%9F%98%84\"><span class=\"invisible\">http://</span><span class=\"ellipsis\">example.com/te</span><span class=\"invisible\">st😄</span></a>");
expect(emojify("<span class=\"invisible\">:luigi:</span>", { ":luigi:": { static_url: "luigi.exe" } }))
.toEqual("<span class=\"invisible\">:luigi:</span>");
});
it('avoid emojifying on invisible text with nested tags', () => {
expect(emojify('<span class="invisible">😄<span class="foo">bar</span>😴</span>😇'))
.toEqual('<span class="invisible">😄<span class="foo">bar</span>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg">');
expect(emojify('<span class="invisible">😄<span class="invisible">😕</span>😴</span>😇'))
.toEqual('<span class="invisible">😄<span class="invisible">😕</span>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg">');
expect(emojify('<span class="invisible">😄<br>😴</span>😇'))
.toEqual('<span class="invisible">😄<br>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg">');
it("avoid emojifying on invisible text with nested tags", () => {
expect(emojify("<span class=\"invisible\">😄<span class=\"foo\">bar</span>😴</span>😇"))
.toEqual("<span class=\"invisible\">😄<span class=\"foo\">bar</span>😴</span><img draggable=\"false\" class=\"emojione\" alt=\"😇\" title=\":innocent:\" src=\"/emoji/1f607.svg\">");
expect(emojify("<span class=\"invisible\">😄<span class=\"invisible\">😕</span>😴</span>😇"))
.toEqual("<span class=\"invisible\">😄<span class=\"invisible\">😕</span>😴</span><img draggable=\"false\" class=\"emojione\" alt=\"😇\" title=\":innocent:\" src=\"/emoji/1f607.svg\">");
expect(emojify("<span class=\"invisible\">😄<br>😴</span>😇"))
.toEqual("<span class=\"invisible\">😄<br>😴</span><img draggable=\"false\" class=\"emojione\" alt=\"😇\" title=\":innocent:\" src=\"/emoji/1f607.svg\">");
});
it('does not emojify emojis with textual presentation VS15 character', () => {
expect(emojify('✴︎')) // This is U+2734 EIGHT POINTED BLACK STAR then U+FE0E VARIATION SELECTOR-15
.toEqual('✴︎');
it("does not emojify emojis with textual presentation VS15 character", () => {
expect(emojify("✴︎")) // This is U+2734 EIGHT POINTED BLACK STAR then U+FE0E VARIATION SELECTOR-15
.toEqual("✴︎");
});
it('does an simple emoji properly', () => {
expect(emojify('♀♂'))
.toEqual('<img draggable="false" class="emojione" alt="♀" title=":female_sign:" src="/emoji/2640.svg"><img draggable="false" class="emojione" alt="♂" title=":male_sign:" src="/emoji/2642.svg">');
it("does an simple emoji properly", () => {
expect(emojify("♀♂"))
.toEqual("<img draggable=\"false\" class=\"emojione\" alt=\"♀\" title=\":female_sign:\" src=\"/emoji/2640.svg\"><img draggable=\"false\" class=\"emojione\" alt=\"♂\" title=\":male_sign:\" src=\"/emoji/2642.svg\">");
});
it('does an emoji containing ZWJ properly', () => {
expect(emojify('💂‍♀️💂‍♂️'))
.toEqual('<img draggable="false" class="emojione" alt="💂\u200D♀️" title=":female-guard:" src="/emoji/1f482-200d-2640-fe0f_border.svg"><img draggable="false" class="emojione" alt="💂\u200D♂️" title=":male-guard:" src="/emoji/1f482-200d-2642-fe0f_border.svg">');
it("does an emoji containing ZWJ properly", () => {
expect(emojify("💂‍♀️💂‍♂️"))
.toEqual("<img draggable=\"false\" class=\"emojione\" alt=\"💂\u200D♀️\" title=\":female-guard:\" src=\"/emoji/1f482-200d-2640-fe0f_border.svg\"><img draggable=\"false\" class=\"emojione\" alt=\"💂\u200D♂️\" title=\":male-guard:\" src=\"/emoji/1f482-200d-2642-fe0f_border.svg\">");
});
it('keeps ordering as expected (issue fixed by PR 20677)', () => {
expect(emojify('<p>💕 <a class="hashtag" href="https://example.com/tags/foo" rel="nofollow noopener noreferrer" target="_blank">#<span>foo</span></a> test: foo.</p>'))
.toEqual('<p><img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg"> <a class="hashtag" href="https://example.com/tags/foo" rel="nofollow noopener noreferrer" target="_blank">#<span>foo</span></a> test: foo.</p>');
it("keeps ordering as expected (issue fixed by PR 20677)", () => {
expect(emojify("<p>💕 <a class=\"hashtag\" href=\"https://example.com/tags/foo\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">#<span>foo</span></a> test: foo.</p>"))
.toEqual("<p><img draggable=\"false\" class=\"emojione\" alt=\"💕\" title=\":two_hearts:\" src=\"/emoji/1f495.svg\"> <a class=\"hashtag\" href=\"https://example.com/tags/foo\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">#<span>foo</span></a> test: foo.</p>");
});
});
});
@@ -1,177 +1,177 @@
import { emojiIndex } from 'emoji-mart';
import { pick } from 'lodash';
import { emojiIndex } from "emoji-mart";
import { pick } from "lodash";
import { search } from '../emoji_mart_search_light';
import { search } from "../emoji_mart_search_light";
const trimEmojis = emoji => pick(emoji, ['id', 'unified', 'native', 'custom']);
const trimEmojis = emoji => pick(emoji, ["id", "unified", "native", "custom"]);
describe('emoji_index', () => {
it('should give same result for emoji_index_light and emoji-mart', () => {
describe("emoji_index", () => {
it("should give same result for emoji_index_light and emoji-mart", () => {
const expected = [
{
id: 'pineapple',
unified: '1f34d',
native: '🍍',
id: "pineapple",
unified: "1f34d",
native: "🍍",
},
];
expect(search('pineapple').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('pineapple').map(trimEmojis)).toEqual(expected);
expect(search("pineapple").map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search("pineapple").map(trimEmojis)).toEqual(expected);
});
it('orders search results correctly', () => {
it("orders search results correctly", () => {
const expected = [
{
id: 'apple',
unified: '1f34e',
native: '🍎',
id: "apple",
unified: "1f34e",
native: "🍎",
},
{
id: 'pineapple',
unified: '1f34d',
native: '🍍',
id: "pineapple",
unified: "1f34d",
native: "🍍",
},
{
id: 'green_apple',
unified: '1f34f',
native: '🍏',
id: "green_apple",
unified: "1f34f",
native: "🍏",
},
{
id: 'iphone',
unified: '1f4f1',
native: '📱',
id: "iphone",
unified: "1f4f1",
native: "📱",
},
];
expect(search('apple').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('apple').map(trimEmojis)).toEqual(expected);
expect(search("apple").map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search("apple").map(trimEmojis)).toEqual(expected);
});
it('can include/exclude categories', () => {
expect(search('flag', { include: ['people'] })).toEqual([]);
expect(emojiIndex.search('flag', { include: ['people'] })).toEqual([]);
it("can include/exclude categories", () => {
expect(search("flag", { include: ["people"] })).toEqual([]);
expect(emojiIndex.search("flag", { include: ["people"] })).toEqual([]);
});
it('(different behavior from emoji-mart) do not erases custom emoji if not passed again', () => {
it("(different behavior from emoji-mart) do not erases custom emoji if not passed again", () => {
const custom = [
{
id: 'mastodon',
name: 'mastodon',
short_names: ['mastodon'],
text: '',
id: "mastodon",
name: "mastodon",
short_names: ["mastodon"],
text: "",
emoticons: [],
keywords: ['mastodon'],
imageUrl: 'http://example.com',
keywords: ["mastodon"],
imageUrl: "http://example.com",
custom: true,
},
];
search('', { custom });
emojiIndex.search('', { custom });
search("", { custom });
emojiIndex.search("", { custom });
const expected = [];
const lightExpected = [
{
id: 'mastodon',
id: "mastodon",
custom: true,
},
];
expect(search('masto').map(trimEmojis)).toEqual(lightExpected);
expect(emojiIndex.search('masto').map(trimEmojis)).toEqual(expected);
expect(search("masto").map(trimEmojis)).toEqual(lightExpected);
expect(emojiIndex.search("masto").map(trimEmojis)).toEqual(expected);
});
it('(different behavior from emoji-mart) erases custom emoji if another is passed', () => {
it("(different behavior from emoji-mart) erases custom emoji if another is passed", () => {
const custom = [
{
id: 'mastodon',
name: 'mastodon',
short_names: ['mastodon'],
text: '',
id: "mastodon",
name: "mastodon",
short_names: ["mastodon"],
text: "",
emoticons: [],
keywords: ['mastodon'],
imageUrl: 'http://example.com',
keywords: ["mastodon"],
imageUrl: "http://example.com",
custom: true,
},
];
search('', { custom });
emojiIndex.search('', { custom });
search("", { custom });
emojiIndex.search("", { custom });
const expected = [];
expect(search('masto', { custom: [] }).map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('masto').map(trimEmojis)).toEqual(expected);
expect(search("masto", { custom: [] }).map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search("masto").map(trimEmojis)).toEqual(expected);
});
it('handles custom emoji', () => {
it("handles custom emoji", () => {
const custom = [
{
id: 'mastodon',
name: 'mastodon',
short_names: ['mastodon'],
text: '',
id: "mastodon",
name: "mastodon",
short_names: ["mastodon"],
text: "",
emoticons: [],
keywords: ['mastodon'],
imageUrl: 'http://example.com',
keywords: ["mastodon"],
imageUrl: "http://example.com",
custom: true,
},
];
search('', { custom });
emojiIndex.search('', { custom });
search("", { custom });
emojiIndex.search("", { custom });
const expected = [
{
id: 'mastodon',
id: "mastodon",
custom: true,
},
];
expect(search('masto', { custom }).map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('masto', { custom }).map(trimEmojis)).toEqual(expected);
expect(search("masto", { custom }).map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search("masto", { custom }).map(trimEmojis)).toEqual(expected);
});
it('should filter only emojis we care about, exclude pineapple', () => {
const emojisToShowFilter = emoji => emoji.unified !== '1F34D';
expect(search('apple', { emojisToShowFilter }).map((obj) => obj.id))
.not.toContain('pineapple');
expect(emojiIndex.search('apple', { emojisToShowFilter }).map((obj) => obj.id))
.not.toContain('pineapple');
it("should filter only emojis we care about, exclude pineapple", () => {
const emojisToShowFilter = emoji => emoji.unified !== "1F34D";
expect(search("apple", { emojisToShowFilter }).map((obj) => obj.id))
.not.toContain("pineapple");
expect(emojiIndex.search("apple", { emojisToShowFilter }).map((obj) => obj.id))
.not.toContain("pineapple");
});
it('does an emoji whose unified name is irregular', () => {
it("does an emoji whose unified name is irregular", () => {
const expected = [
{
'id': 'water_polo',
'unified': '1f93d',
'native': '🤽',
"id": "water_polo",
"unified": "1f93d",
"native": "🤽",
},
{
'id': 'man-playing-water-polo',
'unified': '1f93d-200d-2642-fe0f',
'native': '🤽‍♂️',
"id": "man-playing-water-polo",
"unified": "1f93d-200d-2642-fe0f",
"native": "🤽‍♂️",
},
{
'id': 'woman-playing-water-polo',
'unified': '1f93d-200d-2640-fe0f',
'native': '🤽‍♀️',
"id": "woman-playing-water-polo",
"unified": "1f93d-200d-2640-fe0f",
"native": "🤽‍♀️",
},
];
expect(search('polo').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('polo').map(trimEmojis)).toEqual(expected);
expect(search("polo").map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search("polo").map(trimEmojis)).toEqual(expected);
});
it('can search for thinking_face', () => {
it("can search for thinking_face", () => {
const expected = [
{
id: 'thinking_face',
unified: '1f914',
native: '🤔',
id: "thinking_face",
unified: "1f914",
native: "🤔",
},
];
expect(search('thinking_fac').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('thinking_fac').map(trimEmojis)).toEqual(expected);
expect(search("thinking_fac").map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search("thinking_fac").map(trimEmojis)).toEqual(expected);
});
it('can search for woman-facepalming', () => {
it("can search for woman-facepalming", () => {
const expected = [
{
id: 'woman-facepalming',
unified: '1f926-200d-2640-fe0f',
native: '🤦‍♀️',
id: "woman-facepalming",
unified: "1f926-200d-2640-fe0f",
native: "🤦‍♀️",
},
];
expect(search('woman-facep').map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search('woman-facep').map(trimEmojis)).toEqual(expected);
expect(search("woman-facep").map(trimEmojis)).toEqual(expected);
expect(emojiIndex.search("woman-facep").map(trimEmojis)).toEqual(expected);
});
});
+43 -41
View File
@@ -1,10 +1,10 @@
import Trie from 'substring-trie';
import Trie from "substring-trie";
import { assetHost } from 'mastodon/utils/config';
import { assetHost } from "mastodon/utils/config";
import { autoPlayGif } from '../../initial_state';
import { autoPlayGif } from "../../initial_state";
import unicodeMapping from './emoji_unicode_mapping_light';
import unicodeMapping from "./emoji_unicode_mapping_light";
const trie = new Trie(Object.keys(unicodeMapping));
@@ -14,12 +14,12 @@ const emojiFilenames = (emojis) => {
};
// Emoji requiring extra borders depending on theme
const darkEmoji = emojiFilenames(['🎱', '🐜', '⚫', '🖤', '⬛', '◼️', '◾', '◼️', '✒️', '▪️', '💣', '🎳', '📷', '📸', '♣️', '🕶️', '✴️', '🔌', '💂‍♀️', '📽️', '🍳', '🦍', '💂', '🔪', '🕳️', '🕹️', '🕋', '🖊️', '🖋️', '💂‍♂️', '🎤', '🎓', '🎥', '🎼', '♠️', '🎩', '🦃', '📼', '📹', '🎮', '🐃', '🏴', '🐞', '🕺', '📱', '📲', '🚲']);
const lightEmoji = emojiFilenames(['👽', '⚾', '🐔', '☁️', '💨', '🕊️', '👀', '🍥', '👻', '🐐', '❕', '❔', '⛸️', '🌩️', '🔊', '🔇', '📃', '🌧️', '🐏', '🍚', '🍙', '🐓', '🐑', '💀', '☠️', '🌨️', '🔉', '🔈', '💬', '💭', '🏐', '🏳️', '⚪', '⬜', '◽', '◻️', '▫️']);
const darkEmoji = emojiFilenames(["🎱", "🐜", "⚫", "🖤", "⬛", "◼️", "◾", "◼️", "✒️", "▪️", "💣", "🎳", "📷", "📸", "♣️", "🕶️", "✴️", "🔌", "💂‍♀️", "📽️", "🍳", "🦍", "💂", "🔪", "🕳️", "🕹️", "🕋", "🖊️", "🖋️", "💂‍♂️", "🎤", "🎓", "🎥", "🎼", "♠️", "🎩", "🦃", "📼", "📹", "🎮", "🐃", "🏴", "🐞", "🕺", "📱", "📲", "🚲"]);
const lightEmoji = emojiFilenames(["👽", "⚾", "🐔", "☁️", "💨", "🕊️", "👀", "🍥", "👻", "🐐", "❕", "❔", "⛸️", "🌩️", "🔊", "🔇", "📃", "🌧️", "🐏", "🍚", "🍙", "🐓", "🐑", "💀", "☠️", "🌨️", "🔉", "🔈", "💬", "💭", "🏐", "🏳️", "⚪", "⬜", "◽", "◻️", "▫️"]);
const emojiFilename = (filename) => {
const borderedEmoji = (document.body && document.body.classList.contains('theme-mastodon-light')) ? lightEmoji : darkEmoji;
return borderedEmoji.includes(filename) ? (filename + '_border') : filename;
const borderedEmoji = (document.body && document.body.classList.contains("theme-mastodon-light")) ? lightEmoji : darkEmoji;
return borderedEmoji.includes(filename) ? (filename + "_border") : filename;
};
const emojifyTextNode = (node, customEmojis) => {
@@ -40,7 +40,7 @@ const emojifyTextNode = (node, customEmojis) => {
i += str.codePointAt(i) < 65536 ? 1 : 2;
}
} else {
while (i < str.length && str[i] !== ':' && !(unicode_emoji = trie.search(str.slice(i)))) {
while (i < str.length && str[i] !== ":" && !(unicode_emoji = trie.search(str.slice(i)))) {
i += str.codePointAt(i) < 65536 ? 1 : 2;
}
}
@@ -51,8 +51,8 @@ const emojifyTextNode = (node, customEmojis) => {
}
let rend, replacement = null;
if (str[i] === ':') { // Potentially the start of a custom emoji :shortcode:
rend = str.indexOf(':', i + 1) + 1;
if (str[i] === ":") { // Potentially the start of a custom emoji :shortcode:
rend = str.indexOf(":", i + 1) + 1;
// no matching ending ':', skip
if (!rend) {
@@ -72,14 +72,14 @@ const emojifyTextNode = (node, customEmojis) => {
// now got a replacee as ':shortcode:'
// if you want additional emoji handler, add statements below which set replacement and return true.
const filename = autoPlayGif ? custom_emoji.url : custom_emoji.static_url;
replacement = document.createElement('img');
replacement.setAttribute('draggable', 'false');
replacement.setAttribute('class', 'emojione custom-emoji');
replacement.setAttribute('alt', shortcode);
replacement.setAttribute('title', shortcode);
replacement.setAttribute('src', filename);
replacement.setAttribute('data-original', custom_emoji.url);
replacement.setAttribute('data-static', custom_emoji.static_url);
replacement = document.createElement("img");
replacement.setAttribute("draggable", "false");
replacement.setAttribute("class", "emojione custom-emoji");
replacement.setAttribute("alt", shortcode);
replacement.setAttribute("title", shortcode);
replacement.setAttribute("src", filename);
replacement.setAttribute("data-original", custom_emoji.url);
replacement.setAttribute("data-static", custom_emoji.static_url);
} else { // start of an unicode emoji
rend = i + unicode_emoji.length;
@@ -90,14 +90,14 @@ const emojifyTextNode = (node, customEmojis) => {
}
const { filename, shortCode } = unicodeMapping[unicode_emoji];
const title = shortCode ? `:${shortCode}:` : '';
const title = shortCode ? `:${shortCode}:` : "";
replacement = document.createElement('img');
replacement.setAttribute('draggable', 'false');
replacement.setAttribute('class', 'emojione');
replacement.setAttribute('alt', unicode_emoji);
replacement.setAttribute('title', title);
replacement.setAttribute('src', `${assetHost}/emoji/${emojiFilename(filename)}.svg`);
replacement = document.createElement("img");
replacement.setAttribute("draggable", "false");
replacement.setAttribute("class", "emojione");
replacement.setAttribute("alt", unicode_emoji);
replacement.setAttribute("title", title);
replacement.setAttribute("src", `${assetHost}/emoji/${emojiFilename(filename)}.svg`);
}
// Add the processed-up-to-now string and the emoji replacement
@@ -114,23 +114,25 @@ const emojifyTextNode = (node, customEmojis) => {
const emojifyNode = (node, customEmojis) => {
for (const child of node.childNodes) {
switch(child.nodeType) {
case Node.TEXT_NODE:
emojifyTextNode(child, customEmojis);
break;
case Node.ELEMENT_NODE:
if (!child.classList.contains('invisible'))
emojifyNode(child, customEmojis);
break;
case Node.TEXT_NODE:
emojifyTextNode(child, customEmojis);
break;
case Node.ELEMENT_NODE:
if (!child.classList.contains("invisible")) {
emojifyNode(child, customEmojis);
}
break;
}
}
};
const emojify = (str, customEmojis = {}) => {
const wrapper = document.createElement('div');
const wrapper = document.createElement("div");
wrapper.innerHTML = str;
if (!Object.keys(customEmojis).length)
if (!Object.keys(customEmojis).length) {
customEmojis = null;
}
emojifyNode(wrapper, customEmojis);
@@ -143,24 +145,24 @@ export const buildCustomEmojis = (customEmojis) => {
const emojis = [];
customEmojis.forEach(emoji => {
const shortcode = emoji.get('shortcode');
const url = autoPlayGif ? emoji.get('url') : emoji.get('static_url');
const name = shortcode.replace(':', '');
const shortcode = emoji.get("shortcode");
const url = autoPlayGif ? emoji.get("url") : emoji.get("static_url");
const name = shortcode.replace(":", "");
emojis.push({
id: name,
name,
short_names: [name],
text: '',
text: "",
emoticons: [],
keywords: [name],
imageUrl: url,
custom: true,
customCategory: emoji.get('category'),
customCategory: emoji.get("category"),
});
});
return emojis;
};
export const categoriesFromEmojis = customEmojis => customEmojis.reduce((set, emoji) => set.add(emoji.get('category') ? `custom-${emoji.get('category')}` : 'custom'), new Set(['custom']));
export const categoriesFromEmojis = customEmojis => customEmojis.reduce((set, emoji) => set.add(emoji.get("category") ? `custom-${emoji.get("category")}` : "custom"), new Set(["custom"]));
+10 -10
View File
@@ -1,5 +1,5 @@
import type { BaseEmoji, EmojiData, NimbleEmojiIndex } from 'emoji-mart';
import type { Category, Data, Emoji } from 'emoji-mart/dist-es/utils/data';
import { type BaseEmoji, type EmojiData, type NimbleEmojiIndex } from "emoji-mart";
import { type Category, type Data, type Emoji } from "emoji-mart/dist-es/utils/data";
/*
* The 'search' property, although not defined in the [`Emoji`]{@link node_modules/@types/emoji-mart/dist-es/utils/data.d.ts#Emoji} type,
@@ -17,15 +17,15 @@ export type Skins = null;
export type FilenameData = string[] | string[][];
export type ShortCodesToEmojiDataKey =
| EmojiData['id']
| BaseEmoji['native']
| keyof NimbleEmojiIndex['emojis'];
| EmojiData["id"]
| BaseEmoji["native"]
| keyof NimbleEmojiIndex["emojis"];
export type SearchData = [
BaseEmoji['native'],
Emoji['short_names'],
BaseEmoji["native"],
Emoji["short_names"],
Search,
Emoji['unified'],
Emoji["unified"],
];
export type ShortCodesToEmojiData = Record<
@@ -38,7 +38,7 @@ export type EmojiCompressed = [
ShortCodesToEmojiData,
Skins,
Category[],
Data['aliases'],
Data["aliases"],
EmojisWithoutShortCodes,
];
@@ -49,4 +49,4 @@ export type EmojiCompressed = [
*/
declare const emojiCompressed: EmojiCompressed;
export default emojiCompressed; // eslint-disable-line import/no-default-export
export default emojiCompressed;
@@ -1,5 +1,4 @@
/* eslint-disable import/no-commonjs --
We need to use CommonJS here due to preval */
// @preval
// http://www.unicode.org/Public/emoji/5.0/emoji-test.txt
// This file contains the compressed version of the emoji data from
@@ -7,13 +6,13 @@
// It's designed to be emitted in an array format to take up less space
// over the wire.
const { emojiIndex } = require('emoji-mart');
let data = require('emoji-mart/data/all.json');
const { uncompress: emojiMartUncompress } = require('emoji-mart/dist/utils/data');
const { emojiIndex } = require("emoji-mart");
let data = require("emoji-mart/data/all.json");
const { uncompress: emojiMartUncompress } = require("emoji-mart/dist/utils/data");
const emojiMap = require('./emoji_map.json');
const { unicodeToFilename } = require('./unicode_to_filename');
const { unicodeToUnifiedName } = require('./unicode_to_unified_name');
const emojiMap = require("./emoji_map.json");
const { unicodeToFilename } = require("./unicode_to_filename");
const { unicodeToUnifiedName } = require("./unicode_to_unified_name");
if(data.compressed) {
@@ -22,8 +21,8 @@ if(data.compressed) {
const emojiMartData = data;
const excluded = ['®', '©', '™'];
const skinTones = ['🏻', '🏼', '🏽', '🏾', '🏿'];
const excluded = ["®", "©", "™"];
const skinTones = ["🏻", "🏼", "🏽", "🏾", "🏿"];
const shortcodeMap = {};
const shortCodesToEmojiData = {};
@@ -33,8 +32,8 @@ Object.keys(emojiIndex.emojis).forEach(key => {
let emoji = emojiIndex.emojis[key];
// Emojis with skin tone modifiers are stored like this
if (Object.prototype.hasOwnProperty.call(emoji, '1')) {
emoji = emoji['1'];
if (Object.prototype.hasOwnProperty.call(emoji, "1")) {
emoji = emoji["1"];
}
shortcodeMap[emoji.native] = emoji.id;
@@ -42,7 +41,7 @@ Object.keys(emojiIndex.emojis).forEach(key => {
const stripModifiers = unicode => {
skinTones.forEach(tone => {
unicode = unicode.replace(tone, '');
unicode = unicode.replace(tone, "");
});
return unicode;
@@ -58,7 +57,7 @@ Object.keys(emojiMap).forEach(key => {
let shortcode = shortcodeMap[normalizedKey];
if (!shortcode) {
shortcode = shortcodeMap[normalizedKey + '\uFE0F'];
shortcode = shortcodeMap[normalizedKey + "\uFE0F"];
}
const filename = emojiMap[key];
@@ -70,7 +69,7 @@ Object.keys(emojiMap).forEach(key => {
filenameData.push(filename);
}
if (typeof shortcode === 'undefined') {
if (typeof shortcode === "undefined") {
emojisWithoutShortCodes.push(filenameData);
} else {
if (!Array.isArray(shortCodesToEmojiData[shortcode])) {
@@ -85,17 +84,17 @@ Object.keys(emojiIndex.emojis).forEach(key => {
let emoji = emojiIndex.emojis[key];
// Emojis with skin tone modifiers are stored like this
if (Object.prototype.hasOwnProperty.call(emoji, '1')) {
emoji = emoji['1'];
if (Object.prototype.hasOwnProperty.call(emoji, "1")) {
emoji = emoji["1"];
}
const { native } = emoji;
let { short_names, search, unified } = emojiMartData.emojis[key];
if (short_names[0] !== key) {
throw new Error('The compressor expects the first short_code to be the ' +
'key. It may need to be rewritten if the emoji change such that this ' +
'is no longer the case.');
throw new Error("The compressor expects the first short_code to be the " +
"key. It may need to be rewritten if the emoji change such that this " +
"is no longer the case.");
}
short_names = short_names.slice(1); // first short name can be inferred from the key
@@ -1,19 +1,19 @@
// The output of this module is designed to mimic emoji-mart's
// "data" object, such that we can use it for a light version of emoji-mart's
// emojiIndex.search functionality.
import type { BaseEmoji } from 'emoji-mart';
import type { Emoji } from 'emoji-mart/dist-es/utils/data';
import { type BaseEmoji } from "emoji-mart";
import { type Emoji } from "emoji-mart/dist-es/utils/data";
import type { Search, ShortCodesToEmojiData } from './emoji_compressed';
import emojiCompressed from './emoji_compressed';
import { unicodeToUnifiedName } from './unicode_to_unified_name';
import { type Search, type ShortCodesToEmojiData } from "./emoji_compressed";
import emojiCompressed from "./emoji_compressed";
import { unicodeToUnifiedName } from "./unicode_to_unified_name";
type Emojis = {
[key in NonNullable<keyof ShortCodesToEmojiData>]: {
native: BaseEmoji['native'];
search: Search;
short_names: Emoji['short_names'];
unified: Emoji['unified'];
native: BaseEmoji["native"],
search: Search,
short_names: Emoji["short_names"],
unified: Emoji["unified"],
};
};
@@ -40,7 +40,9 @@ Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
unified = unicodeToUnifiedName(native);
}
if (short_names) short_names = [shortCode].concat(short_names);
if (short_names) {
short_names = [shortCode].concat(short_names);
}
emojis[shortCode] = {
native,
search,
@@ -1,8 +1,8 @@
// This code is largely borrowed from:
// https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/emoji-index.js
import * as data from './emoji_mart_data_light';
import { getData, getSanitizedData, uniq, intersect } from './emoji_utils';
import * as data from "./emoji_mart_data_light";
import { getData, getSanitizedData, uniq, intersect } from "./emoji_utils";
let originalPool = {};
let index = {};
@@ -39,7 +39,9 @@ function clearCustomEmojis(pool) {
}
function addCustomToPool(custom, pool) {
if (customEmojisList.length) clearCustomEmojis(pool);
if (customEmojisList.length) {
clearCustomEmojis(pool);
}
custom.forEach((emoji) => {
let emojiId = emoji.id || emoji.short_names[0];
@@ -56,8 +58,9 @@ function addCustomToPool(custom, pool) {
function search(value, { emojisToShowFilter, maxResults, include, exclude, custom } = {}) {
if (custom !== undefined) {
if (customEmojisList !== custom)
if (customEmojisList !== custom) {
addCustomToPool(custom, originalPool);
}
} else {
custom = [];
}
@@ -70,8 +73,8 @@ function search(value, { emojisToShowFilter, maxResults, include, exclude, custo
pool = originalPool;
if (value.length) {
if (value === '-' || value === '-1') {
return [emojisList['-1']];
if (value === "-" || value === "-1") {
return [emojisList["-1"]];
}
let values = value.toLowerCase().split(/[\s|,\-_]+/),
@@ -95,8 +98,8 @@ function search(value, { emojisToShowFilter, maxResults, include, exclude, custo
});
if (custom.length) {
let customIsIncluded = include && include.length ? include.indexOf('custom') > -1 : true;
let customIsExcluded = exclude && exclude.length ? exclude.indexOf('custom') > -1 : false;
let customIsIncluded = include && include.length ? include.indexOf("custom") > -1 : true;
let customIsExcluded = exclude && exclude.length ? exclude.indexOf("custom") > -1 : false;
if (customIsIncluded && !customIsExcluded) {
addCustomToPool(custom, pool);
}
@@ -129,7 +132,9 @@ function search(value, { emojisToShowFilter, maxResults, include, exclude, custo
if (subIndex !== -1) {
let score = subIndex + 1;
if (sub === id) score = 0;
if (sub === id) {
score = 0;
}
aIndex.results.push(emojisList[id]);
aIndex.pool[id] = emoji;
@@ -1,5 +1,5 @@
import Emoji from 'emoji-mart/dist-es/components/emoji/emoji';
import Picker from 'emoji-mart/dist-es/components/picker/picker';
import Emoji from "emoji-mart/dist-es/components/emoji/emoji";
import Picker from "emoji-mart/dist-es/components/picker/picker";
export {
Picker,
@@ -2,8 +2,8 @@
// (i.e. the svg filename) and a shortCode intended to be shown
// as a "title" attribute in an HTML element (aka tooltip).
import emojiCompressed from './emoji_compressed';
import { unicodeToFilename } from './unicode_to_filename';
import emojiCompressed from "./emoji_compressed";
import { unicodeToFilename } from "./unicode_to_filename";
const [
shortCodesToEmojiData,
@@ -1,7 +1,7 @@
// This code is largely borrowed from:
// https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/index.js
import * as data from './emoji_mart_data_light';
import * as data from "./emoji_mart_data_light";
const buildSearch = (data) => {
const search = [];
@@ -27,7 +27,7 @@ const buildSearch = (data) => {
addToSearch(data.keywords, false);
addToSearch(data.emoticons, false);
return search.join(',');
return search.join(",");
};
const _String = String;
@@ -40,9 +40,9 @@ const stringFromCodePoint = _String.fromCodePoint || function () {
let index = -1;
let length = arguments.length;
if (!length) {
return '';
return "";
}
let result = '';
let result = "";
while (++index < length) {
let codePoint = Number(arguments[index]);
if (
@@ -51,7 +51,7 @@ const stringFromCodePoint = _String.fromCodePoint || function () {
codePoint > 0x10FFFF || // not a valid Unicode code point
Math.floor(codePoint) !== codePoint // not an integer
) {
throw RangeError('Invalid code point: ' + codePoint);
throw RangeError("Invalid code point: " + codePoint);
}
if (codePoint <= 0xFFFF) { // BMP code point
codeUnits.push(codePoint);
@@ -75,12 +75,12 @@ const _JSON = JSON;
const COLONS_REGEX = /^(?::([^:]+):)(?::skin-tone-(\d):)?$/;
const SKINS = [
'1F3FA', '1F3FB', '1F3FC',
'1F3FD', '1F3FE', '1F3FF',
"1F3FA", "1F3FB", "1F3FC",
"1F3FD", "1F3FE", "1F3FF",
];
function unifiedToNative(unified) {
let unicodes = unified.split('-'),
let unicodes = unified.split("-"),
codePoints = unicodes.map((u) => `0x${u}`);
return stringFromCodePoint.apply(null, codePoints);
@@ -124,7 +124,7 @@ function getSanitizedData() {
function getData(emoji, skin, set) {
let emojiData = {};
if (typeof emoji === 'string') {
if (typeof emoji === "string") {
let matches = emoji.match(COLONS_REGEX);
if (matches) {
@@ -220,7 +220,7 @@ function deepMerge(a, b) {
value = b[key];
}
if (typeof value === 'object') {
if (typeof value === "object") {
value = deepMerge(originalValue, value);
}
@@ -232,13 +232,13 @@ function deepMerge(a, b) {
// https://github.com/sonicdoe/measure-scrollbar
function measureScrollbar() {
const div = document.createElement('div');
const div = document.createElement("div");
div.style.width = '100px';
div.style.height = '100px';
div.style.overflow = 'scroll';
div.style.position = 'absolute';
div.style.top = '-9999px';
div.style.width = "100px";
div.style.height = "100px";
div.style.overflow = "scroll";
div.style.position = "absolute";
div.style.top = "-9999px";
document.body.appendChild(div);
const scrollbarWidth = div.offsetWidth - div.clientWidth;
@@ -1,10 +1,9 @@
/* eslint-disable import/no-commonjs --
We need to use CommonJS here as its imported into a preval file (`emoji_compressed.js`) */
// taken from:
// https://github.com/twitter/twemoji/blob/47732c7/twemoji-generator.js#L848-L866
exports.unicodeToFilename = (str) => {
let result = '';
let result = "";
let charCode = 0;
let p = 0;
let i = 0;
@@ -12,7 +11,7 @@ exports.unicodeToFilename = (str) => {
charCode = str.charCodeAt(i++);
if (p) {
if (result.length > 0) {
result += '-';
result += "-";
}
result += (0x10000 + ((p - 0xD800) << 10) + (charCode - 0xDC00)).toString(16);
p = 0;
@@ -20,7 +19,7 @@ exports.unicodeToFilename = (str) => {
p = charCode;
} else {
if (result.length > 0) {
result += '-';
result += "-";
}
result += charCode.toString(16);
}
@@ -1,20 +1,19 @@
/* eslint-disable import/no-commonjs --
We need to use CommonJS here as its imported into a preval file (`emoji_compressed.js`) */
function padLeft(str, num) {
while (str.length < num) {
str = '0' + str;
str = "0" + str;
}
return str;
}
exports.unicodeToUnifiedName = (str) => {
let output = '';
let output = "";
for (let i = 0; i < str.length; i += 2) {
if (i > 0) {
output += '-';
output += "-";
}
output += padLeft(str.codePointAt(i).toString(16).toUpperCase(), 4);