@jackuait/blok 0.6.0-beta.5 → 0.6.0-beta.6
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 +16 -169
- package/bin/blok.mjs +10 -0
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-XA2L0_-K.mjs → blok-BOtlKwVO.mjs} +877 -783
- package/dist/chunks/{i18next-loader-Ci2zhA-n.mjs → i18next-loader-CJNShSyT.mjs} +1 -1
- package/dist/chunks/{index-R38OiQ_d.mjs → index-BUAPAChM.mjs} +1 -1
- package/dist/chunks/{inline-tool-convert-e3PyuxB6.mjs → inline-tool-convert-UoYdJJic.mjs} +1 -1
- package/dist/{messages-BGxiFoZf.mjs → chunks/messages-7QoX8DkW.mjs} +14 -14
- package/dist/{messages-UX4gkere.mjs → chunks/messages-BMXCuEKO.mjs} +5 -5
- package/dist/{messages-wp_1b1hD.mjs → chunks/messages-BSbjsyHY.mjs} +16 -16
- package/dist/chunks/{messages-DChXyvh2.mjs → messages-BdeLo0N9.mjs} +14 -14
- package/dist/chunks/{messages-B9fe4dQJ.mjs → messages-C2htQ_3F.mjs} +12 -12
- package/dist/{messages-BNe6LuHW.mjs → chunks/messages-C9eaarcK.mjs} +7 -7
- package/dist/chunks/messages-CKI54h6O.mjs +62 -0
- package/dist/{messages-DjvaFRqx.mjs → chunks/messages-CQwpzUFp.mjs} +6 -6
- package/dist/{messages-EL5ARzmK.mjs → chunks/messages-CVw84KdI.mjs} +7 -7
- package/dist/chunks/{messages-49thXXGz.mjs → messages-Diu6jAaR.mjs} +6 -6
- package/dist/{messages-Bfiw5w_W.mjs → chunks/messages-DvFLX36Q.mjs} +10 -10
- package/dist/chunks/{messages-QtoE8uEv.mjs → messages-Dzwxv9v1.mjs} +8 -8
- package/dist/cli.mjs +50 -0
- package/dist/full.mjs +15 -15
- package/dist/locales.mjs +12 -12
- package/dist/{chunks/messages-BGxiFoZf.mjs → messages-7QoX8DkW.mjs} +14 -14
- package/dist/{chunks/messages-UX4gkere.mjs → messages-BMXCuEKO.mjs} +5 -5
- package/dist/{chunks/messages-wp_1b1hD.mjs → messages-BSbjsyHY.mjs} +16 -16
- package/dist/{messages-DChXyvh2.mjs → messages-BdeLo0N9.mjs} +14 -14
- package/dist/{messages-B9fe4dQJ.mjs → messages-C2htQ_3F.mjs} +12 -12
- package/dist/{chunks/messages-BNe6LuHW.mjs → messages-C9eaarcK.mjs} +7 -7
- package/dist/messages-CKI54h6O.mjs +62 -0
- package/dist/{chunks/messages-DjvaFRqx.mjs → messages-CQwpzUFp.mjs} +6 -6
- package/dist/{chunks/messages-EL5ARzmK.mjs → messages-CVw84KdI.mjs} +7 -7
- package/dist/{messages-49thXXGz.mjs → messages-Diu6jAaR.mjs} +6 -6
- package/dist/{chunks/messages-Bfiw5w_W.mjs → messages-DvFLX36Q.mjs} +10 -10
- package/dist/{messages-QtoE8uEv.mjs → messages-Dzwxv9v1.mjs} +8 -8
- package/dist/tools.mjs +222 -207
- package/dist/vendor.LICENSE.txt +1 -1
- package/package.json +13 -8
- package/src/cli/commands/migration.ts +16 -0
- package/src/cli/commands/migrationContent.ts +6 -0
- package/src/cli/index.ts +47 -0
- package/src/cli/utils/output.ts +10 -0
- package/src/components/i18n/locales/bn/messages.json +16 -16
- package/src/components/i18n/locales/fil/messages.json +7 -7
- package/src/components/i18n/locales/hi/messages.json +14 -14
- package/src/components/i18n/locales/id/messages.json +6 -6
- package/src/components/i18n/locales/mr/messages.json +14 -14
- package/src/components/i18n/locales/ms/messages.json +6 -6
- package/src/components/i18n/locales/ne/messages.json +12 -12
- package/src/components/i18n/locales/si/messages.json +8 -8
- package/src/components/i18n/locales/ta/messages.json +7 -7
- package/src/components/i18n/locales/te/messages.json +35 -35
- package/src/components/i18n/locales/th/messages.json +5 -5
- package/src/components/i18n/locales/vi/messages.json +10 -10
- package/src/components/modules/api/history.ts +64 -0
- package/src/components/modules/api/index.ts +1 -0
- package/src/components/modules/api/readonly.ts +11 -1
- package/src/components/modules/blockManager/blockManager.ts +7 -0
- package/src/components/modules/blockManager/yjs-sync.ts +12 -2
- package/src/components/modules/index.ts +3 -0
- package/src/components/modules/readonly.ts +11 -0
- package/src/components/modules/yjs/index.ts +23 -0
- package/src/tools/table/index.ts +20 -0
- package/src/tools/table/table-add-controls.ts +8 -0
- package/src/tools/table/table-cell-blocks.ts +15 -5
- package/src/types-internal/blok-modules.d.ts +2 -0
- package/types/api/history.d.ts +33 -0
- package/types/api/index.d.ts +1 -0
- package/types/api/readonly.d.ts +12 -2
- package/types/index.d.ts +3 -0
- package/dist/chunks/messages-DsVNtdgM.mjs +0 -62
- package/dist/messages-DsVNtdgM.mjs +0 -62
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
|
-
"blockSettings.dragToMove": "తరలించడానికి
|
|
3
|
-
"blockSettings.clickToOpenMenu": "
|
|
4
|
-
"toolbox.addBelow": "క్రింద జోడించడానికి
|
|
5
|
-
"toolbox.optionAddAbove": "పైన జోడించడానికి Option
|
|
6
|
-
"toolbox.ctrlAddAbove": "పైన జోడించడానికి Ctrl
|
|
2
|
+
"blockSettings.dragToMove": "తరలించడానికి లాగండి",
|
|
3
|
+
"blockSettings.clickToOpenMenu": "జాబితా తెరవడానికి నొక్కండి",
|
|
4
|
+
"toolbox.addBelow": "క్రింద జోడించడానికి నొక్కండి",
|
|
5
|
+
"toolbox.optionAddAbove": "పైన జోడించడానికి Option-నొక్కండి",
|
|
6
|
+
"toolbox.ctrlAddAbove": "పైన జోడించడానికి Ctrl-నొక్కండి",
|
|
7
7
|
"popover.search": "వెతకండి",
|
|
8
8
|
"popover.nothingFound": "ఏమీ కనుగొనబడలేదు",
|
|
9
9
|
"popover.convertTo": "మార్చు",
|
|
10
|
-
"toolNames.text": "
|
|
10
|
+
"toolNames.text": "వచనం",
|
|
11
11
|
"toolNames.heading": "శీర్షిక",
|
|
12
12
|
"toolNames.link": "లింక్",
|
|
13
|
-
"toolNames.bold": "
|
|
14
|
-
"toolNames.italic": "
|
|
15
|
-
"toolNames.bulletedList": "
|
|
16
|
-
"toolNames.numberedList": "
|
|
13
|
+
"toolNames.bold": "గాఢం",
|
|
14
|
+
"toolNames.italic": "వాలు",
|
|
15
|
+
"toolNames.bulletedList": "చుక్కల జాబితా",
|
|
16
|
+
"toolNames.numberedList": "అంకెల జాబితా",
|
|
17
17
|
"toolNames.todoList": "చేయవలసిన పనుల జాబితా",
|
|
18
18
|
"tools.link.addLink": "లింక్ జోడించండి",
|
|
19
19
|
"tools.link.invalidLink": "చెల్లని లింక్",
|
|
20
20
|
"tools.stub.error": "లోపం",
|
|
21
|
-
"tools.stub.blockCannotBeDisplayed": "ఈ
|
|
21
|
+
"tools.stub.blockCannotBeDisplayed": "ఈ విభాగాన్ని ప్రదర్శించలేము",
|
|
22
22
|
"tools.header.heading1": "శీర్షిక 1",
|
|
23
23
|
"tools.header.heading2": "శీర్షిక 2",
|
|
24
24
|
"tools.header.heading3": "శీర్షిక 3",
|
|
@@ -27,33 +27,33 @@
|
|
|
27
27
|
"tools.header.heading6": "శీర్షిక 6",
|
|
28
28
|
"tools.list.placeholder": "జాబితా",
|
|
29
29
|
"blockSettings.delete": "తొలగించు",
|
|
30
|
-
"a11y.dragHandle": "
|
|
31
|
-
"a11y.dragHandleRole": "
|
|
32
|
-
"a11y.dragStarted": "
|
|
33
|
-
"a11y.dragStartedMultiple": "{count}
|
|
34
|
-
"a11y.dropPosition": "{total} లో {position} స్థానంలో
|
|
35
|
-
"a11y.dropCancelled": "
|
|
36
|
-
"a11y.blockMoved": "
|
|
37
|
-
"a11y.blocksMoved": "{count}
|
|
38
|
-
"a11y.blockDuplicated": "
|
|
39
|
-
"a11y.blocksDuplicated": "{count}
|
|
40
|
-
"a11y.movedUp": "
|
|
41
|
-
"a11y.movedDown": "
|
|
42
|
-
"a11y.atTop": "
|
|
43
|
-
"a11y.atBottom": "
|
|
44
|
-
"tools.paragraph.placeholder": "ఏదైనా రాయండి లేదా ఎంచుకోడానికి / నొక్కండి",
|
|
30
|
+
"a11y.dragHandle": "విభాగం తరలించడానికి లాగండి లేదా జాబితా కోసం నొక్కండి",
|
|
31
|
+
"a11y.dragHandleRole": "లాగు పట్టిక",
|
|
32
|
+
"a11y.dragStarted": "విభాగం తరలుతోంది",
|
|
33
|
+
"a11y.dragStartedMultiple": "{count} విభాగాలు తరలుతున్నాయి",
|
|
34
|
+
"a11y.dropPosition": "{total} లో {position} స్థానంలో వదులుతుంది",
|
|
35
|
+
"a11y.dropCancelled": "లాగడం రద్దు చేయబడింది",
|
|
36
|
+
"a11y.blockMoved": "విభాగం {total} లో {position} స్థానానికి తరలించబడింది",
|
|
37
|
+
"a11y.blocksMoved": "{count} విభాగాలు {position} స్థానానికి తరలించబడ్డాయి",
|
|
38
|
+
"a11y.blockDuplicated": "విభాగం {total} లో {position} స్థానంలో నకలు చేయబడింది",
|
|
39
|
+
"a11y.blocksDuplicated": "{count} విభాగాలు {position} స్థానం నుండి నకలు చేయబడ్డాయి",
|
|
40
|
+
"a11y.movedUp": "విభాగం {total} లో {position} స్థానానికి పైకి తరలించబడింది",
|
|
41
|
+
"a11y.movedDown": "విభాగం {total} లో {position} స్థానానికి క్రిందికి తరలించబడింది",
|
|
42
|
+
"a11y.atTop": "విభాగం పైన ఉంది, పైకి తరలించలేము",
|
|
43
|
+
"a11y.atBottom": "విభాగం క్రింద ఉంది, క్రిందికి తరలించలేము",
|
|
44
|
+
"tools.paragraph.placeholder": "ఏదైనా రాయండి లేదా సాధనం ఎంచుకోడానికి / నొక్కండి",
|
|
45
45
|
"tools.table.title": "పట్టిక",
|
|
46
|
-
"tools.table.clearSelection": "
|
|
47
|
-
"tools.table.headerColumn": "
|
|
48
|
-
"tools.table.insertColumnLeft": "ఎడమవైపు
|
|
49
|
-
"tools.table.insertColumnRight": "కుడివైపు
|
|
46
|
+
"tools.table.clearSelection": "తుడుచు",
|
|
47
|
+
"tools.table.headerColumn": "శీర్ష స్తంభం",
|
|
48
|
+
"tools.table.insertColumnLeft": "ఎడమవైపు స్తంభం చొప్పించు",
|
|
49
|
+
"tools.table.insertColumnRight": "కుడివైపు స్తంభం చొప్పించు",
|
|
50
50
|
"tools.table.deleteColumn": "తొలగించు",
|
|
51
|
-
"tools.table.headerRow": "
|
|
51
|
+
"tools.table.headerRow": "శీర్ష వరుస",
|
|
52
52
|
"tools.table.insertRowAbove": "పైన వరుస చొప్పించు",
|
|
53
53
|
"tools.table.insertRowBelow": "క్రింద వరుస చొప్పించు",
|
|
54
54
|
"tools.table.deleteRow": "తొలగించు",
|
|
55
|
-
"tools.table.clickToAddRow": "కొత్త వరుస జోడించడానికి
|
|
56
|
-
"tools.table.dragToAddRemoveRows": "వరుసలు జోడించడానికి లేదా తొలగించడానికి
|
|
57
|
-
"tools.table.clickToAddColumn": "కొత్త
|
|
58
|
-
"tools.table.dragToAddRemoveColumns": "
|
|
55
|
+
"tools.table.clickToAddRow": "కొత్త వరుస జోడించడానికి నొక్కండి",
|
|
56
|
+
"tools.table.dragToAddRemoveRows": "వరుసలు జోడించడానికి లేదా తొలగించడానికి లాగండి",
|
|
57
|
+
"tools.table.clickToAddColumn": "కొత్త స్తంభం జోడించడానికి నొక్కండి",
|
|
58
|
+
"tools.table.dragToAddRemoveColumns": "స్తంభాలు జోడించడానికి లేదా తొలగించడానికి లాగండి"
|
|
59
59
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"blockSettings.dragToMove": "ลากเพื่อย้าย",
|
|
3
3
|
"blockSettings.clickToOpenMenu": "คลิกเพื่อเปิดเมนู",
|
|
4
|
-
"toolbox.addBelow": "
|
|
5
|
-
"toolbox.optionAddAbove": "⌥
|
|
6
|
-
"toolbox.ctrlAddAbove": "Ctrl
|
|
4
|
+
"toolbox.addBelow": "คลิกเพื่อเพิ่มด้านล่าง",
|
|
5
|
+
"toolbox.optionAddAbove": "⌥ คลิกเพื่อเพิ่มด้านบน",
|
|
6
|
+
"toolbox.ctrlAddAbove": "Ctrl คลิกเพื่อเพิ่มด้านบน",
|
|
7
7
|
"popover.search": "ค้นหา",
|
|
8
8
|
"popover.nothingFound": "ไม่พบผลลัพธ์",
|
|
9
9
|
"popover.convertTo": "แปลงเป็น",
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
"a11y.dropCancelled": "ยกเลิกการลาก",
|
|
36
36
|
"a11y.blockMoved": "ย้ายบล็อกไปตำแหน่ง {position} จาก {total}",
|
|
37
37
|
"a11y.blocksMoved": "ย้าย {count} บล็อกไปตำแหน่ง {position}",
|
|
38
|
-
"a11y.blockDuplicated": "
|
|
38
|
+
"a11y.blockDuplicated": "คัดลอกบล็อกที่ตำแหน่ง {position} จาก {total}",
|
|
39
39
|
"a11y.blocksDuplicated": "คัดลอก {count} บล็อก เริ่มจากตำแหน่ง {position}",
|
|
40
40
|
"a11y.movedUp": "ย้ายบล็อกขึ้น ตำแหน่ง {position} จาก {total}",
|
|
41
41
|
"a11y.movedDown": "ย้ายบล็อกลง ตำแหน่ง {position} จาก {total}",
|
|
42
42
|
"a11y.atTop": "บล็อกอยู่บนสุดแล้ว ไม่สามารถย้ายขึ้นได้",
|
|
43
43
|
"a11y.atBottom": "บล็อกอยู่ล่างสุดแล้ว ไม่สามารถย้ายลงได้",
|
|
44
|
-
"tools.paragraph.placeholder": "เขียนอะไรสักอย่าง หรือกด /
|
|
44
|
+
"tools.paragraph.placeholder": "เขียนอะไรสักอย่าง หรือกด / เพื่อเลือกเครื่องมือ",
|
|
45
45
|
"tools.table.title": "ตาราง",
|
|
46
46
|
"tools.table.clearSelection": "ล้าง",
|
|
47
47
|
"tools.table.headerColumn": "คอลัมน์หัวข้อ",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"blockSettings.dragToMove": "Kéo để di chuyển",
|
|
3
3
|
"blockSettings.clickToOpenMenu": "Nhấp để mở menu",
|
|
4
|
-
"toolbox.addBelow": "
|
|
5
|
-
"toolbox.optionAddAbove": "⌥
|
|
6
|
-
"toolbox.ctrlAddAbove": "Ctrl
|
|
4
|
+
"toolbox.addBelow": "Nhấp để thêm bên dưới",
|
|
5
|
+
"toolbox.optionAddAbove": "⌥ Nhấp để thêm bên trên",
|
|
6
|
+
"toolbox.ctrlAddAbove": "Ctrl+Nhấp để thêm bên trên",
|
|
7
7
|
"popover.search": "Tìm kiếm",
|
|
8
8
|
"popover.nothingFound": "Không tìm thấy",
|
|
9
|
-
"popover.convertTo": "Chuyển
|
|
9
|
+
"popover.convertTo": "Chuyển sang",
|
|
10
10
|
"toolNames.text": "Văn bản",
|
|
11
11
|
"toolNames.heading": "Tiêu đề",
|
|
12
12
|
"toolNames.link": "Liên kết",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"tools.header.heading5": "Tiêu đề 5",
|
|
27
27
|
"tools.header.heading6": "Tiêu đề 6",
|
|
28
28
|
"tools.list.placeholder": "Danh sách",
|
|
29
|
-
"tools.paragraph.placeholder": "Viết gì đó hoặc nhấn / để chọn",
|
|
29
|
+
"tools.paragraph.placeholder": "Viết gì đó hoặc nhấn / để chọn công cụ",
|
|
30
30
|
"tools.table.title": "Bảng",
|
|
31
31
|
"tools.table.clearSelection": "Xóa",
|
|
32
32
|
"tools.table.headerColumn": "Cột tiêu đề",
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
"a11y.dragHandleRole": "tay nắm kéo",
|
|
47
47
|
"a11y.dragStarted": "Đang kéo khối",
|
|
48
48
|
"a11y.dragStartedMultiple": "Đang kéo {count} khối",
|
|
49
|
-
"a11y.dropPosition": "Sẽ thả vào vị trí {position}
|
|
49
|
+
"a11y.dropPosition": "Sẽ thả vào vị trí {position} trong {total}",
|
|
50
50
|
"a11y.dropCancelled": "Đã hủy kéo",
|
|
51
|
-
"a11y.blockMoved": "Khối đã được di chuyển đến vị trí {position}
|
|
51
|
+
"a11y.blockMoved": "Khối đã được di chuyển đến vị trí {position} trong {total}",
|
|
52
52
|
"a11y.blocksMoved": "{count} khối đã được di chuyển đến vị trí {position}",
|
|
53
|
-
"a11y.blockDuplicated": "Khối đã được sao chép tại vị trí {position}
|
|
53
|
+
"a11y.blockDuplicated": "Khối đã được sao chép tại vị trí {position} trong {total}",
|
|
54
54
|
"a11y.blocksDuplicated": "{count} khối đã được sao chép từ vị trí {position}",
|
|
55
|
-
"a11y.movedUp": "Khối đã di chuyển lên
|
|
56
|
-
"a11y.movedDown": "Khối đã di chuyển xuống
|
|
55
|
+
"a11y.movedUp": "Khối đã di chuyển lên đến vị trí {position} trong {total}",
|
|
56
|
+
"a11y.movedDown": "Khối đã di chuyển xuống đến vị trí {position} trong {total}",
|
|
57
57
|
"a11y.atTop": "Khối đang ở trên cùng, không thể di chuyển lên",
|
|
58
58
|
"a11y.atBottom": "Khối đang ở dưới cùng, không thể di chuyển xuống"
|
|
59
59
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module HistoryAPI
|
|
3
|
+
* @copyright <CodeX> 2018
|
|
4
|
+
*
|
|
5
|
+
* Provides public methods for undo/redo operations
|
|
6
|
+
*/
|
|
7
|
+
import type { History } from '../../../../types/api';
|
|
8
|
+
import { Module } from '../../__module';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @class HistoryAPI
|
|
12
|
+
*/
|
|
13
|
+
export class HistoryAPI extends Module {
|
|
14
|
+
/**
|
|
15
|
+
* Available methods
|
|
16
|
+
* @returns {History}
|
|
17
|
+
*/
|
|
18
|
+
public get methods(): History {
|
|
19
|
+
return {
|
|
20
|
+
undo: (): void => this.undo(),
|
|
21
|
+
redo: (): void => this.redo(),
|
|
22
|
+
canUndo: (): boolean => this.canUndo(),
|
|
23
|
+
canRedo: (): boolean => this.canRedo(),
|
|
24
|
+
clear: (): void => this.clear(),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Undo the last operation
|
|
30
|
+
*/
|
|
31
|
+
public undo(): void {
|
|
32
|
+
this.Blok.YjsManager.undo();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Redo the last undone operation
|
|
37
|
+
*/
|
|
38
|
+
public redo(): void {
|
|
39
|
+
this.Blok.YjsManager.redo();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check if undo is available
|
|
44
|
+
* @returns {boolean} true if undo is available
|
|
45
|
+
*/
|
|
46
|
+
public canUndo(): boolean {
|
|
47
|
+
return this.Blok.YjsManager.canUndo();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check if redo is available
|
|
52
|
+
* @returns {boolean} true if redo is available
|
|
53
|
+
*/
|
|
54
|
+
public canRedo(): boolean {
|
|
55
|
+
return this.Blok.YjsManager.canRedo();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Clear all history
|
|
60
|
+
*/
|
|
61
|
+
public clear(): void {
|
|
62
|
+
this.Blok.YjsManager.clear();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -21,6 +21,7 @@ export class API extends Module {
|
|
|
21
21
|
caret: this.Blok.CaretAPI.methods,
|
|
22
22
|
tools: this.Blok.ToolsAPI.methods,
|
|
23
23
|
events: this.Blok.EventsAPI.methods,
|
|
24
|
+
history: this.Blok.HistoryAPI.methods,
|
|
24
25
|
listeners: this.Blok.ListenersAPI.methods,
|
|
25
26
|
notifier: this.Blok.NotifierAPI.methods,
|
|
26
27
|
sanitizer: this.Blok.SanitizerAPI.methods,
|
|
@@ -12,9 +12,10 @@ export class ReadOnlyAPI extends Module {
|
|
|
12
12
|
public get methods(): ReadOnly {
|
|
13
13
|
const getIsEnabled = (): boolean => this.isEnabled;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
return {
|
|
17
17
|
toggle: (state): Promise<boolean> => this.toggle(state),
|
|
18
|
+
set: (state): Promise<boolean> => this.set(state),
|
|
18
19
|
get isEnabled(): boolean {
|
|
19
20
|
return getIsEnabled();
|
|
20
21
|
},
|
|
@@ -30,6 +31,15 @@ export class ReadOnlyAPI extends Module {
|
|
|
30
31
|
return this.Blok.ReadOnly.toggle(state);
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Set read-only mode to the specified boolean state
|
|
36
|
+
* @param {boolean} state - read-only state to set
|
|
37
|
+
* @returns {Promise<boolean>} the new read-only state
|
|
38
|
+
*/
|
|
39
|
+
public set(state: boolean): Promise<boolean> {
|
|
40
|
+
return this.Blok.ReadOnly.set(state);
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
/**
|
|
34
44
|
* Returns current read-only state
|
|
35
45
|
*/
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { BlockToolData, OutputBlockData, PasteEvent } from '../../../../types';
|
|
8
8
|
import type { BlockTuneData } from '../../../../types/block-tunes/block-tune-data';
|
|
9
9
|
import type { BlockMutationEventMap, BlockMutationType } from '../../../../types/events/block';
|
|
10
|
+
import { BlockAddedMutationType } from '../../../../types/events/block/BlockAdded';
|
|
10
11
|
import { BlockChangedMutationType } from '../../../../types/events/block/BlockChanged';
|
|
11
12
|
import { BlockRemovedMutationType } from '../../../../types/events/block/BlockRemoved';
|
|
12
13
|
import { Module } from '../../__module';
|
|
@@ -307,6 +308,12 @@ export class BlockManager extends Module {
|
|
|
307
308
|
replaceBlock: (index, newBlock) => {
|
|
308
309
|
this.blocksStore.replace(index, newBlock);
|
|
309
310
|
},
|
|
311
|
+
onBlockRemoved: (block, index) => {
|
|
312
|
+
this.blockDidMutated(BlockRemovedMutationType, block, { index });
|
|
313
|
+
},
|
|
314
|
+
onBlockAdded: (block, index) => {
|
|
315
|
+
this.blockDidMutated(BlockAddedMutationType, block, { index });
|
|
316
|
+
},
|
|
310
317
|
},
|
|
311
318
|
this.blocksStore
|
|
312
319
|
);
|
|
@@ -43,6 +43,10 @@ export interface SyncHandlers {
|
|
|
43
43
|
updateIndentation: (block: Block) => void;
|
|
44
44
|
/** Called to replace a block at a specific index with a new block instance */
|
|
45
45
|
replaceBlock: (index: number, newBlock: Block) => void;
|
|
46
|
+
/** Called when a block is removed during undo/redo (before DOM removal) */
|
|
47
|
+
onBlockRemoved: (block: Block, index: number) => void;
|
|
48
|
+
/** Called when a block is added during undo/redo (after insertion) */
|
|
49
|
+
onBlockAdded: (block: Block, index: number) => void;
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
/**
|
|
@@ -273,10 +277,12 @@ export class BlockYjsSync {
|
|
|
273
277
|
bindEventsImmediately: true,
|
|
274
278
|
});
|
|
275
279
|
|
|
276
|
-
// Insert into blocks store at correct position - caller must handle this
|
|
277
|
-
// This is a limitation - we need the blocksStore.insert method
|
|
278
280
|
this.blocksStore.insert(targetIndex, block);
|
|
279
281
|
|
|
282
|
+
// Emit block-added event so listeners (e.g., TableCellBlocks) can
|
|
283
|
+
// claim the block for the correct cell during undo/redo
|
|
284
|
+
this.handlers.onBlockAdded(block, targetIndex);
|
|
285
|
+
|
|
280
286
|
// Apply indentation if needed
|
|
281
287
|
if (parentId !== undefined) {
|
|
282
288
|
this.handlers.updateIndentation(block);
|
|
@@ -300,6 +306,10 @@ export class BlockYjsSync {
|
|
|
300
306
|
return;
|
|
301
307
|
}
|
|
302
308
|
|
|
309
|
+
// Emit block-removed event BEFORE removal so listeners can inspect
|
|
310
|
+
// the block's DOM position (e.g., which table cell it's in)
|
|
311
|
+
this.handlers.onBlockRemoved(block, index);
|
|
312
|
+
|
|
303
313
|
// Remove from DOM
|
|
304
314
|
this.blocksStore.remove(index);
|
|
305
315
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BlocksAPI } from './api/blocks';
|
|
2
2
|
import { CaretAPI } from './api/caret';
|
|
3
3
|
import { EventsAPI } from './api/events';
|
|
4
|
+
import { HistoryAPI } from './api/history';
|
|
4
5
|
import { I18nAPI } from './api/i18n';
|
|
5
6
|
import { API } from './api/index';
|
|
6
7
|
import { InlineToolbarAPI } from './api/inlineToolbar';
|
|
@@ -44,6 +45,7 @@ export {
|
|
|
44
45
|
BlocksAPI,
|
|
45
46
|
CaretAPI,
|
|
46
47
|
EventsAPI,
|
|
48
|
+
HistoryAPI,
|
|
47
49
|
I18nAPI,
|
|
48
50
|
API,
|
|
49
51
|
InlineToolbarAPI,
|
|
@@ -91,6 +93,7 @@ export const Modules = {
|
|
|
91
93
|
BlocksAPI,
|
|
92
94
|
CaretAPI,
|
|
93
95
|
EventsAPI,
|
|
96
|
+
HistoryAPI,
|
|
94
97
|
I18nAPI,
|
|
95
98
|
API,
|
|
96
99
|
InlineToolbarAPI,
|
|
@@ -125,6 +125,17 @@ export class ReadOnly extends Module {
|
|
|
125
125
|
return this.readOnlyEnabled;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Set read-only mode to the specified boolean state
|
|
130
|
+
* Unlike toggle(), this method requires a parameter and does not have default toggle behavior
|
|
131
|
+
* Call all Modules `toggleReadOnly` method and re-render Blok
|
|
132
|
+
* @param state - read-only state to set (required)
|
|
133
|
+
* @returns the new read-only state
|
|
134
|
+
*/
|
|
135
|
+
public async set(state: boolean): Promise<boolean> {
|
|
136
|
+
return this.toggle(state);
|
|
137
|
+
}
|
|
138
|
+
|
|
128
139
|
/**
|
|
129
140
|
* Throws an error about tools which don't support read-only mode
|
|
130
141
|
*/
|
|
@@ -189,6 +189,29 @@ export class YjsManager extends Module {
|
|
|
189
189
|
this.undoHistory.redo();
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Check if undo is available.
|
|
194
|
+
* @returns true if undo is available
|
|
195
|
+
*/
|
|
196
|
+
public canUndo(): boolean {
|
|
197
|
+
return this.undoHistory.canUndo();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Check if redo is available.
|
|
202
|
+
* @returns true if redo is available
|
|
203
|
+
*/
|
|
204
|
+
public canRedo(): boolean {
|
|
205
|
+
return this.undoHistory.canRedo();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Clear all history.
|
|
210
|
+
*/
|
|
211
|
+
public clear(): void {
|
|
212
|
+
this.undoHistory.clear();
|
|
213
|
+
}
|
|
214
|
+
|
|
192
215
|
/**
|
|
193
216
|
* Stop capturing changes into current undo group.
|
|
194
217
|
* Call this to force next change into a new undo entry.
|
package/src/tools/table/index.ts
CHANGED
|
@@ -72,6 +72,7 @@ export class Table implements BlockTool {
|
|
|
72
72
|
private element: HTMLDivElement | null = null;
|
|
73
73
|
private blockId: string | undefined;
|
|
74
74
|
private pendingHighlight: PendingHighlight | null = null;
|
|
75
|
+
private isNewTable = false;
|
|
75
76
|
|
|
76
77
|
constructor({ data, config, api, readOnly, block }: BlockToolConstructorOptions<TableData, TableConfig>) {
|
|
77
78
|
this.api = api;
|
|
@@ -127,6 +128,8 @@ export class Table implements BlockTool {
|
|
|
127
128
|
wrapper.setAttribute('data-blok-table-readonly', '');
|
|
128
129
|
}
|
|
129
130
|
|
|
131
|
+
this.isNewTable = this.data.content.length === 0;
|
|
132
|
+
|
|
130
133
|
const rows = this.data.content.length || this.config.rows || DEFAULT_ROWS;
|
|
131
134
|
const cols = this.data.content[0]?.length || this.config.cols || DEFAULT_COLS;
|
|
132
135
|
|
|
@@ -178,6 +181,10 @@ export class Table implements BlockTool {
|
|
|
178
181
|
|
|
179
182
|
this.data.content = this.cellBlocks?.initializeCells(this.data.content) ?? this.data.content;
|
|
180
183
|
|
|
184
|
+
if (this.isNewTable) {
|
|
185
|
+
populateNewCells(gridEl, this.cellBlocks);
|
|
186
|
+
}
|
|
187
|
+
|
|
181
188
|
if (this.data.initialColWidth === undefined) {
|
|
182
189
|
const widths = this.data.colWidths ?? readPixelWidths(gridEl);
|
|
183
190
|
|
|
@@ -190,6 +197,12 @@ export class Table implements BlockTool {
|
|
|
190
197
|
this.initAddControls(gridEl);
|
|
191
198
|
this.initRowColControls(gridEl);
|
|
192
199
|
this.initCellSelection(gridEl);
|
|
200
|
+
|
|
201
|
+
if (this.isNewTable) {
|
|
202
|
+
const firstEditable = gridEl.querySelector<HTMLElement>('[contenteditable="true"]');
|
|
203
|
+
|
|
204
|
+
firstEditable?.focus();
|
|
205
|
+
}
|
|
193
206
|
}
|
|
194
207
|
|
|
195
208
|
public save(blockContent: HTMLElement): TableData {
|
|
@@ -313,6 +326,13 @@ export class Table implements BlockTool {
|
|
|
313
326
|
wrapper: this.element,
|
|
314
327
|
grid: gridEl,
|
|
315
328
|
i18n: this.api.i18n,
|
|
329
|
+
getNewColumnWidth: () => {
|
|
330
|
+
const colWidths = this.data.colWidths ?? readPixelWidths(gridEl);
|
|
331
|
+
|
|
332
|
+
return this.data.initialColWidth !== undefined
|
|
333
|
+
? Math.round((this.data.initialColWidth / 2) * 100) / 100
|
|
334
|
+
: computeHalfAvgWidth(colWidths);
|
|
335
|
+
},
|
|
316
336
|
onAddRow: () => {
|
|
317
337
|
this.grid.addRow(gridEl);
|
|
318
338
|
populateNewCells(gridEl, this.cellBlocks);
|
|
@@ -56,6 +56,8 @@ interface TableAddControlsOptions {
|
|
|
56
56
|
onDragAddCol: () => void;
|
|
57
57
|
onDragRemoveCol: () => void;
|
|
58
58
|
onDragEnd: () => void;
|
|
59
|
+
/** Returns the pixel width of a newly added column, used as the drag unit size. */
|
|
60
|
+
getNewColumnWidth?: () => number;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
/**
|
|
@@ -89,6 +91,7 @@ export class TableAddControls {
|
|
|
89
91
|
private boundPointerUp: (e: PointerEvent) => void;
|
|
90
92
|
private boundRowPointerDown: (e: PointerEvent) => void;
|
|
91
93
|
private boundColPointerDown: (e: PointerEvent) => void;
|
|
94
|
+
private getNewColumnWidth: (() => number) | undefined;
|
|
92
95
|
|
|
93
96
|
constructor(options: TableAddControlsOptions) {
|
|
94
97
|
this.wrapper = options.wrapper;
|
|
@@ -103,6 +106,7 @@ export class TableAddControls {
|
|
|
103
106
|
this.onDragAddCol = options.onDragAddCol;
|
|
104
107
|
this.onDragRemoveCol = options.onDragRemoveCol;
|
|
105
108
|
this.onDragEnd = options.onDragEnd;
|
|
109
|
+
this.getNewColumnWidth = options.getNewColumnWidth;
|
|
106
110
|
this.boundMouseMove = this.handleMouseMove.bind(this);
|
|
107
111
|
this.boundMouseLeave = this.handleMouseLeave.bind(this);
|
|
108
112
|
this.boundPointerMove = this.handlePointerMove.bind(this);
|
|
@@ -283,6 +287,10 @@ export class TableAddControls {
|
|
|
283
287
|
return lastRow?.offsetHeight || 30;
|
|
284
288
|
}
|
|
285
289
|
|
|
290
|
+
if (this.getNewColumnWidth) {
|
|
291
|
+
return this.getNewColumnWidth();
|
|
292
|
+
}
|
|
293
|
+
|
|
286
294
|
const firstRow = this.grid.querySelector('[data-blok-table-row]');
|
|
287
295
|
|
|
288
296
|
if (!firstRow) {
|
|
@@ -229,6 +229,7 @@ export class TableCellBlocks {
|
|
|
229
229
|
* Initialize all cells with blocks.
|
|
230
230
|
* - Empty cells or legacy string cells get a new paragraph block.
|
|
231
231
|
* - Cells that already have block references get those blocks mounted.
|
|
232
|
+
* - If referenced blocks are missing from BlockManager, a fallback paragraph is created.
|
|
232
233
|
*/
|
|
233
234
|
public initializeCells(content: LegacyCellContent[][]): CellContent[][] {
|
|
234
235
|
const rowElements = this.gridElement.querySelectorAll(`[${ROW_ATTR}]`);
|
|
@@ -257,9 +258,12 @@ export class TableCellBlocks {
|
|
|
257
258
|
return;
|
|
258
259
|
}
|
|
259
260
|
|
|
260
|
-
|
|
261
|
-
this.mountBlocksInCell(container, cellContent.blocks)
|
|
262
|
-
|
|
261
|
+
const mountedIds = isCellWithBlocks(cellContent)
|
|
262
|
+
? this.mountBlocksInCell(container, cellContent.blocks)
|
|
263
|
+
: [];
|
|
264
|
+
|
|
265
|
+
if (mountedIds.length > 0) {
|
|
266
|
+
normalizedRow.push({ blocks: mountedIds });
|
|
263
267
|
} else {
|
|
264
268
|
const text = typeof cellContent === 'string' ? cellContent : '';
|
|
265
269
|
const block = this.api.blocks.insert('paragraph', { text }, {}, this.api.blocks.getBlocksCount(), false);
|
|
@@ -291,9 +295,12 @@ export class TableCellBlocks {
|
|
|
291
295
|
}
|
|
292
296
|
|
|
293
297
|
/**
|
|
294
|
-
* Mount existing blocks into a cell container by their IDs
|
|
298
|
+
* Mount existing blocks into a cell container by their IDs.
|
|
299
|
+
* Returns the IDs of blocks that were successfully mounted.
|
|
295
300
|
*/
|
|
296
|
-
private mountBlocksInCell(container: HTMLElement, blockIds: string[]):
|
|
301
|
+
private mountBlocksInCell(container: HTMLElement, blockIds: string[]): string[] {
|
|
302
|
+
const mountedIds: string[] = [];
|
|
303
|
+
|
|
297
304
|
for (const blockId of blockIds) {
|
|
298
305
|
const index = this.api.blocks.getBlockIndex(blockId);
|
|
299
306
|
|
|
@@ -308,7 +315,10 @@ export class TableCellBlocks {
|
|
|
308
315
|
}
|
|
309
316
|
|
|
310
317
|
container.appendChild(block.holder);
|
|
318
|
+
mountedIds.push(blockId);
|
|
311
319
|
}
|
|
320
|
+
|
|
321
|
+
return mountedIds;
|
|
312
322
|
}
|
|
313
323
|
|
|
314
324
|
/**
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { BlocksAPI } from '../components/modules/api/blocks';
|
|
3
3
|
import { CaretAPI } from '../components/modules/api/caret';
|
|
4
4
|
import { EventsAPI } from '../components/modules/api/events';
|
|
5
|
+
import { HistoryAPI } from '../components/modules/api/history';
|
|
5
6
|
import { I18nAPI } from '../components/modules/api/i18n';
|
|
6
7
|
import { API } from '../components/modules/api/index';
|
|
7
8
|
import { InlineToolbarAPI } from '../components/modules/api/inlineToolbar';
|
|
@@ -45,6 +46,7 @@ export interface BlokModules {
|
|
|
45
46
|
CaretAPI: CaretAPI,
|
|
46
47
|
ToolsAPI: ToolsAPI,
|
|
47
48
|
EventsAPI: EventsAPI,
|
|
49
|
+
HistoryAPI: HistoryAPI,
|
|
48
50
|
I18nAPI: I18nAPI,
|
|
49
51
|
API: API,
|
|
50
52
|
InlineToolbarAPI: InlineToolbarAPI,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes Blok's history API
|
|
3
|
+
*/
|
|
4
|
+
export interface History {
|
|
5
|
+
/**
|
|
6
|
+
* Undo the last operation
|
|
7
|
+
*/
|
|
8
|
+
undo(): void;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Redo the last undone operation
|
|
12
|
+
*/
|
|
13
|
+
redo(): void;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if undo is available
|
|
17
|
+
*
|
|
18
|
+
* @returns {boolean} true if undo is available
|
|
19
|
+
*/
|
|
20
|
+
canUndo(): boolean;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Check if redo is available
|
|
24
|
+
*
|
|
25
|
+
* @returns {boolean} true if redo is available
|
|
26
|
+
*/
|
|
27
|
+
canRedo(): boolean;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Clear all history
|
|
31
|
+
*/
|
|
32
|
+
clear(): void;
|
|
33
|
+
}
|
package/types/api/index.d.ts
CHANGED
package/types/api/readonly.d.ts
CHANGED
|
@@ -3,10 +3,20 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export interface ReadOnly {
|
|
5
5
|
/**
|
|
6
|
-
* Set
|
|
6
|
+
* Set read-only mode to the specified boolean state
|
|
7
7
|
*
|
|
8
|
-
* @param {Boolean
|
|
8
|
+
* @param {Boolean} state - read-only state to set
|
|
9
|
+
* @returns {Promise<boolean>} the new read-only state
|
|
10
|
+
*/
|
|
11
|
+
set: (state: boolean) => Promise<boolean>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Toggle read-only state (deprecated - use set() instead)
|
|
15
|
+
* Without parameter, toggles current state. With parameter, sets to specified state.
|
|
16
|
+
*
|
|
17
|
+
* @param {Boolean|undefined} state - optional state to set (if omitted, toggles)
|
|
9
18
|
* @returns {Promise<boolean>} current value
|
|
19
|
+
* @deprecated Use `set()` method for clearer intent
|
|
10
20
|
*/
|
|
11
21
|
toggle: (state?: boolean) => Promise<boolean>;
|
|
12
22
|
|
package/types/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
Blocks,
|
|
17
17
|
Caret,
|
|
18
18
|
Events,
|
|
19
|
+
History,
|
|
19
20
|
InlineToolbar,
|
|
20
21
|
Listeners,
|
|
21
22
|
Notifier,
|
|
@@ -90,6 +91,7 @@ export {
|
|
|
90
91
|
Blocks,
|
|
91
92
|
Caret,
|
|
92
93
|
Events,
|
|
94
|
+
History,
|
|
93
95
|
InlineToolbar,
|
|
94
96
|
Listeners,
|
|
95
97
|
Notifier,
|
|
@@ -127,6 +129,7 @@ export interface API {
|
|
|
127
129
|
caret: Caret;
|
|
128
130
|
tools: Tools;
|
|
129
131
|
events: Events;
|
|
132
|
+
history: History;
|
|
130
133
|
listeners: Listeners;
|
|
131
134
|
notifier: Notifier;
|
|
132
135
|
sanitizer: Sanitizer;
|