@kodaeditor/core 1.0.1 → 1.0.2

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 (49) hide show
  1. package/dist/docx-import.d.ts +11 -11
  2. package/dist/editor.d.ts +109 -159
  3. package/dist/fallback.d.ts +7 -8
  4. package/dist/i18n.d.ts +15 -26
  5. package/dist/import-formats.d.ts +19 -17
  6. package/dist/index.d.ts +4 -4
  7. package/dist/kodaeditor-core.umd.cjs +1 -1
  8. package/dist/kodaeditor.js +1 -1
  9. package/dist/kodaeditor.umd.cjs +1 -1
  10. package/dist/license.d.ts +46 -50
  11. package/dist/schema.d.ts +7 -7
  12. package/dist/serialize.d.ts +11 -11
  13. package/dist/web-component.d.ts +71 -213
  14. package/package.json +2 -5
  15. package/dist/commands.d.ts +0 -15
  16. package/dist/docx-alignment.d.ts +0 -14
  17. package/dist/docx-breaks.d.ts +0 -31
  18. package/dist/docx-forms.d.ts +0 -28
  19. package/dist/docx-headers.d.ts +0 -22
  20. package/dist/docx-images.d.ts +0 -41
  21. package/dist/docx-math.d.ts +0 -18
  22. package/dist/docx-styles.d.ts +0 -53
  23. package/dist/docx-symbols.d.ts +0 -19
  24. package/dist/docx-text-styles.d.ts +0 -27
  25. package/dist/floatingToolbar.d.ts +0 -7
  26. package/dist/group-icons.d.ts +0 -17
  27. package/dist/icons.d.ts +0 -1
  28. package/dist/image-view.d.ts +0 -27
  29. package/dist/markdown.d.ts +0 -4
  30. package/dist/menubar.d.ts +0 -60
  31. package/dist/offline-license.d.ts +0 -36
  32. package/dist/pagination.d.ts +0 -11
  33. package/dist/paste.d.ts +0 -54
  34. package/dist/pdf-import-cdn.d.ts +0 -2
  35. package/dist/pdf-import.d.ts +0 -8
  36. package/dist/print.d.ts +0 -18
  37. package/dist/rtf-images.d.ts +0 -24
  38. package/dist/search.d.ts +0 -17
  39. package/dist/slashMenu.d.ts +0 -8
  40. package/dist/styles.d.ts +0 -8
  41. package/dist/table-split.d.ts +0 -26
  42. package/dist/table-view.d.ts +0 -34
  43. package/dist/tableColumnTrade.d.ts +0 -15
  44. package/dist/tableToolbar.d.ts +0 -14
  45. package/dist/toc-view.d.ts +0 -23
  46. package/dist/toolbar-editor.d.ts +0 -89
  47. package/dist/validate-signature.d.ts +0 -64
  48. package/dist/xlsx-import-cdn.d.ts +0 -1
  49. package/dist/xlsx-import.d.ts +0 -2
@@ -1,15 +1,14 @@
1
1
  import type { DocxImportResult } from './docx-import';
2
2
  import { type Strings } from './i18n';
3
3
  /**
4
- * База класса. В браузере это HTMLElement, в среде без DOM - пустой класс.
4
+ * Class base: HTMLElement in a browser, an empty class where there is no DOM.
5
5
  *
6
- * Нужно потому, что `class X extends HTMLElement` исполняется при ЗАГРУЗКЕ
7
- * модуля, а не при создании элемента: без подмены сам факт
8
- * `import '@kodaeditor/core'` падал с «HTMLElement is not defined» при
9
- * серверном рендеринге (Next.js, Nuxt, SvelteKit импортируют модули хоста в
10
- * Node). Регистрация <koda-editor> и без того выполняется только при наличии
11
- * window - см. index.ts, - так что на сервере этот класс просто никогда не
12
- * используется.
6
+ * `class X extends HTMLElement` runs when the MODULE LOADS, not when an
7
+ * element is created, so without this substitution the mere act of
8
+ * `import '@kodaeditor/core'` threw "HTMLElement is not defined" during
9
+ * server-side rendering (Next.js, Nuxt and SvelteKit import host modules in
10
+ * Node). Registration of <koda-editor> already happens only when a window
11
+ * exists, so on the server this class is simply never used.
13
12
  */
14
13
  declare const ElementBase: typeof HTMLElement;
