@inshapardaz/likhari-react 0.1.21-dev.192 → 0.1.21-dev.194
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/dist/EditorRoot.d.ts.map +1 -1
- package/dist/EditorRoot.js +11 -2
- package/dist/components/SpellcheckPanel.d.ts +13 -0
- package/dist/components/SpellcheckPanel.d.ts.map +1 -0
- package/dist/components/SpellcheckPanel.js +82 -0
- package/dist/components/Toolbar.d.ts +4 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +2 -3
- package/dist/find/findReplaceActions.d.ts +13 -0
- package/dist/find/findReplaceActions.d.ts.map +1 -1
- package/dist/find/findReplaceActions.js +2 -2
- package/dist/i18n/strings.d.ts +11 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +33 -0
- package/dist/spellcheck/SpellHighlightPlugin.d.ts +8 -0
- package/dist/spellcheck/SpellHighlightPlugin.d.ts.map +1 -0
- package/dist/spellcheck/SpellHighlightPlugin.js +57 -0
- package/dist/spellcheck/spellcheckActions.d.ts +21 -0
- package/dist/spellcheck/spellcheckActions.d.ts.map +1 -0
- package/dist/spellcheck/spellcheckActions.js +38 -0
- package/dist/theme/editor.css +127 -0
- package/package.json +1 -1
- package/dist/cleanup/textCleanupActions.d.ts +0 -8
- package/dist/cleanup/textCleanupActions.d.ts.map +0 -1
- package/dist/cleanup/textCleanupActions.js +0 -28
package/dist/EditorRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAKzH,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAOjE,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAKzH,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAOjE,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAehF,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMnE,yEAAyE;AACzE,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,YAAY,GAAG,KAAK,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,uGAAuG;IACvG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3E,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IACrC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IAClD,iBAAiB,IAAI,OAAO,CAAC;IAC7B,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAQD,eAAO,MAAM,UAAU,uGAwYrB,CAAC"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -27,6 +27,8 @@ import { PoetryPlugin } from './plugins/PoetryPlugin.js';
|
|
|
27
27
|
import { PoetryResizer } from './blocks/PoetryResizer.js';
|
|
28
28
|
import { DraftRestore } from './components/DraftRestore.js';
|
|
29
29
|
import { FindReplaceBar } from './components/FindReplaceBar.js';
|
|
30
|
+
import { SpellcheckPanel } from './components/SpellcheckPanel.js';
|
|
31
|
+
import { SpellHighlightPlugin } from './spellcheck/SpellHighlightPlugin.js';
|
|
30
32
|
import { LeaveDialog } from './components/LeaveDialog.js';
|
|
31
33
|
import { clearDraft, createDraftId, hasDraftContent, pruneDrafts, writeDraft, } from './persistence/draftStorage.js';
|
|
32
34
|
import { ImageOptionsContext } from './image/ImageOptionsContext.js';
|
|
@@ -69,6 +71,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
69
71
|
const lastSavedJsonRef = useRef(null);
|
|
70
72
|
const [isDirty, setIsDirty] = useState(false);
|
|
71
73
|
const [findOpen, setFindOpen] = useState(false);
|
|
74
|
+
const [spellOpen, setSpellOpen] = useState(false);
|
|
72
75
|
const isDirtyRef = useRef(isDirty);
|
|
73
76
|
isDirtyRef.current = isDirty;
|
|
74
77
|
const autosaveTimerRef = useRef(null);
|
|
@@ -281,9 +284,15 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
281
284
|
// rather than colliding on a shared one.
|
|
282
285
|
const portalTargetId = useId();
|
|
283
286
|
const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
|
|
284
|
-
return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsxs(UiStringsContext.Provider, { value: strings, children: [_jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, onSave: handleSave, findOpen: findOpen, onToggleFind: () =>
|
|
287
|
+
return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsxs(UiStringsContext.Provider, { value: strings, children: [_jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, onSave: handleSave, findOpen: findOpen, onToggleFind: () => {
|
|
288
|
+
setFindOpen((v) => !v);
|
|
289
|
+
setSpellOpen(false);
|
|
290
|
+
}, spellOpen: spellOpen, onToggleSpell: () => {
|
|
291
|
+
setSpellOpen((v) => !v);
|
|
292
|
+
setFindOpen(false);
|
|
293
|
+
}, isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
|
|
285
294
|
? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
|
|
286
|
-
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsxs("div", { className: "likhari-canvas-frame", children: [config.findReplace && findOpen && _jsx(FindReplaceBar, { strings: strings, dir: dir, onClose: () => setFindOpen(false) }), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) })] }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
295
|
+
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsxs("div", { className: "likhari-canvas-frame", children: [config.findReplace && findOpen && _jsx(FindReplaceBar, { strings: strings, dir: dir, onClose: () => setFindOpen(false) }), config.language.spellCheck && spellOpen && _jsx(SpellcheckPanel, { strings: strings, dir: dir, onClose: () => setSpellOpen(false) }), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, spellCheck: false, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) })] }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.language.spellCheck && _jsx(SpellHighlightPlugin, {}), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
287
296
|
handleSave();
|
|
288
297
|
settleLeave(true);
|
|
289
298
|
}, onSaveDraft: () => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Strings } from '../i18n/strings.js';
|
|
2
|
+
/**
|
|
3
|
+
* Steps through the misspelled words one at a time, like the find widget.
|
|
4
|
+
* Each word is selected in the editor as it comes up, and its suggestions
|
|
5
|
+
* can replace it. Checking reads the document on demand, so it never flags
|
|
6
|
+
* words while the user is still typing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function SpellcheckPanel({ strings, dir, onClose }: {
|
|
9
|
+
strings: Strings;
|
|
10
|
+
dir: 'ltr' | 'rtl';
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=SpellcheckPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpellcheckPanel.d.ts","sourceRoot":"","sources":["../../src/components/SpellcheckPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAmB/C;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,+BA2IvH"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
+
import { IconChevronDown, IconX } from '@tabler/icons-react';
|
|
5
|
+
import { $replaceMatch, $selectMatch } from '../find/findReplaceActions.js';
|
|
6
|
+
import { $collectMisspellings } from '../spellcheck/spellcheckActions.js';
|
|
7
|
+
import { getSpeller, hasSpellDictionary } from '../spellcheck/spellDictionaries.js';
|
|
8
|
+
const LANGUAGES = [
|
|
9
|
+
{ value: 'en', label: 'English' },
|
|
10
|
+
{ value: 'ur', label: 'اردو' },
|
|
11
|
+
{ value: 'pa-shahmukhi', label: 'پنجابی (شاہ مکھی)' },
|
|
12
|
+
];
|
|
13
|
+
const SUGGESTIONS_PER_WORD = 3;
|
|
14
|
+
/**
|
|
15
|
+
* Steps through the misspelled words one at a time, like the find widget.
|
|
16
|
+
* Each word is selected in the editor as it comes up, and its suggestions
|
|
17
|
+
* can replace it. Checking reads the document on demand, so it never flags
|
|
18
|
+
* words while the user is still typing.
|
|
19
|
+
*/
|
|
20
|
+
export function SpellcheckPanel({ strings, dir, onClose }) {
|
|
21
|
+
const [editor] = useLexicalComposerContext();
|
|
22
|
+
const t = strings.spellcheck;
|
|
23
|
+
const [language, setLanguage] = useState('en');
|
|
24
|
+
const [items, setItems] = useState(null);
|
|
25
|
+
const [index, setIndex] = useState(0);
|
|
26
|
+
const [checking, setChecking] = useState(false);
|
|
27
|
+
const available = hasSpellDictionary(language);
|
|
28
|
+
const current = items?.[index];
|
|
29
|
+
// Selects an item in the editor and focuses the editor, so the selection is
|
|
30
|
+
// drawn (Lexical only draws it while the editor has focus).
|
|
31
|
+
const show = (list, at) => {
|
|
32
|
+
const item = list[at];
|
|
33
|
+
if (!item)
|
|
34
|
+
return;
|
|
35
|
+
editor.update(() => $selectMatch(item.match), { discrete: true });
|
|
36
|
+
editor.getElementByKey(item.match.anchorKey)?.scrollIntoView({ block: 'center' });
|
|
37
|
+
editor.focus();
|
|
38
|
+
};
|
|
39
|
+
const check = async () => {
|
|
40
|
+
const speller = getSpeller(language);
|
|
41
|
+
if (!speller)
|
|
42
|
+
return;
|
|
43
|
+
setChecking(true);
|
|
44
|
+
const resolved = await speller;
|
|
45
|
+
const found = editor.getEditorState().read(() => $collectMisspellings({ ltr: resolved, rtl: resolved }));
|
|
46
|
+
const list = found.map((m) => ({
|
|
47
|
+
...m,
|
|
48
|
+
suggestions: resolved.suggest(m.word).slice(0, SUGGESTIONS_PER_WORD),
|
|
49
|
+
}));
|
|
50
|
+
setItems(list);
|
|
51
|
+
setIndex(0);
|
|
52
|
+
setChecking(false);
|
|
53
|
+
show(list, 0);
|
|
54
|
+
};
|
|
55
|
+
const step = (delta) => {
|
|
56
|
+
if (!items || items.length === 0)
|
|
57
|
+
return;
|
|
58
|
+
const next = (index + delta + items.length) % items.length;
|
|
59
|
+
setIndex(next);
|
|
60
|
+
show(items, next);
|
|
61
|
+
};
|
|
62
|
+
// Replacing changes the document, so the list is checked again afterwards.
|
|
63
|
+
// Only a word still at the same place is replaced, in case the document
|
|
64
|
+
// changed since the check.
|
|
65
|
+
const replace = async (item, suggestion) => {
|
|
66
|
+
const speller = getSpeller(language);
|
|
67
|
+
if (!speller)
|
|
68
|
+
return;
|
|
69
|
+
const resolved = await speller;
|
|
70
|
+
editor.update(() => {
|
|
71
|
+
const match = $collectMisspellings({ ltr: resolved, rtl: resolved }).find((m) => m.word === item.word && m.match.anchorKey === item.match.anchorKey && m.match.anchorOffset === item.match.anchorOffset);
|
|
72
|
+
if (match)
|
|
73
|
+
$replaceMatch(match.match, suggestion);
|
|
74
|
+
}, { discrete: true });
|
|
75
|
+
await check();
|
|
76
|
+
};
|
|
77
|
+
const status = items === null ? '' : items.length === 0 ? t.noMisspellings : `${index + 1} / ${items.length}`;
|
|
78
|
+
return (_jsxs("div", { className: "likhari-spell-panel", role: "region", "aria-label": t.title, dir: dir, children: [_jsxs("div", { className: "likhari-spell-header", children: [_jsx("strong", { children: t.title }), _jsx("button", { type: "button", className: "likhari-spell-icon", onClick: onClose, "aria-label": t.close, title: t.close, children: _jsx(IconX, { size: 14, stroke: 1.75 }) })] }), _jsxs("div", { className: "likhari-spell-controls", children: [_jsx("select", { "aria-label": t.language, value: language, onChange: (e) => {
|
|
79
|
+
setLanguage(e.target.value);
|
|
80
|
+
setItems(null);
|
|
81
|
+
}, children: LANGUAGES.map((l) => (_jsxs("option", { value: l.value, children: [l.label, hasSpellDictionary(l.value) ? '' : ` (${t.noDictionary})`] }, l.value))) }), _jsx("button", { type: "button", onClick: check, disabled: !available || checking, children: t.check })] }), !available && _jsx("p", { className: "likhari-spell-note", children: t.noDictionary }), items !== null && (_jsxs("div", { className: "likhari-spell-nav", children: [_jsx("span", { className: "likhari-spell-status", "aria-live": "polite", children: status }), _jsx("button", { type: "button", className: "likhari-spell-icon", onClick: () => step(-1), disabled: items.length === 0, "aria-label": t.previous, title: t.previous, children: _jsx(IconChevronDown, { size: 14, stroke: 1.75, style: { transform: 'rotate(180deg)' } }) }), _jsx("button", { type: "button", className: "likhari-spell-icon", onClick: () => step(1), disabled: items.length === 0, "aria-label": t.next, title: t.next, children: _jsx(IconChevronDown, { size: 14, stroke: 1.75 }) })] })), current && (_jsxs("div", { className: "likhari-spell-item", children: [_jsx("span", { className: "likhari-spell-word", children: current.word }), current.suggestions.length === 0 ? (_jsx("span", { className: "likhari-spell-note", children: t.noSuggestions })) : (_jsx("div", { className: "likhari-spell-suggestions", children: current.suggestions.map((s) => (_jsx("button", { type: "button", className: "likhari-spell-suggestion", onClick: () => replace(current, s), children: s }, s))) }))] }))] }));
|
|
82
|
+
}
|
|
@@ -7,6 +7,9 @@ export interface ToolbarProps {
|
|
|
7
7
|
/** Whether the find-and-replace widget is open, and how to toggle it (owned by EditorRoot). */
|
|
8
8
|
findOpen?: boolean;
|
|
9
9
|
onToggleFind?: () => void;
|
|
10
|
+
/** Whether the spellcheck panel is open, and how to toggle it (owned by EditorRoot). */
|
|
11
|
+
spellOpen?: boolean;
|
|
12
|
+
onToggleSpell?: () => void;
|
|
10
13
|
onSave?: () => void;
|
|
11
14
|
isDirty?: boolean;
|
|
12
15
|
showSave?: boolean;
|
|
@@ -19,5 +22,5 @@ export interface ToolbarProps {
|
|
|
19
22
|
/** Autosave drafts: when set, the toolbar offers a Drafts button that lists and restores them. */
|
|
20
23
|
drafts?: DraftsToolbarOptions;
|
|
21
24
|
}
|
|
22
|
-
export declare function Toolbar({ config, onSave, isDirty, showSave, findOpen, onToggleFind, fontOptions, direction, locale, drafts }: ToolbarProps): import("react").JSX.Element;
|
|
25
|
+
export declare function Toolbar({ config, onSave, isDirty, showSave, findOpen, onToggleFind, spellOpen, onToggleSpell, fontOptions, direction, locale, drafts }: ToolbarProps): import("react").JSX.Element;
|
|
23
26
|
//# sourceMappingURL=Toolbar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAqFA,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAA6D,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAItG,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AA+gBvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,YAAY,EAAE,SAAiB,EAAE,aAAa,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAwkC1N"}
|
|
@@ -8,7 +8,6 @@ import { $createParagraphNode } from 'lexical';
|
|
|
8
8
|
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode } from '@lexical/rich-text';
|
|
9
9
|
import { $isListNode, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, } from '@lexical/list';
|
|
10
10
|
import { $findMatchingParent, $insertNodeToNearestRoot } from '@lexical/utils';
|
|
11
|
-
import { $cleanUpText } from '../cleanup/textCleanupActions.js';
|
|
12
11
|
import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
13
12
|
import { ImageDialog } from '../image/ImageDialog.js';
|
|
14
13
|
import { $createImageNode } from '../image/ImageNode.js';
|
|
@@ -183,7 +182,7 @@ function PoetryMenuItems({ strings, layout, scale, centered, onAction, }) {
|
|
|
183
182
|
};
|
|
184
183
|
return (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: t.menuLabel }), item(IconColumns1, t.singleColumn, setLayout('single'), layout === 'single'), item(IconColumns2, t.twoColumn, setLayout('two-column'), layout === 'two-column'), item(IconArrowsShuffle, t.staggered, setLayout('staggered'), layout === 'staggered'), _jsx(Menu.Divider, {}), _jsx(Menu.Divider, {}), item(IconRowInsertTop, t.insertCoupletBefore, () => $insertCoupletRelativeToSelection('before')), item(IconRowInsertBottom, t.insertCoupletAfter, () => $insertCoupletRelativeToSelection('after')), item(IconArrowsMinimize, t.tighterSpacing, () => $adjustPoetrySpacing(-1), !canStep(POETRY_SPACINGS, scale.spacing, -1)), item(IconArrowsMaximize, t.looserSpacing, () => $adjustPoetrySpacing(1), !canStep(POETRY_SPACINGS, scale.spacing, 1)), layout === 'staggered' && (_jsxs(_Fragment, { children: [item(IconArrowsMinimize, t.narrowerCouplets, () => $adjustPoetryStagger(-1), !canStep(POETRY_STAGGERS, scale.stagger, -1)), item(IconArrowsMaximize, t.widerCouplets, () => $adjustPoetryStagger(1), !canStep(POETRY_STAGGERS, scale.stagger, 1))] })), layout === 'two-column' && (_jsxs(_Fragment, { children: [item(IconAlignCenter, centered ? t.uncenterCouplet : t.centerCouplet, () => $setCoupletCentered(!centered)), item(IconColumns2, t.narrowerGutter, () => $adjustPoetryGutter(-1), !canStep(POETRY_GUTTERS, scale.gutter, -1)), item(IconColumns2, t.widerGutter, () => $adjustPoetryGutter(1), !canStep(POETRY_GUTTERS, scale.gutter, 1))] })), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red'), item(IconTrash, t.deletePoetry, $deletePoetryBlock, false, 'red')] }));
|
|
185
184
|
}
|
|
186
|
-
export function Toolbar({ config, onSave, isDirty, showSave, findOpen = false, onToggleFind, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
185
|
+
export function Toolbar({ config, onSave, isDirty, showSave, findOpen = false, onToggleFind, spellOpen = false, onToggleSpell, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
187
186
|
const [editor] = useLexicalComposerContext();
|
|
188
187
|
const [state, setState] = useState(INITIAL_STATE);
|
|
189
188
|
const strings = useStrings(locale);
|
|
@@ -812,7 +811,7 @@ export function Toolbar({ config, onSave, isDirty, showSave, findOpen = false, o
|
|
|
812
811
|
showStubInsertGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [(config.images.linked || config.images.embedded) && (_jsx(ToolbarButton, { icon: IconPhoto, title: strings.toolbar.insertImage, onClick: openImageDialog })), config.blocks.pageBreak && (_jsx(ToolbarButton, { icon: IconPageBreak, title: strings.toolbar.insertPageBreak, onClick: () => editor.dispatchCommand(INSERT_PAGE_BREAK_COMMAND, undefined) })), config.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), config.columns && _jsx(ToolbarButton, { icon: IconColumns, title: strings.toolbar.insertColumns, onClick: openLayoutDialog }), config.footnotes && (_jsx(ToolbarButton, { icon: IconNumber1Small, title: strings.toolbar.insertFootnote, onClick: () => editor.dispatchCommand(INSERT_FOOTNOTE_COMMAND, undefined) })), config.blocks.horizontalRule && (_jsx(ToolbarButton, { icon: IconSeparatorHorizontal, title: strings.toolbar.insertHorizontalRule, onClick: () => editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined) })), config.findReplace && (_jsx(ToolbarButton, { icon: IconSearch, title: strings.findReplace.toggle, active: findOpen, onClick: onToggleFind })), config.poetry.enabled && locale !== 'en' && (_jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.insertPoetryCouplet, onClick: () => editor.dispatchCommand(INSERT_POETRY_COUPLET_COMMAND, { layout: config.poetry.defaultLayout }) }))] }, "stubInsert")),
|
|
813
812
|
config.tables && state.inTable && (_jsx("div", { className: "likhari-toolbar-group", children: _jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx("button", { type: "button", className: "likhari-toolbar-button", "data-active": "true", "aria-pressed": "true", "aria-haspopup": "menu", "aria-label": strings.toolbar.tableOptions, title: strings.toolbar.tableOptions, onMouseDown: (e) => e.preventDefault(), children: _jsx(IconTableOptions, { size: ICON_SIZE, stroke: ICON_STROKE }) }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: state.tableRows, columns: state.tableColumns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction }) })] }) }, "tableActions")),
|
|
814
813
|
config.poetry.enabled && state.inPoetry && (_jsx("div", { className: "likhari-toolbar-group", children: _jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 200, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx("button", { type: "button", className: "likhari-toolbar-button", "data-active": "true", "aria-pressed": "true", "aria-haspopup": "menu", "aria-label": strings.toolbar.poetryOptions, title: strings.toolbar.poetryOptions, onMouseDown: (e) => e.preventDefault(), children: _jsx(IconFeather, { size: ICON_SIZE, stroke: ICON_STROKE }) }) }), _jsx(Menu.Dropdown, { children: _jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }) })] }) }, "poetryActions")),
|
|
815
|
-
showLanguageGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [config.language.autocorrect && _jsx(StubButton, { icon: IconWand, title: strings.toolbar.autocorrect, comingSoon: strings.toolbar.comingSoon }), config.language.textCleanup &&
|
|
814
|
+
showLanguageGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [config.language.autocorrect && _jsx(StubButton, { icon: IconWand, title: strings.toolbar.autocorrect, comingSoon: strings.toolbar.comingSoon }), config.language.textCleanup && _jsx(StubButton, { icon: IconSparkles, title: strings.toolbar.textCleanup, comingSoon: strings.toolbar.comingSoon }), config.language.spellCheck && (_jsx(ToolbarButton, { icon: IconAbc, title: strings.toolbar.spellChecker, active: spellOpen, onClick: onToggleSpell }))] }, "language")),
|
|
816
815
|
];
|
|
817
816
|
return (_jsxs("div", { className: "likhari-toolbar", role: "toolbar", "aria-label": strings.toolbar.ariaLabel, ref: toolbarContainerRef, children: [fixedGroups, movableGroups
|
|
818
817
|
.filter((group) => !overflowGroupKeys.has(group.key))
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type TextNode } from 'lexical';
|
|
1
2
|
/** A match as a Lexical selection range: start and end points, each in a text node. */
|
|
2
3
|
export interface FindMatch {
|
|
3
4
|
anchorKey: string;
|
|
@@ -5,6 +6,18 @@ export interface FindMatch {
|
|
|
5
6
|
focusKey: string;
|
|
6
7
|
focusOffset: number;
|
|
7
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Text nodes grouped by their parent, in document order. A match is searched
|
|
11
|
+
* for within one parent only, so it never spans two paragraphs or table
|
|
12
|
+
* cells, but it can span the several text nodes that formatting splits a
|
|
13
|
+
* paragraph into.
|
|
14
|
+
*/
|
|
15
|
+
export declare function $textGroups(): TextNode[][];
|
|
16
|
+
/** The text node and offset that a character index in a group falls in. */
|
|
17
|
+
export declare function $locate(group: TextNode[], index: number, end: boolean): {
|
|
18
|
+
key: string;
|
|
19
|
+
offset: number;
|
|
20
|
+
};
|
|
8
21
|
/** Every non-overlapping occurrence of `query` in the document, case-sensitive. */
|
|
9
22
|
export declare function $findMatches(query: string): FindMatch[];
|
|
10
23
|
/** Makes the match the editor's selection, so it's highlighted and scrolled to. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findReplaceActions.d.ts","sourceRoot":"","sources":["../../src/find/findReplaceActions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"findReplaceActions.d.ts","sourceRoot":"","sources":["../../src/find/findReplaceActions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoF,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE1H,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,QAAQ,EAAE,EAAE,CAS1C;AAED,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAUvG;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAcvD;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAKnD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAMzE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAItE"}
|
|
@@ -5,7 +5,7 @@ import { $createRangeSelection, $getRoot, $getSelection, $isRangeSelection, $set
|
|
|
5
5
|
* cells, but it can span the several text nodes that formatting splits a
|
|
6
6
|
* paragraph into.
|
|
7
7
|
*/
|
|
8
|
-
function $textGroups() {
|
|
8
|
+
export function $textGroups() {
|
|
9
9
|
const groups = new Map();
|
|
10
10
|
for (const node of $getRoot().getAllTextNodes()) {
|
|
11
11
|
const parentKey = node.getParentOrThrow().getKey();
|
|
@@ -18,7 +18,7 @@ function $textGroups() {
|
|
|
18
18
|
return [...groups.values()];
|
|
19
19
|
}
|
|
20
20
|
/** The text node and offset that a character index in a group falls in. */
|
|
21
|
-
function $locate(group, index, end) {
|
|
21
|
+
export function $locate(group, index, end) {
|
|
22
22
|
let start = 0;
|
|
23
23
|
for (const node of group) {
|
|
24
24
|
const length = node.getTextContent().length;
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -169,6 +169,17 @@ export interface Strings {
|
|
|
169
169
|
noMatches: string;
|
|
170
170
|
close: string;
|
|
171
171
|
};
|
|
172
|
+
spellcheck: {
|
|
173
|
+
title: string;
|
|
174
|
+
language: string;
|
|
175
|
+
check: string;
|
|
176
|
+
close: string;
|
|
177
|
+
noDictionary: string;
|
|
178
|
+
noMisspellings: string;
|
|
179
|
+
previous: string;
|
|
180
|
+
next: string;
|
|
181
|
+
noSuggestions: string;
|
|
182
|
+
};
|
|
172
183
|
link: {
|
|
173
184
|
menuLabel: string;
|
|
174
185
|
noUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n/strings.js
CHANGED
|
@@ -152,6 +152,17 @@ const en = {
|
|
|
152
152
|
noMatches: 'No matches',
|
|
153
153
|
close: 'Close',
|
|
154
154
|
},
|
|
155
|
+
spellcheck: {
|
|
156
|
+
title: 'Spell check',
|
|
157
|
+
language: 'Language',
|
|
158
|
+
check: 'Check',
|
|
159
|
+
close: 'Close',
|
|
160
|
+
noDictionary: 'No dictionary installed',
|
|
161
|
+
noMisspellings: 'No misspellings found',
|
|
162
|
+
previous: 'Previous',
|
|
163
|
+
next: 'Next',
|
|
164
|
+
noSuggestions: 'No suggestions',
|
|
165
|
+
},
|
|
155
166
|
link: {
|
|
156
167
|
menuLabel: 'Link',
|
|
157
168
|
noUrl: '(no URL)',
|
|
@@ -385,6 +396,17 @@ const ur = {
|
|
|
385
396
|
noMatches: 'کوئی میچ نہیں',
|
|
386
397
|
close: 'بند کریں',
|
|
387
398
|
},
|
|
399
|
+
spellcheck: {
|
|
400
|
+
title: 'ہجے کی جانچ',
|
|
401
|
+
language: 'زبان',
|
|
402
|
+
check: 'جانچیں',
|
|
403
|
+
close: 'بند کریں',
|
|
404
|
+
noDictionary: 'کوئی لغت نصب نہیں',
|
|
405
|
+
noMisspellings: 'کوئی غلط ہجے نہیں ملے',
|
|
406
|
+
previous: 'پچھلا',
|
|
407
|
+
next: 'اگلا',
|
|
408
|
+
noSuggestions: 'کوئی تجویز نہیں',
|
|
409
|
+
},
|
|
388
410
|
link: {
|
|
389
411
|
menuLabel: 'لنک',
|
|
390
412
|
noUrl: '(کوئی یو آر ایل نہیں)',
|
|
@@ -618,6 +640,17 @@ const paShahmukhi = {
|
|
|
618
640
|
noMatches: 'کوئی ملدا نئیں',
|
|
619
641
|
close: 'بند کرo',
|
|
620
642
|
},
|
|
643
|
+
spellcheck: {
|
|
644
|
+
title: 'ہجے دی جانچ',
|
|
645
|
+
language: 'بولی',
|
|
646
|
+
check: 'جانچو',
|
|
647
|
+
close: 'بند کرو',
|
|
648
|
+
noDictionary: 'کوئی شبدکوش نئیں لگی',
|
|
649
|
+
noMisspellings: 'کوئی غلط ہجے نئیں لبھے',
|
|
650
|
+
previous: 'پچھلا',
|
|
651
|
+
next: 'اگلا',
|
|
652
|
+
noSuggestions: 'کوئی تجویز نئیں',
|
|
653
|
+
},
|
|
621
654
|
link: {
|
|
622
655
|
menuLabel: 'لنک',
|
|
623
656
|
noUrl: '(کوئی یو آر ایل نئیں)',
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Underlines misspelled words the way the browser does, without changing the
|
|
3
|
+
* document: ranges are set on the rendered text through the CSS Custom
|
|
4
|
+
* Highlight API. Checking is debounced so typing stays smooth. In browsers
|
|
5
|
+
* without the API, nothing is underlined.
|
|
6
|
+
*/
|
|
7
|
+
export declare function SpellHighlightPlugin(): null;
|
|
8
|
+
//# sourceMappingURL=SpellHighlightPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpellHighlightPlugin.d.ts","sourceRoot":"","sources":["../../src/spellcheck/SpellHighlightPlugin.tsx"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,wBAAgB,oBAAoB,SAgDnC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
+
import { $collectMisspellings } from './spellcheckActions.js';
|
|
4
|
+
import { getSpeller } from './spellDictionaries.js';
|
|
5
|
+
/** The CSS Custom Highlight name; editor.css styles it as a red wavy underline. */
|
|
6
|
+
const HIGHLIGHT = 'likhari-spelling';
|
|
7
|
+
const DEBOUNCE_MS = 300;
|
|
8
|
+
/**
|
|
9
|
+
* Underlines misspelled words the way the browser does, without changing the
|
|
10
|
+
* document: ranges are set on the rendered text through the CSS Custom
|
|
11
|
+
* Highlight API. Checking is debounced so typing stays smooth. In browsers
|
|
12
|
+
* without the API, nothing is underlined.
|
|
13
|
+
*/
|
|
14
|
+
export function SpellHighlightPlugin() {
|
|
15
|
+
const [editor] = useLexicalComposerContext();
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (typeof CSS === 'undefined' || !('highlights' in CSS))
|
|
18
|
+
return;
|
|
19
|
+
let checkers = null;
|
|
20
|
+
let timer;
|
|
21
|
+
let active = true;
|
|
22
|
+
const paint = () => {
|
|
23
|
+
if (!active || !checkers)
|
|
24
|
+
return;
|
|
25
|
+
const found = editor.getEditorState().read(() => $collectMisspellings(checkers));
|
|
26
|
+
const ranges = [];
|
|
27
|
+
for (const misspelling of found) {
|
|
28
|
+
for (const segment of misspelling.segments) {
|
|
29
|
+
const text = editor.getElementByKey(segment.key)?.firstChild;
|
|
30
|
+
if (!text || text.nodeType !== Node.TEXT_NODE)
|
|
31
|
+
continue;
|
|
32
|
+
const range = document.createRange();
|
|
33
|
+
range.setStart(text, segment.start);
|
|
34
|
+
range.setEnd(text, segment.end);
|
|
35
|
+
ranges.push(range);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
CSS.highlights.set(HIGHLIGHT, new Highlight(...ranges));
|
|
39
|
+
};
|
|
40
|
+
const schedule = () => {
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
timer = setTimeout(paint, DEBOUNCE_MS);
|
|
43
|
+
};
|
|
44
|
+
const unregister = editor.registerUpdateListener(schedule);
|
|
45
|
+
Promise.all([getSpeller('en'), getSpeller('ur')]).then(async ([en, ur]) => {
|
|
46
|
+
checkers = { ltr: en ? await en : undefined, rtl: ur ? await ur : undefined };
|
|
47
|
+
schedule();
|
|
48
|
+
});
|
|
49
|
+
return () => {
|
|
50
|
+
active = false;
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
unregister();
|
|
53
|
+
CSS.highlights.delete(HIGHLIGHT);
|
|
54
|
+
};
|
|
55
|
+
}, [editor]);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type FindMatch } from '../find/findReplaceActions.js';
|
|
2
|
+
import { type Speller } from './spellDictionaries.js';
|
|
3
|
+
/** The checker for each text direction: English for LTR blocks, Urdu for RTL. */
|
|
4
|
+
export interface Checkers {
|
|
5
|
+
ltr?: Speller;
|
|
6
|
+
rtl?: Speller;
|
|
7
|
+
}
|
|
8
|
+
/** The part of a misspelled word that falls inside one text node. */
|
|
9
|
+
export interface Segment {
|
|
10
|
+
key: string;
|
|
11
|
+
start: number;
|
|
12
|
+
end: number;
|
|
13
|
+
}
|
|
14
|
+
export interface Misspelling {
|
|
15
|
+
word: string;
|
|
16
|
+
match: FindMatch;
|
|
17
|
+
segments: Segment[];
|
|
18
|
+
}
|
|
19
|
+
/** Every word in the document its block's checker does not recognise. */
|
|
20
|
+
export declare function $collectMisspellings(checkers: Checkers): Misspelling[];
|
|
21
|
+
//# sourceMappingURL=spellcheckActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spellcheckActions.d.ts","sourceRoot":"","sources":["../../src/spellcheck/spellcheckActions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE5D,iFAAiF;AACjF,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,EAAE,CAmBtE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { $textGroups, $locate } from '../find/findReplaceActions.js';
|
|
2
|
+
import { wordsIn } from './spellDictionaries.js';
|
|
3
|
+
/** Every word in the document its block's checker does not recognise. */
|
|
4
|
+
export function $collectMisspellings(checkers) {
|
|
5
|
+
const found = [];
|
|
6
|
+
for (const group of $textGroups()) {
|
|
7
|
+
const direction = group[0].getParentOrThrow().getDirection();
|
|
8
|
+
const speller = direction === 'rtl' ? checkers.rtl : checkers.ltr;
|
|
9
|
+
if (!speller)
|
|
10
|
+
continue;
|
|
11
|
+
const text = group.map((node) => node.getTextContent()).join('');
|
|
12
|
+
for (const span of wordsIn(text)) {
|
|
13
|
+
if (speller.correct(span.word))
|
|
14
|
+
continue;
|
|
15
|
+
const start = $locate(group, span.start, false);
|
|
16
|
+
const end = $locate(group, span.end, true);
|
|
17
|
+
found.push({
|
|
18
|
+
word: span.word,
|
|
19
|
+
match: { anchorKey: start.key, anchorOffset: start.offset, focusKey: end.key, focusOffset: end.offset },
|
|
20
|
+
segments: segmentsOf(group, span.start, span.end),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return found;
|
|
25
|
+
}
|
|
26
|
+
function segmentsOf(group, start, end) {
|
|
27
|
+
const segments = [];
|
|
28
|
+
let offset = 0;
|
|
29
|
+
for (const node of group) {
|
|
30
|
+
const length = node.getTextContent().length;
|
|
31
|
+
const from = Math.max(start, offset);
|
|
32
|
+
const to = Math.min(end, offset + length);
|
|
33
|
+
if (to > from)
|
|
34
|
+
segments.push({ key: node.getKey(), start: from - offset, end: to - offset });
|
|
35
|
+
offset += length;
|
|
36
|
+
}
|
|
37
|
+
return segments;
|
|
38
|
+
}
|
package/dist/theme/editor.css
CHANGED
|
@@ -870,3 +870,130 @@
|
|
|
870
870
|
opacity: 0.8;
|
|
871
871
|
white-space: nowrap;
|
|
872
872
|
}
|
|
873
|
+
|
|
874
|
+
/* Spellcheck panel: same top-right floating spot as the find widget, which
|
|
875
|
+
closes when this opens. */
|
|
876
|
+
.likhari-spell-panel {
|
|
877
|
+
position: absolute;
|
|
878
|
+
z-index: 5;
|
|
879
|
+
top: 8px;
|
|
880
|
+
right: 16px;
|
|
881
|
+
width: max-content;
|
|
882
|
+
max-width: min(360px, calc(100% - 32px));
|
|
883
|
+
max-height: 60%;
|
|
884
|
+
overflow-y: auto;
|
|
885
|
+
overflow-x: hidden;
|
|
886
|
+
padding: 8px;
|
|
887
|
+
border: 1px solid var(--editor-line);
|
|
888
|
+
border-radius: 6px;
|
|
889
|
+
background: var(--editor-paper-dim);
|
|
890
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
891
|
+
font-size: 13px;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
.likhari-spell-panel[dir='rtl'] {
|
|
895
|
+
right: auto;
|
|
896
|
+
left: 16px;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
.likhari-spell-header,
|
|
900
|
+
.likhari-spell-controls {
|
|
901
|
+
display: flex;
|
|
902
|
+
flex-wrap: wrap;
|
|
903
|
+
align-items: center;
|
|
904
|
+
justify-content: space-between;
|
|
905
|
+
gap: 6px;
|
|
906
|
+
margin-bottom: 6px;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
.likhari-spell-controls select {
|
|
910
|
+
min-width: 0;
|
|
911
|
+
max-width: 100%;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
.likhari-spell-panel button {
|
|
915
|
+
padding: 2px 8px;
|
|
916
|
+
border: 1px solid var(--editor-line);
|
|
917
|
+
border-radius: 4px;
|
|
918
|
+
background: transparent;
|
|
919
|
+
color: inherit;
|
|
920
|
+
cursor: pointer;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
.likhari-spell-panel button:disabled {
|
|
924
|
+
opacity: 0.5;
|
|
925
|
+
cursor: default;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
.likhari-spell-icon {
|
|
929
|
+
display: inline-flex;
|
|
930
|
+
align-items: center;
|
|
931
|
+
justify-content: center;
|
|
932
|
+
width: 24px;
|
|
933
|
+
height: 24px;
|
|
934
|
+
padding: 0 !important;
|
|
935
|
+
border: none !important;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
.likhari-spell-note {
|
|
939
|
+
margin: 4px 0;
|
|
940
|
+
opacity: 0.8;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
.likhari-spell-list {
|
|
944
|
+
list-style: none;
|
|
945
|
+
margin: 0;
|
|
946
|
+
padding: 0;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
.likhari-spell-list li {
|
|
950
|
+
display: flex;
|
|
951
|
+
flex-wrap: wrap;
|
|
952
|
+
align-items: center;
|
|
953
|
+
gap: 4px;
|
|
954
|
+
padding: 4px 0;
|
|
955
|
+
border-top: 1px solid var(--editor-line);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
.likhari-spell-word {
|
|
959
|
+
font-weight: 600;
|
|
960
|
+
color: #b42318 !important;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
.likhari-spell-suggestion {
|
|
964
|
+
font-size: 12px;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
/* Misspelled words, underlined like the browser's own spellcheck. Styled
|
|
968
|
+
through the CSS Custom Highlight API by SpellHighlightPlugin. */
|
|
969
|
+
::highlight(likhari-spelling) {
|
|
970
|
+
text-decoration: red wavy underline;
|
|
971
|
+
text-decoration-skip-ink: none;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
.likhari-spell-nav {
|
|
975
|
+
display: flex;
|
|
976
|
+
align-items: center;
|
|
977
|
+
justify-content: flex-end;
|
|
978
|
+
gap: 4px;
|
|
979
|
+
margin-bottom: 6px;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
.likhari-spell-status {
|
|
983
|
+
opacity: 0.8;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
.likhari-spell-item {
|
|
987
|
+
display: flex;
|
|
988
|
+
flex-direction: column;
|
|
989
|
+
gap: 6px;
|
|
990
|
+
padding-top: 6px;
|
|
991
|
+
border-top: 1px solid var(--editor-line);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
.likhari-spell-suggestions {
|
|
995
|
+
display: flex;
|
|
996
|
+
flex-wrap: wrap;
|
|
997
|
+
gap: 4px;
|
|
998
|
+
}
|
|
999
|
+
|
package/package.json
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tidies the whole document in place: Unicode NFC normalisation (Arabic-script
|
|
3
|
-
* text can store the same visible letters in different code points), collapsed
|
|
4
|
-
* repeated spaces, and empty text nodes removed. Formatting is kept, since each
|
|
5
|
-
* text node is only changed, never replaced. Returns how many text nodes changed.
|
|
6
|
-
*/
|
|
7
|
-
export declare function $cleanUpText(): number;
|
|
8
|
-
//# sourceMappingURL=textCleanupActions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"textCleanupActions.d.ts","sourceRoot":"","sources":["../../src/cleanup/textCleanupActions.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAMrC"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { $getRoot } from 'lexical';
|
|
2
|
-
/** Runs of two or more spaces or tabs, collapsed to one space. */
|
|
3
|
-
const REPEATED_SPACE = /[ \t]{2,}/g;
|
|
4
|
-
/**
|
|
5
|
-
* Tidies the whole document in place: Unicode NFC normalisation (Arabic-script
|
|
6
|
-
* text can store the same visible letters in different code points), collapsed
|
|
7
|
-
* repeated spaces, and empty text nodes removed. Formatting is kept, since each
|
|
8
|
-
* text node is only changed, never replaced. Returns how many text nodes changed.
|
|
9
|
-
*/
|
|
10
|
-
export function $cleanUpText() {
|
|
11
|
-
let changed = 0;
|
|
12
|
-
for (const node of $getRoot().getAllTextNodes()) {
|
|
13
|
-
if (cleanNode(node))
|
|
14
|
-
changed += 1;
|
|
15
|
-
}
|
|
16
|
-
return changed;
|
|
17
|
-
}
|
|
18
|
-
function cleanNode(node) {
|
|
19
|
-
const text = node.getTextContent();
|
|
20
|
-
const cleaned = text.normalize('NFC').replace(REPEATED_SPACE, ' ');
|
|
21
|
-
if (cleaned === text)
|
|
22
|
-
return false;
|
|
23
|
-
if (cleaned === '')
|
|
24
|
-
node.remove();
|
|
25
|
-
else
|
|
26
|
-
node.setTextContent(cleaned);
|
|
27
|
-
return true;
|
|
28
|
-
}
|