mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-16 09:18:46 +00:00
[Glitch] Provides legacy fallback for browser that don't support regex flag v
Port 28b0e5ee78 to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
@@ -15,17 +15,6 @@ export const SKIN_TONE_CODES = [
|
||||
0x1f3ff, // Dark skin tone
|
||||
] as const;
|
||||
|
||||
// TODO: Test and create fallback for browsers that do not handle the /v flag.
|
||||
export const UNICODE_EMOJI_REGEX = /\p{RGI_Emoji}/v;
|
||||
// See: https://www.unicode.org/reports/tr51/#valid-emoji-tag-sequences
|
||||
export const UNICODE_FLAG_EMOJI_REGEX =
|
||||
/\p{RGI_Emoji_Flag_Sequence}|\p{RGI_Emoji_Tag_Sequence}/v;
|
||||
export const CUSTOM_EMOJI_REGEX = /:([a-z0-9_]+):/i;
|
||||
export const ANY_EMOJI_REGEX = new RegExp(
|
||||
`(${UNICODE_EMOJI_REGEX.source}|${CUSTOM_EMOJI_REGEX.source})`,
|
||||
'gv',
|
||||
);
|
||||
|
||||
// Emoji rendering modes. A mode is what we are using to render emojis, a style is what the user has selected.
|
||||
export const EMOJI_MODE_NATIVE = 'native';
|
||||
export const EMOJI_MODE_NATIVE_WITH_FLAGS = 'native-flags';
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
EMOJI_TYPE_UNICODE,
|
||||
EMOJI_TYPE_CUSTOM,
|
||||
EMOJI_STATE_MISSING,
|
||||
ANY_EMOJI_REGEX,
|
||||
} from './constants';
|
||||
import {
|
||||
searchCustomEmojisByShortcodes,
|
||||
@@ -32,7 +31,12 @@ import type {
|
||||
LocaleOrCustom,
|
||||
UnicodeEmojiToken,
|
||||
} from './types';
|
||||
import { emojiLogger, stringHasAnyEmoji, stringHasUnicodeFlags } from './utils';
|
||||
import {
|
||||
anyEmojiRegex,
|
||||
emojiLogger,
|
||||
stringHasAnyEmoji,
|
||||
stringHasUnicodeFlags,
|
||||
} from './utils';
|
||||
|
||||
const log = emojiLogger('render');
|
||||
|
||||
@@ -207,7 +211,7 @@ export function tokenizeText(text: string): TokenizedText {
|
||||
|
||||
const tokens = [];
|
||||
let lastIndex = 0;
|
||||
for (const match of text.matchAll(ANY_EMOJI_REGEX)) {
|
||||
for (const match of text.matchAll(anyEmojiRegex())) {
|
||||
if (match.index > lastIndex) {
|
||||
tokens.push(text.slice(lastIndex, match.index));
|
||||
}
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
import debug from 'debug';
|
||||
|
||||
import {
|
||||
CUSTOM_EMOJI_REGEX,
|
||||
UNICODE_EMOJI_REGEX,
|
||||
UNICODE_FLAG_EMOJI_REGEX,
|
||||
} from './constants';
|
||||
import { emojiRegexPolyfill } from '@/flavours/glitch/polyfills';
|
||||
|
||||
export function emojiLogger(segment: string) {
|
||||
return debug(`emojis:${segment}`);
|
||||
}
|
||||
|
||||
export function stringHasUnicodeEmoji(input: string): boolean {
|
||||
return UNICODE_EMOJI_REGEX.test(input);
|
||||
return new RegExp(EMOJI_REGEX, supportedFlags()).test(input);
|
||||
}
|
||||
|
||||
export function stringHasUnicodeFlags(input: string): boolean {
|
||||
return UNICODE_FLAG_EMOJI_REGEX.test(input);
|
||||
if (supportsRegExpSets()) {
|
||||
return new RegExp(
|
||||
'\\p{RGI_Emoji_Flag_Sequence}|\\p{RGI_Emoji_Tag_Sequence}',
|
||||
'v',
|
||||
).test(input);
|
||||
}
|
||||
return new RegExp(
|
||||
// First range is regional indicator symbols,
|
||||
// Second is a black flag + 0-9|a-z tag chars + cancel tag.
|
||||
// See: https://en.wikipedia.org/wiki/Regional_indicator_symbol
|
||||
'(?:\uD83C[\uDDE6-\uDDFF]){2}|\uD83C\uDFF4(?:\uDB40[\uDC30-\uDC7A])+\uDB40\uDC7F',
|
||||
).test(input);
|
||||
}
|
||||
|
||||
// Constant as this is supported by all browsers.
|
||||
const CUSTOM_EMOJI_REGEX = /:([a-z0-9_]+):/i;
|
||||
export function stringHasCustomEmoji(input: string) {
|
||||
return CUSTOM_EMOJI_REGEX.test(input);
|
||||
}
|
||||
@@ -25,3 +34,23 @@ export function stringHasCustomEmoji(input: string) {
|
||||
export function stringHasAnyEmoji(input: string) {
|
||||
return stringHasUnicodeEmoji(input) || stringHasCustomEmoji(input);
|
||||
}
|
||||
|
||||
export function anyEmojiRegex() {
|
||||
return new RegExp(
|
||||
`${EMOJI_REGEX}|${CUSTOM_EMOJI_REGEX.source}`,
|
||||
supportedFlags('gi'),
|
||||
);
|
||||
}
|
||||
|
||||
function supportsRegExpSets() {
|
||||
return 'unicodeSets' in RegExp.prototype;
|
||||
}
|
||||
|
||||
function supportedFlags(flags = '') {
|
||||
if (supportsRegExpSets()) {
|
||||
return `${flags}v`;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
const EMOJI_REGEX = emojiRegexPolyfill?.source ?? '\\p{RGI_Emoji}';
|
||||
|
||||
@@ -20,5 +20,16 @@ export function loadPolyfills() {
|
||||
loadIntlPolyfills(),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- those properties might not exist in old browsers, even if they are always here in types
|
||||
needsExtraPolyfills && importExtraPolyfills(),
|
||||
loadEmojiPolyfills(),
|
||||
]);
|
||||
}
|
||||
|
||||
// In the case of no /v support, rely on the emojibase data.
|
||||
async function loadEmojiPolyfills() {
|
||||
if (!('unicodeSets' in RegExp.prototype)) {
|
||||
emojiRegexPolyfill = (await import('emojibase-regex/emoji')).default;
|
||||
}
|
||||
}
|
||||
|
||||
// Null unless polyfill is needed.
|
||||
export let emojiRegexPolyfill: RegExp | null = null;
|
||||
|
||||
Reference in New Issue
Block a user