It's time for Intl.Segmenter
Remove runes2
This commit is contained in:
parent
e0c2570875
commit
531147cbc3
49
package-lock.json
generated
49
package-lock.json
generated
|
@ -9,6 +9,7 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formatjs/intl-localematcher": "~0.5.4",
|
"@formatjs/intl-localematcher": "~0.5.4",
|
||||||
|
"@formatjs/intl-segmenter": "~11.5.5",
|
||||||
"@formkit/auto-animate": "~0.8.1",
|
"@formkit/auto-animate": "~0.8.1",
|
||||||
"@github/text-expander-element": "~2.6.1",
|
"@github/text-expander-element": "~2.6.1",
|
||||||
"@iconify-icons/mingcute": "~1.2.9",
|
"@iconify-icons/mingcute": "~1.2.9",
|
||||||
|
@ -33,8 +34,7 @@
|
||||||
"react-intersection-observer": "~9.8.1",
|
"react-intersection-observer": "~9.8.1",
|
||||||
"react-quick-pinch-zoom": "~5.1.0",
|
"react-quick-pinch-zoom": "~5.1.0",
|
||||||
"react-router-dom": "6.6.2",
|
"react-router-dom": "6.6.2",
|
||||||
"runes2": "~1.1.4",
|
"string-length": "6.0.0",
|
||||||
"string-length": "5.0.1",
|
|
||||||
"swiped-events": "~1.1.9",
|
"swiped-events": "~1.1.9",
|
||||||
"toastify-js": "~1.12.0",
|
"toastify-js": "~1.12.0",
|
||||||
"uid": "~2.0.2",
|
"uid": "~2.0.2",
|
||||||
|
@ -2924,6 +2924,15 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@formatjs/ecma402-abstract": {
|
||||||
|
"version": "1.18.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz",
|
||||||
|
"integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/intl-localematcher": "0.5.4",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@formatjs/intl-localematcher": {
|
"node_modules/@formatjs/intl-localematcher": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
||||||
|
@ -2932,6 +2941,16 @@
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@formatjs/intl-segmenter": {
|
||||||
|
"version": "11.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-segmenter/-/intl-segmenter-11.5.5.tgz",
|
||||||
|
"integrity": "sha512-mMbJKFGzwYJBcwfL9EfqFje75Ce5WPar5rSi7wWvFtBPFY2Zi1cWIss7FSm2MNNM9l1BycBAsBQuXFt+Hd+0tQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "1.18.2",
|
||||||
|
"@formatjs/intl-localematcher": "0.5.4",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@formkit/auto-animate": {
|
"node_modules/@formkit/auto-animate": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.1.tgz",
|
||||||
|
@ -3967,15 +3986,6 @@
|
||||||
"tslib": "^2.0.3"
|
"tslib": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/char-regex": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.20"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
|
@ -7116,11 +7126,6 @@
|
||||||
"queue-microtask": "^1.2.2"
|
"queue-microtask": "^1.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/runes2": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/runes2/-/runes2-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-LNPnEDPOOU4ehF71m5JoQyzT2yxwD6ZreFJ7MxZUAoMKNMY1XrAo60H1CUoX5ncSm0rIuKlqn9JZNRrRkNou2g=="
|
|
||||||
},
|
|
||||||
"node_modules/safe-buffer": {
|
"node_modules/safe-buffer": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
@ -7262,16 +7267,14 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/string-length": {
|
"node_modules/string-length": {
|
||||||
"version": "5.0.1",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/string-length/-/string-length-6.0.0.tgz",
|
||||||
"integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==",
|
"integrity": "sha512-1U361pxZHEQ+FeSjzqRpV+cu2vTzYeWeafXFLykiFlv4Vc0n3njgU8HrMbyik5uwm77naWMuVG8fhEF+Ovb1Kg==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"char-regex": "^2.0.0",
|
"strip-ansi": "^7.1.0"
|
||||||
"strip-ansi": "^7.0.1"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.20"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formatjs/intl-localematcher": "~0.5.4",
|
"@formatjs/intl-localematcher": "~0.5.4",
|
||||||
|
"@formatjs/intl-segmenter": "~11.5.5",
|
||||||
"@formkit/auto-animate": "~0.8.1",
|
"@formkit/auto-animate": "~0.8.1",
|
||||||
"@github/text-expander-element": "~2.6.1",
|
"@github/text-expander-element": "~2.6.1",
|
||||||
"@iconify-icons/mingcute": "~1.2.9",
|
"@iconify-icons/mingcute": "~1.2.9",
|
||||||
|
@ -35,8 +36,7 @@
|
||||||
"react-intersection-observer": "~9.8.1",
|
"react-intersection-observer": "~9.8.1",
|
||||||
"react-quick-pinch-zoom": "~5.1.0",
|
"react-quick-pinch-zoom": "~5.1.0",
|
||||||
"react-router-dom": "6.6.2",
|
"react-router-dom": "6.6.2",
|
||||||
"runes2": "~1.1.4",
|
"string-length": "6.0.0",
|
||||||
"string-length": "5.0.1",
|
|
||||||
"swiped-events": "~1.1.9",
|
"swiped-events": "~1.1.9",
|
||||||
"toastify-js": "~1.12.0",
|
"toastify-js": "~1.12.0",
|
||||||
"uid": "~2.0.2",
|
"uid": "~2.0.2",
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { deepEqual } from 'fast-equals';
|
||||||
import { forwardRef } from 'preact/compat';
|
import { forwardRef } from 'preact/compat';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { substring } from 'runes2';
|
|
||||||
import stringLength from 'string-length';
|
import stringLength from 'string-length';
|
||||||
import { uid } from 'uid/single';
|
import { uid } from 'uid/single';
|
||||||
import { useDebouncedCallback, useThrottledCallback } from 'use-debounce';
|
import { useDebouncedCallback, useThrottledCallback } from 'use-debounce';
|
||||||
|
@ -131,6 +130,7 @@ const SCAN_RE = new RegExp(
|
||||||
'g',
|
'g',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const segmenter = new Intl.Segmenter();
|
||||||
function highlightText(text, { maxCharacters = Infinity }) {
|
function highlightText(text, { maxCharacters = Infinity }) {
|
||||||
// Accept text string, return formatted HTML string
|
// Accept text string, return formatted HTML string
|
||||||
// Escape all HTML special characters
|
// Escape all HTML special characters
|
||||||
|
@ -143,19 +143,25 @@ function highlightText(text, { maxCharacters = Infinity }) {
|
||||||
|
|
||||||
// Exceeded characters limit
|
// Exceeded characters limit
|
||||||
const { composerCharacterCount } = states;
|
const { composerCharacterCount } = states;
|
||||||
let leftoverHTML = '';
|
|
||||||
if (composerCharacterCount > maxCharacters) {
|
if (composerCharacterCount > maxCharacters) {
|
||||||
// NOTE: runes2 substring considers surrogate pairs
|
|
||||||
// const leftoverCount = composerCharacterCount - maxCharacters;
|
|
||||||
// Highlight exceeded characters
|
// Highlight exceeded characters
|
||||||
leftoverHTML =
|
let withinLimitHTML = '',
|
||||||
'<mark class="compose-highlight-exceeded">' +
|
exceedLimitHTML = '';
|
||||||
// html.slice(-leftoverCount) +
|
const htmlSegments = segmenter.segment(html);
|
||||||
substring(html, maxCharacters) +
|
for (const { segment, index } of htmlSegments) {
|
||||||
'</mark>';
|
if (index < maxCharacters) {
|
||||||
// html = html.slice(0, -leftoverCount);
|
withinLimitHTML += segment;
|
||||||
html = substring(html, 0, maxCharacters);
|
} else {
|
||||||
return html + leftoverHTML;
|
exceedLimitHTML += segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exceedLimitHTML) {
|
||||||
|
exceedLimitHTML =
|
||||||
|
'<mark class="compose-highlight-exceeded">' +
|
||||||
|
exceedLimitHTML +
|
||||||
|
'</mark>';
|
||||||
|
}
|
||||||
|
return withinLimitHTML + exceedLimitHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html
|
return html
|
||||||
|
|
|
@ -2,6 +2,9 @@ import './index.css';
|
||||||
|
|
||||||
import './cloak-mode.css';
|
import './cloak-mode.css';
|
||||||
|
|
||||||
|
// Polyfill needed for Firefox < 122
|
||||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1423593
|
||||||
|
import '@formatjs/intl-segmenter/polyfill';
|
||||||
import { render } from 'preact';
|
import { render } from 'preact';
|
||||||
import { HashRouter } from 'react-router-dom';
|
import { HashRouter } from 'react-router-dom';
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue