@inshapardaz/likhari-react 0.1.19 → 0.1.21-dev.192
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 +4 -2
- package/dist/cleanup/textCleanupActions.d.ts +8 -0
- package/dist/cleanup/textCleanupActions.d.ts.map +1 -0
- package/dist/cleanup/textCleanupActions.js +28 -0
- package/dist/components/FindReplaceBar.d.ts +13 -0
- package/dist/components/FindReplaceBar.d.ts.map +1 -0
- package/dist/components/FindReplaceBar.js +72 -0
- package/dist/components/Toolbar.d.ts +4 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +5 -4
- package/dist/find/findReplaceActions.d.ts +23 -0
- package/dist/find/findReplaceActions.d.ts.map +1 -0
- package/dist/find/findReplaceActions.js +81 -0
- package/dist/i18n/strings.d.ts +13 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +39 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/spellcheck/dictionaries/en/LICENSE.txt +347 -0
- package/dist/spellcheck/dictionaries/en/index.aff +205 -0
- package/dist/spellcheck/dictionaries/en/index.dic +49569 -0
- package/dist/spellcheck/spellDictionaries.d.ts +40 -0
- package/dist/spellcheck/spellDictionaries.d.ts.map +1 -0
- package/dist/spellcheck/spellDictionaries.js +62 -0
- package/dist/theme/editor.css +115 -0
- package/package.json +8 -6
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;AAahF,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,uGA2XrB,CAAC"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -26,6 +26,7 @@ import { FootnotePlugin } from './plugins/FootnotePlugin.js';
|
|
|
26
26
|
import { PoetryPlugin } from './plugins/PoetryPlugin.js';
|
|
27
27
|
import { PoetryResizer } from './blocks/PoetryResizer.js';
|
|
28
28
|
import { DraftRestore } from './components/DraftRestore.js';
|
|
29
|
+
import { FindReplaceBar } from './components/FindReplaceBar.js';
|
|
29
30
|
import { LeaveDialog } from './components/LeaveDialog.js';
|
|
30
31
|
import { clearDraft, createDraftId, hasDraftContent, pruneDrafts, writeDraft, } from './persistence/draftStorage.js';
|
|
31
32
|
import { ImageOptionsContext } from './image/ImageOptionsContext.js';
|
|
@@ -67,6 +68,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
67
68
|
const editorStateRef = useRef(null);
|
|
68
69
|
const lastSavedJsonRef = useRef(null);
|
|
69
70
|
const [isDirty, setIsDirty] = useState(false);
|
|
71
|
+
const [findOpen, setFindOpen] = useState(false);
|
|
70
72
|
const isDirtyRef = useRef(isDirty);
|
|
71
73
|
isDirtyRef.current = isDirty;
|
|
72
74
|
const autosaveTimerRef = useRef(null);
|
|
@@ -279,9 +281,9 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
279
281
|
// rather than colliding on a shared one.
|
|
280
282
|
const portalTargetId = useId();
|
|
281
283
|
const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
|
|
282
|
-
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, isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
|
|
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: () => setFindOpen((v) => !v), isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
|
|
283
285
|
? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
|
|
284
|
-
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _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: () => {
|
|
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: () => {
|
|
285
287
|
handleSave();
|
|
286
288
|
settleLeave(true);
|
|
287
289
|
}, onSaveDraft: () => {
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textCleanupActions.d.ts","sourceRoot":"","sources":["../../src/cleanup/textCleanupActions.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAMrC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Strings } from '../i18n/strings.js';
|
|
2
|
+
/**
|
|
3
|
+
* A compact find widget, right-aligned above the canvas (VS Code style). The
|
|
4
|
+
* first row is search; a chevron reveals the second row for replace. Typing
|
|
5
|
+
* only counts matches — the editor's selection moves to a match only when the
|
|
6
|
+
* user asks (next, previous, replace), so typing keeps going into the bar.
|
|
7
|
+
*/
|
|
8
|
+
export declare function FindReplaceBar({ strings, dir, onClose }: {
|
|
9
|
+
strings: Strings;
|
|
10
|
+
dir: 'ltr' | 'rtl';
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=FindReplaceBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FindReplaceBar.d.ts","sourceRoot":"","sources":["../../src/components/FindReplaceBar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C;;;;;GAKG;AACH,wBAAgB,cAAc,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,+BA0HtH"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
+
import { IconChevronDown, IconChevronRight, IconRepeat, IconReplace, IconX } from '@tabler/icons-react';
|
|
5
|
+
import { $findMatches, $replaceAll, $replaceMatch, $selectMatch } from '../find/findReplaceActions.js';
|
|
6
|
+
/**
|
|
7
|
+
* A compact find widget, right-aligned above the canvas (VS Code style). The
|
|
8
|
+
* first row is search; a chevron reveals the second row for replace. Typing
|
|
9
|
+
* only counts matches — the editor's selection moves to a match only when the
|
|
10
|
+
* user asks (next, previous, replace), so typing keeps going into the bar.
|
|
11
|
+
*/
|
|
12
|
+
export function FindReplaceBar({ strings, dir, onClose }) {
|
|
13
|
+
const [editor] = useLexicalComposerContext();
|
|
14
|
+
const t = strings.findReplace;
|
|
15
|
+
const [query, setQuery] = useState('');
|
|
16
|
+
const [replacement, setReplacement] = useState('');
|
|
17
|
+
const [showReplace, setShowReplace] = useState(false);
|
|
18
|
+
const [index, setIndex] = useState(0);
|
|
19
|
+
const [count, setCount] = useState(0);
|
|
20
|
+
// Runs `action` against the current matches inside a committed update, then
|
|
21
|
+
// syncs the count and index. Selecting a match is up to the action, so
|
|
22
|
+
// typing never moves the editor's selection.
|
|
23
|
+
const run = (action) => {
|
|
24
|
+
let result = { nextIndex: 0, matches: [], select: false };
|
|
25
|
+
editor.update(() => {
|
|
26
|
+
result = action($findMatches(query));
|
|
27
|
+
const match = result.matches[result.nextIndex];
|
|
28
|
+
if (result.select && match)
|
|
29
|
+
$selectMatch(match);
|
|
30
|
+
}, { discrete: true });
|
|
31
|
+
setCount(result.matches.length);
|
|
32
|
+
setIndex(result.nextIndex);
|
|
33
|
+
const match = result.matches[result.nextIndex];
|
|
34
|
+
if (result.select && match) {
|
|
35
|
+
// Lexical only draws the selection while the editor has focus, so focus it
|
|
36
|
+
// here; the match stays selected and visible.
|
|
37
|
+
editor.getElementByKey(match.anchorKey)?.scrollIntoView({ block: 'center' });
|
|
38
|
+
editor.focus();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
run((matches) => ({ nextIndex: 0, matches, select: false }));
|
|
43
|
+
// Re-count when the query changes; `run` closes over it.
|
|
44
|
+
}, [query]);
|
|
45
|
+
const step = (delta) => run((matches) => ({
|
|
46
|
+
matches,
|
|
47
|
+
nextIndex: matches.length === 0 ? 0 : (index + delta + matches.length) % matches.length,
|
|
48
|
+
select: true,
|
|
49
|
+
}));
|
|
50
|
+
const replaceCurrent = () => run((matches) => {
|
|
51
|
+
const match = matches[index];
|
|
52
|
+
if (match)
|
|
53
|
+
$replaceMatch(match, replacement);
|
|
54
|
+
const after = $findMatches(query);
|
|
55
|
+
return { matches: after, nextIndex: Math.min(index, Math.max(0, after.length - 1)), select: true };
|
|
56
|
+
});
|
|
57
|
+
const replaceEverything = () => run(() => {
|
|
58
|
+
$replaceAll(query, replacement);
|
|
59
|
+
return { matches: $findMatches(query), nextIndex: 0, select: false };
|
|
60
|
+
});
|
|
61
|
+
const status = query === '' ? '' : count === 0 ? t.noMatches : `${index + 1} / ${count}`;
|
|
62
|
+
const Chevron = showReplace ? IconChevronDown : IconChevronRight;
|
|
63
|
+
return (_jsxs("div", { className: "likhari-find-widget", role: "search", dir: dir, children: [_jsxs("div", { className: "likhari-find-row", children: [_jsx("button", { type: "button", className: "likhari-find-icon", onClick: () => setShowReplace((v) => !v), "aria-label": t.replace, "aria-expanded": showReplace, title: t.replace, children: _jsx(Chevron, { size: 14, stroke: 1.75 }) }), _jsx("input", { "aria-label": t.find, placeholder: t.findPlaceholder, value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: (e) => {
|
|
64
|
+
if (e.key === 'Enter')
|
|
65
|
+
step(e.shiftKey ? -1 : 1);
|
|
66
|
+
if (e.key === 'Escape')
|
|
67
|
+
onClose();
|
|
68
|
+
}, autoFocus: true }), _jsx("span", { className: "likhari-find-status", "aria-live": "polite", children: status }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-prev", onClick: () => step(-1), disabled: count === 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-find-icon likhari-find-next", onClick: () => step(1), disabled: count === 0, "aria-label": t.next, title: t.next, children: _jsx(IconChevronDown, { size: 14, stroke: 1.75 }) }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-close", onClick: onClose, "aria-label": t.close, title: t.close, children: _jsx(IconX, { size: 14, stroke: 1.75 }) })] }), showReplace && (_jsxs("div", { className: "likhari-find-row", children: [_jsx("span", { className: "likhari-find-icon-spacer", "aria-hidden": "true" }), _jsx("input", { className: "likhari-find-replace-input", "aria-label": t.replace, placeholder: t.replacePlaceholder, value: replacement, onChange: (e) => setReplacement(e.target.value), onKeyDown: (e) => {
|
|
69
|
+
if (e.key === 'Enter' && count > 0)
|
|
70
|
+
replaceCurrent();
|
|
71
|
+
} }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-replace-one", onClick: replaceCurrent, disabled: count === 0, "aria-label": t.replaceOne, title: t.replaceOne, children: _jsx(IconReplace, { size: 14, stroke: 1.75 }) }), _jsx("button", { type: "button", className: "likhari-find-icon likhari-find-replace-all", onClick: replaceEverything, disabled: count === 0, "aria-label": t.replaceAll, title: t.replaceAll, children: _jsx(IconRepeat, { size: 14, stroke: 1.75 }) })] }))] }));
|
|
72
|
+
}
|
|
@@ -4,6 +4,9 @@ import { type FontOption } from '../fonts/index.js';
|
|
|
4
4
|
import type { Locale } from '../i18n/strings.js';
|
|
5
5
|
export interface ToolbarProps {
|
|
6
6
|
config: ResolvedEditorFeatureConfig;
|
|
7
|
+
/** Whether the find-and-replace widget is open, and how to toggle it (owned by EditorRoot). */
|
|
8
|
+
findOpen?: boolean;
|
|
9
|
+
onToggleFind?: () => void;
|
|
7
10
|
onSave?: () => void;
|
|
8
11
|
isDirty?: boolean;
|
|
9
12
|
showSave?: boolean;
|
|
@@ -16,5 +19,5 @@ export interface ToolbarProps {
|
|
|
16
19
|
/** Autosave drafts: when set, the toolbar offers a Drafts button that lists and restores them. */
|
|
17
20
|
drafts?: DraftsToolbarOptions;
|
|
18
21
|
}
|
|
19
|
-
export declare function Toolbar({ config, onSave, isDirty, showSave, fontOptions, direction, locale, drafts }: ToolbarProps): import("react").JSX.Element;
|
|
22
|
+
export declare function Toolbar({ config, onSave, isDirty, showSave, findOpen, onToggleFind, fontOptions, direction, locale, drafts }: ToolbarProps): import("react").JSX.Element;
|
|
20
23
|
//# 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":"AAsFA,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,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,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAwkCxL"}
|
|
@@ -8,6 +8,7 @@ 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';
|
|
11
12
|
import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
12
13
|
import { ImageDialog } from '../image/ImageDialog.js';
|
|
13
14
|
import { $createImageNode } from '../image/ImageNode.js';
|
|
@@ -29,7 +30,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
|
|
|
29
30
|
import { setStyleProperty } from '../utils/style.js';
|
|
30
31
|
import { useStrings } from '../i18n/useStrings.js';
|
|
31
32
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
32
|
-
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconArrowsMaximize, IconArrowsMinimize, IconArrowsShuffle, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
33
|
+
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconSearch, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconArrowsMaximize, IconArrowsMinimize, IconArrowsShuffle, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
33
34
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
34
35
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
35
36
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
@@ -182,7 +183,7 @@ function PoetryMenuItems({ strings, layout, scale, centered, onAction, }) {
|
|
|
182
183
|
};
|
|
183
184
|
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')] }));
|
|
184
185
|
}
|
|
185
|
-
export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
186
|
+
export function Toolbar({ config, onSave, isDirty, showSave, findOpen = false, onToggleFind, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
186
187
|
const [editor] = useLexicalComposerContext();
|
|
187
188
|
const [state, setState] = useState(INITIAL_STATE);
|
|
188
189
|
const strings = useStrings(locale);
|
|
@@ -808,10 +809,10 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
808
809
|
restoreSelection();
|
|
809
810
|
openLinkDialog();
|
|
810
811
|
}, onRemove: removeLink, strings: strings }) })] })) : (_jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.insertLink, onClick: openLinkDialog })) }, "link")),
|
|
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.poetry.enabled && locale !== 'en' && (_jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.insertPoetryCouplet, onClick: () => editor.dispatchCommand(INSERT_POETRY_COUPLET_COMMAND, { layout: config.poetry.defaultLayout }) }))] }, "stubInsert")),
|
|
812
|
+
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")),
|
|
812
813
|
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")),
|
|
813
814
|
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")),
|
|
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(
|
|
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 && (_jsx(ToolbarButton, { icon: IconSparkles, title: strings.toolbar.textCleanup, onClick: () => editor.update(() => $cleanUpText(), { discrete: true }) })), config.language.spellCheck && _jsx(StubButton, { icon: IconAbc, title: strings.toolbar.spellChecker, comingSoon: strings.toolbar.comingSoon })] }, "language")),
|
|
815
816
|
];
|
|
816
817
|
return (_jsxs("div", { className: "likhari-toolbar", role: "toolbar", "aria-label": strings.toolbar.ariaLabel, ref: toolbarContainerRef, children: [fixedGroups, movableGroups
|
|
817
818
|
.filter((group) => !overflowGroupKeys.has(group.key))
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** A match as a Lexical selection range: start and end points, each in a text node. */
|
|
2
|
+
export interface FindMatch {
|
|
3
|
+
anchorKey: string;
|
|
4
|
+
anchorOffset: number;
|
|
5
|
+
focusKey: string;
|
|
6
|
+
focusOffset: number;
|
|
7
|
+
}
|
|
8
|
+
/** Every non-overlapping occurrence of `query` in the document, case-sensitive. */
|
|
9
|
+
export declare function $findMatches(query: string): FindMatch[];
|
|
10
|
+
/** Makes the match the editor's selection, so it's highlighted and scrolled to. */
|
|
11
|
+
export declare function $selectMatch(match: FindMatch): void;
|
|
12
|
+
/**
|
|
13
|
+
* Replaces one match, keeping the formatting of the text around it. The
|
|
14
|
+
* replacement takes the formatting of the match's first character.
|
|
15
|
+
*/
|
|
16
|
+
export declare function $replaceMatch(match: FindMatch, replacement: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Replaces every match. Walks from the last match to the first, so each
|
|
19
|
+
* replacement leaves the positions of the matches before it unchanged.
|
|
20
|
+
* Returns how many were replaced.
|
|
21
|
+
*/
|
|
22
|
+
export declare function $replaceAll(query: string, replacement: string): number;
|
|
23
|
+
//# sourceMappingURL=findReplaceActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findReplaceActions.d.ts","sourceRoot":"","sources":["../../src/find/findReplaceActions.ts"],"names":[],"mappings":"AAEA,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;AAgCD,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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { $createRangeSelection, $getRoot, $getSelection, $isRangeSelection, $setSelection } from 'lexical';
|
|
2
|
+
/**
|
|
3
|
+
* Text nodes grouped by their parent, in document order. A match is searched
|
|
4
|
+
* for within one parent only, so it never spans two paragraphs or table
|
|
5
|
+
* cells, but it can span the several text nodes that formatting splits a
|
|
6
|
+
* paragraph into.
|
|
7
|
+
*/
|
|
8
|
+
function $textGroups() {
|
|
9
|
+
const groups = new Map();
|
|
10
|
+
for (const node of $getRoot().getAllTextNodes()) {
|
|
11
|
+
const parentKey = node.getParentOrThrow().getKey();
|
|
12
|
+
const group = groups.get(parentKey);
|
|
13
|
+
if (group)
|
|
14
|
+
group.push(node);
|
|
15
|
+
else
|
|
16
|
+
groups.set(parentKey, [node]);
|
|
17
|
+
}
|
|
18
|
+
return [...groups.values()];
|
|
19
|
+
}
|
|
20
|
+
/** The text node and offset that a character index in a group falls in. */
|
|
21
|
+
function $locate(group, index, end) {
|
|
22
|
+
let start = 0;
|
|
23
|
+
for (const node of group) {
|
|
24
|
+
const length = node.getTextContent().length;
|
|
25
|
+
const inside = end ? index > start && index <= start + length : index >= start && index < start + length;
|
|
26
|
+
if (inside)
|
|
27
|
+
return { key: node.getKey(), offset: index - start };
|
|
28
|
+
start += length;
|
|
29
|
+
}
|
|
30
|
+
const last = group[group.length - 1];
|
|
31
|
+
return { key: last.getKey(), offset: last.getTextContent().length };
|
|
32
|
+
}
|
|
33
|
+
/** Every non-overlapping occurrence of `query` in the document, case-sensitive. */
|
|
34
|
+
export function $findMatches(query) {
|
|
35
|
+
if (query === '')
|
|
36
|
+
return [];
|
|
37
|
+
const matches = [];
|
|
38
|
+
for (const group of $textGroups()) {
|
|
39
|
+
const text = group.map((node) => node.getTextContent()).join('');
|
|
40
|
+
let index = text.indexOf(query);
|
|
41
|
+
while (index !== -1) {
|
|
42
|
+
const start = $locate(group, index, false);
|
|
43
|
+
const end = $locate(group, index + query.length, true);
|
|
44
|
+
matches.push({ anchorKey: start.key, anchorOffset: start.offset, focusKey: end.key, focusOffset: end.offset });
|
|
45
|
+
index = text.indexOf(query, index + query.length);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return matches;
|
|
49
|
+
}
|
|
50
|
+
/** Makes the match the editor's selection, so it's highlighted and scrolled to. */
|
|
51
|
+
export function $selectMatch(match) {
|
|
52
|
+
const selection = $createRangeSelection();
|
|
53
|
+
selection.anchor.set(match.anchorKey, match.anchorOffset, 'text');
|
|
54
|
+
selection.focus.set(match.focusKey, match.focusOffset, 'text');
|
|
55
|
+
$setSelection(selection);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Replaces one match, keeping the formatting of the text around it. The
|
|
59
|
+
* replacement takes the formatting of the match's first character.
|
|
60
|
+
*/
|
|
61
|
+
export function $replaceMatch(match, replacement) {
|
|
62
|
+
$selectMatch(match);
|
|
63
|
+
const selection = $getSelection();
|
|
64
|
+
if (!$isRangeSelection(selection))
|
|
65
|
+
return;
|
|
66
|
+
if (replacement === '')
|
|
67
|
+
selection.removeText();
|
|
68
|
+
else
|
|
69
|
+
selection.insertText(replacement);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Replaces every match. Walks from the last match to the first, so each
|
|
73
|
+
* replacement leaves the positions of the matches before it unchanged.
|
|
74
|
+
* Returns how many were replaced.
|
|
75
|
+
*/
|
|
76
|
+
export function $replaceAll(query, replacement) {
|
|
77
|
+
const matches = $findMatches(query);
|
|
78
|
+
for (let i = matches.length - 1; i >= 0; i--)
|
|
79
|
+
$replaceMatch(matches[i], replacement);
|
|
80
|
+
return matches.length;
|
|
81
|
+
}
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -156,6 +156,19 @@ export interface Strings {
|
|
|
156
156
|
deleteCouplet: string;
|
|
157
157
|
deletePoetry: string;
|
|
158
158
|
};
|
|
159
|
+
findReplace: {
|
|
160
|
+
toggle: string;
|
|
161
|
+
find: string;
|
|
162
|
+
replace: string;
|
|
163
|
+
findPlaceholder: string;
|
|
164
|
+
replacePlaceholder: string;
|
|
165
|
+
previous: string;
|
|
166
|
+
next: string;
|
|
167
|
+
replaceOne: string;
|
|
168
|
+
replaceAll: string;
|
|
169
|
+
noMatches: string;
|
|
170
|
+
close: string;
|
|
171
|
+
};
|
|
159
172
|
link: {
|
|
160
173
|
menuLabel: string;
|
|
161
174
|
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
|
@@ -139,6 +139,19 @@ const en = {
|
|
|
139
139
|
deleteCouplet: 'Delete couplet',
|
|
140
140
|
deletePoetry: 'Delete poetry',
|
|
141
141
|
},
|
|
142
|
+
findReplace: {
|
|
143
|
+
toggle: 'Find and replace',
|
|
144
|
+
find: 'Find',
|
|
145
|
+
replace: 'Replace',
|
|
146
|
+
findPlaceholder: 'Text to find',
|
|
147
|
+
replacePlaceholder: 'Replacement text',
|
|
148
|
+
previous: 'Previous',
|
|
149
|
+
next: 'Next',
|
|
150
|
+
replaceOne: 'Replace',
|
|
151
|
+
replaceAll: 'Replace all',
|
|
152
|
+
noMatches: 'No matches',
|
|
153
|
+
close: 'Close',
|
|
154
|
+
},
|
|
142
155
|
link: {
|
|
143
156
|
menuLabel: 'Link',
|
|
144
157
|
noUrl: '(no URL)',
|
|
@@ -359,6 +372,19 @@ const ur = {
|
|
|
359
372
|
deleteCouplet: 'شعر حذف کریں',
|
|
360
373
|
deletePoetry: 'پوری شاعری حذف کریں',
|
|
361
374
|
},
|
|
375
|
+
findReplace: {
|
|
376
|
+
toggle: 'تلاش اور تبدیلی',
|
|
377
|
+
find: 'تلاش کریں',
|
|
378
|
+
replace: 'تبدیل کریں',
|
|
379
|
+
findPlaceholder: 'جو متن تلاش کرنا ہے',
|
|
380
|
+
replacePlaceholder: 'تبدیل کرنے کا متن',
|
|
381
|
+
previous: 'پچھلا',
|
|
382
|
+
next: 'اگلا',
|
|
383
|
+
replaceOne: 'تبدیل کریں',
|
|
384
|
+
replaceAll: 'سب تبدیل کریں',
|
|
385
|
+
noMatches: 'کوئی میچ نہیں',
|
|
386
|
+
close: 'بند کریں',
|
|
387
|
+
},
|
|
362
388
|
link: {
|
|
363
389
|
menuLabel: 'لنک',
|
|
364
390
|
noUrl: '(کوئی یو آر ایل نہیں)',
|
|
@@ -579,6 +605,19 @@ const paShahmukhi = {
|
|
|
579
605
|
deleteCouplet: 'شعر مٹاؤ',
|
|
580
606
|
deletePoetry: 'ساری شاعری مٹاؤ',
|
|
581
607
|
},
|
|
608
|
+
findReplace: {
|
|
609
|
+
toggle: 'لبھو تے بدلو',
|
|
610
|
+
find: 'لبھo',
|
|
611
|
+
replace: 'بدلo',
|
|
612
|
+
findPlaceholder: 'جو لبھنا اے',
|
|
613
|
+
replacePlaceholder: 'بدلن والا متن',
|
|
614
|
+
previous: 'پچھلا',
|
|
615
|
+
next: 'اگلا',
|
|
616
|
+
replaceOne: 'بدلo',
|
|
617
|
+
replaceAll: 'سارے بدلo',
|
|
618
|
+
noMatches: 'کوئی ملدا نئیں',
|
|
619
|
+
close: 'بند کرo',
|
|
620
|
+
},
|
|
582
621
|
link: {
|
|
583
622
|
menuLabel: 'لنک',
|
|
584
623
|
noUrl: '(کوئی یو آر ایل نئیں)',
|
package/dist/index.d.ts
CHANGED
|
@@ -8,4 +8,5 @@ export { DEFAULT_FONT_OPTIONS, URDU_WEB_FONT_OPTIONS, FONT_SIZES_PX } from './fo
|
|
|
8
8
|
export type { FontOption } from './fonts/index.js';
|
|
9
9
|
export { STRINGS, getStrings, useStrings, useUiStrings, UiStringsContext } from './i18n/index.js';
|
|
10
10
|
export type { Locale, Strings } from './i18n/index.js';
|
|
11
|
+
export { registerSpellDictionary, hasSpellDictionary, type HunspellFiles, type SpellLanguage } from './spellcheck/spellDictionaries.js';
|
|
11
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC1G,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AACzF,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC1G,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AACzF,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,3 +3,4 @@ export { defaultMantineTheme } from './theme/mantineTheme.js';
|
|
|
3
3
|
export { ImageNode, $createImageNode, $isImageNode } from './image/ImageNode.js';
|
|
4
4
|
export { DEFAULT_FONT_OPTIONS, URDU_WEB_FONT_OPTIONS, FONT_SIZES_PX } from './fonts/index.js';
|
|
5
5
|
export { STRINGS, getStrings, useStrings, useUiStrings, UiStringsContext } from './i18n/index.js';
|
|
6
|
+
export { registerSpellDictionary, hasSpellDictionary } from './spellcheck/spellDictionaries.js';
|