@kodaeditor/core 1.0.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.
Files changed (55) hide show
  1. package/LICENSE.md +83 -0
  2. package/README.md +94 -0
  3. package/THIRD-PARTY-LICENSES.txt +1811 -0
  4. package/dist/commands.d.ts +15 -0
  5. package/dist/docx-alignment.d.ts +14 -0
  6. package/dist/docx-breaks.d.ts +31 -0
  7. package/dist/docx-forms.d.ts +28 -0
  8. package/dist/docx-headers.d.ts +22 -0
  9. package/dist/docx-images.d.ts +41 -0
  10. package/dist/docx-import.d.ts +36 -0
  11. package/dist/docx-math.d.ts +18 -0
  12. package/dist/docx-styles.d.ts +53 -0
  13. package/dist/docx-symbols.d.ts +19 -0
  14. package/dist/docx-text-styles.d.ts +27 -0
  15. package/dist/editor.d.ts +372 -0
  16. package/dist/fallback.d.ts +13 -0
  17. package/dist/floatingToolbar.d.ts +7 -0
  18. package/dist/group-icons.d.ts +17 -0
  19. package/dist/i18n.d.ts +214 -0
  20. package/dist/icons.d.ts +1 -0
  21. package/dist/image-view.d.ts +27 -0
  22. package/dist/import-formats.d.ts +41 -0
  23. package/dist/index.d.ts +15 -0
  24. package/dist/kodaeditor-core.umd.cjs +1 -0
  25. package/dist/kodaeditor.js +1 -0
  26. package/dist/kodaeditor.umd.cjs +1 -0
  27. package/dist/license.d.ts +90 -0
  28. package/dist/markdown.d.ts +4 -0
  29. package/dist/menubar.d.ts +60 -0
  30. package/dist/offline-license.d.ts +36 -0
  31. package/dist/pagination.d.ts +11 -0
  32. package/dist/paste.d.ts +54 -0
  33. package/dist/pdf-import-cdn.d.ts +2 -0
  34. package/dist/pdf-import.d.ts +8 -0
  35. package/dist/print.d.ts +18 -0
  36. package/dist/rtf-images.d.ts +24 -0
  37. package/dist/schema.d.ts +14 -0
  38. package/dist/search.d.ts +17 -0
  39. package/dist/serialize.d.ts +20 -0
  40. package/dist/slashMenu.d.ts +8 -0
  41. package/dist/styles.d.ts +8 -0
  42. package/dist/table-split.d.ts +26 -0
  43. package/dist/table-view.d.ts +34 -0
  44. package/dist/tableColumnTrade.d.ts +15 -0
  45. package/dist/tableToolbar.d.ts +14 -0
  46. package/dist/toc-view.d.ts +23 -0
  47. package/dist/toolbar-editor.d.ts +89 -0
  48. package/dist/validate-signature.d.ts +64 -0
  49. package/dist/vendor/pdf.min.mjs +29 -0
  50. package/dist/vendor/pdf.worker.min.mjs +29 -0
  51. package/dist/vendor/xlsx.full.min.js +24 -0
  52. package/dist/web-component.d.ts +383 -0
  53. package/dist/xlsx-import-cdn.d.ts +1 -0
  54. package/dist/xlsx-import.d.ts +2 -0
  55. package/package.json +88 -0
