@blocknote/core 0.29.1 → 0.30.1
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/README.md +125 -0
- package/dist/blocknote.cjs +9 -9
- package/dist/blocknote.cjs.map +1 -1
- package/dist/blocknote.js +1501 -1359
- package/dist/blocknote.js.map +1 -1
- package/dist/comments.cjs.map +1 -1
- package/dist/comments.js.map +1 -1
- package/dist/locales.cjs +1 -1
- package/dist/locales.cjs.map +1 -1
- package/dist/locales.js +751 -9
- package/dist/locales.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +7 -8
- package/src/api/README.md +1 -1
- package/src/api/blockManipulation/commands/insertBlocks/__snapshots__/insertBlocks.test.ts.snap +0 -7
- package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.test.ts +19 -14
- package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +5 -5
- package/src/api/blockManipulation/commands/mergeBlocks/__snapshots__/mergeBlocks.test.ts.snap +0 -5
- package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.ts +3 -3
- package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts +12 -12
- package/src/api/blockManipulation/commands/moveBlocks/__snapshots__/moveBlocks.test.ts.snap +0 -20
- package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.test.ts +14 -14
- package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.ts +16 -16
- package/src/api/blockManipulation/commands/nestBlock/nestBlock.ts +8 -8
- package/src/api/blockManipulation/commands/replaceBlocks/__snapshots__/replaceBlocks.test.ts.snap +0 -12
- package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.ts +12 -12
- package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +7 -7
- package/src/api/blockManipulation/commands/splitBlock/__snapshots__/splitBlock.test.ts.snap +0 -6
- package/src/api/blockManipulation/commands/splitBlock/splitBlock.test.ts +10 -10
- package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +2 -2
- package/src/api/blockManipulation/commands/updateBlock/__snapshots__/updateBlock.test.ts.snap +0 -17
- package/src/api/blockManipulation/commands/updateBlock/updateBlock.test.ts +42 -42
- package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +18 -18
- package/src/api/blockManipulation/getBlock/getBlock.ts +9 -9
- package/src/api/blockManipulation/insertContentAt.ts +1 -1
- package/src/api/blockManipulation/selections/selection.ts +11 -11
- package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.ts +7 -7
- package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.ts +6 -6
- package/src/api/blockManipulation/tables/tables.test.ts +106 -106
- package/src/api/blockManipulation/tables/tables.ts +35 -35
- package/src/api/clipboard/fromClipboard/fileDropExtension.ts +2 -2
- package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +9 -9
- package/src/api/clipboard/fromClipboard/handleVSCodePaste.ts +3 -3
- package/src/api/clipboard/fromClipboard/pasteExtension.ts +21 -3
- package/src/api/clipboard/toClipboard/copyExtension.ts +22 -22
- package/src/api/exporters/html/externalHTMLExporter.ts +6 -6
- package/src/api/exporters/html/internalHTMLSerializer.ts +3 -3
- package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +16 -16
- package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +14 -14
- package/src/api/exporters/markdown/markdownExporter.ts +3 -3
- package/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts +3 -3
- package/src/api/getBlockInfoFromPos.ts +6 -6
- package/src/api/nodeConversions/blockToNode.ts +26 -26
- package/src/api/nodeConversions/fragmentToBlocks.ts +1 -1
- package/src/api/nodeConversions/nodeToBlock.ts +37 -33
- package/src/api/nodeUtil.test.ts +16 -16
- package/src/api/nodeUtil.ts +10 -10
- package/src/api/parsers/html/parseHTML.ts +1 -1
- package/src/api/parsers/html/util/nestedLists.ts +2 -2
- package/src/api/parsers/markdown/parseMarkdown.ts +1 -1
- package/src/api/pmUtil.ts +4 -4
- package/src/api/positionMapping.test.ts +3 -3
- package/src/api/positionMapping.ts +5 -5
- package/src/blocks/AudioBlockContent/AudioBlockContent.ts +9 -4
- package/src/blocks/CodeBlockContent/CodeBlockContent.ts +40 -26
- package/src/blocks/FileBlockContent/FileBlockContent.ts +7 -2
- package/src/blocks/FileBlockContent/helpers/parse/parseFigureElement.ts +2 -2
- package/src/blocks/FileBlockContent/helpers/render/createAddFileButton.ts +5 -5
- package/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.ts +2 -2
- package/src/blocks/FileBlockContent/helpers/render/createFileNameWithIcon.ts +1 -1
- package/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.ts +15 -8
- package/src/blocks/FileBlockContent/helpers/toExternalHTML/createFigureWithCaption.ts +1 -1
- package/src/blocks/FileBlockContent/helpers/toExternalHTML/createLinkWithCaption.ts +1 -1
- package/src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +2 -2
- package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +9 -6
- package/src/blocks/ImageBlockContent/ImageBlockContent.ts +14 -6
- package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +13 -29
- package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +24 -13
- package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +1 -1
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +1 -1
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +13 -30
- package/src/blocks/ListItemBlockContent/getListItemContent.ts +115 -0
- package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +1 -1
- package/src/blocks/PageBreakBlockContent/getPageBreakSlashMenuItems.ts +3 -3
- package/src/blocks/PageBreakBlockContent/schema.ts +2 -2
- package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +9 -5
- package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +10 -5
- package/src/blocks/README.md +1 -1
- package/src/blocks/TableBlockContent/TableBlockContent.ts +76 -19
- package/src/blocks/TableBlockContent/TableExtension.ts +3 -3
- package/src/blocks/VideoBlockContent/VideoBlockContent.ts +14 -6
- package/src/blocks/defaultBlockHelpers.ts +24 -8
- package/src/blocks/defaultBlockTypeGuards.ts +16 -16
- package/src/blocks/defaultBlocks.ts +3 -3
- package/src/comments/threadstore/DefaultThreadStoreAuth.ts +3 -3
- package/src/comments/threadstore/ThreadStore.ts +1 -1
- package/src/comments/threadstore/TipTapThreadStore.ts +10 -10
- package/src/comments/threadstore/yjs/RESTYjsThreadStore.ts +4 -4
- package/src/comments/threadstore/yjs/YjsThreadStore.test.ts +2 -2
- package/src/comments/threadstore/yjs/YjsThreadStore.ts +14 -14
- package/src/comments/threadstore/yjs/YjsThreadStoreBase.ts +1 -1
- package/src/comments/threadstore/yjs/yjsHelpers.ts +6 -6
- package/src/editor/Block.css +10 -1
- package/src/editor/BlockNoteEditor.test.ts +3 -3
- package/src/editor/BlockNoteEditor.ts +110 -61
- package/src/editor/BlockNoteExtensions.ts +24 -15
- package/src/editor/BlockNoteSchema.ts +4 -4
- package/src/editor/BlockNoteTipTapEditor.ts +10 -10
- package/src/editor/README.md +1 -1
- package/src/editor/cursorPositionTypes.ts +1 -1
- package/src/editor/editor.css +15 -3
- package/src/editor/selectionTypes.ts +1 -1
- package/src/editor/transformPasted.ts +2 -2
- package/src/exporter/Exporter.ts +5 -5
- package/src/exporter/mapping.ts +7 -7
- package/src/extensions/BackgroundColor/BackgroundColorMark.ts +1 -1
- package/src/extensions/Collaboration/CursorPlugin.ts +152 -0
- package/src/extensions/Collaboration/SyncPlugin.ts +15 -0
- package/src/extensions/Collaboration/UndoPlugin.ts +14 -0
- package/src/extensions/Comments/CommentsPlugin.ts +9 -9
- package/src/extensions/Comments/userstore/UserStore.ts +2 -2
- package/src/extensions/FilePanel/FilePanelPlugin.ts +37 -28
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +6 -8
- package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +29 -26
- package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +11 -11
- package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +4 -4
- package/src/extensions/Placeholder/PlaceholderPlugin.ts +10 -10
- package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +2 -2
- package/src/extensions/README.md +1 -1
- package/src/extensions/SideMenu/MultipleNodeSelection.ts +1 -1
- package/src/extensions/SideMenu/SideMenuPlugin.ts +31 -31
- package/src/extensions/SideMenu/dragging.ts +8 -8
- package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +17 -17
- package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +2 -2
- package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +12 -12
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +54 -53
- package/src/extensions/TrailingNode/TrailingNodeExtension.ts +1 -1
- package/src/extensions/UniqueID/UniqueID.ts +6 -6
- package/src/extensions/getDraggableBlockFromElement.ts +1 -1
- package/src/fonts/inter.css +18 -9
- package/src/i18n/locales/index.ts +2 -0
- package/src/i18n/locales/ru.ts +2 -2
- package/src/i18n/locales/sk.ts +355 -0
- package/src/i18n/locales/zh-tw.ts +390 -0
- package/src/locales.ts +1 -1
- package/src/pm-nodes/BlockContainer.ts +7 -6
- package/src/pm-nodes/BlockGroup.ts +1 -1
- package/src/pm-nodes/Doc.ts +4 -4
- package/src/schema/README.md +1 -1
- package/src/schema/blocks/createSpec.ts +15 -15
- package/src/schema/blocks/internal.ts +17 -18
- package/src/schema/blocks/types.ts +27 -26
- package/src/schema/inlineContent/createSpec.ts +16 -20
- package/src/schema/inlineContent/internal.ts +9 -9
- package/src/schema/inlineContent/types.ts +26 -26
- package/src/schema/propTypes.ts +8 -8
- package/src/schema/styles/createSpec.ts +2 -2
- package/src/schema/styles/internal.ts +7 -7
- package/src/schema/styles/types.ts +2 -2
- package/src/util/EventEmitter.ts +4 -4
- package/src/util/README.md +1 -1
- package/src/util/combineByGroup.ts +1 -1
- package/src/util/table.ts +33 -30
- package/types/src/api/blockManipulation/setupTestEnv.d.ts +8 -4
- package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +8 -4
- package/types/src/blocks/ListItemBlockContent/getListItemContent.d.ts +28 -0
- package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +8 -4
- package/types/src/blocks/defaultBlockHelpers.d.ts +1 -0
- package/types/src/blocks/defaultBlocks.d.ts +16 -8
- package/types/src/editor/BlockNoteEditor.d.ts +21 -2
- package/types/src/extensions/Collaboration/CursorPlugin.d.ts +31 -0
- package/types/src/extensions/Collaboration/SyncPlugin.d.ts +7 -0
- package/types/src/extensions/Collaboration/UndoPlugin.d.ts +6 -0
- package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +1 -1
- package/types/src/i18n/locales/index.d.ts +2 -0
- package/types/src/i18n/locales/sk.d.ts +313 -0
- package/types/src/i18n/locales/zh-tw.d.ts +2 -0
- package/types/src/schema/blocks/types.d.ts +2 -1
- package/src/extensions/Collaboration/createCollaborationExtensions.ts +0 -147
- package/types/src/extensions/Collaboration/createCollaborationExtensions.d.ts +0 -17
|
@@ -46,7 +46,7 @@ let dragImageElement: HTMLElement | undefined;
|
|
|
46
46
|
// TODO consider switching this to jotai, it is a bit messy and noisy
|
|
47
47
|
export type TableHandlesState<
|
|
48
48
|
I extends InlineContentSchema,
|
|
49
|
-
S extends StyleSchema
|
|
49
|
+
S extends StyleSchema,
|
|
50
50
|
> = {
|
|
51
51
|
show: boolean;
|
|
52
52
|
showAddOrRemoveRowsButton: boolean;
|
|
@@ -146,7 +146,7 @@ function hideElements(selector: string, rootEl: Document | ShadowRoot) {
|
|
|
146
146
|
|
|
147
147
|
export class TableHandlesView<
|
|
148
148
|
I extends InlineContentSchema,
|
|
149
|
-
S extends StyleSchema
|
|
149
|
+
S extends StyleSchema,
|
|
150
150
|
> implements PluginView
|
|
151
151
|
{
|
|
152
152
|
public state?: TableHandlesState<I, S>;
|
|
@@ -169,7 +169,7 @@ export class TableHandlesView<
|
|
|
169
169
|
S
|
|
170
170
|
>,
|
|
171
171
|
private readonly pmView: EditorView,
|
|
172
|
-
emitUpdate: (state: TableHandlesState<I, S>) => void
|
|
172
|
+
emitUpdate: (state: TableHandlesState<I, S>) => void,
|
|
173
173
|
) {
|
|
174
174
|
this.emitUpdate = () => {
|
|
175
175
|
if (!this.state) {
|
|
@@ -185,11 +185,11 @@ export class TableHandlesView<
|
|
|
185
185
|
|
|
186
186
|
pmView.root.addEventListener(
|
|
187
187
|
"dragover",
|
|
188
|
-
this.dragOverHandler as EventListener
|
|
188
|
+
this.dragOverHandler as EventListener,
|
|
189
189
|
);
|
|
190
190
|
pmView.root.addEventListener(
|
|
191
191
|
"drop",
|
|
192
|
-
this.dropHandler as unknown as EventListener
|
|
192
|
+
this.dropHandler as unknown as EventListener,
|
|
193
193
|
);
|
|
194
194
|
}
|
|
195
195
|
|
|
@@ -264,7 +264,7 @@ export class TableHandlesView<
|
|
|
264
264
|
| undefined;
|
|
265
265
|
|
|
266
266
|
const pmNodeInfo = this.editor.transact((tr) =>
|
|
267
|
-
getNodeById(blockEl.id, tr.doc)
|
|
267
|
+
getNodeById(blockEl.id, tr.doc),
|
|
268
268
|
);
|
|
269
269
|
if (!pmNodeInfo) {
|
|
270
270
|
throw new Error(`Block with ID ${blockEl.id} not found`);
|
|
@@ -275,7 +275,7 @@ export class TableHandlesView<
|
|
|
275
275
|
this.editor.pmSchema,
|
|
276
276
|
this.editor.schema.blockSchema,
|
|
277
277
|
this.editor.schema.inlineContentSchema,
|
|
278
|
-
this.editor.schema.styleSchema
|
|
278
|
+
this.editor.schema.styleSchema,
|
|
279
279
|
);
|
|
280
280
|
|
|
281
281
|
if (checkBlockIsDefaultType("table", block, this.editor)) {
|
|
@@ -368,7 +368,7 @@ export class TableHandlesView<
|
|
|
368
368
|
|
|
369
369
|
hideElements(
|
|
370
370
|
".prosemirror-dropcursor-block, .prosemirror-dropcursor-inline",
|
|
371
|
-
this.pmView.root
|
|
371
|
+
this.pmView.root,
|
|
372
372
|
);
|
|
373
373
|
|
|
374
374
|
// The mouse cursor coordinates, bounded to the table's bounding box. The
|
|
@@ -377,11 +377,11 @@ export class TableHandlesView<
|
|
|
377
377
|
const boundedMouseCoords = {
|
|
378
378
|
left: Math.min(
|
|
379
379
|
Math.max(event.clientX, this.state.referencePosTable.left + 1),
|
|
380
|
-
this.state.referencePosTable.right - 1
|
|
380
|
+
this.state.referencePosTable.right - 1,
|
|
381
381
|
),
|
|
382
382
|
top: Math.min(
|
|
383
383
|
Math.max(event.clientY, this.state.referencePosTable.top + 1),
|
|
384
|
-
this.state.referencePosTable.bottom - 1
|
|
384
|
+
this.state.referencePosTable.bottom - 1,
|
|
385
385
|
),
|
|
386
386
|
};
|
|
387
387
|
|
|
@@ -390,7 +390,7 @@ export class TableHandlesView<
|
|
|
390
390
|
const tableCellElements = this.pmView.root
|
|
391
391
|
.elementsFromPoint(boundedMouseCoords.left, boundedMouseCoords.top)
|
|
392
392
|
.filter(
|
|
393
|
-
(element) => element.tagName === "TD" || element.tagName === "TH"
|
|
393
|
+
(element) => element.tagName === "TD" || element.tagName === "TH",
|
|
394
394
|
);
|
|
395
395
|
if (tableCellElements.length === 0) {
|
|
396
396
|
return;
|
|
@@ -461,7 +461,7 @@ export class TableHandlesView<
|
|
|
461
461
|
this.state.colIndex === undefined
|
|
462
462
|
) {
|
|
463
463
|
throw new Error(
|
|
464
|
-
"Attempted to drop table row or column, but no table block was hovered prior."
|
|
464
|
+
"Attempted to drop table row or column, but no table block was hovered prior.",
|
|
465
465
|
);
|
|
466
466
|
}
|
|
467
467
|
|
|
@@ -476,7 +476,7 @@ export class TableHandlesView<
|
|
|
476
476
|
!canRowBeDraggedInto(
|
|
477
477
|
this.state.block,
|
|
478
478
|
draggingState.originalIndex,
|
|
479
|
-
rowIndex
|
|
479
|
+
rowIndex,
|
|
480
480
|
)
|
|
481
481
|
) {
|
|
482
482
|
// If the target row is invalid, don't move the row
|
|
@@ -485,7 +485,7 @@ export class TableHandlesView<
|
|
|
485
485
|
const newTable = moveRow(
|
|
486
486
|
this.state.block,
|
|
487
487
|
draggingState.originalIndex,
|
|
488
|
-
rowIndex
|
|
488
|
+
rowIndex,
|
|
489
489
|
);
|
|
490
490
|
this.editor.updateBlock(this.state.block, {
|
|
491
491
|
type: "table",
|
|
@@ -499,7 +499,7 @@ export class TableHandlesView<
|
|
|
499
499
|
!canColumnBeDraggedInto(
|
|
500
500
|
this.state.block,
|
|
501
501
|
draggingState.originalIndex,
|
|
502
|
-
colIndex
|
|
502
|
+
colIndex,
|
|
503
503
|
)
|
|
504
504
|
) {
|
|
505
505
|
// If the target column is invalid, don't move the column
|
|
@@ -508,7 +508,7 @@ export class TableHandlesView<
|
|
|
508
508
|
const newTable = moveColumn(
|
|
509
509
|
this.state.block,
|
|
510
510
|
draggingState.originalIndex,
|
|
511
|
-
colIndex
|
|
511
|
+
colIndex,
|
|
512
512
|
);
|
|
513
513
|
const [columnWidth] = columnWidths.splice(draggingState.originalIndex, 1);
|
|
514
514
|
columnWidths.splice(colIndex, 0, columnWidth);
|
|
@@ -538,6 +538,7 @@ export class TableHandlesView<
|
|
|
538
538
|
this.state.block = this.editor.getBlock(this.state.block.id)!;
|
|
539
539
|
if (
|
|
540
540
|
!this.state.block ||
|
|
541
|
+
this.state.block.type !== "table" ||
|
|
541
542
|
// when collaborating, the table element might be replaced and out of date
|
|
542
543
|
// because yjs replaces the element when for example you change the color via the side menu
|
|
543
544
|
!this.tableElement?.isConnected
|
|
@@ -551,7 +552,7 @@ export class TableHandlesView<
|
|
|
551
552
|
}
|
|
552
553
|
|
|
553
554
|
const { height: rowCount, width: colCount } = getDimensionsOfTable(
|
|
554
|
-
this.state.block
|
|
555
|
+
this.state.block,
|
|
555
556
|
);
|
|
556
557
|
|
|
557
558
|
if (
|
|
@@ -574,7 +575,7 @@ export class TableHandlesView<
|
|
|
574
575
|
|
|
575
576
|
if (!tableBody) {
|
|
576
577
|
throw new Error(
|
|
577
|
-
"Table block does not contain a 'tbody' HTML element. This should never happen."
|
|
578
|
+
"Table block does not contain a 'tbody' HTML element. This should never happen.",
|
|
578
579
|
);
|
|
579
580
|
}
|
|
580
581
|
|
|
@@ -602,11 +603,11 @@ export class TableHandlesView<
|
|
|
602
603
|
this.pmView.dom.removeEventListener("mousedown", this.viewMousedownHandler);
|
|
603
604
|
this.pmView.root.removeEventListener(
|
|
604
605
|
"dragover",
|
|
605
|
-
this.dragOverHandler as EventListener
|
|
606
|
+
this.dragOverHandler as EventListener,
|
|
606
607
|
);
|
|
607
608
|
this.pmView.root.removeEventListener(
|
|
608
609
|
"drop",
|
|
609
|
-
this.dropHandler as unknown as EventListener
|
|
610
|
+
this.dropHandler as unknown as EventListener,
|
|
610
611
|
);
|
|
611
612
|
}
|
|
612
613
|
}
|
|
@@ -615,7 +616,7 @@ export const tableHandlesPluginKey = new PluginKey("TableHandlesPlugin");
|
|
|
615
616
|
|
|
616
617
|
export class TableHandlesProsemirrorPlugin<
|
|
617
618
|
I extends InlineContentSchema,
|
|
618
|
-
S extends StyleSchema
|
|
619
|
+
S extends StyleSchema,
|
|
619
620
|
> extends EventEmitter<any> {
|
|
620
621
|
private view: TableHandlesView<I, S> | undefined;
|
|
621
622
|
public readonly plugin: Plugin;
|
|
@@ -625,7 +626,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
625
626
|
BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>,
|
|
626
627
|
I,
|
|
627
628
|
S
|
|
628
|
-
|
|
629
|
+
>,
|
|
629
630
|
) {
|
|
630
631
|
super();
|
|
631
632
|
this.plugin = new Plugin({
|
|
@@ -684,18 +685,18 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
684
685
|
if (this.view.state.draggingState.draggedCellOrientation === "row") {
|
|
685
686
|
const cellsInRow = getCellsAtRowHandle(
|
|
686
687
|
this.view.state.block,
|
|
687
|
-
newIndex
|
|
688
|
+
newIndex,
|
|
688
689
|
);
|
|
689
690
|
|
|
690
691
|
cellsInRow.forEach(({ row, col }) => {
|
|
691
692
|
// Gets each row in the table.
|
|
692
693
|
const rowResolvedPos = state.doc.resolve(
|
|
693
|
-
tableResolvedPos.posAtIndex(row) + 1
|
|
694
|
+
tableResolvedPos.posAtIndex(row) + 1,
|
|
694
695
|
);
|
|
695
696
|
|
|
696
697
|
// Gets the cell within the row.
|
|
697
698
|
const cellResolvedPos = state.doc.resolve(
|
|
698
|
-
rowResolvedPos.posAtIndex(col) + 1
|
|
699
|
+
rowResolvedPos.posAtIndex(col) + 1,
|
|
699
700
|
);
|
|
700
701
|
const cellNode = cellResolvedPos.node();
|
|
701
702
|
// Creates a decoration at the start or end of each cell,
|
|
@@ -724,24 +725,24 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
724
725
|
widget.style.height = "4px";
|
|
725
726
|
|
|
726
727
|
return widget;
|
|
727
|
-
})
|
|
728
|
+
}),
|
|
728
729
|
);
|
|
729
730
|
});
|
|
730
731
|
} else {
|
|
731
732
|
const cellsInColumn = getCellsAtColumnHandle(
|
|
732
733
|
this.view.state.block,
|
|
733
|
-
newIndex
|
|
734
|
+
newIndex,
|
|
734
735
|
);
|
|
735
736
|
|
|
736
737
|
cellsInColumn.forEach(({ row, col }) => {
|
|
737
738
|
// Gets each row in the table.
|
|
738
739
|
const rowResolvedPos = state.doc.resolve(
|
|
739
|
-
tableResolvedPos.posAtIndex(row) + 1
|
|
740
|
+
tableResolvedPos.posAtIndex(row) + 1,
|
|
740
741
|
);
|
|
741
742
|
|
|
742
743
|
// Gets the cell within the row.
|
|
743
744
|
const cellResolvedPos = state.doc.resolve(
|
|
744
|
-
rowResolvedPos.posAtIndex(col) + 1
|
|
745
|
+
rowResolvedPos.posAtIndex(col) + 1,
|
|
745
746
|
);
|
|
746
747
|
const cellNode = cellResolvedPos.node();
|
|
747
748
|
|
|
@@ -772,7 +773,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
772
773
|
widget.style.width = "4px";
|
|
773
774
|
|
|
774
775
|
return widget;
|
|
775
|
-
})
|
|
776
|
+
}),
|
|
776
777
|
);
|
|
777
778
|
});
|
|
778
779
|
}
|
|
@@ -800,7 +801,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
800
801
|
this.view!.state.colIndex === undefined
|
|
801
802
|
) {
|
|
802
803
|
throw new Error(
|
|
803
|
-
"Attempted to drag table column, but no table block was hovered prior."
|
|
804
|
+
"Attempted to drag table column, but no table block was hovered prior.",
|
|
804
805
|
);
|
|
805
806
|
}
|
|
806
807
|
|
|
@@ -818,7 +819,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
818
819
|
originalIndex: this.view!.state!.colIndex,
|
|
819
820
|
newIndex: this.view!.state!.colIndex,
|
|
820
821
|
tablePos: this.view!.tablePos,
|
|
821
|
-
})
|
|
822
|
+
}),
|
|
822
823
|
);
|
|
823
824
|
|
|
824
825
|
if (!this.editor.prosemirrorView) {
|
|
@@ -843,7 +844,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
843
844
|
this.view!.state.rowIndex === undefined
|
|
844
845
|
) {
|
|
845
846
|
throw new Error(
|
|
846
|
-
"Attempted to drag table row, but no table block was hovered prior."
|
|
847
|
+
"Attempted to drag table row, but no table block was hovered prior.",
|
|
847
848
|
);
|
|
848
849
|
}
|
|
849
850
|
|
|
@@ -861,7 +862,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
861
862
|
originalIndex: this.view!.state!.rowIndex,
|
|
862
863
|
newIndex: this.view!.state!.rowIndex,
|
|
863
864
|
tablePos: this.view!.tablePos,
|
|
864
|
-
})
|
|
865
|
+
}),
|
|
865
866
|
);
|
|
866
867
|
|
|
867
868
|
if (!this.editor.prosemirrorView) {
|
|
@@ -880,7 +881,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
880
881
|
dragEnd = () => {
|
|
881
882
|
if (this.view!.state === undefined) {
|
|
882
883
|
throw new Error(
|
|
883
|
-
"Attempted to drag table row, but no table block was hovered prior."
|
|
884
|
+
"Attempted to drag table row, but no table block was hovered prior.",
|
|
884
885
|
);
|
|
885
886
|
}
|
|
886
887
|
|
|
@@ -914,7 +915,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
914
915
|
|
|
915
916
|
getCellsAtRowHandle = (
|
|
916
917
|
block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
|
|
917
|
-
relativeRowIndex: RelativeCellIndices["row"]
|
|
918
|
+
relativeRowIndex: RelativeCellIndices["row"],
|
|
918
919
|
) => {
|
|
919
920
|
return getCellsAtRowHandle(block, relativeRowIndex);
|
|
920
921
|
};
|
|
@@ -924,7 +925,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
924
925
|
*/
|
|
925
926
|
getCellsAtColumnHandle = (
|
|
926
927
|
block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
|
|
927
|
-
relativeColumnIndex: RelativeCellIndices["col"]
|
|
928
|
+
relativeColumnIndex: RelativeCellIndices["col"],
|
|
928
929
|
) => {
|
|
929
930
|
return getCellsAtColumnHandle(block, relativeColumnIndex);
|
|
930
931
|
};
|
|
@@ -936,7 +937,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
936
937
|
private setCellSelection = (
|
|
937
938
|
state: EditorState,
|
|
938
939
|
relativeStartCell: RelativeCellIndices,
|
|
939
|
-
relativeEndCell: RelativeCellIndices = relativeStartCell
|
|
940
|
+
relativeEndCell: RelativeCellIndices = relativeStartCell,
|
|
940
941
|
) => {
|
|
941
942
|
const view = this.view;
|
|
942
943
|
|
|
@@ -946,18 +947,18 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
946
947
|
|
|
947
948
|
const tableResolvedPos = state.doc.resolve(view.tablePos! + 1);
|
|
948
949
|
const startRowResolvedPos = state.doc.resolve(
|
|
949
|
-
tableResolvedPos.posAtIndex(relativeStartCell.row) + 1
|
|
950
|
+
tableResolvedPos.posAtIndex(relativeStartCell.row) + 1,
|
|
950
951
|
);
|
|
951
952
|
const startCellResolvedPos = state.doc.resolve(
|
|
952
953
|
// No need for +1, since CellSelection expects the position before the cell
|
|
953
|
-
startRowResolvedPos.posAtIndex(relativeStartCell.col)
|
|
954
|
+
startRowResolvedPos.posAtIndex(relativeStartCell.col),
|
|
954
955
|
);
|
|
955
956
|
const endRowResolvedPos = state.doc.resolve(
|
|
956
|
-
tableResolvedPos.posAtIndex(relativeEndCell.row) + 1
|
|
957
|
+
tableResolvedPos.posAtIndex(relativeEndCell.row) + 1,
|
|
957
958
|
);
|
|
958
959
|
const endCellResolvedPos = state.doc.resolve(
|
|
959
960
|
// No need for +1, since CellSelection expects the position before the cell
|
|
960
|
-
endRowResolvedPos.posAtIndex(relativeEndCell.col)
|
|
961
|
+
endRowResolvedPos.posAtIndex(relativeEndCell.col),
|
|
961
962
|
);
|
|
962
963
|
|
|
963
964
|
// Begin a new transaction to set the selection
|
|
@@ -965,7 +966,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
965
966
|
|
|
966
967
|
// Set the selection to the given cell or a range of cells
|
|
967
968
|
tr.setSelection(
|
|
968
|
-
new CellSelection(startCellResolvedPos, endCellResolvedPos)
|
|
969
|
+
new CellSelection(startCellResolvedPos, endCellResolvedPos),
|
|
969
970
|
);
|
|
970
971
|
|
|
971
972
|
// Quickly apply the transaction to get the new state to update the selection before splitting the cell
|
|
@@ -979,14 +980,14 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
979
980
|
index: RelativeCellIndices["row"] | RelativeCellIndices["col"],
|
|
980
981
|
direction:
|
|
981
982
|
| { orientation: "row"; side: "above" | "below" }
|
|
982
|
-
| { orientation: "column"; side: "left" | "right" }
|
|
983
|
+
| { orientation: "column"; side: "left" | "right" },
|
|
983
984
|
) => {
|
|
984
985
|
this.editor.exec((beforeState, dispatch) => {
|
|
985
986
|
const state = this.setCellSelection(
|
|
986
987
|
beforeState,
|
|
987
988
|
direction.orientation === "row"
|
|
988
989
|
? { row: index, col: 0 }
|
|
989
|
-
: { row: 0, col: index }
|
|
990
|
+
: { row: 0, col: index },
|
|
990
991
|
);
|
|
991
992
|
|
|
992
993
|
if (direction.orientation === "row") {
|
|
@@ -1010,7 +1011,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
1010
1011
|
*/
|
|
1011
1012
|
removeRowOrColumn = (
|
|
1012
1013
|
index: RelativeCellIndices["row"] | RelativeCellIndices["col"],
|
|
1013
|
-
direction: "row" | "column"
|
|
1014
|
+
direction: "row" | "column",
|
|
1014
1015
|
) => {
|
|
1015
1016
|
if (direction === "row") {
|
|
1016
1017
|
return this.editor.exec((beforeState, dispatch) => {
|
|
@@ -1043,7 +1044,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
1043
1044
|
? this.setCellSelection(
|
|
1044
1045
|
beforeState,
|
|
1045
1046
|
cellsToMerge.relativeStartCell,
|
|
1046
|
-
cellsToMerge.relativeEndCell
|
|
1047
|
+
cellsToMerge.relativeEndCell,
|
|
1047
1048
|
)
|
|
1048
1049
|
: beforeState;
|
|
1049
1050
|
|
|
@@ -1099,10 +1100,10 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
1099
1100
|
// Assumes we are within a tableParagraph
|
|
1100
1101
|
// And find the from and to cells by resolving the positions
|
|
1101
1102
|
$fromCell = tr.doc.resolve(
|
|
1102
|
-
selection.$from.pos - selection.$from.parentOffset - 1
|
|
1103
|
+
selection.$from.pos - selection.$from.parentOffset - 1,
|
|
1103
1104
|
);
|
|
1104
1105
|
$toCell = tr.doc.resolve(
|
|
1105
|
-
selection.$to.pos - selection.$to.parentOffset - 1
|
|
1106
|
+
selection.$to.pos - selection.$to.parentOffset - 1,
|
|
1106
1107
|
);
|
|
1107
1108
|
|
|
1108
1109
|
// Opt-out when the selection is not pointing into cells
|
|
@@ -1113,7 +1114,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
1113
1114
|
|
|
1114
1115
|
// Find the row and table that the from and to cells are in
|
|
1115
1116
|
const $fromRow = tr.doc.resolve(
|
|
1116
|
-
$fromCell.pos - $fromCell.parentOffset - 1
|
|
1117
|
+
$fromCell.pos - $fromCell.parentOffset - 1,
|
|
1117
1118
|
);
|
|
1118
1119
|
const $toRow = tr.doc.resolve($toCell.pos - $toCell.parentOffset - 1);
|
|
1119
1120
|
|
|
@@ -1155,7 +1156,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
1155
1156
|
getMergeDirection = (
|
|
1156
1157
|
block:
|
|
1157
1158
|
| BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>
|
|
1158
|
-
| undefined
|
|
1159
|
+
| undefined,
|
|
1159
1160
|
) => {
|
|
1160
1161
|
return this.editor.transact((tr) => {
|
|
1161
1162
|
const isSelectingTableCells = isTableCellSelection(tr.selection)
|
|
@@ -1187,7 +1188,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
1187
1188
|
|
|
1188
1189
|
cropEmptyRowsOrColumns = (
|
|
1189
1190
|
block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
|
|
1190
|
-
removeEmpty: "columns" | "rows"
|
|
1191
|
+
removeEmpty: "columns" | "rows",
|
|
1191
1192
|
) => {
|
|
1192
1193
|
return cropEmptyRowsOrColumns(block, removeEmpty);
|
|
1193
1194
|
};
|
|
@@ -1195,7 +1196,7 @@ export class TableHandlesProsemirrorPlugin<
|
|
|
1195
1196
|
addRowsOrColumns = (
|
|
1196
1197
|
block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
|
|
1197
1198
|
addType: "columns" | "rows",
|
|
1198
|
-
numToAdd: number
|
|
1199
|
+
numToAdd: number,
|
|
1199
1200
|
) => {
|
|
1200
1201
|
return addRowsOrColumns(block, addType, numToAdd);
|
|
1201
1202
|
};
|
|
@@ -35,7 +35,7 @@ function removeDuplicates(array: any, by = JSON.stringify) {
|
|
|
35
35
|
*/
|
|
36
36
|
function findDuplicates(items: any) {
|
|
37
37
|
const filtered = items.filter(
|
|
38
|
-
(el: any, index: number) => items.indexOf(el) !== index
|
|
38
|
+
(el: any, index: number) => items.indexOf(el) !== index,
|
|
39
39
|
);
|
|
40
40
|
const duplicates = removeDuplicates(filtered);
|
|
41
41
|
return duplicates;
|
|
@@ -154,7 +154,7 @@ const UniqueID = Extension.create({
|
|
|
154
154
|
const { types, attributeName, generateID } = this.options;
|
|
155
155
|
const transform = combineTransactionSteps(
|
|
156
156
|
oldState.doc,
|
|
157
|
-
transactions as any
|
|
157
|
+
transactions as any,
|
|
158
158
|
);
|
|
159
159
|
const { mapping } = transform;
|
|
160
160
|
// get changed ranges based on the old state
|
|
@@ -166,7 +166,7 @@ const UniqueID = Extension.create({
|
|
|
166
166
|
newRange,
|
|
167
167
|
(node) => {
|
|
168
168
|
return types.includes(node.type.name);
|
|
169
|
-
}
|
|
169
|
+
},
|
|
170
170
|
);
|
|
171
171
|
const newIds = newNodes
|
|
172
172
|
.map(({ node }) => node.attrs[attributeName])
|
|
@@ -193,7 +193,7 @@ const UniqueID = Extension.create({
|
|
|
193
193
|
if (wasInitial) {
|
|
194
194
|
// the old state was the "initial content"
|
|
195
195
|
const jsonNode = JSON.parse(
|
|
196
|
-
JSON.stringify(newState.doc.toJSON())
|
|
196
|
+
JSON.stringify(newState.doc.toJSON()),
|
|
197
197
|
);
|
|
198
198
|
jsonNode.content[0].content[0].attrs.id = "initialBlockId";
|
|
199
199
|
// would the new state with the fix also be the "initial content"?
|
|
@@ -308,7 +308,7 @@ const UniqueID = Extension.create({
|
|
|
308
308
|
[attributeName]: null,
|
|
309
309
|
},
|
|
310
310
|
removeId(node.content),
|
|
311
|
-
node.marks
|
|
311
|
+
node.marks,
|
|
312
312
|
);
|
|
313
313
|
list.push(nodeWithoutId);
|
|
314
314
|
});
|
|
@@ -319,7 +319,7 @@ const UniqueID = Extension.create({
|
|
|
319
319
|
return new Slice(
|
|
320
320
|
removeId(slice.content),
|
|
321
321
|
slice.openStart,
|
|
322
|
-
slice.openEnd
|
|
322
|
+
slice.openEnd,
|
|
323
323
|
);
|
|
324
324
|
},
|
|
325
325
|
},
|
package/src/fonts/inter.css
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
font-family: "Inter";
|
|
6
6
|
font-style: normal;
|
|
7
7
|
font-weight: 100;
|
|
8
|
-
src:
|
|
8
|
+
src:
|
|
9
|
+
local(""),
|
|
9
10
|
url("./inter-v12-latin/inter-v12-latin-100.woff2") format("woff2"),
|
|
10
11
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
11
12
|
url("./inter-v12-latin/inter-v12-latin-100.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
@@ -15,7 +16,8 @@
|
|
|
15
16
|
font-family: "Inter";
|
|
16
17
|
font-style: normal;
|
|
17
18
|
font-weight: 200;
|
|
18
|
-
src:
|
|
19
|
+
src:
|
|
20
|
+
local(""),
|
|
19
21
|
url("./inter-v12-latin/inter-v12-latin-200.woff2") format("woff2"),
|
|
20
22
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
21
23
|
url("./inter-v12-latin/inter-v12-latin-200.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
@@ -25,7 +27,8 @@
|
|
|
25
27
|
font-family: "Inter";
|
|
26
28
|
font-style: normal;
|
|
27
29
|
font-weight: 300;
|
|
28
|
-
src:
|
|
30
|
+
src:
|
|
31
|
+
local(""),
|
|
29
32
|
url("./inter-v12-latin/inter-v12-latin-300.woff2") format("woff2"),
|
|
30
33
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
31
34
|
url("./inter-v12-latin/inter-v12-latin-300.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
@@ -35,7 +38,8 @@
|
|
|
35
38
|
font-family: "Inter";
|
|
36
39
|
font-style: normal;
|
|
37
40
|
font-weight: 400;
|
|
38
|
-
src:
|
|
41
|
+
src:
|
|
42
|
+
local(""),
|
|
39
43
|
url("./inter-v12-latin/inter-v12-latin-regular.woff2") format("woff2"),
|
|
40
44
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
41
45
|
url("./inter-v12-latin/inter-v12-latin-regular.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
@@ -45,7 +49,8 @@
|
|
|
45
49
|
font-family: "Inter";
|
|
46
50
|
font-style: normal;
|
|
47
51
|
font-weight: 500;
|
|
48
|
-
src:
|
|
52
|
+
src:
|
|
53
|
+
local(""),
|
|
49
54
|
url("./inter-v12-latin/inter-v12-latin-500.woff2") format("woff2"),
|
|
50
55
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
51
56
|
url("./inter-v12-latin/inter-v12-latin-500.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
@@ -55,7 +60,8 @@
|
|
|
55
60
|
font-family: "Inter";
|
|
56
61
|
font-style: normal;
|
|
57
62
|
font-weight: 600;
|
|
58
|
-
src:
|
|
63
|
+
src:
|
|
64
|
+
local(""),
|
|
59
65
|
url("./inter-v12-latin/inter-v12-latin-600.woff2") format("woff2"),
|
|
60
66
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
61
67
|
url("./inter-v12-latin/inter-v12-latin-600.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
@@ -65,7 +71,8 @@
|
|
|
65
71
|
font-family: "Inter";
|
|
66
72
|
font-style: normal;
|
|
67
73
|
font-weight: 700;
|
|
68
|
-
src:
|
|
74
|
+
src:
|
|
75
|
+
local(""),
|
|
69
76
|
url("./inter-v12-latin/inter-v12-latin-700.woff2") format("woff2"),
|
|
70
77
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
71
78
|
url("./inter-v12-latin/inter-v12-latin-700.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
@@ -75,7 +82,8 @@
|
|
|
75
82
|
font-family: "Inter";
|
|
76
83
|
font-style: normal;
|
|
77
84
|
font-weight: 800;
|
|
78
|
-
src:
|
|
85
|
+
src:
|
|
86
|
+
local(""),
|
|
79
87
|
url("./inter-v12-latin/inter-v12-latin-800.woff2") format("woff2"),
|
|
80
88
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
81
89
|
url("./inter-v12-latin/inter-v12-latin-800.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
@@ -85,7 +93,8 @@
|
|
|
85
93
|
font-family: "Inter";
|
|
86
94
|
font-style: normal;
|
|
87
95
|
font-weight: 900;
|
|
88
|
-
src:
|
|
96
|
+
src:
|
|
97
|
+
local(""),
|
|
89
98
|
url("./inter-v12-latin/inter-v12-latin-900.woff2") format("woff2"),
|
|
90
99
|
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
91
100
|
url("./inter-v12-latin/inter-v12-latin-900.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
package/src/i18n/locales/ru.ts
CHANGED
|
@@ -42,7 +42,7 @@ export const ru: Dictionary = {
|
|
|
42
42
|
},
|
|
43
43
|
bullet_list: {
|
|
44
44
|
title: "Маркированный список",
|
|
45
|
-
subtext: "Для отображения неупорядоченного
|
|
45
|
+
subtext: "Для отображения неупорядоченного списка",
|
|
46
46
|
aliases: [
|
|
47
47
|
"ul",
|
|
48
48
|
"li",
|
|
@@ -158,7 +158,7 @@ export const ru: Dictionary = {
|
|
|
158
158
|
},
|
|
159
159
|
},
|
|
160
160
|
placeholders: {
|
|
161
|
-
default: "
|
|
161
|
+
default: "Введите текст или введите «/» для команд",
|
|
162
162
|
heading: "Заголовок",
|
|
163
163
|
bulletListItem: "Список",
|
|
164
164
|
numberedListItem: "Список",
|