@richhtmleditor/spellcheck 1.1.0

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.
@@ -0,0 +1,47 @@
1
+ import type { EditorPlugin } from "@richhtmleditor/core";
2
+ export type LanguageToolMatch = {
3
+ message: string;
4
+ shortMessage: string;
5
+ offset: number;
6
+ length: number;
7
+ replacements: Array<{
8
+ value: string;
9
+ }>;
10
+ rule: {
11
+ id: string;
12
+ description: string;
13
+ category: {
14
+ id: string;
15
+ name: string;
16
+ };
17
+ };
18
+ };
19
+ export type SpellcheckOptions = {
20
+ /**
21
+ * 'browser' toggles the native `spellcheck` attribute on the content area.
22
+ * 'languagetool' calls the LanguageTool REST API and underlines errors inline.
23
+ * Default: 'browser'
24
+ */
25
+ provider?: "browser" | "languagetool";
26
+ /** LanguageTool API base URL. Default: 'https://api.languagetool.org/v2' */
27
+ languagetoolUrl?: string;
28
+ /** BCP47 language code passed to LanguageTool. Default: 'en-US' */
29
+ language?: string;
30
+ /** Debounce ms before sending to LanguageTool after the user stops typing. Default: 900 */
31
+ debounceMs?: number;
32
+ /** Called with raw LanguageTool matches after each check. */
33
+ onMatches?: (matches: LanguageToolMatch[]) => void;
34
+ };
35
+ /**
36
+ * Spell & grammar check plugin.
37
+ *
38
+ * Browser-native mode: toggles the `spellcheck` attribute on the content area.
39
+ * LanguageTool mode: POSTs text to the LT REST API and underlines errors inline.
40
+ *
41
+ * ```ts
42
+ * import { createSpellcheckPlugin } from "@richhtmleditor/spellcheck";
43
+ * createEditor({ plugins: [createSpellcheckPlugin({ provider: "languagetool" })] });
44
+ * ```
45
+ */
46
+ export declare function createSpellcheckPlugin(options?: SpellcheckOptions): EditorPlugin;
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAyB,MAAM,sBAAsB,CAAC;AAEhG,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CACnF,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,cAAc,CAAC;IACtC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;CACpD,CAAC;AA2JF;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,iBAAsB,GAAG,YAAY,CA6FpF"}
package/dist/index.js ADDED
@@ -0,0 +1,241 @@
1
+ const HIGHLIGHT_CLASS = "de-spell-error";
2
+ const POPOVER_CLASS = "de-spell-popover";
3
+ function debounce(fn, ms) {
4
+ let timer = null;
5
+ return ((...args) => {
6
+ if (timer !== null)
7
+ clearTimeout(timer);
8
+ timer = setTimeout(() => fn(...args), ms);
9
+ });
10
+ }
11
+ function clearHighlights(contentEl) {
12
+ for (const el of Array.from(contentEl.querySelectorAll(`.${HIGHLIGHT_CLASS}`))) {
13
+ const parent = el.parentNode;
14
+ if (!parent)
15
+ continue;
16
+ while (el.firstChild)
17
+ parent.insertBefore(el.firstChild, el);
18
+ parent.removeChild(el);
19
+ }
20
+ contentEl.normalize();
21
+ }
22
+ function applyHighlights(contentEl, matches) {
23
+ clearHighlights(contentEl);
24
+ const text = contentEl.textContent ?? "";
25
+ // Walk text nodes and wrap error ranges
26
+ let globalOffset = 0;
27
+ function walkNode(node) {
28
+ if (node.nodeType === Node.TEXT_NODE) {
29
+ const nodeText = node.textContent ?? "";
30
+ const nodeStart = globalOffset;
31
+ const nodeEnd = globalOffset + nodeText.length;
32
+ const relevantMatches = matches.filter((m) => m.offset < nodeEnd && m.offset + m.length > nodeStart);
33
+ if (relevantMatches.length > 0) {
34
+ const frag = document.createDocumentFragment();
35
+ let cursor = 0;
36
+ for (const match of relevantMatches) {
37
+ const start = Math.max(0, match.offset - nodeStart);
38
+ const end = Math.min(nodeText.length, match.offset + match.length - nodeStart);
39
+ if (start > cursor) {
40
+ frag.appendChild(document.createTextNode(nodeText.slice(cursor, start)));
41
+ }
42
+ if (start < end) {
43
+ const span = document.createElement("span");
44
+ span.className = HIGHLIGHT_CLASS;
45
+ span.title = match.message;
46
+ span.dataset.replacements = JSON.stringify(match.replacements.slice(0, 5).map((r) => r.value));
47
+ span.textContent = nodeText.slice(start, end);
48
+ frag.appendChild(span);
49
+ }
50
+ cursor = end;
51
+ }
52
+ if (cursor < nodeText.length) {
53
+ frag.appendChild(document.createTextNode(nodeText.slice(cursor)));
54
+ }
55
+ node.parentNode?.replaceChild(frag, node);
56
+ }
57
+ globalOffset += nodeText.length;
58
+ return;
59
+ }
60
+ for (const child of Array.from(node.childNodes)) {
61
+ walkNode(child);
62
+ }
63
+ }
64
+ void text; // suppress unused warning
65
+ walkNode(contentEl);
66
+ }
67
+ async function checkWithLanguageTool(text, url, language) {
68
+ const body = new URLSearchParams({ text, language });
69
+ const res = await fetch(`${url}/check`, {
70
+ method: "POST",
71
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
72
+ body: body.toString()
73
+ });
74
+ if (!res.ok)
75
+ return [];
76
+ const data = await res.json();
77
+ return data.matches ?? [];
78
+ }
79
+ function mountSuggestionPopover(contentEl) {
80
+ let popover = null;
81
+ const close = () => {
82
+ popover?.remove();
83
+ popover = null;
84
+ };
85
+ const onClick = (e) => {
86
+ const target = e.target;
87
+ const errorSpan = target?.closest(`.${HIGHLIGHT_CLASS}`);
88
+ if (!errorSpan) {
89
+ close();
90
+ return;
91
+ }
92
+ close();
93
+ const replacements = JSON.parse(errorSpan.dataset.replacements ?? "[]");
94
+ if (!replacements.length)
95
+ return;
96
+ popover = document.createElement("div");
97
+ popover.className = POPOVER_CLASS;
98
+ popover.setAttribute("role", "listbox");
99
+ popover.setAttribute("aria-label", "Spelling suggestions");
100
+ for (const suggestion of replacements) {
101
+ const btn = document.createElement("button");
102
+ btn.type = "button";
103
+ btn.className = `${POPOVER_CLASS}__item`;
104
+ btn.textContent = suggestion;
105
+ btn.addEventListener("click", (ev) => {
106
+ ev.stopPropagation();
107
+ errorSpan.replaceWith(document.createTextNode(suggestion));
108
+ close();
109
+ });
110
+ popover.appendChild(btn);
111
+ }
112
+ const ignoreBtn = document.createElement("button");
113
+ ignoreBtn.type = "button";
114
+ ignoreBtn.className = `${POPOVER_CLASS}__item ${POPOVER_CLASS}__item--ignore`;
115
+ ignoreBtn.textContent = "Ignore";
116
+ ignoreBtn.addEventListener("click", (ev) => {
117
+ ev.stopPropagation();
118
+ const text = errorSpan.textContent ?? "";
119
+ errorSpan.replaceWith(document.createTextNode(text));
120
+ close();
121
+ });
122
+ popover.appendChild(ignoreBtn);
123
+ const rect = errorSpan.getBoundingClientRect();
124
+ const hostRect = contentEl.getBoundingClientRect();
125
+ popover.style.cssText = `position:absolute;z-index:500;top:${rect.bottom - hostRect.top + 4}px;left:${rect.left - hostRect.left}px;`;
126
+ contentEl.parentElement?.appendChild(popover);
127
+ };
128
+ contentEl.addEventListener("click", onClick);
129
+ document.addEventListener("click", close);
130
+ return () => {
131
+ contentEl.removeEventListener("click", onClick);
132
+ document.removeEventListener("click", close);
133
+ close();
134
+ };
135
+ }
136
+ /**
137
+ * Spell & grammar check plugin.
138
+ *
139
+ * Browser-native mode: toggles the `spellcheck` attribute on the content area.
140
+ * LanguageTool mode: POSTs text to the LT REST API and underlines errors inline.
141
+ *
142
+ * ```ts
143
+ * import { createSpellcheckPlugin } from "@richhtmleditor/spellcheck";
144
+ * createEditor({ plugins: [createSpellcheckPlugin({ provider: "languagetool" })] });
145
+ * ```
146
+ */
147
+ export function createSpellcheckPlugin(options = {}) {
148
+ const provider = options.provider ?? "browser";
149
+ const ltUrl = options.languagetoolUrl ?? "https://api.languagetool.org/v2";
150
+ const language = options.language ?? "en-US";
151
+ const debounceMs = options.debounceMs ?? 900;
152
+ let active = false;
153
+ const tool = {
154
+ id: "spellcheck",
155
+ type: "toggle",
156
+ label: "Spell",
157
+ icon: "spellcheck",
158
+ display: "icon",
159
+ tooltip: provider === "browser"
160
+ ? "Toggle browser spell check"
161
+ : "Toggle LanguageTool spell & grammar check",
162
+ onClick: () => { }
163
+ };
164
+ return {
165
+ id: "richhtmleditor-spellcheck",
166
+ tools: [tool],
167
+ attach: (editor) => {
168
+ const host = editor.element;
169
+ const contentEl = host.querySelector(".de-content");
170
+ if (!contentEl)
171
+ return () => { };
172
+ let destroyPopover = null;
173
+ let checkTimer = null;
174
+ const runLtCheck = async () => {
175
+ if (!active || provider !== "languagetool")
176
+ return;
177
+ const text = contentEl.textContent ?? "";
178
+ if (!text.trim()) {
179
+ clearHighlights(contentEl);
180
+ return;
181
+ }
182
+ try {
183
+ const matches = await checkWithLanguageTool(text, ltUrl, language);
184
+ options.onMatches?.(matches);
185
+ applyHighlights(contentEl, matches);
186
+ }
187
+ catch { /* network error — silently skip */ }
188
+ };
189
+ const debouncedCheck = debounce(runLtCheck, debounceMs);
190
+ const toggleSpellcheck = () => {
191
+ active = !active;
192
+ if (provider === "browser") {
193
+ contentEl.setAttribute("spellcheck", active ? "true" : "false");
194
+ return;
195
+ }
196
+ // LanguageTool
197
+ if (active) {
198
+ destroyPopover = mountSuggestionPopover(contentEl);
199
+ editor.on("change", debouncedCheck);
200
+ void runLtCheck();
201
+ }
202
+ else {
203
+ clearHighlights(contentEl);
204
+ destroyPopover?.();
205
+ destroyPopover = null;
206
+ }
207
+ };
208
+ // Patch the tool's onClick at attach time
209
+ const toolDef = tool;
210
+ toolDef.onClick = toggleSpellcheck;
211
+ // Inject minimal CSS
212
+ const styleId = "de-spellcheck-styles";
213
+ if (!document.getElementById(styleId)) {
214
+ const style = document.createElement("style");
215
+ style.id = styleId;
216
+ style.textContent = `
217
+ .${HIGHLIGHT_CLASS}{border-bottom:2px solid #dc2626;cursor:pointer;}
218
+ .${POPOVER_CLASS}{background:var(--de-toolbar-bg,#fff);border:1px solid var(--de-border,#e2e8f0);border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,.12);padding:4px;min-width:120px;display:flex;flex-direction:column;gap:2px;}
219
+ .${POPOVER_CLASS}__item{text-align:left;padding:6px 10px;border:none;background:none;cursor:pointer;border-radius:6px;font-size:.875rem;}
220
+ .${POPOVER_CLASS}__item:hover{background:var(--de-primary-hover,#eff6ff);}
221
+ .${POPOVER_CLASS}__item--ignore{color:var(--de-text-muted,#64748b);font-style:italic;}
222
+ `.trim();
223
+ document.head.appendChild(style);
224
+ }
225
+ return () => {
226
+ if (active) {
227
+ active = false;
228
+ if (provider === "browser")
229
+ contentEl.removeAttribute("spellcheck");
230
+ else {
231
+ clearHighlights(contentEl);
232
+ destroyPopover?.();
233
+ }
234
+ }
235
+ if (checkTimer)
236
+ clearTimeout(checkTimer);
237
+ };
238
+ }
239
+ };
240
+ }
241
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@richhtmleditor/spellcheck",
3
+ "version": "1.1.0",
4
+ "description": "Spell & grammar check plugin for Rich HTML Editor (browser-native + LanguageTool API).",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": ["dist", "README.md"],
16
+ "scripts": {
17
+ "build": "tsc -p tsconfig.json",
18
+ "prepack": "node ../../scripts/assert-pack-ready.mjs"
19
+ },
20
+ "dependencies": {
21
+ "@richhtmleditor/core": "^1.1.0"
22
+ },
23
+ "keywords": ["richhtmleditor", "spellcheck", "grammar", "languagetool"],
24
+ "license": "MIT",
25
+ "publishConfig": { "access": "public" },
26
+ "engines": { "node": ">=18" }
27
+ }