15
14
  export declare class KodaEditorElement extends ElementBase {
@@ -18,37 +17,14 @@ export declare class KodaEditorElement extends ElementBase {
18
17
  private buttons;
19
18
  private contentEl?;
20
19
  private stringsValue;
21
- /** Локаль, выбранная при подключении: нужна там, где язык уходит наружу -
22
- * в атрибут lang содержимого (словарь проверки орфографии) и в печать. */
23
20
  private localeValue;
24
- /** Задал ли язык сам разработчик (атрибут locale или lang на элементе).
25
- * Если нет - язык области НЕ навязывается: он наследуется от страницы
26
- * через границу теневого дерева, и это правильнее нашего умолчания. */
27
21
  private localeExplicit;
28
22
  private internals?;
29
23
  private pendingValue?;
30
- /** Словарь клиента, заданный свойством до монтирования. */
31
24
  private pendingStrings?;
32
25
  private suppressChange;
33
26
  private fsKeyHandler?;
34
- /**
35
- * Номер цикла монтирования. Нужен, чтобы асинхронная проверка лицензии
36
- * знала, тот ли редактор она застала: при реконсиляции во фреймворках
37
- * элемент отключают и тут же подключают снова, и результаты проверок
38
- * прошлых циклов приходили в уже новый редактор - водяные знаки копились
39
- * (проверено: три знака после трёх циклов remove/append).
40
- */
41
27
  private mountGeneration;
42
- /**
43
- * Запасное поле формы для браузеров без ElementInternals.
44
- *
45
- * attachInternals появился в Safari только в 16.4 (март 2023), а корпоративные
46
- * маки застревают на старых версиях macOS надолго. Там Shadow DOM есть, то
47
- * есть редактор поднимается полноценно и откат на textarea НЕ срабатывает -
48
- * а значение в форму не попадает, потому что некому его туда положить.
49
- * Пользователь печатает, жмёт «Отправить», на сервер не уходит ничего. Тот же
50
- * молчаливый класс, что и потерянный name в откате (исправлено 11.09.2026).
51
- */
52
28
  private shadowFormInput?;
53
29
  private searchBar?;
54
30
  private searchFindInput?;
@@ -61,14 +37,14 @@ export declare class KodaEditorElement extends ElementBase {
61
37
  private readonly onPasteRich;
62
38
  static get observedAttributes(): string[];
63
39
  /**
64
- * Реакция на смену атрибутов после монтирования.
40
+ * Reacts to attribute changes after the element is mounted.
65
41
  *
66
- * Раньше observedAttributes был объявлен, а самого коллбэка в пакете не было
67
- * вовсе: интегратор менял placeholder или aria-label и получал молчаливое
68
- * бездействие вместо заявленного спецификацией поведения.
42
+ * Before mounting, values are picked up in connectedCallback, so early
43
+ * calls are ignored - the browser also fires this callback while parsing
44
+ * the markup.
69
45
  *
70
- * До монтирования значения подхватываются в connectedCallback, поэтому
71
- * ранние вызовы (браузер дёргает коллбэк и при разборе разметки) игнорируем.
46
+ * Note that `locale` and `lang` are read once, when the element connects.
47
+ * Changing them later logs a warning instead of silently doing nothing.
72
48
  */
73
49
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
74
50
  connectedCallback(): void;
@@ -79,157 +55,105 @@ export declare class KodaEditorElement extends ElementBase {
79
55
  private getSavedLayout;
80
56
  private saveLayout;
81
57
  private clearLayout;
82
- /** Токены текущей раскладки (для редактора). Дефолт - из TOOLBAR + выпадашки.
83
- * Без 'style' (выпадашка «Абзац») - её заменяет галерея «Стили» в TOOLBAR;
84
- * 'style' остаётся доступной в палитре карандаша. */
85
58
  private defaultTokens;
86
- /** Человекочитаемая подпись токена для диалога настройки. */
87
59
  private tokenLabel;
88
- /** Иконка токена (HTML svg) - для палитры/превью карандаша. '' если без иконки. */
89
60
  private tokenIcon;
90
- /** Все токены, доступные для добавления в палитре карандаша (без разделителя). */
91
61
  private allTokens;
92
- /**
93
- * Разбор сохранённой раскладки. Поддерживает два формата (обратносовместимо):
94
- * - строка токенов: "style | bold italic | export" (старый, конфиг интегратора)
95
- * - JSON-массив LayoutEntry с группами (новый, карандаш) - начинается с '['
96
- */
97
62
  private parseLayout;
98
- /** Нормализация одной записи раскладки из недоверенного JSON. */
99
63
  private normalizeEntry;
100
- /** Текущая раскладка как записи (для карандаша). Дефолт - плоский список токенов. */
101
64
  private currentEntries;
102
- /** Сериализовать раскладку: JSON если есть группы, иначе компактная строка токенов. */
103
65
  private serializeEntries;
104
- /** Сохранить раскладку (из карандаша) и пересобрать панель. */
105
66
  private saveEntries;
106
67
  private appendCustomizeButton;
107
- /** Запуск редактора панели «карандаш» (drag-and-drop прямо на тулбаре). */
108
68
  private openToolbarEditor;
109
- /**
110
- * Кнопка-группа: обложка + название + ▾, по клику раскрывает меню с вложенными
111
- * кнопками. Сами кнопки внутри выполняют свои команды (как на панели).
112
- */
113
69
  private appendGroupButton;
114
- /** Выпадающее меню кнопки-группы со вложенными кнопками. */
115
70
  private openGroupMenu;
116
- /** Выполнить действие редактора и обновить состояние тулбара. */
117
71
  private menuRun;
118
- /** Пункты меню «Таблица» - переиспользуются и в верхнем меню, и в контекстном. */
119
72
  private tableMenuItems;
120
- /** Декларативная структура верхнего меню. Действия переиспуют методы редактора. */
121
73
  private buildMenus;
122
- /** Контекстное меню по элементу под курсором (правый клик). */
123
74
  private buildContextMenu;
124
75
  private onContextMenu;
125
- /** Вырезать/копировать через нативную команду (выделение редактора). */
126
76
  private execEdit;
127
- /** Запомнить формат текущей позиции и включить «кисть» (следующее выделение - применит). */
128
77
  private armFormatPainter;
129
78
  private disarmFormatPainter;
130
- /** Анализ документа на типичные проблемы доступности (WCAG-ориентировочно). */
79
+ /** Checks the document for common accessibility problems (WCAG-oriented). */
131
80
  checkAccessibility(): {
132
81
  issue: string;
133
82
  count: number;
134
83
  }[];
135
- /** Диалог результатов проверки доступности. */
136
84
  private openAccessibilityCheck;
137
85
  private spellcheckOn;
138
86
  /**
139
- * Включить/выключить браузерную проверку орфографии.
87
+ * Turns the browser spell checker on or off.
140
88
  *
141
- * Словарь выбирает браузер по атрибуту lang, поэтому язык области - это не
142
- * косметика: под чужим словарём подчёркивается весь текст.
89
+ * The browser picks the dictionary from the lang attribute, so the language
90
+ * of the editing area is not cosmetic: under the wrong dictionary every
91
+ * word is underlined.
143
92
  *
144
- * Если разработчик задал язык (locale или lang на элементе) - берём его.
145
- * Если не задал, наше умолчание навязывать нельзя: 'en' посадил бы японскую
146
- * страницу на английский словарь, то есть ровно та ошибка, ради которой этот
147
- * код и переписан. Вместо этого копируем язык страницы.
93
+ * If you set a language (the locale or lang attribute on the element), that
94
+ * is what is used. If you do not, the language of the page is copied
95
+ * instead - imposing a default here would put, say, a Japanese page on an
96
+ * English dictionary.
148
97
  *
149
- * Копируем ЯВНО, а не полагаемся на наследование: Firefox не передаёт язык
150
- * через границу теневого дерева. Замер на <html lang="ja"> и редакторе без
151
- * locale: Chromium и WebKit считают область японской, Firefox - нет. Если
152
- * языка нет и у страницы, атрибут не ставится - пусть решает браузер.
98
+ * The page language is copied EXPLICITLY rather than left to inheritance,
99
+ * because Firefox does not pass lang across the shadow boundary while
100
+ * Chromium and WebKit do. If the page has no language either, no attribute
101
+ * is set and the browser decides.
153
102
  */
154
103
  setSpellcheck(on: boolean): void;
155
104
  isSpellcheckOn(): boolean;
156
105
  setPagination(on: boolean): void;
157
106
  isPaginated(): boolean;
158
- /** Строка диалога свойств: подпись + поле. */
159
107
  private propRow;
160
108
  private propSelect;
161
109
  private propInput;
162
- /**
163
- * Word-подобная вставка таблицы: сетка с наведением (динамически расширяется
164
- * до 20×20) + ручной ввод числа строк/столбцов для больших таблиц.
165
- */
166
110
  private openTableGridPicker;
167
111
  /**
168
- * Словарь интерфейса клиента: СВОЙ язык без нашего участия.
112
+ * Your own interface dictionary: any language, without waiting for us.
169
113
  *
170
- * Зачем: встроенных локалей две (en, ru), а редактор встраивают в системы,
171
- * где с документами весь день работают люди, английского не знающие -
172
- * госуслуги, банки, страховые, медицина. Держать в ядре словари всех рынков
173
- * означало бы поддерживать их вечно и всё равно не угадать. Поэтому клиент
174
- * может задать свой словарь сам: полный перевод или несколько переименованных
175
- * кнопок.
114
+ * Seven locales ship with the editor, but it gets embedded in systems whose
115
+ * users work with documents all day and may not read any of them. Shipping
116
+ * a dictionary for every market would mean maintaining them forever and
117
+ * still missing one, so you can supply your own: a full translation or just
118
+ * a few renamed buttons.
176
119
  *
177
- * Два способа, оба читаются при монтировании (как и атрибут locale):
178
- * - свойство: el.strings = { bold: 'Negrita', ... } ДО вставки в DOM;
179
- * - атрибут strings-ref="id" -> <script type="application/json"> с тем же
180
- * объектом; удобно для серверного рендера и разметки без JS.
120
+ * Two ways, both read when the element mounts (like the locale attribute):
121
+ * - property: el.strings = { bold: 'Negrita', ... } BEFORE it enters the DOM;
122
+ * - attribute strings-ref="id" pointing at a
123
+ * <script type="application/json"> holding the same object, which suits
124
+ * server-side rendering and markup without JavaScript.
181
125
  *
182
- * Переопределения накладываются ПОВЕРХ выбранной локали, поэтому переводить
183
- * всё необязательно: незаданные ключи остаются как были. Тип Strings
184
- * экспортируется пакетом, так что у клиента на TypeScript есть проверка имён.
126
+ * Overrides are applied ON TOP of the chosen locale, so you need not
127
+ * translate everything: keys you leave out keep their original text. The
128
+ * Strings type is exported by the package, so TypeScript checks the names.
185
129
  */
186
130
  set strings(overrides: Partial<Strings>);
187
131
  get strings(): Strings;
188
- /** Собрать переопределения из свойства и из strings-ref. Только строки. */
189
132
  private collectStringOverrides;
190
- /**
191
- * Кладёт значение в форму там, где ElementInternals недоступен: скрытым
192
- * полем с тем же именем. Ничего не делает, если internals есть (современные
193
- * браузеры) или если имя не задано - без имени поле всё равно не отправится.
194
- */
195
133
  private syncFallbackFormValue;
196
- /** Транзиентная подсказка внизу редактора (автоисчезает). */
197
134
  private flashNotice;
198
- /**
199
- * Разделить ячейку как в Word. Объединённую - сразу разъединяем (понятное
200
- * действие). Обычную - диалог «Столбцов × Строк».
201
- */
202
135
  private openSplitCellDialog;
203
- /** Объединить ячейки; при одиночном выделении - понятная подсказка. */
204
136
  private mergeCellsWithHint;
205
- /** Каркас диалога свойств: backdrop + заголовок + строки + Отмена/Применить. */
206
137
  private buildPropsDialog;
207
138
  private openTablePropsDialog;
208
139
  private openCellPropsDialog;
209
- /** Доступные поля: из атрибута merge-fields (JSON) или дефолтный набор реквизитов. */
210
140
  private getMergeFields;
211
- /** Диалог вставки поля шаблона. */
212
141
  private openMergeFieldPicker;
213
- /** Публичный API: вставить поле шаблона программно. */
142
+ /** Inserts a merge field programmatically. */
214
143
  insertMergeField(key: string, label?: string): void;
215
- /** Публичный API: HTML с полями, развёрнутыми в {{key}} (для ЭДО-подстановки). */
144
+ /** Returns the HTML with merge fields expanded to {{key}}, ready for mail merge. */
216
145
  getMergeText(): string;
217
- /** Диалог ввода текста сноски, затем вставка маркера. */
218
146
  private openFootnotePrompt;
219
- /** Публичный API: вставить сноску / получить тексты сносок / вставить оглавление. */
147
+ /** Inserts a footnote, reads footnote texts, or inserts a table of contents. */
220
148
  insertFootnote(text: string): void;
221
149
  getFootnotes(): string[];
222
150
  insertTableOfContents(): void;
223
- /** Набор быстрых стилей: тип блока + интервалы + превью для галереи. */
224
151
  private styleGallery;
225
- /** Галерея стилей - выпадающая панель с превью каждого стиля. */
226
152
  private openStyleGallery;
227
- /** Диалог ввода комментария к выделению. */
228
153
  private openCommentPrompt;
229
154
  private onCommentClick;
230
- /** Попап комментария: текст + кнопка «Разрешить». */
231
155
  private openCommentPopup;
232
- /** Публичный API комментариев. */
156
+ /** Comment API. */
233
157
  addComment(text: string, author?: string): string | null;
234
158
  getComments(): {
235
159
  id: string;
@@ -250,7 +174,7 @@ export declare class KodaEditorElement extends ElementBase {
250
174
  private versionsKey;
251
175
  private readVersions;
252
176
  private writeVersions;
253
- /** Сохранить снимок текущего документа как именованную версию. */
177
+ /** Saves a snapshot of the current document as a named version. */
254
178
  saveVersion(name?: string): void;
255
179
  getVersions(): {
256
180
  id: string;
@@ -260,157 +184,91 @@ export declare class KodaEditorElement extends ElementBase {
260
184
  }[];
261
185
  restoreVersion(id: string): void;
262
186
  deleteVersion(id: string): void;
263
- /** Диалог истории версий: сохранить текущую, восстановить/удалить прошлые. */
264
187
  private openVersionHistory;
265
- /** Пересобирает панель из текущей раскладки (после сохранения/сброса). */
266
188
  private rebuildToolbar;
267
- /** Один токен спецификации `toolbar="..."` -> элемент панели. Неизвестный - пропуск. */
268
189
  private appendToolbarToken;
269
- /** Рендер одной записи панели (разделитель / контрол цвета / кнопка). */
270
190
  private appendEntry;
271
191
  private onToolbarKeydown;
272
192
  private refreshToolbar;
273
- /** Общий конструктор выпадашки панели. */
274
193
  private makeSelect;
275
194
  private buildStyleSelect;
276
195
  private buildFontSelect;
277
196
  private buildSizeSelect;
278
- /** Кнопка выбора цвета (текст/выделение): иконка + скрытый input[type=color]. */
279
197
  private buildColorControl;
280
- /** Поля выбора цвета, ожидающие появления теневого корня. */
281
198
  private pendingColorInputs;
282
- /**
283
- * Кладёт поле выбора цвета в теневой корень.
284
- *
285
- * При первом построении панель собирается ДО attachShadow, корня ещё нет -
286
- * такое поле копится и уходит в корень сразу после его создания. При
287
- * перестроении панели (настройка кнопок) корень уже есть, и поле попадает
288
- * туда немедленно. Ни в одном из случаев поле не оказывается внутри кнопки.
289
- */
290
199
  private placeColorInput;
291
- /** Простой диалог ссылки (URL): ставит/снимает ссылку на выделении. */
292
200
  private openLinkPrompt;
293
- /**
294
- * Диалог выбора режима импорта PDF: текст (редактируемо) / картинки (точный
295
- * растр) / как PDF (встроить файл). Возвращает выбор или null (отмена).
296
- */
297
201
  private pickPdfMode;
298
- /**
299
- * Меню экспорта: PDF / Word / HTML / Markdown / TXT / CSV. Всё client-side -
300
- * содержимое не уходит на сервер. Выбор формата вызывает нужный метод Editor.
301
- */
302
202
  private openExportPicker;
303
- /**
304
- * Чекер импорта: «Файл с компьютера» или «По ссылке (URL)». Оба пути -
305
- * client-side: файл читается в браузере, URL загружается fetch-ом самого
306
- * браузера (наш сервер не участвует).
307
- */
308
203
  private openImportPicker;
309
204
  /**
310
- * Импорт файла по URL (client-side fetch браузером). Картинки вставляются
311
- * по ссылке напрямую (без скачивания - обходит CORS на отображение).
312
- * Документы скачиваются в Blob и идут тем же путём, что файл с диска;
313
- * PDF спрашивает режим (текст/картинки/встроить). Ошибки CORS/сети -
314
- * понятное событие importerror.
205
+ * Imports a file from a URL, fetched by the browser. Images are inserted by
206
+ * link without downloading, which avoids CORS restrictions on display.
207
+ * Documents are fetched into a Blob and follow the same path as a file from
208
+ * disk; for a PDF the editor asks how to insert it (text, images or
209
+ * embedded). CORS and network failures surface as an importerror event.
315
210
  */
316
211
  importFromUrl(url: string): Promise<void>;
317
- /** Единое событие об ошибке импорта. */
318
212
  private emitImportError;
319
- /**
320
- * Показывает оверлей «Обработка…» поверх редактора на время долгой операции
321
- * (парсинг PDF/конвертация). Возвращает функцию-скрывалку. Без него медленные
322
- * импорты выглядят как «клик не сработал».
323
- */
324
213
  private showLoading;
325
214
  private static readonly IMPORT_ACCEPT_ALL;
326
- /**
327
- * Открыть системный диалог выбора файла с заданным accept и импортировать
328
- * выбранный файл. Используется и атомарными кнопками (Word/PDF/Excel/Текст),
329
- * и общей кнопкой (полный accept).
330
- */
331
215
  private openFilePicker;
332
- /**
333
- * Общая обработка импортируемого файла: PDF - с выбором режима (текст/картинки/
334
- * встроить), остальное - автодетект. Индикатор загрузки + события change/importerror.
335
- */
336
216
  private handleImportedFile;
337
- /** Общая кнопка импорта «Файл с компьютера» (legacy): полный accept. */
338
217
  private pickImportFile;
339
218
  /**
340
- * Публичный API: программный импорт .docx (File/ArrayBuffer). Возвращает
341
- * предупреждения движка (неподдержанные стили, текст в текстовых полях
342
- * и т.п.) - раньше терялись здесь молча (Promise<void>), хотя editor.ts
343
- * их уже собирал; хост может их показать пользователю или проигнорировать.
219
+ * Imports a .docx programmatically (File or ArrayBuffer) and returns the
220
+ * converter's warnings - unsupported styles, text inside shapes and the
221
+ * like. Show them to the user or ignore them, as suits your application.
344
222
  */
345
223
  importDocx(source: File | ArrayBuffer): Promise<DocxImportResult | undefined>;
346
- /** Публичный API: импорт файла (.docx/.csv/.txt/.md/картинка) с автодетектом. */
224
+ /** Imports a file (.docx, .csv, .txt, .md or an image), detecting the type. */
347
225
  importFile(file: File): Promise<void>;
348
- /** Публичный API: экспорт в Markdown (скачивание .md). */
226
+ /** Exports to Markdown and downloads the .md file. */
349
227
  exportMarkdown(): void;
350
- /** Публичный API: экспорт в HTML / TXT / CSV / Word (.doc). Client-side. */
228
+ /** Exports to HTML, TXT, CSV or Word (.doc). Runs entirely in the browser. */
351
229
  exportHtml(): void;
352
230
  exportText(): void;
353
231
  exportCsv(): void;
354
232
  exportWord(): void;
355
- /** Публичный API: импорт PDF как картинок (страницы -> изображения). */
233
+ /** Imports a PDF as images, one image per page. */
356
234
  importPdfAsImages(file: File): Promise<void>;
357
- /** Публичный API: встроить PDF «как есть» (iframe, client-side). */
235
+ /** Embeds a PDF as it is, in an iframe, without converting it. */
358
236
  importPdfAsEmbed(file: File): Promise<void>;
359
- /** Публичный API: следующая вставка - только текст. */
237
+ /** Makes the next paste plain text only. */
360
238
  armPlainPaste(): void;
361
239
  /**
362
- * Публичный API: вставка «богатого» буфера из companion-расширения
363
- * (полный HTML + RTF в обход песочницы). Расширение зовёт этот метод
364
- * напрямую или через DOM-событие `koda-paste-rich`.
240
+ * Pastes rich clipboard content supplied by the companion browser
241
+ * extension (full HTML plus RTF, which the page sandbox cannot read on its
242
+ * own). The extension calls this method directly or dispatches the
243
+ * `koda-paste-rich` DOM event.
365
244
  */
366
245
  pasteRich(html: string, rtf?: string): void;
367
- /** Диалог вставки картинки: по ссылке/пути или загрузкой файла. */
368
246
  private openImageDialog;
369
- /**
370
- * Загрузка картинки: на сервер клиента (upload-url) или встраивание base64.
371
- *
372
- * Две вещи, которых здесь раньше не было:
373
- * - проверка типа и размера ДО отправки. Атрибут accept у поля выбора -
374
- * только подсказка, перетаскивание его не спрашивает;
375
- * - отказ сервера больше не подменяется тихо на data-URI. Раньше клиент,
376
- * отклонивший файл на 20 МБ, получал ровно тот же файл, но внутри
377
- * документа в base64: пользователь видел успех, а в базу уезжал
378
- * многомегабайтный кусок. Если upload-url задан, встраивание base64 -
379
- * это не «запасной путь», а тихая подмена договорённости.
380
- */
381
247
  private handleImageFile;
382
- /** Вставка картинки в редактор (ProseMirror). */
383
248
  private insertImageSmart;
384
249
  private checkLicense;
385
- /**
386
- * Агрессивный демо-знак: диагональное замощение по всей канве (фон листа,
387
- * растёт с документом и покрывает все страницы) + sticky-пилюля сверху для
388
- * доступности. Не блокирует ввод (pointer-events:none / фон).
389
- */
390
250
  private applyDemoWatermark;
391
- /** SVG-тайл с диагональным текстом знака → data-URI для background-image. */
392
251
  private demoWatermarkUri;
393
252
  getContent(): string;
394
253
  setContent(html: string): void;
395
254
  getJSON(): unknown;
396
- /** Экспорт документа в PDF (печать средствами браузера, client-side). */
255
+ /** Exports to PDF through the browser print dialog, with no server involved. */
397
256
  exportPdf(): void;
398
- /** value - как у нативного поля: чтение/запись HTML. Работает с v-model. */
257
+ /** value behaves like a native form field: reads and writes HTML. Works with v-model. */
399
258
  get value(): string;
400
259
  set value(html: string);
401
- /** Сброс формы (<form>.reset() или кнопка type=reset) - очищаем редактор. */
260
+ /** Form reset (<form>.reset() or a type=reset button) clears the editor. */
402
261
  formResetCallback(): void;
403
- /** Переключить полноэкранный режим (на весь экран, без сервера/прав). */
262
+ /** Toggles full-screen mode. */
404
263
  toggleFullscreen(): void;
405
- /** Панель найти/заменить (скрыта по умолчанию). */
406
264
  private buildSearchBar;
407
- /** Показать/скрыть панель поиска. */
265
+ /** Shows or hides the search bar. */
408
266
  toggleSearch(show?: boolean): void;
409
267
  }
410
268
  /**
411
- * Регистрирует <koda-editor>. Идемпотентно по конкретному тегу.
412
- * Для произвольного тега используется анонимный подкласс - один класс
413
- * нельзя зарегистрировать под двумя именами (define бросит ошибку).
269
+ * Registers <koda-editor>. Calling it twice for the same tag is harmless.
270
+ * A custom tag gets an anonymous subclass, because one class cannot be
271
+ * registered under two names - customElements.define would throw.
414
272
  */
415
273
  export declare function defineKodaEditor(tag?: string): void;
416
274
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kodaeditor/core",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "WYSIWYG rich-text editor as a web component. Pastes Word, Excel and Google Docs content without losing tables, lists or formatting. Self-hosted, framework-agnostic.",
5
5
  "keywords": [
6
6
  "wysiwyg",
@@ -30,7 +30,6 @@
30
30
  "main": "./dist/kodaeditor.umd.cjs",
31
31
  "module": "./dist/kodaeditor.js",
32
32
  "types": "./dist/index.d.ts",
33
- "//exports": "Два варианта поставки в ОДНОМ пакете, выбор за покупателем и без переписки с нами. По умолчанию (\".\") - полная сборка: всё внутри, ни одного обращения в сеть, это важнее веса для закрытых контуров. \"./light\" - сборка без pdf.js и xlsx (1,1 МБ вместо 3,1): их файлы лежат в \"./vendor\" и грузятся только когда пользователь реально открывает PDF или Excel. Оба варианта обфусцируются при публикации.",
34
33
  "exports": {
35
34
  ".": {
36
35
  "types": "./dist/index.d.ts",
@@ -50,17 +49,15 @@
50
49
  ],
51
50
  "scripts": {
52
51
  "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
53
- "build": "npm run clean && tsc -p tsconfig.json && vite build",
52
+ "build": "npm run clean && tsc -p tsconfig.json && node ../../scripts/strip-private-docs.mjs dist && node ../../scripts/prune-internal-types.mjs dist && vite build",
54
53
  "build:split": "vite build --config vite.config.split.ts && node ../../scripts/copy-vendor.mjs",
55
54
  "build:protected": "npm run build:split && node ../../scripts/obfuscate.mjs dist/kodaeditor-core.umd.cjs dist/kodaeditor-core.obf.umd.cjs",
56
55
  "build:standalone-protected": "npm run build && node ../../scripts/obfuscate.mjs dist/kodaeditor.js dist/kodaeditor.js && node ../../scripts/obfuscate.mjs dist/kodaeditor.umd.cjs dist/kodaeditor.umd.cjs",
57
56
  "typecheck": "tsc --noEmit",
58
57
  "test": "vitest run",
59
58
  "prepack": "npm run build:standalone-protected && npm run build:split && node ../../scripts/obfuscate.mjs dist/kodaeditor-core.umd.cjs dist/kodaeditor-core.umd.cjs && node -e \"require('fs').copyFileSync('../../LICENSE.md','LICENSE.md')\" && node ../../scripts/check-ssr-import.mjs",
60
- "//postpack": "Возвращает ОБА варианта сборки читаемыми. Оба - потому что npm run build начинается с clean и стирает лёгкую сборку вместе с vendor: после упаковки в рабочем каталоге не оставалось того, что уехало в пакет, и \"./light\" переставал резолвиться локально. prepack обфусцирует dist ПРЯМО В РАБОЧЕМ КАТАЛОГЕ. Тарбол уже собран, на его содержимое это не влияет, но разработчик остаётся с нечитаемой сборкой и теряет время, не понимая почему. Возвращаем обычную сборку сразу, а не помним об этом.",
61
59
  "postpack": "npm run build && npm run build:split"
62
60
  },
63
- "comment": "ВСЕ библиотеки ВСТРОЕНЫ в dist (один файл, inlineDynamicImports). Поэтому у пакета НЕТ runtime-зависимостей: npm i тарболла НЕ тянет ничего из npm/CDN. Сборочные либы - в devDependencies. build:protected/build:split - отдельный, сейчас НЕ используемый нигде путь поставки (лёгкий CDN-вариант без pdf.js/xlsx, грузит их с внешнего CDN vendor-хостинга) - ссылается на chayxonajon.uz, который больше не наш домен; не трогаем, не часть текущей npm-поставки. Для npm publish защищённость обеспечивает НОВЫЙ build:standalone-protected - обфусцирует именно те файлы (dist/kodaeditor.js, dist/kodaeditor.umd.cjs), на которые ссылаются main/module/exports; запускается автоматически через prepack перед npm pack/publish, поэтому руками вызывать не обязательно.",
64
61
  "devDependencies": {
65
62
  "@types/turndown": "^5.0.6",
66
63
  "dompurify": "^3.4.15",
@@ -1,15 +0,0 @@
1
- import type { Command } from 'prosemirror-state';
2
- import type { Node as PMNode } from 'prosemirror-model';
3
- import type { Strings } from './i18n';
4
- /** Создаёт узел таблицы rows×cols с шапкой в первой строке. */
5
- export declare function createTable(rows: number, cols: number): PMNode;
6
- export interface SlashItem {
7
- titleKey: keyof Strings;
8
- icon: string;
9
- keywords: string[];
10
- command: Command;
11
- }
12
- /** Пункты slash-меню (порядок = порядок показа). */
13
- export declare const SLASH_ITEMS: SlashItem[];
14
- /** Фильтр пунктов по запросу (название + ключевые слова). */
15
- export declare function filterSlashItems(query: string, strings: Strings): SlashItem[];
@@ -1,14 +0,0 @@
1
- /**
2
- * Восстановление выравнивания абзацев при импорте .docx (w:jc).
3
- *
4
- * mammoth не переносит прямое форматирование абзаца, включая text-align —
5
- * из-за этого правое выравнивание сумм/дат в ячейках таблиц (частый паттерн
6
- * реальных инвойсов) и центрированные заголовки терялись. Схема редактора
7
- * это выравнивание УЖЕ поддерживает (paragraph.attrs.align, см. schema.ts) —
8
- * не хватало только источника данных на стороне docx-импорта. Тот же
9
- * text-match паттерн, что docx-text-styles.ts использует для цвета/размера.
10
- */
11
- /** Читает .docx и возвращает text-align по тексту абзацев. Безопасно к ошибкам. */
12
- export declare function extractDocxAlignment(arrayBuffer: ArrayBuffer): Promise<Map<string, string>>;
13
- /** Накладывает text-align на блоки mammoth-вывода по тексту абзаца. */
14
- export declare function applyDocxAlignment(root: HTMLElement, alignment: Map<string, string>): void;
@@ -1,31 +0,0 @@
1
- /**
2
- * Разрывы страниц/секций при импорте .docx.
3
- *
4
- * mammoth теряет ручной разрыв страницы (Ctrl+Enter -> <w:br w:type="page"/>) и
5
- * разрыв секции «с новой страницы» (<w:sectPr> внутри w:pPr). В многостраничных
6
- * ЭДО это смысловая граница: «приложение — с новой страницы», «акт / протокол».
7
- * Без неё две страницы сливаются в сплошной поток.
8
- *
9
- * В потоковом HTML-редакторе постраничности нет, поэтому НАМЕРЕННЫЙ разрыв
10
- * показываем горизонтальной линией <hr class="koda-pagebreak"> (схема её знает —
11
- * это кнопка «Горизонтальная линия»). Автопагинацию (w:lastRenderedPageBreak —
12
- * лишь подсказка рендера) и continuous-секции НЕ трогаем: это не границы.
13
- *
14
- * Делается в два шага: (1) в document.xml на месте разрыва ставим текстовый
15
- * сентинел ДО mammoth; (2) в готовом HTML сентинел -> <hr>, разрезая абзац
16
- * через Range (корректно делит вложенное форматирование).
17
- */
18
- /** Невидимый маркер (private-use) на месте разрыва — переживает mammoth как текст. */
19
- export declare const PB_SENTINEL = "\uE000EUZPAGEBREAK\uE000";
20
- /**
21
- * Мутирует parsed document.xml: ручной page-break и параграф-уровневый sectPr
22
- * «с новой страницы» -> текстовый сентинел. Возвращает true при изменении.
23
- * Часть общего препроцессинга (один repack zip).
24
- */
25
- export declare function replaceBreaksInDoc(doc: Document): boolean;
26
- /**
27
- * В готовом HTML: сентинел -> <hr class="koda-pagebreak">. Абзац, содержащий
28
- * сентинел, разрезается через Range (хвост с сохранением вложенного
29
- * форматирования выносится в новый блок). Возвращает true при изменении.
30
- */
31
- export declare function splitPageBreaks(root: HTMLElement): boolean;
@@ -1,28 +0,0 @@
1
- /**
2
- * Чекбоксы форм при импорте .docx (анкеты ЭДО: ☒ Согласен / ☐ ...).
3
- *
4
- * mammoth теряет состояние чекбоксов: и современных content-control
5
- * (w14:checkbox), и legacy form-field (w:checkBox в w:ffData). Остаётся только
6
- * текст метки — не видно, отмечено или нет. Здесь чекбоксы заменяются в
7
- * document.xml на символ ☒ (отмечен) / ☐ (пустой) ДО mammoth, так состояние
8
- * сохраняется как читаемый символ.
9
- */
10
- /**
11
- * Мутирует parsed document.xml: чекбоксы -> ☒/☐. Возвращает true, если что-то
12
- * заменено. Чистая DOM-операция (общий repack с формулами).
13
- */
14
- export declare function replaceCheckboxesInDoc(doc: Document): boolean;
15
- /**
16
- * Разворачивает w:fldSimple: mammoth ИГНОРИРУЕТ содержимое простых полей (DATE,
17
- * NUMPAGES, REF и т.п.), теряя кэшированное значение. Здесь дети fldSimple
18
- * (последний вычисленный результат) выносятся наружу как обычные прогоны, и
19
- * значение поля сохраняется как текст. Возвращает true, если что-то развёрнуто.
20
- */
21
- export declare function unwrapSimpleFields(doc: Document): boolean;
22
- /**
23
- * Tab-лидеры (точечные/подчёркнутые линии заполнения — «Подпись.........» в
24
- * формах ЭДО) mammoth теряет вместе с табом. Здесь tab-символ в абзаце с
25
- * tab-стопом, у которого есть w:leader, заменяется на строку лид-символов —
26
- * чтобы линия для подписи/заполнения осталась видимой. Возвращает true при замене.
27
- */
28
- export declare function replaceTabLeadersInDoc(doc: Document): boolean;