@@ -0,0 +1,372 @@
1
+ import { EditorView } from 'prosemirror-view';
2
+ import { type ImportFormat } from './import-formats';
3
+ import { type DocxImportResult } from './docx-import';
4
+ import { type Strings } from './i18n';
5
+ export interface EditorOptions {
6
+ /** Контейнер, в который монтируется редактор. */
7
+ element: HTMLElement;
8
+ /** Начальный HTML-контент. */
9
+ content?: string;
10
+ /** Подсказка, когда документ пуст. */
11
+ placeholder?: string;
12
+ /** Доступное имя для скринридеров (ARIA). */
13
+ ariaLabel?: string;
14
+ /** Локализованные строки UI (для slash-меню и floating-тулбара). */
15
+ strings?: Strings;
16
+ /** Колбэк при каждом изменении документа. */
17
+ onChange?: (html: string) => void;
18
+ /** Колбэки для плавающей панели таблицы (открыть диалог вместо «голой» команды). */
19
+ tableCallbacks?: {
20
+ onSplitCell?: () => void;
21
+ onMergeCells?: () => void;
22
+ };
23
+ }
24
+ declare const schema: import("prosemirror-model").Schema<keyof import("orderedmap").default<import("prosemirror-model").NodeSpec>, keyof import("orderedmap").default<import("prosemirror-model").MarkSpec>>;
25
+ /** Свойства ячейки таблицы (диалог «Свойства ячейки»). */
26
+ export interface CellProps {
27
+ background?: string;
28
+ textAlign?: string;
29
+ verticalAlign?: string;
30
+ borderWidth?: number;
31
+ borderColor?: string;
32
+ }
33
+ /** Свойства таблицы (диалог «Свойства таблицы»). */
34
+ export interface TableProps {
35
+ width?: string;
36
+ align?: string;
37
+ borderWidth?: number;
38
+ borderColor?: string;
39
+ }
40
+ export declare class Editor {
41
+ readonly view: EditorView;
42
+ private readonly onChange?;
43
+ /**
44
+ * Подтверждена ли лицензия. Влияет ТОЛЬКО на пометку в выгрузках - ничего
45
+ * не отключает и не блокирует: принцип «деградация, а не блокировка»
46
+ * остаётся, редактор работает целиком в любом случае.
47
+ */
48
+ private licensed;
49
+ /**
50
+ * Промис идущей проверки лицензии. Нужен потому, что licensed стартует с
51
+ * false, а решение приходит только после сети: без ожидания ЛЮБАЯ выгрузка
52
+ * в первые секунды после монтирования уносила бы ознакомительную пометку в
53
+ * документ оплатившего клиента. Окно тем шире, чем хуже наша связь - до 6
54
+ * секунд при недоступном сервере лицензий, - и сценарий «открыл документ,
55
+ * нажал Печать» в него укладывается, а маршрут вида /print/:id в
56
+ * хост-приложении попадает туда почти всегда.
57
+ *
58
+ * Обратное решение (считать лицензию действующей до ответа) не годится: оно
59
+ * дало бы неоплатившим повторяемое окно чистых выгрузок.
60
+ */
61
+ private licenseCheck;
62
+ /** Строки интерфейса - нужны для текста пометки на языке пользователя. */
63
+ private readonly strings;
64
+ private placeholderText;
65
+ private premiumPaste;
66
+ private pendingRtf;
67
+ private pastePlainOnce;
68
+ private pdfModeResolver?;
69
+ private readonly tocViews;
70
+ private readonly trackState;
71
+ private readonly paginationState;
72
+ constructor(opts: EditorOptions);
73
+ /** Текущий документ как чистый HTML. */
74
+ getHTML(): string;
75
+ /**
76
+ * Заменить содержимое из HTML-строки.
77
+ *
78
+ * Через транзакцию, а не пересозданием state, чтобы сохранить историю
79
+ * undo/redo - иначе Ctrl+Z после программной установки молча не работает.
80
+ */
81
+ setHTML(html: string): void;
82
+ /**
83
+ * Импорт файла .docx прямо в редактор. Возвращает предупреждения движка
84
+ * (неподдержанные стили и т.п.) - UI может их показать или проигнорировать.
85
+ */
86
+ importDocx(source: File | ArrayBuffer): Promise<DocxImportResult>;
87
+ /** Вставляет HTML в позицию курсора (НЕ заменяя весь документ). */
88
+ insertHtmlAtCursor(html: string): void;
89
+ /**
90
+ * Единый импорт файла: детект типа -> нужный обработчик. .docx ОТКРЫВАЕТ
91
+ * (заменяет документ); картинка/CSV/txt ВСТАВЛЯЮТСЯ в курсор. Бросает для
92
+ * неподдержанного типа. Точка подключения для кнопки/drag-drop/paste.
93
+ */
94
+ importFile(file: File): Promise<ImportFormat>;
95
+ /** Импорт PDF как картинок: каждая страница -> PNG, вставляется в документ. */
96
+ importPdfAsImages(file: File): Promise<void>;
97
+ /**
98
+ * Импорт PDF «как есть»: встраивает сам файл (data-URL) блоком-iframe.
99
+ * Полностью client-side, на сервер не уходит. Просмотр - встроенным
100
+ * PDF-вьюером браузера; редактировать содержимое нельзя (atom-узел).
101
+ */
102
+ importPdfAsEmbed(file: File): Promise<void>;
103
+ /** Хост задаёт спрашивалку режима PDF (текст/картинки/встроить). */
104
+ setPdfModeResolver(fn: () => Promise<'text' | 'images' | 'embed' | null>): void;
105
+ /**
106
+ * Импорт PDF с выбором режима, если хост задал резолвер (drag-drop, буфер).
107
+ * Без резолвера - поведение по умолчанию (текст), как раньше.
108
+ */
109
+ importPdfWithChoice(file: File): Promise<void>;
110
+ /**
111
+ * Вставка «богатого» буфера, полученного из companion-расширения в обход
112
+ * браузерной песочницы: на вход полный сырой HTML + RTF (с встроенными
113
+ * картинками). Прогоняем тот же премиум-пайплайн и вставляем в курсор.
114
+ */
115
+ pasteRich(html: string, rtf?: string): void;
116
+ /**
117
+ * Сменить подсказку пустого документа на лету. Нужна хосту: атрибут
118
+ * placeholder заявлен в observedAttributes веб-компонента, и до этого
119
+ * изменение атрибута молча ничего не делало - подсказка была вшита в
120
+ * плагин при создании редактора.
121
+ */
122
+ setPlaceholder(text: string): void;
123
+ /** Сменить доступное имя области ввода (атрибут aria-label у хоста). */
124
+ setAriaLabel(label: string): void;
125
+ /** Документ как JSON (для хранения в БД без потери структуры). */
126
+ getJSON(): Record<string, unknown>;
127
+ /** Пустой ли документ (нет текстового содержимого). */
128
+ isEmpty(): boolean;
129
+ /** Включает/выключает премиум smart-paste (по лицензии). */
130
+ /**
131
+ * Отметить лицензию подтверждённой. Ставит хост после проверки (valid или
132
+ * grace). До этого выгрузки несут ознакомительную пометку.
133
+ */
134
+ setLicensed(on: boolean): void;
135
+ /**
136
+ * Ознакомительная пометка в ВЫГРУЗКАХ.
137
+ *
138
+ * Зачем она нужна отдельно от знака на экране: знак видит тот, кто работает
139
+ * в редакторе, а платит не он. Пометка же уходит туда, где продукт отдаёт
140
+ * ценность наружу - в договор, счёт, отчёт, которые компания отправляет
141
+ * своему клиенту. Отправить такой документ со строкой об ознакомительном
142
+ * режиме нельзя, и это делает работу без лицензии невозможной по деловым
143
+ * причинам, а не по техническим.
144
+ *
145
+ * Что при этом НЕ делается: ничего не отключается, экспорт работает
146
+ * полностью, файл открывается и читается. Деградация, а не блокировка.
147
+ *
148
+ * Честно: снять это со стороны страницы по-прежнему можно - код исполняется
149
+ * у клиента. Барьер остаётся юридическим, пометка лишь делает нарушение
150
+ * видимым тому, кому документ придёт.
151
+ */
152
+ private trialNotice;
153
+ /** Пометка для текстовых форматов (txt, md, csv): отдельной строкой в конце. */
154
+ private appendTrialText;
155
+ /** Пометка для HTML-подобных форматов: абзацем в конце документа. */
156
+ private appendTrialHtml;
157
+ setPremiumPaste(on: boolean): void;
158
+ /** Следующая вставка - только текст (для кнопки тулбара). */
159
+ armPlainPaste(): void;
160
+ /**
161
+ * Передаёт редактору промис идущей проверки лицензии. Вызывает web-компонент
162
+ * сразу после монтирования; при использовании ядра напрямую промиса нет и
163
+ * поведение прежнее.
164
+ */
165
+ setLicenseCheck(p: Promise<unknown>): void;
166
+ /**
167
+ * Ждёт решения по лицензии перед выгрузкой. Потолок 7 секунд - чуть больше
168
+ * сетевого таймаута самой проверки (6 с), то есть в норме мы упираемся в её
169
+ * собственный таймаут, а не в этот. Потолок здесь на случай проверки, которая
170
+ * по какой-то причине не завершилась вовсе: выгрузка не должна зависнуть.
171
+ */
172
+ private licenseSettled;
173
+ /**
174
+ * Экспорт документа в PDF средствами браузера (печать). Client-side:
175
+ * содержимое не уходит на сервер (важно для ЭДО), рендер браузерный = WYSIWYG.
176
+ */
177
+ exportPdf(): Promise<void>;
178
+ /** Экспорт документа в Markdown (скачивание .md). Client-side. */
179
+ exportMarkdown(): Promise<void>;
180
+ /** Экспорт в самодостаточный HTML-файл (.html). Client-side. */
181
+ exportHtml(): Promise<void>;
182
+ /** Экспорт в простой текст (.txt). Client-side. */
183
+ exportText(): Promise<void>;
184
+ /** Экспорт таблиц документа в CSV (.csv). Client-side. */
185
+ exportCsv(): Promise<void>;
186
+ /** Экспорт в Word (.doc - Word-совместимый HTML). Client-side, без библиотек. */
187
+ exportWord(): Promise<void>;
188
+ focus(): void;
189
+ /** Текущее состояние поиска для UI: всего совпадений и номер активного (1-based). */
190
+ searchInfo(): {
191
+ count: number;
192
+ current: number;
193
+ };
194
+ private scrollToActiveMatch;
195
+ /** Задать поисковый запрос (подсветит все совпадения, перейдёт к первому). */
196
+ setSearchQuery(query: string): {
197
+ count: number;
198
+ current: number;
199
+ };
200
+ /** К следующему совпадению (с циклом). */
201
+ searchNext(): {
202
+ count: number;
203
+ current: number;
204
+ };
205
+ /** К предыдущему совпадению (с циклом). */
206
+ searchPrev(): {
207
+ count: number;
208
+ current: number;
209
+ };
210
+ /** Заменить активное совпадение. */
211
+ replaceCurrentMatch(replacement: string): {
212
+ count: number;
213
+ current: number;
214
+ };
215
+ /** Заменить все совпадения. Возвращает число замен. */
216
+ replaceAll(replacement: string): number;
217
+ /** Сбросить поиск (убрать подсветку). */
218
+ clearSearch(): void;
219
+ destroy(): void;
220
+ private run;
221
+ toggleMark(name: keyof typeof schema.marks): void;
222
+ setHeading(level: number): void;
223
+ setParagraph(): void;
224
+ /**
225
+ * Применить стиль из галереи (система стилей): тип блока + интервалы одним
226
+ * действием. blockquote оборачивает; heading/paragraph меняют тип с атрибутами.
227
+ */
228
+ applyBlockStyle(style: {
229
+ type: 'paragraph' | 'heading' | 'blockquote';
230
+ level?: number;
231
+ spacing?: string | null;
232
+ }): void;
233
+ toggleBulletList(): void;
234
+ toggleOrderedList(): void;
235
+ wrapBlockquote(): void;
236
+ /** Выделить весь документ (для пункта меню «Выделить всё»). */
237
+ selectAll(): void;
238
+ /** Пустое ли выделение (каретка без диапазона). */
239
+ isSelectionEmpty(): boolean;
240
+ private copiedMarks;
241
+ /** Запомнить форматирование текущей позиции (для «кисти формата»). */
242
+ copyFormat(): void;
243
+ hasCopiedFormat(): boolean;
244
+ /** Применить запомненное форматирование к выделению (заменяет инлайн-формат). */
245
+ applyCopiedFormat(): void;
246
+ setCodeBlock(): void;
247
+ /** Применить марку с атрибутами к выделению (или к будущему вводу, если пусто). */
248
+ private applyAttrMark;
249
+ private clearAttrMark;
250
+ /**
251
+ * Безопасно ли CSS-значение для подстановки в одно объявление style:
252
+ * запрещаем выход из объявления (`;{}`), HTML-брейкаут (`<>`) и опасные
253
+ * CSS-функции (url(), expression(), @import, комментарии). Защита от
254
+ * хранимой CSS-инъекции, если в сеттер передадут недоверенную строку.
255
+ */
256
+ private safeCss;
257
+ /** Размер шрифта, напр. "16px" (пусто - сбросить; невалидное - игнор). */
258
+ setFontSize(size: string): void;
259
+ /** Семейство шрифта (пусто - сбросить; невалидное - игнор). */
260
+ setFontFamily(family: string): void;
261
+ /** Цвет текста (пусто - сбросить; невалидное - игнор). */
262
+ setTextColor(color: string): void;
263
+ /** Выделение фоном (пусто - снять; невалидное - игнор). */
264
+ setHighlight(color: string): void;
265
+ /** Снять всё инлайн-форматирование в выделении (или у каретки - отложенные марки). */
266
+ clearFormatting(): void;
267
+ /** Поставить/заменить ссылку на выделении (пусто - вставить URL текстом). */
268
+ setLink(href: string): void;
269
+ /** Снять ссылку с выделения. */
270
+ unsetLink(): void;
271
+ /** Текущее значение атрибута марки у каретки (для отражения в выпадашке). */
272
+ currentMarkAttr(name: keyof typeof schema.marks, attr: string): string | null;
273
+ /** Текущий блочный стиль: 'paragraph' | 'h1'..'h6' | 'blockquote'. */
274
+ currentBlock(): string;
275
+ /** Выравнивание текущих абзацев/заголовков. */
276
+ setAlign(align: string): void;
277
+ /** Активно ли выравнивание (для подсветки кнопок). */
278
+ isAlignActive(align: string): boolean;
279
+ /** Вставить изображение по src (URL, путь или data-URI). */
280
+ insertImage(src: string, alt?: string): void;
281
+ /** Вставить поле шаблона (merge field) - inline-чип для подстановки реквизита ЭДО. */
282
+ insertMergeField(key: string, label?: string): void;
283
+ /**
284
+ * HTML документа с полями шаблона, развёрнутыми в плейсхолдеры {{key}} -
285
+ * для ЭДО-систем, которые подставляют значения по {{...}}, а не по
286
+ * data-атрибутам. Без аргумента берёт текущий документ.
287
+ */
288
+ getMergeText(html?: string): string;
289
+ /** Вставить сноску с текстом (надстрочный номер; нумерация - авто). */
290
+ insertFootnote(text: string): void;
291
+ /** Тексты всех сносок документа по порядку (для секции сносок при печати/экспорте). */
292
+ getFootnotes(): string[];
293
+ /** Вставить блок оглавления (наполняется заголовками автоматически). */
294
+ insertTableOfContents(): void;
295
+ private commentSeq;
296
+ /** Добавить комментарий к выделению; возвращает id (или null, если нет выделения/текста). */
297
+ addComment(text: string, author?: string): string | null;
298
+ /** Все комментарии документа (по первому появлению), в порядке текста. */
299
+ getComments(): {
300
+ id: string;
301
+ text: string;
302
+ author: string | null;
303
+ }[];
304
+ /** Снять (разрешить) комментарий по id - убирает подсветку с текста. */
305
+ resolveComment(id: string): void;
306
+ /** Комментарии под кареткой/выделением (для всплывающего попапа). */
307
+ commentsAtSelection(): {
308
+ id: string;
309
+ text: string;
310
+ author: string | null;
311
+ }[];
312
+ /** Включить/выключить режим рецензирования (новый текст помечается как вставка). */
313
+ setTrackChanges(on: boolean): void;
314
+ isTrackingChanges(): boolean;
315
+ /** Включить/выключить страничный вид (границы страниц A4). */
316
+ setPagination(on: boolean): void;
317
+ isPaginated(): boolean;
318
+ /** Предложить удаление выделенного текста (зачёркивается, не удаляется). */
319
+ markDeletion(): void;
320
+ /** Диапазоны помеченных правок (текстовые узлы с insertion/deletion). */
321
+ private collectChangeRanges;
322
+ /** Кол-во предложенных правок (для UI). */
323
+ getChangeCount(): {
324
+ insertions: number;
325
+ deletions: number;
326
+ };
327
+ /** Принять все правки: вставки остаются (снимаем метку), удаления применяются. */
328
+ acceptAllChanges(): void;
329
+ /** Отклонить все правки: вставки удаляются, удаления отменяются (текст остаётся). */
330
+ rejectAllChanges(): void;
331
+ /** Вставить горизонтальную линию (<hr>) в позицию курсора. */
332
+ insertHorizontalRule(): void;
333
+ insertTable(rows?: number, cols?: number): void;
334
+ tableAddRow(): void;
335
+ tableAddColumn(): void;
336
+ tableDeleteRow(): void;
337
+ tableDeleteColumn(): void;
338
+ /** Объединить выделенные ячейки (нужно выделение нескольких ячеек). */
339
+ tableMergeCells(): void;
340
+ /**
341
+ * Разделить ячейку. С аргументами (cols, rows) - Word-режим: делит одиночную
342
+ * ячейку на сетку cols×rows. Без аргументов или для уже объединённой ячейки -
343
+ * встроенный splitCell (разъединяет обратно в 1×1).
344
+ */
345
+ tableSplitCell(cols?: number, rows?: number): void;
346
+ /** Можно ли разъединить текущую ячейку (она объединена: colspan/rowspan > 1). */
347
+ isMergedCell(): boolean;
348
+ /** Выделено ли 2+ ячейки (CellSelection охватывает несколько ячеек). */
349
+ hasMultiCellSelection(): boolean;
350
+ tableDelete(): void;
351
+ /** Найти таблицу, охватывающую текущее выделение. */
352
+ private findCurrentTable;
353
+ /** Применить колбэк к каждой выделенной ячейке (или текущей, если выделения ячеек нет). */
354
+ private forEachSelectedCell;
355
+ /** Свойства текущей ячейки - для предзаполнения диалога. */
356
+ getCellProps(): CellProps;
357
+ /** Применить свойства к выделенным ячейкам. */
358
+ setCellProps(props: CellProps): void;
359
+ /** Свойства текущей таблицы - для предзаполнения диалога. */
360
+ getTableProps(): TableProps;
361
+ /** Применить свойства к таблице (ширина/выравнивание) и, опционально, рамку ко всем ячейкам. */
362
+ setTableProps(props: TableProps): void;
363
+ /** В таблице ли сейчас курсор (для активации пунктов «Свойства…»). */
364
+ isInTable(): boolean;
365
+ undo(): void;
366
+ redo(): void;
367
+ /** Активна ли марка в текущем выделении (для подсветки кнопок). */
368
+ isMarkActive(name: keyof typeof schema.marks): boolean;
369
+ /** Является ли текущий блок узлом данного типа (для подсветки H1/H2/абзаца). */
370
+ isNodeType(name: string, attrs?: Record<string, unknown>): boolean;
371
+ }
372
+ export {};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Деградация для старых браузеров.
3
+ *
4
+ * Корпоративное требование — «не ломаться». На современных браузерах работает
5
+ * полноценный редактор (Web Component + Shadow DOM). Если браузер их не
6
+ * поддерживает (очень старые версии), вместо редактора показывается обычная
7
+ * textarea: ввод работает, формы получают значение, продукт не падает белым
8
+ * экраном.
9
+ */
10
+ /** Поддерживает ли браузер полноценный редактор. */
11
+ export declare function supportsModernEditor(): boolean;
12
+ /** Заменяет все <koda-editor> на textarea (режим деградации). */
13
+ export declare function installFallback(tag?: string): void;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Floating toolbar (Notion-UX): по выделению текста всплывает мини-панель
3
+ * форматирования над выделением (жирный/курсив/подчёркнутый/зачёркнутый).
4
+ */
5
+ import { Plugin } from 'prosemirror-state';
6
+ import type { Strings } from './i18n';
7
+ export declare function floatingToolbarPlugin(strings: Strings): Plugin;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Нейтральные обложки-контейнеры (нарисованы в том же line-стиле, что и пакет
3
+ * панели). Их нет среди команд, поэтому держим здесь — для группы это
4
+ * естественнее, чем «B»/«ссылка» в роли обложки.
5
+ */
6
+ export declare const GROUP_EXTRA_ICONS: Record<string, string>;
7
+ /** Популярные emoji для обложки группы (iconKind:'emoji', сам символ хранится). */
8
+ export declare const GROUP_EMOJI: string[];
9
+ /** Тип обложки кнопки-группы. */
10
+ export type GroupIconKind = 'builtin' | 'emoji' | 'image';
11
+ /**
12
+ * Ключи иконок для вкладки «Иконки» лого-пикера: сперва нейтральные обложки,
13
+ * затем все иконки панели (тот же пакет). Дедуп на случай пересечений.
14
+ */
15
+ export declare function groupIconKeys(): string[];
16
+ /** Отрисовать обложку группы в HTML (для кнопки/превью). */
17
+ export declare function renderGroupIcon(kind: GroupIconKind, icon: string): string;
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Локализация интерфейса KodaEditor.
3
+ *
4
+ * Поддержка: английский (по умолчанию - глобальный рынок) и русский.
5
+ * Локаль задаётся атрибутом locale на <koda-editor> ("en" | "ru") или
6
+ * наследуется из lang. Переводятся только строки UI (подсказки кнопок,
7
+ * ARIA-метки, водяной знак) - содержимое документа не трогается.
8
+ *
9
+ * До 01.09.2026 английской локали не было вообще, а resolveLocale() без
10
+ * явного locale-атрибута откатывалась на 'ru' - для нового глобального
11
+ * бренда это было реальной проблемой (не косметика: любой англоязычный
12
+ * покупатель без явного locale получал русский тулбар). Добавлен 'en',
13
+ * дефолт сменён.
14
+ *
15
+ * Узбекский (uz-latn/uz-cyrl) убран в тот же день - был сделан под
16
+ * конкретного локального заказчика (meplab), тот больше не действует.
17
+ * Полная версия с узбекским сохранена в git-ветке
18
+ * archive/meplab-uzbek-locale, не удалена безвозвратно.
19
+ */
20
+ export type Locale = 'en' | 'ru' | 'es' | 'de' | 'ja' | 'fr' | 'ko';
21
+ export interface Strings {
22
+ bold: string;
23
+ italic: string;
24
+ underline: string;
25
+ strike: string;
26
+ h1: string;
27
+ h2: string;
28
+ h3: string;
29
+ paragraph: string;
30
+ font: string;
31
+ textSize: string;
32
+ bulletList: string;
33
+ orderedList: string;
34
+ quote: string;
35
+ codeBlock: string;
36
+ undo: string;
37
+ redo: string;
38
+ pastePlain: string;
39
+ openDocx: string;
40
+ exportPdf: string;
41
+ importFile: string;
42
+ exportMarkdown: string;
43
+ export: string;
44
+ exportTitle: string;
45
+ importTitle: string;
46
+ importFromFile: string;
47
+ importFromUrl: string;
48
+ importUrlPlaceholder: string;
49
+ importUrlInvalid: string;
50
+ importUrlFailed: string;
51
+ importing: string;
52
+ importPdfImages: string;
53
+ importDocx: string;
54
+ importPdf: string;
55
+ importExcel: string;
56
+ importText: string;
57
+ exportWord: string;
58
+ exportHtml: string;
59
+ exportText: string;
60
+ exportCsv: string;
61
+ insertTable: string;
62
+ tableRows: string;
63
+ tableCols: string;
64
+ tableAddRow: string;
65
+ tableAddColumn: string;
66
+ tableDeleteRow: string;
67
+ tableDeleteColumn: string;
68
+ tableMergeCells: string;
69
+ tableSplitCell: string;
70
+ mergeCellsHint: string;
71
+ splitCellTitle: string;
72
+ splitCellHint: string;
73
+ commentHint: string;
74
+ formatPainterHint: string;
75
+ tableDelete: string;
76
+ image: string;
77
+ link: string;
78
+ textColor: string;
79
+ highlight: string;
80
+ clearFormat: string;
81
+ superscript: string;
82
+ subscript: string;
83
+ horizontalRule: string;
84
+ find: string;
85
+ replace: string;
86
+ replaceAll: string;
87
+ searchNext: string;
88
+ searchPrev: string;
89
+ searchClose: string;
90
+ fullscreen: string;
91
+ imageUrl: string;
92
+ imageInsert: string;
93
+ imageUpload: string;
94
+ cancel: string;
95
+ customizeToolbar: string;
96
+ customizeAdd: string;
97
+ customizeSeparator: string;
98
+ customizeReset: string;
99
+ customizeDone: string;
100
+ customizeHint: string;
101
+ customizeAvailable: string;
102
+ customizeRemove: string;
103
+ customizeGroup: string;
104
+ customizeGroupCreate: string;
105
+ customizeUngroup: string;
106
+ customizeGroupName: string;
107
+ customizeGroupIcon: string;
108
+ customizeIconBuiltin: string;
109
+ customizeIconEmoji: string;
110
+ customizeIconUpload: string;
111
+ alignLeft: string;
112
+ alignCenter: string;
113
+ alignRight: string;
114
+ editorLabel: string;
115
+ toolbarLabel: string;
116
+ toolbarHint: string;
117
+ trialExportNotice: string;
118
+ importFailed: string;
119
+ imageTooBig: string;
120
+ imageWrongType: string;
121
+ imageUploadFailed: string;
122
+ watermark: string;
123
+ /** Короткий текст для замощения канвы (диагональный водяной знак демо). */
124
+ watermarkShort: string;
125
+ menubarLabel: string;
126
+ menuFile: string;
127
+ menuEdit: string;
128
+ menuInsert: string;
129
+ menuFormat: string;
130
+ menuTable: string;
131
+ menuView: string;
132
+ menuImport: string;
133
+ menuExport: string;
134
+ menuRow: string;
135
+ menuColumn: string;
136
+ menuCell: string;
137
+ menuStyle: string;
138
+ menuAlign: string;
139
+ selectAll: string;
140
+ cut: string;
141
+ copy: string;
142
+ print: string;
143
+ tableProps: string;
144
+ cellProps: string;
145
+ propWidth: string;
146
+ propAlign: string;
147
+ propBorder: string;
148
+ propBorderColor: string;
149
+ propBackground: string;
150
+ propTextAlign: string;
151
+ propVerticalAlign: string;
152
+ valNone: string;
153
+ valTop: string;
154
+ valMiddle: string;
155
+ valBottom: string;
156
+ apply: string;
157
+ mergeField: string;
158
+ mergeFieldTitle: string;
159
+ mfDate: string;
160
+ mfDocNumber: string;
161
+ mfFullName: string;
162
+ mfOrg: string;
163
+ mfInn: string;
164
+ mfPosition: string;
165
+ mfAddress: string;
166
+ mfSignature: string;
167
+ footnote: string;
168
+ footnotePrompt: string;
169
+ toc: string;
170
+ tocTitle: string;
171
+ styles: string;
172
+ styleNormal: string;
173
+ styleCompact: string;
174
+ styleSpacious: string;
175
+ h4: string;
176
+ comment: string;
177
+ commentPrompt: string;
178
+ commentResolve: string;
179
+ commentSelectText: string;
180
+ trackChanges: string;
181
+ suggestDelete: string;
182
+ acceptAll: string;
183
+ rejectAll: string;
184
+ versionHistory: string;
185
+ versionSave: string;
186
+ versionRestore: string;
187
+ versionNone: string;
188
+ versionNamePh: string;
189
+ versionUnnamed: string;
190
+ formatPainter: string;
191
+ a11yCheck: string;
192
+ a11yNoIssues: string;
193
+ a11yImgNoAlt: string;
194
+ a11yHeadingSkip: string;
195
+ a11yEmptyLink: string;
196
+ a11yTableNoHeader: string;
197
+ spellcheck: string;
198
+ pagination: string;
199
+ }
200
+ /**
201
+ * Нормализует произвольную строку локали к поддерживаемой.
202
+ * По умолчанию (locale-атрибут не задан или не распознан) - 'en': продукт
203
+ * продаётся глобально под брендом KodaEditor, английский - базовый язык
204
+ * рынка. Явный 'ru' по-прежнему распознаётся и работает как раньше.
205
+ *
206
+ * Узбекский (uz-latn/uz-cyrl) убран из публичного пакета 01.09.2026 -
207
+ * был сделан под конкретного локального заказчика (meplab), тот больше
208
+ * не действует; полная версия с узбекским сохранена в git-ветке
209
+ * archive/meplab-uzbek-locale, не удалена безвозвратно. Старое значение
210
+ * locale="uz-latn"/"uz-cyrl" теперь просто тихо откатывается на 'en' -
211
+ * не ошибка, деградация в духе остального проекта (не блокировка).
212
+ */
213
+ export declare function resolveLocale(input?: string | null): Locale;
214
+ export declare function getStrings(locale: Locale): Strings;
@@ -0,0 +1 @@
1
+ export declare const TOOLBAR_ICONS: Record<string, string>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * NodeView картинки с ручкой ресайза (правый-нижний угол). Тянем мышью —
3
+ * меняется ширина; по отпусканию ширина пишется в атрибут width узла (т.е.
4
+ * сохраняется в HTML как style="width:NNpx"). Ручка видна при наведении или
5
+ * когда картинка выделена.
6
+ */
7
+ import type { Node as PMNode } from 'prosemirror-model';
8
+ import type { EditorView, NodeView } from 'prosemirror-view';
9
+ export declare class ImageNodeView implements NodeView {
10
+ dom: HTMLElement;
11
+ private img;
12
+ private node;
13
+ private view;
14
+ private getPos;
15
+ constructor(node: PMNode, view: EditorView, getPos: () => number | undefined);
16
+ /**
17
+ * Режим обрезки: накладывает слой поверх картинки, пользователь тянет рамку
18
+ * выделения (pointer = мышь/touch), затем «Применить» вырезает область через
19
+ * canvas в новый data-URL (client-side, на сервер не уходит).
20
+ */
21
+ private enterCrop;
22
+ /** Вырезает область (в координатах отображения) через canvas -> новый src. */
23
+ private applyCrop;
24
+ private startResize;
25
+ update(node: PMNode): boolean;
26
+ ignoreMutation(): boolean;
27
+ }