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",
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "~0.5.4",
|
||||
"@formatjs/intl-segmenter": "~11.5.5",
|
||||
"@formkit/auto-animate": "~0.8.1",
|
||||
"@github/text-expander-element": "~2.6.1",
|
||||
"@iconify-icons/mingcute": "~1.2.9",
|
||||
|
@ -33,8 +34,7 @@
|
|||
"react-intersection-observer": "~9.8.1",
|
||||
"react-quick-pinch-zoom": "~5.1.0",
|
||||
"react-router-dom": "6.6.2",
|
||||
"runes2": "~1.1.4",
|
||||
"string-length": "5.0.1",
|
||||
"string-length": "6.0.0",
|
||||
"swiped-events": "~1.1.9",
|
||||
"toastify-js": "~1.12.0",
|
||||
"uid": "~2.0.2",
|
||||
|
@ -2924,6 +2924,15 @@
|
|||
"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": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
||||
|
@ -2932,6 +2941,16 @@
|
|||
"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": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.1.tgz",
|
||||
|
@ -3967,15 +3986,6 @@
|
|||
"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": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
|
@ -7116,11 +7126,6 @@
|
|||
"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": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -7262,16 +7267,14 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/string-length": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz",
|
||||
"integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==",
|
||||
"license": "MIT",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-6.0.0.tgz",
|
||||
"integrity": "sha512-1U361pxZHEQ+FeSjzqRpV+cu2vTzYeWeafXFLykiFlv4Vc0n3njgU8HrMbyik5uwm77naWMuVG8fhEF+Ovb1Kg==",
|
||||
"dependencies": {
|
||||
"char-regex": "^2.0.0",
|
||||
"strip-ansi": "^7.0.1"
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "~0.5.4",
|
||||
"@formatjs/intl-segmenter": "~11.5.5",
|
||||
"@formkit/auto-animate": "~0.8.1",
|
||||
"@github/text-expander-element": "~2.6.1",
|
||||
"@iconify-icons/mingcute": "~1.2.9",
|
||||
|
@ -35,8 +36,7 @@
|
|||
"react-intersection-observer": "~9.8.1",
|
||||
"react-quick-pinch-zoom": "~5.1.0",
|
||||
"react-router-dom": "6.6.2",
|
||||
"runes2": "~1.1.4",
|
||||
"string-length": "5.0.1",
|
||||
"string-length": "6.0.0",
|
||||
"swiped-events": "~1.1.9",
|
||||
"toastify-js": "~1.12.0",
|
||||
"uid": "~2.0.2",
|
||||
|
|
|
@ -6,7 +6,6 @@ import { deepEqual } from 'fast-equals';
|
|||
import { forwardRef } from 'preact/compat';
|
||||
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { substring } from 'runes2';
|
||||
import stringLength from 'string-length';
|
||||
import { uid } from 'uid/single';
|
||||
import { useDebouncedCallback, useThrottledCallback } from 'use-debounce';
|
||||
|
@ -131,6 +130,7 @@ const SCAN_RE = new RegExp(
|
|||
'g',
|
||||
);
|
||||
|
||||
const segmenter = new Intl.Segmenter();
|
||||
function highlightText(text, { maxCharacters = Infinity }) {
|
||||
// Accept text string, return formatted HTML string
|
||||
// Escape all HTML special characters
|
||||
|
@ -143,19 +143,25 @@ function highlightText(text, { maxCharacters = Infinity }) {
|
|||
|
||||
// Exceeded characters limit
|
||||
const { composerCharacterCount } = states;
|
||||
let leftoverHTML = '';
|
||||
if (composerCharacterCount > maxCharacters) {
|
||||
// NOTE: runes2 substring considers surrogate pairs
|
||||
// const leftoverCount = composerCharacterCount - maxCharacters;
|
||||
// Highlight exceeded characters
|
||||
leftoverHTML =
|
||||
'<mark class="compose-highlight-exceeded">' +
|
||||
// html.slice(-leftoverCount) +
|
||||
substring(html, maxCharacters) +
|
||||
'</mark>';
|
||||
// html = html.slice(0, -leftoverCount);
|
||||
html = substring(html, 0, maxCharacters);
|
||||
return html + leftoverHTML;
|
||||
let withinLimitHTML = '',
|
||||
exceedLimitHTML = '';
|
||||
const htmlSegments = segmenter.segment(html);
|
||||
for (const { segment, index } of htmlSegments) {
|
||||
if (index < maxCharacters) {
|
||||
withinLimitHTML += segment;
|
||||
} else {
|
||||
exceedLimitHTML += segment;
|
||||
}
|
||||
}
|
||||
if (exceedLimitHTML) {
|
||||
exceedLimitHTML =
|
||||
'<mark class="compose-highlight-exceeded">' +
|
||||
exceedLimitHTML +
|
||||
'</mark>';
|
||||
}
|
||||
return withinLimitHTML + exceedLimitHTML;
|
||||
}
|
||||
|
||||
return html
|
||||
|
|
|
@ -2,6 +2,9 @@ import './index.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 { HashRouter } from 'react-router-dom';
|
||||
|
||||
|
|
Loading…
Reference in a new issue