eslint-plugin-formatjs 6.1.0 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/emoji-utils.d.ts +3 -1
- package/emoji-utils.js +47 -5
- package/package.json +4 -3
package/emoji-utils.d.ts
CHANGED
|
@@ -5,7 +5,9 @@ import { type EmojiVersion } from "./emoji-data.generated.js";
|
|
|
5
5
|
export type { EmojiVersion } from "./emoji-data.generated.js";
|
|
6
6
|
/**
|
|
7
7
|
* Check if a string contains any emoji
|
|
8
|
-
* Uses Unicode
|
|
8
|
+
* Uses Unicode 17.0.0 Emoji_Presentation data and variation selector (U+FE0F)
|
|
9
|
+
* to properly detect emoji while avoiding false positives from characters like
|
|
10
|
+
* #, *, digits 0-9, and text symbols like © which have \p{Emoji} but are not visual emoji
|
|
9
11
|
*/
|
|
10
12
|
export declare function hasEmoji(text: string): boolean;
|
|
11
13
|
/**
|
package/emoji-utils.js
CHANGED
|
@@ -2,19 +2,51 @@
|
|
|
2
2
|
* Emoji detection utilities using Intl.Segmenter
|
|
3
3
|
*/
|
|
4
4
|
import { EMOJI_VERSIONS, EMOJI_RANGES } from "./emoji-data.generated.js";
|
|
5
|
+
import * as emojiPresentationRegex from "@unicode/unicode-17.0.0/Binary_Property/Emoji_Presentation/regex.js";
|
|
6
|
+
import * as emojiPropertyRegex from "@unicode/unicode-17.0.0/Binary_Property/Emoji/regex.js";
|
|
5
7
|
/**
|
|
6
8
|
* Cached Intl.Segmenter instance for emoji extraction
|
|
7
9
|
* Reused across all extractEmojis calls for better performance
|
|
8
10
|
*/
|
|
9
11
|
const graphemeSegmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
|
|
10
12
|
/**
|
|
13
|
+
* Regex for detecting emoji using Unicode 17.0.0 Emoji_Presentation data
|
|
14
|
+
* Generated from @unicode/unicode-17.0.0/Binary_Property/Emoji_Presentation
|
|
15
|
+
* This avoids false positives from #, *, digits, and text symbols like ©
|
|
16
|
+
*/
|
|
17
|
+
const emojiPresentationRegexCompiled = emojiPresentationRegex.default ?? emojiPresentationRegex;
|
|
18
|
+
/**
|
|
19
|
+
* Regex for detecting emoji-capable characters using Unicode 17.0.0 Emoji property
|
|
20
|
+
* This includes characters that can have emoji presentation (like ❤, ☀)
|
|
21
|
+
*/
|
|
22
|
+
const emojiPropertyRegexCompiled = emojiPropertyRegex.default ?? emojiPropertyRegex;
|
|
23
|
+
/**
|
|
11
24
|
* Check if a string contains any emoji
|
|
12
|
-
* Uses Unicode
|
|
25
|
+
* Uses Unicode 17.0.0 Emoji_Presentation data and variation selector (U+FE0F)
|
|
26
|
+
* to properly detect emoji while avoiding false positives from characters like
|
|
27
|
+
* #, *, digits 0-9, and text symbols like © which have \p{Emoji} but are not visual emoji
|
|
13
28
|
*/
|
|
14
29
|
export function hasEmoji(text) {
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
30
|
+
// First check for Emoji_Presentation characters (always displayed as emoji)
|
|
31
|
+
if (emojiPresentationRegexCompiled.test(text)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
// Check for variation selector (U+FE0F) which indicates emoji presentation
|
|
35
|
+
// But only if it follows an emoji-capable character to avoid false positives
|
|
36
|
+
// like "Hello\uFE0F" or "A\uFE0F"
|
|
37
|
+
if (text.includes("️")) {
|
|
38
|
+
const segments = graphemeSegmenter.segment(text);
|
|
39
|
+
for (const { segment } of segments) {
|
|
40
|
+
if (segment.includes("️")) {
|
|
41
|
+
// Has VS, check if the character before it has the Emoji property
|
|
42
|
+
const beforeVS = segment.replace(/\uFE0F/g, "");
|
|
43
|
+
if (emojiPropertyRegexCompiled.test(beforeVS)) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
18
50
|
}
|
|
19
51
|
/**
|
|
20
52
|
* Extract all emoji from a string using Intl.Segmenter
|
|
@@ -32,8 +64,18 @@ export function extractEmojis(text) {
|
|
|
32
64
|
const emojis = [];
|
|
33
65
|
for (const { segment } of segments) {
|
|
34
66
|
// Check if this grapheme cluster contains emoji
|
|
35
|
-
|
|
67
|
+
// First check for Emoji_Presentation (always displayed as emoji)
|
|
68
|
+
if (emojiPresentationRegexCompiled.test(segment)) {
|
|
36
69
|
emojis.push(segment);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Check for variation selector (U+FE0F) which indicates emoji presentation
|
|
73
|
+
// But only if it follows an emoji-capable character to avoid false positives
|
|
74
|
+
if (segment.includes("️")) {
|
|
75
|
+
const beforeVS = segment.replace(/\uFE0F/g, "");
|
|
76
|
+
if (emojiPropertyRegexCompiled.test(beforeVS)) {
|
|
77
|
+
emojis.push(segment);
|
|
78
|
+
}
|
|
37
79
|
}
|
|
38
80
|
}
|
|
39
81
|
return emojis;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-formatjs",
|
|
3
3
|
"description": "ESLint plugin for formatjs",
|
|
4
|
-
"version": "6.1.
|
|
4
|
+
"version": "6.1.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Long Ho <holevietlong@gmail.com>",
|
|
7
7
|
"type": "module",
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@types/picomatch": "^4.0.0",
|
|
11
11
|
"@typescript-eslint/utils": "^8.52.0",
|
|
12
|
+
"@unicode/unicode-17.0.0": "^1.6.16",
|
|
12
13
|
"magic-string": "^0.30.0",
|
|
13
14
|
"picomatch": "2 || 3 || 4",
|
|
14
15
|
"tslib": "^2.8.1",
|
|
15
|
-
"@formatjs/icu-messageformat-parser": "3.
|
|
16
|
-
"@formatjs/ts-transformer": "4.3.
|
|
16
|
+
"@formatjs/icu-messageformat-parser": "3.5.0",
|
|
17
|
+
"@formatjs/ts-transformer": "4.3.1"
|
|
17
18
|
},
|
|
18
19
|
"peerDependencies": {
|
|
19
20
|
"eslint": "9"
|