@olddevs/ui 4.5.1 → 4.6.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.
- package/CHANGELOG.md +18 -0
- package/dist/editor/RichTextEditor.d.ts +2 -2
- package/dist/editor/RichTextEditor.d.ts.map +1 -1
- package/dist/editor/RichTextEditor.js +3 -0
- package/dist/editor/RichTextEditor.js.map +1 -1
- package/dist/editor/core/blockTypes.d.ts +2 -8
- package/dist/editor/core/blockTypes.d.ts.map +1 -1
- package/dist/editor/core/blockTypes.js +11 -54
- package/dist/editor/core/blockTypes.js.map +1 -1
- package/dist/editor/core/containers.d.ts.map +1 -1
- package/dist/editor/core/containers.js +1 -0
- package/dist/editor/core/containers.js.map +1 -1
- package/dist/editor/core/customMarkdown.js +1 -1
- package/dist/editor/core/customMarkdown.js.map +1 -1
- package/dist/editor/core/customTool.d.ts +6 -6
- package/dist/editor/core/customTool.d.ts.map +1 -1
- package/dist/editor/core/customToolEngine.d.ts +2 -2
- package/dist/editor/core/extensions.d.ts +7 -2
- package/dist/editor/core/extensions.d.ts.map +1 -1
- package/dist/editor/core/extensions.js +96 -64
- package/dist/editor/core/extensions.js.map +1 -1
- package/dist/editor/core/fieldNotice.d.ts +1 -1
- package/dist/editor/core/insertItems.d.ts +5 -28
- package/dist/editor/core/insertItems.d.ts.map +1 -1
- package/dist/editor/core/insertItems.js +3 -94
- package/dist/editor/core/insertItems.js.map +1 -1
- package/dist/editor/core/insertMenuTool.d.ts +13 -0
- package/dist/editor/core/insertMenuTool.d.ts.map +1 -0
- package/dist/editor/core/insertMenuTool.js +20 -0
- package/dist/editor/core/insertMenuTool.js.map +1 -0
- package/dist/editor/core/schema.d.ts +20 -5
- package/dist/editor/core/schema.d.ts.map +1 -1
- package/dist/editor/core/schema.js +18 -3
- package/dist/editor/core/schema.js.map +1 -1
- package/dist/editor/core/shortcuts.d.ts +56 -5
- package/dist/editor/core/shortcuts.d.ts.map +1 -1
- package/dist/editor/core/shortcuts.js +91 -156
- package/dist/editor/core/shortcuts.js.map +1 -1
- package/dist/editor/core/skeleton.d.ts +1 -1
- package/dist/editor/core/skeleton.d.ts.map +1 -1
- package/dist/editor/core/skeleton.js +1 -0
- package/dist/editor/core/skeleton.js.map +1 -1
- package/dist/editor/core/toolButtons.d.ts +3 -3
- package/dist/editor/core/toolDefinition.d.ts +3 -3
- package/dist/editor/core/toolDescriptor.d.ts +49 -30
- package/dist/editor/core/toolDescriptor.d.ts.map +1 -1
- package/dist/editor/core/toolDescriptor.js +2 -5
- package/dist/editor/core/toolDescriptor.js.map +1 -1
- package/dist/editor/core/toolLoader.d.ts +1 -1
- package/dist/editor/core/toolLoader.d.ts.map +1 -1
- package/dist/editor/core/toolOptions.d.ts +19 -2
- package/dist/editor/core/toolOptions.d.ts.map +1 -1
- package/dist/editor/core/toolOptions.js.map +1 -1
- package/dist/editor/core/tools.d.ts +10 -2
- package/dist/editor/core/tools.d.ts.map +1 -1
- package/dist/editor/core/tools.js +1 -0
- package/dist/editor/core/tools.js.map +1 -1
- package/dist/editor/features/builtins.d.ts +6 -8
- package/dist/editor/features/builtins.d.ts.map +1 -1
- package/dist/editor/features/builtins.js +48 -21
- package/dist/editor/features/builtins.js.map +1 -1
- package/dist/editor/features/code/codeBlockTool.d.ts +5 -6
- package/dist/editor/features/code/codeBlockTool.d.ts.map +1 -1
- package/dist/editor/features/code/codeBlockTool.js +10 -1
- package/dist/editor/features/code/codeBlockTool.js.map +1 -1
- package/dist/editor/features/color/colorTools.d.ts +14 -0
- package/dist/editor/features/color/colorTools.d.ts.map +1 -0
- package/dist/editor/features/color/colorTools.js +39 -0
- package/dist/editor/features/color/colorTools.js.map +1 -0
- package/dist/editor/features/details/details.d.ts +68 -0
- package/dist/editor/features/details/details.d.ts.map +1 -0
- package/dist/editor/features/details/details.js +237 -0
- package/dist/editor/features/details/details.js.map +1 -0
- package/dist/editor/features/details/detailsMarkdown.d.ts +17 -0
- package/dist/editor/features/details/detailsMarkdown.d.ts.map +1 -0
- package/dist/editor/features/details/detailsMarkdown.js +84 -0
- package/dist/editor/features/details/detailsMarkdown.js.map +1 -0
- package/dist/editor/features/details/detailsTool.d.ts +16 -0
- package/dist/editor/features/details/detailsTool.d.ts.map +1 -0
- package/dist/editor/features/details/detailsTool.js +39 -0
- package/dist/editor/features/details/detailsTool.js.map +1 -0
- package/dist/editor/features/emoji/emojiTool.d.ts +1 -1
- package/dist/editor/features/heading/headingTool.d.ts +18 -0
- package/dist/editor/features/heading/headingTool.d.ts.map +1 -0
- package/dist/editor/features/heading/headingTool.js +59 -0
- package/dist/editor/features/heading/headingTool.js.map +1 -0
- package/dist/editor/features/history/historyTool.d.ts +15 -0
- package/dist/editor/features/history/historyTool.d.ts.map +1 -0
- package/dist/editor/features/history/historyTool.js +28 -0
- package/dist/editor/features/history/historyTool.js.map +1 -0
- package/dist/editor/features/image/imageTool.d.ts +19 -0
- package/dist/editor/features/image/imageTool.d.ts.map +1 -0
- package/dist/editor/features/image/imageTool.js +28 -0
- package/dist/editor/features/image/imageTool.js.map +1 -0
- package/dist/editor/features/layout/layoutTool.d.ts +11 -0
- package/dist/editor/features/layout/layoutTool.d.ts.map +1 -0
- package/dist/editor/features/layout/layoutTool.js +20 -0
- package/dist/editor/features/layout/layoutTool.js.map +1 -0
- package/dist/editor/features/lists/listTools.d.ts +15 -0
- package/dist/editor/features/lists/listTools.d.ts.map +1 -0
- package/dist/editor/features/lists/listTools.js +78 -0
- package/dist/editor/features/lists/listTools.js.map +1 -0
- package/dist/editor/features/marks/markTools.d.ts +16 -0
- package/dist/editor/features/marks/markTools.d.ts.map +1 -0
- package/dist/editor/features/marks/markTools.js +43 -0
- package/dist/editor/features/marks/markTools.js.map +1 -0
- package/dist/editor/features/search/searchTool.d.ts +1 -1
- package/dist/editor/features/table/tableTool.d.ts +3 -3
- package/dist/editor/features/wrapper/wrapperTool.d.ts +11 -0
- package/dist/editor/features/wrapper/wrapperTool.d.ts.map +1 -0
- package/dist/editor/features/wrapper/wrapperTool.js +32 -0
- package/dist/editor/features/wrapper/wrapperTool.js.map +1 -0
- package/dist/editor/index.d.ts +1 -1
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js.map +1 -1
- package/dist/editor/schema-entry.d.ts +1 -1
- package/dist/editor/styles/prose.d.ts.map +1 -1
- package/dist/editor/styles/prose.js +26 -0
- package/dist/editor/styles/prose.js.map +1 -1
- package/dist/editor/ui/EditorToolbar.d.ts.map +1 -1
- package/dist/editor/ui/EditorToolbar.js +5 -38
- package/dist/editor/ui/EditorToolbar.js.map +1 -1
- package/dist/editor/ui/SelectionBubble.d.ts.map +1 -1
- package/dist/editor/ui/SelectionBubble.js +1 -1
- package/dist/editor/ui/SelectionBubble.js.map +1 -1
- package/dist/editor/ui/ToolButtonView.d.ts.map +1 -1
- package/dist/editor/ui/ToolButtonView.js +1 -1
- package/dist/editor/ui/ToolButtonView.js.map +1 -1
- package/dist/i18n/defaults.d.ts.map +1 -1
- package/dist/i18n/defaults.js +3 -0
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/messages.d.ts +16 -1
- package/dist/i18n/messages.d.ts.map +1 -1
- package/dist/icons.d.ts +8 -1
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +1 -1
- package/dist/icons.js.map +1 -1
- package/dist/locales/ru.d.ts.map +1 -1
- package/dist/locales/ru.js +3 -0
- package/dist/locales/ru.js.map +1 -1
- package/docs/api/editor-extension.en.md +56 -56
- package/docs/api/editor-extension.md +55 -55
- package/docs/api/messages.en.md +4 -1
- package/docs/api/messages.md +3 -0
- package/docs/api/migration-notes.en.md +3 -3
- package/docs/api/migration-notes.md +2 -2
- package/docs/components/content/rich-text-view.en.md +18 -12
- package/docs/components/content/rich-text-view.md +17 -11
- package/docs/components/inputs/rich-text-editor.en.md +140 -87
- package/docs/components/inputs/rich-text-editor.md +139 -86
- package/docs/conventions.en.md +2 -2
- package/docs/conventions.md +1 -1
- package/docs/getting-started.en.md +9 -9
- package/docs/getting-started.md +8 -8
- package/docs/glossary.en.md +80 -52
- package/docs/glossary.md +79 -51
- package/docs/icons.en.md +4 -1
- package/docs/icons.md +3 -0
- package/package.json +2 -1
- package/src/editor/RichTextEditor.tsx +9 -6
- package/src/editor/core/atomText.ts +2 -2
- package/src/editor/core/blockTypes.ts +19 -83
- package/src/editor/core/containers.ts +4 -2
- package/src/editor/core/customMarkdown.ts +2 -2
- package/src/editor/core/customTool.ts +6 -6
- package/src/editor/core/customToolEngine.ts +9 -9
- package/src/editor/core/extensions.ts +165 -110
- package/src/editor/core/fieldNotice.ts +1 -1
- package/src/editor/core/handle.ts +2 -2
- package/src/editor/core/insertItems.ts +12 -158
- package/src/editor/core/insertMenuTool.ts +32 -0
- package/src/editor/core/jsonDocument.ts +1 -1
- package/src/editor/core/schema.ts +42 -7
- package/src/editor/core/shortcuts.ts +116 -177
- package/src/editor/core/skeleton.ts +4 -3
- package/src/editor/core/toolButtons.ts +3 -3
- package/src/editor/core/toolDefinition.ts +4 -4
- package/src/editor/core/toolDescriptor.ts +65 -52
- package/src/editor/core/toolLoader.ts +3 -3
- package/src/editor/core/toolOptions.ts +21 -2
- package/src/editor/core/tools.ts +10 -1
- package/src/editor/core/viewIsland.ts +1 -1
- package/src/editor/features/builtins.ts +76 -41
- package/src/editor/features/code/codeBlockTool.ts +16 -8
- package/src/editor/features/color/colorTools.ts +68 -0
- package/src/editor/features/details/details.ts +389 -0
- package/src/editor/features/details/detailsMarkdown.ts +158 -0
- package/src/editor/features/details/detailsTool.ts +69 -0
- package/src/editor/features/emoji/emojiTool.tsx +1 -1
- package/src/editor/features/heading/headingTool.ts +96 -0
- package/src/editor/features/history/historyTool.ts +42 -0
- package/src/editor/features/image/imageTool.ts +49 -0
- package/src/editor/features/layout/layoutTool.ts +40 -0
- package/src/editor/features/lists/listTools.ts +112 -0
- package/src/editor/features/marks/markTools.ts +78 -0
- package/src/editor/features/search/searchTool.ts +1 -1
- package/src/editor/features/table/tableTool.ts +3 -3
- package/src/editor/features/toc/tocTool.ts +1 -1
- package/src/editor/features/wrapper/wrapperTool.ts +52 -0
- package/src/editor/index.ts +1 -0
- package/src/editor/schema-entry.ts +1 -1
- package/src/editor/styles/prose.ts +49 -0
- package/src/editor/ui/EditorToolbar.tsx +7 -50
- package/src/editor/ui/SelectionBubble.tsx +2 -5
- package/src/editor/ui/ToolButtonView.tsx +2 -1
- package/src/i18n/defaults.ts +3 -0
- package/src/i18n/messages.ts +14 -1
- package/src/icons.ts +7 -0
- package/src/locales/ru.ts +3 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Editor, Extensions } from "@tiptap/core";
|
|
2
|
+
import type { StarterKitOptions } from "@tiptap/starter-kit";
|
|
2
3
|
import type { ComponentType, ReactNode } from "react";
|
|
3
4
|
import type { UiMessages } from "../../i18n/messages.js";
|
|
4
5
|
import type { IconProps } from "../../icons.js";
|
|
@@ -21,7 +22,7 @@ import type { Tool } from "./tools.js";
|
|
|
21
22
|
* Внутреннее описание встроенного Инструмента (ADR-0058, п. 10).
|
|
22
23
|
*
|
|
23
24
|
* НАДФОРМА. Тип — надмножество будущего публичного описания своего
|
|
24
|
-
* Инструмента: те же
|
|
25
|
+
* Инструмента: те же Extensions, Признаки Блока и UI-записи, а сверху
|
|
25
26
|
* привилегии кита, которых своему Инструменту не дают (теги Схемы кита,
|
|
26
27
|
* модель содержимого, виджеты Панели, своё место в порядке поверхности).
|
|
27
28
|
* Наружу описания встроенных не экспортируются: публичны только имена и
|
|
@@ -31,36 +32,36 @@ import type { Tool } from "./tools.js";
|
|
|
31
32
|
* (`expandTools`, `features/builtins.ts`), и реестры по имени — движок, Меню
|
|
32
33
|
* вставки, «¶», справочник сочетаний и следующие за ними — читают его
|
|
33
34
|
* проекцию (`projectRecords`). Правило «выключенный Инструмент убирает и
|
|
34
|
-
* кнопку, и Схему» этим держится само: записи и
|
|
35
|
+
* кнопку, и Схему» этим держится само: записи и Extensions Инструмента,
|
|
35
36
|
* которого нет в списке, не попадают никуда.
|
|
36
37
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
38
|
+
* У КАЖДОГО ВСТРОЕННОГО — ОПИСАНИЕ: `BUILTIN_TOOLS` полон, и
|
|
39
|
+
* компилятор не даст добавить имя в `TOOLS` без описания. Место записи на
|
|
40
|
+
* поверхности держит порядок кита этой поверхности (`INSERT_ORDER`,
|
|
41
|
+
* `BLOCK_TYPE_ORDER`, `SHORTCUT_ORDER`, `ENGINE_ORDER`), а не описание. Виджеты
|
|
42
|
+
* Панели и Меню выделения, «…», подменю Ручки и поповеры картинки остаются
|
|
43
|
+
* компонентами кита и спрашивают набор по имени (`tools.has`).
|
|
43
44
|
*/
|
|
44
45
|
export interface ToolDescriptor {
|
|
45
46
|
/** Имя Инструмента — то же, что в `tools`; у своего — с Префиксом потребителя. */
|
|
46
47
|
name: Tool | PrefixedName;
|
|
47
48
|
/**
|
|
48
|
-
*
|
|
49
|
-
* старых реестрах. Остальные поля у заглушки пусты, кроме `blockActions`:
|
|
50
|
-
* Действия над Блоком переезжают отдельно от остального и
|
|
51
|
-
* читаются у всех описаний списка, переехавших и нет (`blockActionsOf`).
|
|
52
|
-
*/
|
|
53
|
-
legacy?: true;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Часть для движка: расширения Tiptap Инструмента — Node, Mark, Extension,
|
|
49
|
+
* Extensions: расширения Tiptap Инструмента — Node, Mark, Extension,
|
|
57
50
|
* плагины ProseMirror. Функция от контекста — привилегия кита: встроенным
|
|
58
51
|
* нужны мосты `RichTextEditor` (поповер ссылки, Меню вставки, `Alt+F10`).
|
|
59
52
|
* Второй аргумент — Опции этого Редактора (`options`), если они есть.
|
|
60
53
|
*/
|
|
61
54
|
engine?: (context: ToolEngineContext, options?: object) => Extensions;
|
|
62
55
|
/**
|
|
63
|
-
*
|
|
56
|
+
* Доля StarterKit: ключи `StarterKit.configure`, которые включают Блоки и
|
|
57
|
+
* Метки Инструмента (`bold: {}`, `heading: { levels }`). Привилегия кита.
|
|
58
|
+
* Доли всех описаний сливаются в ОДИН `StarterKit` (`extensions.ts`): так
|
|
59
|
+
* порядок Меток в сохранённом HTML и список пакетов движка остаются теми же,
|
|
60
|
+
* что при StarterKit целиком. Ключ, которого нет ни в одной доле, выключен.
|
|
61
|
+
*/
|
|
62
|
+
starterKit?: (context: ToolEngineContext) => Partial<StarterKitOptions>;
|
|
63
|
+
/**
|
|
64
|
+
* Загрузчик Extensions (`toolLoader.ts`): движок создаётся после
|
|
64
65
|
* загрузчиков всех описаний списка, и `engine` читает отданное `loaded`.
|
|
65
66
|
*/
|
|
66
67
|
load?: ToolLoader;
|
|
@@ -134,7 +135,7 @@ export interface ToolDescriptor {
|
|
|
134
135
|
/** Пункты виджета «¶» Панели: у него свои слова и иконки (`blockTypes.ts`). */
|
|
135
136
|
blockTypes?: readonly BlockTypeItem[];
|
|
136
137
|
/**
|
|
137
|
-
* Строки справочника сочетаний для клавиш, которые
|
|
138
|
+
* Строки справочника сочетаний для клавиш, которые вешают Extensions
|
|
138
139
|
* (`shortcuts.ts`): у записи сочетание — её поле, а у Метки из движка — нет.
|
|
139
140
|
*/
|
|
140
141
|
shortcuts?: readonly ShortcutCommand[];
|
|
@@ -189,8 +190,16 @@ export interface ToolBridge {
|
|
|
189
190
|
/** Символ-триггер Инструмента в списке описаний: публичная запись и имя владельца для сообщений. */
|
|
190
191
|
export type TriggerRecord = CustomTrigger & { tool: string };
|
|
191
192
|
|
|
192
|
-
/**
|
|
193
|
-
|
|
193
|
+
/**
|
|
194
|
+
* Что Extensions встроенного Инструмента получают от `RichTextEditor`: мосты и —
|
|
195
|
+
* вместо всего набора — вопрос `has`. Связи между Инструментами (уровни
|
|
196
|
+
* заголовка при `heading1`, Обёртка в колонке Раскладки, очистка формата)
|
|
197
|
+
* спрашивают его, а не список описаний.
|
|
198
|
+
*/
|
|
199
|
+
export type ToolEngineContext = Omit<EditorExtensionOptions, "tools"> & {
|
|
200
|
+
/** Включён ли Инструмент кита в этом Редакторе. */
|
|
201
|
+
has: (tool: Tool) => boolean;
|
|
202
|
+
};
|
|
194
203
|
|
|
195
204
|
type EditorMessages = UiMessages["editor"];
|
|
196
205
|
|
|
@@ -276,24 +285,38 @@ export type ToolButton = ToolButtonFields &
|
|
|
276
285
|
* Кнопка встроенного Инструмента: публичная форма и привилегии кита, которых
|
|
277
286
|
* своей кнопке не дают.
|
|
278
287
|
*/
|
|
279
|
-
export type KitToolButton = ToolButton &
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
288
|
+
export type KitToolButton = ToolButton &
|
|
289
|
+
(
|
|
290
|
+
| {
|
|
291
|
+
/**
|
|
292
|
+
* Сочетание, которое вешает не кит, а Extensions (`undoRedo` у
|
|
293
|
+
* StarterKit, `Mod-B` у Метки): только подпись — подсказка,
|
|
294
|
+
* `aria-keyshortcuts` и строка справочника. Взаимоисключимо с
|
|
295
|
+
* `shortcut`: та и вешает клавишу, и подписывает её, и две привязки
|
|
296
|
+
* одной клавиши спорили бы.
|
|
297
|
+
*/
|
|
298
|
+
keys: readonly string[];
|
|
299
|
+
shortcut?: undefined;
|
|
300
|
+
}
|
|
301
|
+
| { keys?: undefined }
|
|
302
|
+
) & {
|
|
287
303
|
/**
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
* (поповер ссылки).
|
|
304
|
+
* Группа справочника сочетаний. Нет — строка встаёт в группу Инструмента без
|
|
305
|
+
* заголовка после групп кита, как у своего Инструмента.
|
|
291
306
|
*/
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
|
|
307
|
+
shortcutGroup?: ShortcutGroup;
|
|
308
|
+
/** Рамка поповера, если она не умолчание кита (у кнопки, по содержимому). */
|
|
309
|
+
popoverFrame?: {
|
|
310
|
+
/**
|
|
311
|
+
* `selection` — рамка всегда у выделения, и щелчком по кнопке тоже: поповер
|
|
312
|
+
* правит выделенный текст, и стоит у него при любом способе открыть
|
|
313
|
+
* (поповер ссылки).
|
|
314
|
+
*/
|
|
315
|
+
anchor?: "selection";
|
|
316
|
+
/** Классы размера и отступов рамки вместо умолчания `w-auto p-2`. */
|
|
317
|
+
className?: string;
|
|
318
|
+
};
|
|
295
319
|
};
|
|
296
|
-
};
|
|
297
320
|
|
|
298
321
|
/** Действие над Блоком: пункт меню Ручки Блока, в секции Инструмента перед «Удалить». */
|
|
299
322
|
export interface BlockAction {
|
|
@@ -338,9 +361,9 @@ export interface TextCardRecord {
|
|
|
338
361
|
* Развёрнутый набор Инструментов: список описаний и — как `Set` — имена
|
|
339
362
|
* включённых Инструментов кита.
|
|
340
363
|
*
|
|
341
|
-
* Набор имён — тоже проекция списка:
|
|
342
|
-
*
|
|
343
|
-
*
|
|
364
|
+
* Набор имён — тоже проекция списка: виджеты кита, которые спрашивают набор по
|
|
365
|
+
* имени (`tools.has("table")`), читают его без правок. Свои Инструменты есть
|
|
366
|
+
* только в списке описаний.
|
|
344
367
|
*/
|
|
345
368
|
export interface ToolList extends ReadonlySet<Tool> {
|
|
346
369
|
/**
|
|
@@ -350,8 +373,8 @@ export interface ToolList extends ReadonlySet<Tool> {
|
|
|
350
373
|
*/
|
|
351
374
|
readonly error?: string;
|
|
352
375
|
/**
|
|
353
|
-
* Описания включённых Инструментов: встроенные в порядке
|
|
354
|
-
*
|
|
376
|
+
* Описания включённых Инструментов: встроенные в порядке кита, за ними
|
|
377
|
+
* свои в порядке `tools`.
|
|
355
378
|
*/
|
|
356
379
|
readonly descriptors: readonly ToolDescriptor[];
|
|
357
380
|
}
|
|
@@ -380,11 +403,6 @@ export function toolOptions<Name extends ConfigurableToolName>(
|
|
|
380
403
|
return descriptor?.options as RichTextTools[Name]["options"] | undefined;
|
|
381
404
|
}
|
|
382
405
|
|
|
383
|
-
/** Описания переехавших Инструментов набора — в порядке списка. */
|
|
384
|
-
export function describedTools(tools: ToolList): readonly ToolDescriptor[] {
|
|
385
|
-
return tools.descriptors.filter((descriptor) => !descriptor.legacy);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
406
|
/**
|
|
389
407
|
* Действия над Блоком набора — проекция списка описаний, в порядке кита. Фильтра
|
|
390
408
|
* по Блоку здесь нет: имя и предикат видимости спрашивает меню Ручки на
|
|
@@ -429,7 +447,6 @@ export function blockActionVisible(
|
|
|
429
447
|
* - `order` — место встроенных Инструментов на поверхности, привилегия кита.
|
|
430
448
|
* Инструменты набора вне него идут следом, в порядке списка: так встаёт
|
|
431
449
|
* запись, у которой своего места на поверхности нет.
|
|
432
|
-
* - `legacy` — старый реестр: записи Инструмента, ещё не переехавшего на описание.
|
|
433
450
|
* - `own` — поле описания с записями этой поверхности.
|
|
434
451
|
*
|
|
435
452
|
* Фильтра по включённым Инструментам здесь нет: его держит сам список.
|
|
@@ -437,14 +454,10 @@ export function blockActionVisible(
|
|
|
437
454
|
export function projectRecords<R>(
|
|
438
455
|
tools: ToolList,
|
|
439
456
|
order: readonly Tool[],
|
|
440
|
-
legacy: (name: Tool) => readonly R[] | undefined,
|
|
441
457
|
own: (descriptor: ToolDescriptor) => readonly R[] | undefined
|
|
442
458
|
): R[] {
|
|
443
459
|
const list = tools.descriptors;
|
|
444
460
|
const placed = order.flatMap((name) => list.filter((descriptor) => descriptor.name === name));
|
|
445
461
|
const rest = list.filter((descriptor) => !(order as readonly string[]).includes(descriptor.name));
|
|
446
|
-
return [...placed, ...rest].flatMap(
|
|
447
|
-
// Заглушка `legacy` бывает только у встроенного: имя — из `Tool`.
|
|
448
|
-
(descriptor) => (descriptor.legacy ? legacy(descriptor.name as Tool) : own(descriptor)) ?? []
|
|
449
|
-
);
|
|
462
|
+
return [...placed, ...rest].flatMap((descriptor) => own(descriptor) ?? []);
|
|
450
463
|
}
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
import { devError } from "../../lib/dev-warn.js";
|
|
4
4
|
|
|
5
5
|
/*
|
|
6
|
-
Загрузчики
|
|
6
|
+
Загрузчики Extensions (ADR-0058, п. 1.3 и 11.3–11.6).
|
|
7
7
|
|
|
8
8
|
Промис кэшируется на самой функции загрузчика, а не на Редакторе: второй
|
|
9
9
|
Редактор на странице с тем же Инструментом ничего не ждёт и загрузчик не
|
|
10
10
|
зовёт. Упавший остаётся в кэше упавшим — иначе каждая перерисовка звала бы
|
|
11
11
|
его снова; заново его зовёт только «Повторить» (`retry`). Механизм общий:
|
|
12
|
-
встроенный Инструмент с
|
|
12
|
+
встроенный Инструмент с ленивыми Extensions кладёт свой загрузчик в
|
|
13
13
|
то же поле описания (`ToolDescriptor.load`).
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
/** Загрузчик
|
|
16
|
+
/** Загрузчик Extensions: функция с динамическим импортом. */
|
|
17
17
|
export type ToolLoader = () => Promise<unknown>;
|
|
18
18
|
|
|
19
19
|
/** Ход загрузки: промис не отклоняется никогда, итог — в `done` или `failed`. */
|
|
@@ -59,10 +59,25 @@ export interface TocToolOptions {
|
|
|
59
59
|
listWidth: number | string;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Опции Инструмента `details` (по расширению Details из Tiptap, ADR-0048).
|
|
64
|
+
*/
|
|
65
|
+
export interface DetailsToolOptions {
|
|
66
|
+
/**
|
|
67
|
+
* Пишется ли открытость Блока в Документ: открытый Блок сохраняется с
|
|
68
|
+
* `open` и открытым же отдаётся в `RichTextView`. По умолчанию `false`, как
|
|
69
|
+
* у Tiptap: раскрытый при правке Блок не публикуется раскрытым без спроса,
|
|
70
|
+
* открытость живёт только в показе (в Редакторе и в Просмотре читатель
|
|
71
|
+
* открывает Блок сам). Со `true` Блок, вставленный из Меню вставки, сразу
|
|
72
|
+
* открыт и пишет `open`, а `open` из `value` и вставки читается.
|
|
73
|
+
*/
|
|
74
|
+
persist: boolean;
|
|
75
|
+
}
|
|
76
|
+
|
|
62
77
|
/**
|
|
63
78
|
* Типы Инструментов Редактора по имени: что экран задаёт при настройке (`options`),
|
|
64
79
|
* что читает (`state`) и что вызывает (`commands`). Расширяемый интерфейс, как
|
|
65
|
-
* `Storage` и `Commands` у Tiptap: кит объявляет в нём `search` и `
|
|
80
|
+
* `Storage` и `Commands` у Tiptap: кит объявляет в нём `search`, `toc` и `details`, а
|
|
66
81
|
* потребитель дописывает свои Инструменты через declaration merging:
|
|
67
82
|
*
|
|
68
83
|
* ```ts
|
|
@@ -92,6 +107,10 @@ export interface RichTextTools {
|
|
|
92
107
|
state: TocToolState;
|
|
93
108
|
commands: TocToolCommands;
|
|
94
109
|
};
|
|
110
|
+
// Только Опции: Состояния и Команд у сворачиваемого Блока нет.
|
|
111
|
+
details: {
|
|
112
|
+
options: DetailsToolOptions;
|
|
113
|
+
};
|
|
95
114
|
}
|
|
96
115
|
|
|
97
116
|
/**
|
|
@@ -182,7 +201,7 @@ export function mergeOptions(base: object, given: object): object {
|
|
|
182
201
|
* опции (из JS без типов) заменяется умолчанием, в разработке — один
|
|
183
202
|
* `console.error`; опции своего Инструмента проверяет его автор.
|
|
184
203
|
*
|
|
185
|
-
* Встроенный — только Инструмент с опциями: `search` и `
|
|
204
|
+
* Встроенный — только Инструмент с опциями: `search`, `toc` и `details`. Серверно-безопасна.
|
|
186
205
|
*/
|
|
187
206
|
export function tool<Name extends ConfigurableToolName>(
|
|
188
207
|
name: Name,
|
package/src/editor/core/tools.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* новым именем для него не ломающее. Зато имя без реализации стало бы
|
|
16
16
|
* молчаливой ловушкой: `tools={["x"]}` компилировался бы и ничего не давал.
|
|
17
17
|
* Так пришли `link`, `color`, `highlight`, `align`, `table`, `image`, `emoji`,
|
|
18
|
-
* `layout`, `wrapper` и `source`; зарезервированных имён сейчас нет.
|
|
18
|
+
* `layout`, `wrapper`, `details` и `source`; зарезервированных имён сейчас нет.
|
|
19
19
|
*
|
|
20
20
|
* `heading1` — заголовок первого уровня, надстройка над `heading`:
|
|
21
21
|
* с ним уровни Блока — 1–4, без него — 2–4. Отдельным инструментом он стоит
|
|
@@ -44,6 +44,14 @@
|
|
|
44
44
|
* Выключенный инструмент разворачивает Обёртку из вставки и `value` в Блоки
|
|
45
45
|
* подряд. В `basic` её нет по той же причине, что и Раскладки.
|
|
46
46
|
*
|
|
47
|
+
* `details` — сворачиваемый Блок: заголовок (`summary`) и содержимое из Блоков
|
|
48
|
+
* (`details.ts`), API по расширению Details из Tiptap (ADR-0048: заказчика при
|
|
49
|
+
* выпуске не было). Кнопки Панели у него нет — Меню вставки и меню ручки.
|
|
50
|
+
* Выключенный инструмент разворачивает Блок из вставки и `value`: заголовок
|
|
51
|
+
* становится абзацем, содержимое идёт Блоками следом. Есть в `full`, в `basic`
|
|
52
|
+
* нет — по той же причине, что у Раскладки и Обёртки. Открытость в Документ
|
|
53
|
+
* пишет Опция `tool("details", { persist: true })`.
|
|
54
|
+
*
|
|
47
55
|
* `source` — HTML-режим: кнопка «HTML» фиксированной Панели меняет
|
|
48
56
|
* Документ на поле с его исходным HTML, а выход применяет правку через Схему,
|
|
49
57
|
* как входящий `value`. Своей Схемы у него нет, как у `clearFormatting`:
|
|
@@ -88,6 +96,7 @@ export const TOOLS = [
|
|
|
88
96
|
"image",
|
|
89
97
|
"layout",
|
|
90
98
|
"wrapper",
|
|
99
|
+
"details",
|
|
91
100
|
"emoji",
|
|
92
101
|
"source",
|
|
93
102
|
"search",
|
|
@@ -7,7 +7,7 @@ import { customToolOf } from "./toolDefinition.js";
|
|
|
7
7
|
|
|
8
8
|
Модуль серверный: `RichTextView` выбирает из `tools` лишь то, что нужно
|
|
9
9
|
острову, и отдаёт клиентскому компоненту ссылки на Острова — описание целиком
|
|
10
|
-
(
|
|
10
|
+
(Extensions, функции) через границу RSC не пройдёт. Выбор идёт по
|
|
11
11
|
Документу, как `hasCodeBlocks` у «Копировать»: Остров Блока, которого в
|
|
12
12
|
Документе нет, в клиентский граф не попадает, а значит, и его код не грузится.
|
|
13
13
|
*/
|
|
@@ -2,13 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
import Blockquote from "@tiptap/extension-blockquote";
|
|
4
4
|
import HorizontalRule from "@tiptap/extension-horizontal-rule";
|
|
5
|
-
import { DividerIcon, QuoteIcon
|
|
5
|
+
import { DividerIcon, QuoteIcon } from "../../icons.js";
|
|
6
6
|
import { turnIntoTypes } from "../core/blockTypes.js";
|
|
7
7
|
import type { InsertItem } from "../core/insertItems.js";
|
|
8
|
-
import
|
|
8
|
+
import { INSERT_MENU_TOOL } from "../core/insertMenuTool.js";
|
|
9
|
+
import { SHORTCUT_KEYS, type ShortcutCommand } from "../core/shortcuts.js";
|
|
10
|
+
import { ALIGN_TOOL, COLOR_TOOL, HIGHLIGHT_TOOL } from "./color/colorTools.js";
|
|
9
11
|
import { CODE_BLOCK_TOOL } from "./code/codeBlockTool.js";
|
|
12
|
+
import { DETAILS_TOOL } from "./details/detailsTool.js";
|
|
10
13
|
import { EMOJI_TOOL } from "./emoji/emojiTool.js";
|
|
14
|
+
import { HEADING1_TOOL, HEADING_TOOL } from "./heading/headingTool.js";
|
|
15
|
+
import { HISTORY_TOOL } from "./history/historyTool.js";
|
|
16
|
+
import { IMAGE_TOOL } from "./image/imageTool.js";
|
|
17
|
+
import { LAYOUT_TOOL } from "./layout/layoutTool.js";
|
|
11
18
|
import { LINK_TOOL } from "./link/linkTool.js";
|
|
19
|
+
import { BULLET_LIST_TOOL, ORDERED_LIST_TOOL, TASK_LIST_TOOL } from "./lists/listTools.js";
|
|
20
|
+
import {
|
|
21
|
+
BOLD_TOOL,
|
|
22
|
+
CODE_TOOL,
|
|
23
|
+
ITALIC_TOOL,
|
|
24
|
+
STRIKE_TOOL,
|
|
25
|
+
SUBSCRIPT_TOOL,
|
|
26
|
+
SUPERSCRIPT_TOOL,
|
|
27
|
+
UNDERLINE_TOOL,
|
|
28
|
+
} from "./marks/markTools.js";
|
|
12
29
|
import { devError } from "../../lib/dev-warn.js";
|
|
13
30
|
import type { ToolEntry } from "../core/customTool.js";
|
|
14
31
|
import { describeCustomTool, describeDefinition } from "../core/customToolEngine.js";
|
|
@@ -18,14 +35,14 @@ import { SEARCH_TOOL } from "./search/searchTool.js";
|
|
|
18
35
|
import { TABLE_TOOL } from "./table/tableTool.js";
|
|
19
36
|
import { TOC_TOOL } from "./toc/tocTool.js";
|
|
20
37
|
import { resolveTools, TOOLS, type RichTextEditorPreset, type Tool } from "../core/tools.js";
|
|
21
|
-
import {
|
|
38
|
+
import { WRAPPER_TOOL } from "./wrapper/wrapperTool.js";
|
|
22
39
|
|
|
23
40
|
/** Сочетание цитаты: одна запись на справочник, Меню вставки и «¶». */
|
|
24
41
|
const BLOCKQUOTE_SHORTCUT: ShortcutCommand = {
|
|
25
42
|
id: "blockquote",
|
|
26
43
|
group: "blockType",
|
|
27
44
|
tool: "blockquote",
|
|
28
|
-
keys:
|
|
45
|
+
keys: SHORTCUT_KEYS.blockquote,
|
|
29
46
|
label: (m) => m.blockquote,
|
|
30
47
|
};
|
|
31
48
|
|
|
@@ -43,47 +60,27 @@ const BLOCKQUOTE_ITEMS: readonly InsertItem[] = [
|
|
|
43
60
|
];
|
|
44
61
|
|
|
45
62
|
/**
|
|
46
|
-
* Описания встроенных
|
|
47
|
-
* (ADR-0058, п. 10; тип — `toolDescriptor.ts`).
|
|
63
|
+
* Описания встроенных Инструментов (ADR-0058, п. 10; тип — `toolDescriptor.ts`).
|
|
48
64
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* их не ждёт.
|
|
65
|
+
* Запись полная, по каждому имени `TOOLS`: встроенный Инструмент
|
|
66
|
+
* берётся только из описания, старых реестров по имени нет, и компилятор не
|
|
67
|
+
* пропустит новое имя без описания. Виджеты Панели и Меню выделения остаются
|
|
68
|
+
* компонентами кита и спрашивают набор по имени.
|
|
54
69
|
*/
|
|
55
|
-
export const BUILTIN_TOOLS:
|
|
70
|
+
export const BUILTIN_TOOLS: Record<Tool, ToolDescriptor> = {
|
|
56
71
|
search: SEARCH_TOOL,
|
|
57
72
|
// Оглавление несёт только Опции: полоса и список рисуются в `RichTextEditor`.
|
|
58
73
|
toc: TOC_TOOL,
|
|
74
|
+
layout: LAYOUT_TOOL,
|
|
75
|
+
color: COLOR_TOOL,
|
|
76
|
+
highlight: HIGHLIGHT_TOOL,
|
|
77
|
+
align: ALIGN_TOOL,
|
|
78
|
+
wrapper: WRAPPER_TOOL,
|
|
79
|
+
details: DETAILS_TOOL,
|
|
59
80
|
/*
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
*/
|
|
64
|
-
wrapper: {
|
|
65
|
-
name: "wrapper",
|
|
66
|
-
legacy: true,
|
|
67
|
-
blockActions: [
|
|
68
|
-
{
|
|
69
|
-
id: "unwrap",
|
|
70
|
-
label: (messages) => messages.unwrap,
|
|
71
|
-
icon: UnwrapIcon,
|
|
72
|
-
blocks: [WRAPPER_NODE],
|
|
73
|
-
// Одна правка: Блоки встают на место Обёртки, отмена — одна.
|
|
74
|
-
run: (editor, pos) =>
|
|
75
|
-
void editor
|
|
76
|
-
.chain()
|
|
77
|
-
.focus()
|
|
78
|
-
.command(({ tr }) => unwrapWrapperAt(tr, pos))
|
|
79
|
-
.run(),
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
/*
|
|
84
|
-
Проверочный набор: Инструмент с пунктом вставки и Инструмент
|
|
85
|
-
с «Превратить в». Поля `insertItems` и `engine` совпадают с будущим
|
|
86
|
-
публичным описанием, чтобы его форма проверялась кодом кита.
|
|
81
|
+
Разделитель и цитата: Инструмент с пунктом вставки и Инструмент с
|
|
82
|
+
«Превратить в». Поля `insertItems` и `engine` те же, что у публичного
|
|
83
|
+
описания своего Инструмента: форму проверяет код кита.
|
|
87
84
|
*/
|
|
88
85
|
horizontalRule: {
|
|
89
86
|
name: "horizontalRule",
|
|
@@ -109,11 +106,49 @@ export const BUILTIN_TOOLS: Partial<Record<Tool, ToolDescriptor>> = {
|
|
|
109
106
|
// Клавишу вешает расширение Tiptap; строка справочника — подпись к ней.
|
|
110
107
|
shortcuts: [BLOCKQUOTE_SHORTCUT],
|
|
111
108
|
},
|
|
109
|
+
history: HISTORY_TOOL,
|
|
110
|
+
bold: BOLD_TOOL,
|
|
111
|
+
italic: ITALIC_TOOL,
|
|
112
|
+
underline: UNDERLINE_TOOL,
|
|
113
|
+
strike: STRIKE_TOOL,
|
|
114
|
+
code: CODE_TOOL,
|
|
115
|
+
superscript: SUPERSCRIPT_TOOL,
|
|
116
|
+
subscript: SUBSCRIPT_TOOL,
|
|
117
|
+
heading: HEADING_TOOL,
|
|
118
|
+
heading1: HEADING1_TOOL,
|
|
112
119
|
link: LINK_TOOL,
|
|
120
|
+
bulletList: BULLET_LIST_TOOL,
|
|
121
|
+
orderedList: ORDERED_LIST_TOOL,
|
|
122
|
+
taskList: TASK_LIST_TOOL,
|
|
123
|
+
image: IMAGE_TOOL,
|
|
113
124
|
emoji: EMOJI_TOOL,
|
|
125
|
+
insertMenu: INSERT_MENU_TOOL,
|
|
126
|
+
/*
|
|
127
|
+
Своего расширения у «Очистить форматирование» нет: клавишу `⌘\` держит
|
|
128
|
+
`BlockCommands` ядра (он спрашивает `has("clearFormatting")`), а кнопка в
|
|
129
|
+
«…» — виджет кита. В описании — только строка справочника.
|
|
130
|
+
*/
|
|
131
|
+
clearFormatting: {
|
|
132
|
+
name: "clearFormatting",
|
|
133
|
+
shortcuts: [
|
|
134
|
+
{
|
|
135
|
+
id: "clearFormatting",
|
|
136
|
+
group: "clear",
|
|
137
|
+
tool: "clearFormatting",
|
|
138
|
+
keys: SHORTCUT_KEYS.clearFormatting,
|
|
139
|
+
label: (m) => m.clearFormatting,
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
/*
|
|
144
|
+
HTML-режим — виджет «HTML» Панели и режим `RichTextEditor`, показ по
|
|
145
|
+
`has("source")`. Ни Схемы, ни записей у Инструмента нет, но описание
|
|
146
|
+
есть у каждого встроенного — даже пустое.
|
|
147
|
+
*/
|
|
148
|
+
source: { name: "source" },
|
|
114
149
|
/*
|
|
115
150
|
Ленивые встроенные (ADR-0058, п. 11.1): их нет в `basic`, а
|
|
116
|
-
|
|
151
|
+
Extensions тяжелее 10 кБ gzip, поэтому они грузятся загрузчиком
|
|
117
152
|
(`load`) — тем же, что у своего Инструмента.
|
|
118
153
|
*/
|
|
119
154
|
codeBlock: CODE_BLOCK_TOOL,
|
|
@@ -184,7 +219,7 @@ export function expandTools(
|
|
|
184
219
|
);
|
|
185
220
|
const builtin = TOOLS.filter((name) => names.has(name)).map((name) =>
|
|
186
221
|
resolveOptions(
|
|
187
|
-
BUILTIN_TOOLS[name]
|
|
222
|
+
BUILTIN_TOOLS[name],
|
|
188
223
|
configured.find((entry) => entry.name === name)
|
|
189
224
|
)
|
|
190
225
|
);
|
|
@@ -5,7 +5,7 @@ import { CodeBlockIcon } from "../../../icons.js";
|
|
|
5
5
|
// Только тип: статический импорт модуля втянул бы чанк в «старт».
|
|
6
6
|
import type * as CodeBlockChunk from "./codeBlock.js";
|
|
7
7
|
import { normalizeCodeLanguage, type CodeLanguageId } from "./codeLanguages.js";
|
|
8
|
-
import { shortcutKeys } from "../../core/shortcuts.js";
|
|
8
|
+
import { SHORTCUT_KEYS, shortcutKeys } from "../../core/shortcuts.js";
|
|
9
9
|
import type { ToolDescriptor } from "../../core/toolDescriptor.js";
|
|
10
10
|
import { loaded } from "../../core/toolLoader.js";
|
|
11
11
|
|
|
@@ -57,22 +57,30 @@ const CodeBlockShape = Node.create({
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Блок кода на описании Инструмента (ADR-0058, п. 11.1): его нет в
|
|
60
|
-
* `basic`, а
|
|
60
|
+
* `basic`, а Extensions тяжелее 10 кБ, поэтому они грузятся тем же
|
|
61
61
|
* загрузчиком, что у своего Инструмента. До загрузки Редактор с блоком кода —
|
|
62
62
|
* Скелет (`RichTextEditor.tsx`).
|
|
63
63
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* переезжают позже (ADR-0058, «Последствия»).
|
|
64
|
+
* Сочетание `Mod+Alt+C` вешает расширение, поэтому строка справочника — только
|
|
65
|
+
* подпись (`shortcuts`); клавиши пунктов меню и «Формат ›» берутся из
|
|
66
|
+
* `SHORTCUT_KEYS`, место строки — из `SHORTCUT_ORDER`. Кнопка «Блок кода» меню
|
|
67
|
+
* «…» и «¶» — виджеты Панели и остаются у кита.
|
|
69
68
|
*/
|
|
70
69
|
export const CODE_BLOCK_TOOL: ToolDescriptor = {
|
|
71
70
|
name: "codeBlock",
|
|
72
71
|
load: loadCodeBlock,
|
|
72
|
+
shortcuts: [
|
|
73
|
+
{
|
|
74
|
+
id: "codeBlock",
|
|
75
|
+
group: "blockType",
|
|
76
|
+
tool: "codeBlock",
|
|
77
|
+
keys: SHORTCUT_KEYS.codeBlock,
|
|
78
|
+
label: (m) => m.codeBlock,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
73
81
|
/*
|
|
74
82
|
`Alt+F10` блока кода (в кнопку языка) обязан сработать раньше общего
|
|
75
|
-
`ToolbarFocus`:
|
|
83
|
+
`ToolbarFocus`: Extensions описаний регистрируются после него
|
|
76
84
|
(`extensions.ts`), а из равных по приоритету Tiptap первым опрашивает
|
|
77
85
|
зарегистрированное последним.
|
|
78
86
|
*/
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { SHORTCUT_KEYS } from "../../core/shortcuts.js";
|
|
4
|
+
import type { ToolDescriptor } from "../../core/toolDescriptor.js";
|
|
5
|
+
import {
|
|
6
|
+
HighlightExtension,
|
|
7
|
+
TEXT_COLOR_EXTENSIONS,
|
|
8
|
+
TextAlignExtension,
|
|
9
|
+
} from "./styleExtensions.js";
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
Цвет, маркер и выравнивание пишут `data-color` и `data-align`, а не `style`
|
|
13
|
+
(`styleExtensions.ts`; единственное исключение — цвет автора, `customColor.ts`):
|
|
14
|
+
выключенный Инструмент не отдаёт ни атрибута, ни правила разбора, и такой
|
|
15
|
+
атрибут из вставки отбрасывается.
|
|
16
|
+
|
|
17
|
+
Виджеты — «Маркер» на Панели, «Цвет» и «Маркер» в Меню выделения
|
|
18
|
+
(`ColorMenus.tsx`, `SelectionBubble.tsx`) и ленивый поповер своего цвета —
|
|
19
|
+
остаются у кита, показ по `has(name)`. Сочетаний и пунктов вставки у цвета
|
|
20
|
+
и маркера нет, поэтому их описания — только Extensions.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** Цвет текста: Метка `textStyle` с `data-color` и цвет автора. */
|
|
24
|
+
export const COLOR_TOOL: ToolDescriptor = {
|
|
25
|
+
name: "color",
|
|
26
|
+
engine: () => TEXT_COLOR_EXTENSIONS,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** Маркер: Метка `highlight` с `data-color` (несколько цветов). */
|
|
30
|
+
export const HIGHLIGHT_TOOL: ToolDescriptor = {
|
|
31
|
+
name: "highlight",
|
|
32
|
+
engine: () => [HighlightExtension],
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Выравнивание: `data-align` на абзаце и заголовке.
|
|
37
|
+
*
|
|
38
|
+
* Клавиши `Mod-Shift-L/E/R` вешает само расширение, а три строки справочника —
|
|
39
|
+
* подпись к ним. Меню «Выравнивание ▾» (`AlignMenu`, `FormatMenus.tsx`) — виджет
|
|
40
|
+
* кита, он читает те же сочетания из `SHORTCUT_KEYS`.
|
|
41
|
+
*/
|
|
42
|
+
export const ALIGN_TOOL: ToolDescriptor = {
|
|
43
|
+
name: "align",
|
|
44
|
+
engine: () => [TextAlignExtension],
|
|
45
|
+
shortcuts: [
|
|
46
|
+
{
|
|
47
|
+
id: "alignLeft",
|
|
48
|
+
group: "align",
|
|
49
|
+
tool: "align",
|
|
50
|
+
keys: SHORTCUT_KEYS.alignLeft,
|
|
51
|
+
label: (m) => m.alignLeft,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "alignCenter",
|
|
55
|
+
group: "align",
|
|
56
|
+
tool: "align",
|
|
57
|
+
keys: SHORTCUT_KEYS.alignCenter,
|
|
58
|
+
label: (m) => m.alignCenter,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "alignRight",
|
|
62
|
+
group: "align",
|
|
63
|
+
tool: "align",
|
|
64
|
+
keys: SHORTCUT_KEYS.alignRight,
|
|
65
|
+
label: (m) => m.alignRight,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
};
|