@jackuait/blok 0.6.0-beta.0 → 0.6.0-beta.10
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-Bu9S3SsR.mjs → blok-Buf0btS7.mjs} +2267 -2024
- package/dist/chunks/{i18next-loader-CKuXJ0Av.mjs → i18next-loader-CVf_ZfwA.mjs} +1 -1
- package/dist/chunks/{index-jtZaryNw.mjs → index-C6jsfLLp.mjs} +1 -1
- package/dist/chunks/{inline-tool-convert-CFjyrH30.mjs → inline-tool-convert-BKKEoOqB.mjs} +710 -570
- package/dist/chunks/{messages-C5b7hr_E.mjs → messages-1fC8IMyX.mjs} +16 -2
- package/dist/chunks/{messages-CQj2JU2j.mjs → messages-7QoX8DkW.mjs} +23 -9
- package/dist/{messages-LvFKBBPa.mjs → chunks/messages-7W4d0DwD.mjs} +15 -1
- package/dist/{messages-Bn253WWC.mjs → chunks/messages-9SihnaXQ.mjs} +14 -0
- package/dist/{messages-Bf6Y3_GI.mjs → chunks/messages-B1Aww8q7.mjs} +16 -2
- package/dist/{messages-pA5TvcAj.mjs → chunks/messages-BB5z9Uba.mjs} +14 -0
- package/dist/chunks/{messages-wdqp4610.mjs → messages-BC86qLvI.mjs} +17 -3
- package/dist/chunks/{messages-o24dK6CU.mjs → messages-BELRf6DU.mjs} +16 -2
- package/dist/chunks/{messages-CUZ1x1QD.mjs → messages-BFG6Wlgy.mjs} +16 -2
- package/dist/{messages-B5puUm7R.mjs → chunks/messages-BL0tXcDf.mjs} +15 -1
- package/dist/chunks/{messages-zS1AXZ0y.mjs → messages-BMXCuEKO.mjs} +19 -5
- package/dist/{messages-CyDU5lz9.mjs → chunks/messages-BMv4xwIr.mjs} +16 -2
- package/dist/chunks/{messages-BeUhMpsr.mjs → messages-BSbjsyHY.mjs} +25 -11
- package/dist/chunks/{messages-JGsXAReJ.mjs → messages-BU2nlrLK.mjs} +16 -2
- package/dist/chunks/{messages-srxrv8Yh.mjs → messages-BWF-zUpY.mjs} +17 -3
- package/dist/{messages-CXHd9SUK.mjs → chunks/messages-BYyy6Wqf.mjs} +14 -0
- package/dist/chunks/{messages-DOlC_Tty.mjs → messages-BdeLo0N9.mjs} +24 -10
- package/dist/chunks/{messages-B5jGUnOy.mjs → messages-Bmu_S7GM.mjs} +14 -0
- package/dist/chunks/{messages-BmKCChWZ.mjs → messages-BoJc_p1r.mjs} +14 -0
- package/dist/chunks/{messages-CvaqJFN-.mjs → messages-BogRq8lt.mjs} +15 -1
- package/dist/chunks/{messages-NP1myMGI.mjs → messages-BrPFGbM-.mjs} +14 -0
- package/dist/chunks/{messages-D00OjS2n.mjs → messages-C2htQ_3F.mjs} +24 -10
- package/dist/chunks/{messages-BiExzWJv.mjs → messages-C99mq906.mjs} +15 -1
- package/dist/chunks/{messages-CkFT2gle.mjs → messages-C9eaarcK.mjs} +20 -6
- package/dist/chunks/{messages-BrJHUxQL.mjs → messages-CJdUsQ-c.mjs} +15 -1
- package/dist/chunks/messages-CKI54h6O.mjs +62 -0
- package/dist/{messages-CrsJ1TEJ.mjs → chunks/messages-CLhcMlTc.mjs} +15 -1
- package/dist/{messages-CnvW8Slp.mjs → chunks/messages-CMkNSDTo.mjs} +17 -3
- package/dist/{messages-BlpqL8vG.mjs → chunks/messages-CQwpzUFp.mjs} +19 -5
- package/dist/chunks/{messages-Cu08aLS3.mjs → messages-CVw84KdI.mjs} +21 -7
- package/dist/chunks/{messages-B9Oba7sq.mjs → messages-CY8_RyFE.mjs} +15 -1
- package/dist/chunks/{messages-B5hdXZwA.mjs → messages-CZygwLwM.mjs} +15 -1
- package/dist/chunks/{messages-CVeWVKsV.mjs → messages-CnwibSvh.mjs} +14 -0
- package/dist/chunks/{messages-DbVquYKN.mjs → messages-CqWJcCbY.mjs} +14 -0
- package/dist/{messages-Dg92dXZ5.mjs → chunks/messages-CvGLfqmV.mjs} +14 -0
- package/dist/{messages-AHESHJm_.mjs → chunks/messages-CzTufCHu.mjs} +14 -0
- package/dist/chunks/{messages-Cj-t1bdy.mjs → messages-CznZadDf.mjs} +15 -1
- package/dist/chunks/{messages-DMQIHGRj.mjs → messages-D-ZtY5v0.mjs} +14 -0
- package/dist/chunks/{messages-rRSHQDCX.mjs → messages-D1Hv8XGo.mjs} +14 -0
- package/dist/chunks/{messages-0tDXLuyH.mjs → messages-D5C3J9qr.mjs} +15 -1
- package/dist/chunks/{messages-RvMHb2Ht.mjs → messages-D5iv1Kox.mjs} +16 -2
- package/dist/{messages-zSzDzXej.mjs → chunks/messages-DBRw-7Zc.mjs} +16 -2
- package/dist/chunks/{messages-CeCjVKMW.mjs → messages-DBn76jVV.mjs} +16 -2
- package/dist/chunks/{messages-C7I_AVH2.mjs → messages-DJDG55Vq.mjs} +16 -2
- package/dist/{messages-DDLgIPDF.mjs → chunks/messages-DLfR5bMd.mjs} +16 -2
- package/dist/{messages-CbhuIWRJ.mjs → chunks/messages-DT4dP5uK.mjs} +15 -1
- package/dist/chunks/{messages-B66ZSDCJ.mjs → messages-DhLKYm2j.mjs} +15 -1
- package/dist/{messages-BPqWKx5Z.mjs → chunks/messages-Diu6jAaR.mjs} +17 -3
- package/dist/{messages-BA0rcTCY.mjs → chunks/messages-DnIhyAJk.mjs} +18 -4
- package/dist/chunks/{messages-DV6shA9b.mjs → messages-DnXLrlHh.mjs} +14 -0
- package/dist/chunks/{messages-DcKOuncK.mjs → messages-DprmQg6V.mjs} +16 -2
- package/dist/{messages-CJoBtXU6.mjs → chunks/messages-DqM1LFg5.mjs} +14 -0
- package/dist/chunks/{messages-Cyi2AMmz.mjs → messages-DvFLX36Q.mjs} +25 -11
- package/dist/chunks/{messages-DnbbyJT3.mjs → messages-Dz9L52ol.mjs} +16 -2
- package/dist/chunks/{messages-GC2PhgV3.mjs → messages-Dzwxv9v1.mjs} +23 -9
- package/dist/chunks/{messages-Q4kc_ZtL.mjs → messages-JELdtT6E.mjs} +15 -1
- package/dist/{messages-DY94ykcE.mjs → chunks/messages-LPVfA-8K.mjs} +14 -0
- package/dist/{messages-Cr-RJ7YB.mjs → chunks/messages-O5tQus_0.mjs} +14 -0
- package/dist/chunks/{messages-CbMyJSzS.mjs → messages-Q7AO_FLv.mjs} +17 -3
- package/dist/chunks/{messages-2_xedlYw.mjs → messages-R3hUSvr3.mjs} +15 -1
- package/dist/{messages-CUy1vn-b.mjs → chunks/messages-Xq8UmkVs.mjs} +14 -0
- package/dist/chunks/{messages-BBJgd5jG.mjs → messages-Z9nEU2xK.mjs} +16 -2
- package/dist/chunks/{messages-Cm9aLHeX.mjs → messages-_ErNTNhk.mjs} +15 -1
- package/dist/chunks/{messages-JZUhXTuV.mjs → messages-_ncGrKHh.mjs} +16 -2
- package/dist/chunks/{messages-ftMcCEuO.mjs → messages-kep5wtm4.mjs} +15 -1
- package/dist/chunks/{messages-DteYq0rv.mjs → messages-uKX8WBaD.mjs} +16 -2
- package/dist/chunks/{messages-Bdv-IkfG.mjs → messages-w7v1GNaE.mjs} +15 -1
- package/dist/cli.mjs +50 -0
- package/dist/full.mjs +15 -15
- package/dist/locales.mjs +102 -88
- package/dist/{messages-C5b7hr_E.mjs → messages-1fC8IMyX.mjs} +16 -2
- package/dist/{messages-CQj2JU2j.mjs → messages-7QoX8DkW.mjs} +23 -9
- package/dist/{chunks/messages-LvFKBBPa.mjs → messages-7W4d0DwD.mjs} +15 -1
- package/dist/{chunks/messages-Bn253WWC.mjs → messages-9SihnaXQ.mjs} +14 -0
- package/dist/{chunks/messages-Bf6Y3_GI.mjs → messages-B1Aww8q7.mjs} +16 -2
- package/dist/{chunks/messages-pA5TvcAj.mjs → messages-BB5z9Uba.mjs} +14 -0
- package/dist/{messages-wdqp4610.mjs → messages-BC86qLvI.mjs} +17 -3
- package/dist/{messages-o24dK6CU.mjs → messages-BELRf6DU.mjs} +16 -2
- package/dist/{messages-CUZ1x1QD.mjs → messages-BFG6Wlgy.mjs} +16 -2
- package/dist/{chunks/messages-B5puUm7R.mjs → messages-BL0tXcDf.mjs} +15 -1
- package/dist/{messages-zS1AXZ0y.mjs → messages-BMXCuEKO.mjs} +19 -5
- package/dist/{chunks/messages-CyDU5lz9.mjs → messages-BMv4xwIr.mjs} +16 -2
- package/dist/{messages-BeUhMpsr.mjs → messages-BSbjsyHY.mjs} +25 -11
- package/dist/{messages-JGsXAReJ.mjs → messages-BU2nlrLK.mjs} +16 -2
- package/dist/{messages-srxrv8Yh.mjs → messages-BWF-zUpY.mjs} +17 -3
- package/dist/{chunks/messages-CXHd9SUK.mjs → messages-BYyy6Wqf.mjs} +14 -0
- package/dist/{messages-DOlC_Tty.mjs → messages-BdeLo0N9.mjs} +24 -10
- package/dist/{messages-B5jGUnOy.mjs → messages-Bmu_S7GM.mjs} +14 -0
- package/dist/{messages-BmKCChWZ.mjs → messages-BoJc_p1r.mjs} +14 -0
- package/dist/{messages-CvaqJFN-.mjs → messages-BogRq8lt.mjs} +15 -1
- package/dist/{messages-NP1myMGI.mjs → messages-BrPFGbM-.mjs} +14 -0
- package/dist/{messages-D00OjS2n.mjs → messages-C2htQ_3F.mjs} +24 -10
- package/dist/{messages-BiExzWJv.mjs → messages-C99mq906.mjs} +15 -1
- package/dist/{messages-CkFT2gle.mjs → messages-C9eaarcK.mjs} +20 -6
- package/dist/{messages-BrJHUxQL.mjs → messages-CJdUsQ-c.mjs} +15 -1
- package/dist/messages-CKI54h6O.mjs +62 -0
- package/dist/{chunks/messages-CrsJ1TEJ.mjs → messages-CLhcMlTc.mjs} +15 -1
- package/dist/{chunks/messages-CnvW8Slp.mjs → messages-CMkNSDTo.mjs} +17 -3
- package/dist/{chunks/messages-BlpqL8vG.mjs → messages-CQwpzUFp.mjs} +19 -5
- package/dist/{messages-Cu08aLS3.mjs → messages-CVw84KdI.mjs} +21 -7
- package/dist/{messages-B9Oba7sq.mjs → messages-CY8_RyFE.mjs} +15 -1
- package/dist/{messages-B5hdXZwA.mjs → messages-CZygwLwM.mjs} +15 -1
- package/dist/{messages-CVeWVKsV.mjs → messages-CnwibSvh.mjs} +14 -0
- package/dist/{messages-DbVquYKN.mjs → messages-CqWJcCbY.mjs} +14 -0
- package/dist/{chunks/messages-Dg92dXZ5.mjs → messages-CvGLfqmV.mjs} +14 -0
- package/dist/{chunks/messages-AHESHJm_.mjs → messages-CzTufCHu.mjs} +14 -0
- package/dist/{messages-Cj-t1bdy.mjs → messages-CznZadDf.mjs} +15 -1
- package/dist/{messages-DMQIHGRj.mjs → messages-D-ZtY5v0.mjs} +14 -0
- package/dist/{messages-rRSHQDCX.mjs → messages-D1Hv8XGo.mjs} +14 -0
- package/dist/{messages-0tDXLuyH.mjs → messages-D5C3J9qr.mjs} +15 -1
- package/dist/{messages-RvMHb2Ht.mjs → messages-D5iv1Kox.mjs} +16 -2
- package/dist/{chunks/messages-zSzDzXej.mjs → messages-DBRw-7Zc.mjs} +16 -2
- package/dist/{messages-CeCjVKMW.mjs → messages-DBn76jVV.mjs} +16 -2
- package/dist/{messages-C7I_AVH2.mjs → messages-DJDG55Vq.mjs} +16 -2
- package/dist/{chunks/messages-DDLgIPDF.mjs → messages-DLfR5bMd.mjs} +16 -2
- package/dist/{chunks/messages-CbhuIWRJ.mjs → messages-DT4dP5uK.mjs} +15 -1
- package/dist/{messages-B66ZSDCJ.mjs → messages-DhLKYm2j.mjs} +15 -1
- package/dist/{chunks/messages-BPqWKx5Z.mjs → messages-Diu6jAaR.mjs} +17 -3
- package/dist/{chunks/messages-BA0rcTCY.mjs → messages-DnIhyAJk.mjs} +18 -4
- package/dist/{messages-DV6shA9b.mjs → messages-DnXLrlHh.mjs} +14 -0
- package/dist/{messages-DcKOuncK.mjs → messages-DprmQg6V.mjs} +16 -2
- package/dist/{chunks/messages-CJoBtXU6.mjs → messages-DqM1LFg5.mjs} +14 -0
- package/dist/{messages-Cyi2AMmz.mjs → messages-DvFLX36Q.mjs} +25 -11
- package/dist/{messages-DnbbyJT3.mjs → messages-Dz9L52ol.mjs} +16 -2
- package/dist/{messages-GC2PhgV3.mjs → messages-Dzwxv9v1.mjs} +23 -9
- package/dist/{messages-Q4kc_ZtL.mjs → messages-JELdtT6E.mjs} +15 -1
- package/dist/{chunks/messages-DY94ykcE.mjs → messages-LPVfA-8K.mjs} +14 -0
- package/dist/{chunks/messages-Cr-RJ7YB.mjs → messages-O5tQus_0.mjs} +14 -0
- package/dist/{messages-CbMyJSzS.mjs → messages-Q7AO_FLv.mjs} +17 -3
- package/dist/{messages-2_xedlYw.mjs → messages-R3hUSvr3.mjs} +15 -1
- package/dist/{chunks/messages-CUy1vn-b.mjs → messages-Xq8UmkVs.mjs} +14 -0
- package/dist/{messages-BBJgd5jG.mjs → messages-Z9nEU2xK.mjs} +16 -2
- package/dist/{messages-Cm9aLHeX.mjs → messages-_ErNTNhk.mjs} +15 -1
- package/dist/{messages-JZUhXTuV.mjs → messages-_ncGrKHh.mjs} +16 -2
- package/dist/{messages-ftMcCEuO.mjs → messages-kep5wtm4.mjs} +15 -1
- package/dist/{messages-DteYq0rv.mjs → messages-uKX8WBaD.mjs} +16 -2
- package/dist/{messages-Bdv-IkfG.mjs → messages-w7v1GNaE.mjs} +15 -1
- package/dist/tools.mjs +2005 -1267
- package/dist/vendor.LICENSE.txt +1 -1
- package/package.json +15 -14
- 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/block-tunes/block-tune-delete.ts +3 -2
- package/src/components/blocks.ts +23 -6
- package/src/components/constants/data-attributes.ts +2 -0
- package/src/components/i18n/locales/am/messages.json +15 -1
- package/src/components/i18n/locales/ar/messages.json +14 -0
- package/src/components/i18n/locales/az/messages.json +14 -0
- package/src/components/i18n/locales/bg/messages.json +14 -0
- package/src/components/i18n/locales/bn/messages.json +25 -11
- package/src/components/i18n/locales/bs/messages.json +15 -1
- package/src/components/i18n/locales/cs/messages.json +14 -0
- package/src/components/i18n/locales/da/messages.json +14 -0
- package/src/components/i18n/locales/de/messages.json +14 -0
- package/src/components/i18n/locales/dv/messages.json +15 -1
- package/src/components/i18n/locales/el/messages.json +15 -1
- package/src/components/i18n/locales/en/messages.json +14 -0
- package/src/components/i18n/locales/es/messages.json +14 -0
- package/src/components/i18n/locales/et/messages.json +14 -0
- package/src/components/i18n/locales/fa/messages.json +15 -1
- package/src/components/i18n/locales/fi/messages.json +15 -1
- package/src/components/i18n/locales/fil/messages.json +20 -6
- package/src/components/i18n/locales/fr/messages.json +15 -1
- package/src/components/i18n/locales/gu/messages.json +15 -1
- package/src/components/i18n/locales/he/messages.json +14 -0
- package/src/components/i18n/locales/hi/messages.json +23 -9
- package/src/components/i18n/locales/hr/messages.json +14 -0
- package/src/components/i18n/locales/hu/messages.json +14 -0
- package/src/components/i18n/locales/hy/messages.json +16 -2
- package/src/components/i18n/locales/id/messages.json +19 -5
- package/src/components/i18n/locales/it/messages.json +14 -0
- package/src/components/i18n/locales/ja/messages.json +14 -0
- package/src/components/i18n/locales/ka/messages.json +15 -1
- package/src/components/i18n/locales/km/messages.json +16 -2
- package/src/components/i18n/locales/kn/messages.json +16 -2
- package/src/components/i18n/locales/ko/messages.json +14 -0
- package/src/components/i18n/locales/ku/messages.json +16 -2
- package/src/components/i18n/locales/lo/messages.json +15 -1
- package/src/components/i18n/locales/lt/messages.json +15 -1
- package/src/components/i18n/locales/lv/messages.json +15 -1
- package/src/components/i18n/locales/mk/messages.json +16 -2
- package/src/components/i18n/locales/ml/messages.json +16 -2
- package/src/components/i18n/locales/mn/messages.json +16 -2
- package/src/components/i18n/locales/mr/messages.json +24 -10
- package/src/components/i18n/locales/ms/messages.json +17 -3
- package/src/components/i18n/locales/my/messages.json +16 -2
- package/src/components/i18n/locales/ne/messages.json +24 -10
- package/src/components/i18n/locales/nl/messages.json +15 -1
- package/src/components/i18n/locales/no/messages.json +16 -2
- package/src/components/i18n/locales/pa/messages.json +15 -1
- package/src/components/i18n/locales/pl/messages.json +14 -0
- package/src/components/i18n/locales/ps/messages.json +17 -3
- package/src/components/i18n/locales/pt/messages.json +14 -0
- package/src/components/i18n/locales/ro/messages.json +15 -1
- package/src/components/i18n/locales/ru/messages.json +14 -0
- package/src/components/i18n/locales/sd/messages.json +16 -2
- package/src/components/i18n/locales/si/messages.json +23 -9
- package/src/components/i18n/locales/sk/messages.json +15 -1
- package/src/components/i18n/locales/sl/messages.json +16 -2
- package/src/components/i18n/locales/sq/messages.json +16 -2
- package/src/components/i18n/locales/sr/messages.json +16 -2
- package/src/components/i18n/locales/sv/messages.json +16 -2
- package/src/components/i18n/locales/sw/messages.json +16 -2
- package/src/components/i18n/locales/ta/messages.json +21 -7
- package/src/components/i18n/locales/te/messages.json +40 -26
- package/src/components/i18n/locales/th/messages.json +19 -5
- package/src/components/i18n/locales/tr/messages.json +15 -1
- package/src/components/i18n/locales/ug/messages.json +16 -2
- package/src/components/i18n/locales/uk/messages.json +15 -1
- package/src/components/i18n/locales/ur/messages.json +15 -1
- package/src/components/i18n/locales/vi/messages.json +25 -11
- package/src/components/i18n/locales/yi/messages.json +16 -2
- package/src/components/i18n/locales/zh/messages.json +15 -1
- package/src/components/icons/index.ts +104 -83
- package/src/components/modules/api/blocks.ts +35 -2
- package/src/components/modules/api/history.ts +64 -0
- package/src/components/modules/api/index.ts +2 -0
- package/src/components/modules/api/readonly.ts +11 -1
- package/src/components/modules/blockEvents/composers/markdownShortcuts.ts +12 -1
- package/src/components/modules/blockManager/blockManager.ts +7 -0
- package/src/components/modules/blockManager/operations.ts +3 -2
- package/src/components/modules/blockManager/types.ts +3 -1
- package/src/components/modules/blockManager/yjs-sync.ts +12 -2
- package/src/components/modules/index.ts +3 -0
- package/src/components/modules/normalizeInlineImages.ts +263 -0
- package/src/components/modules/readonly.ts +11 -0
- package/src/components/modules/rectangleSelection.ts +19 -3
- package/src/components/modules/saver.ts +7 -3
- package/src/components/modules/toolbar/blockSettings.ts +3 -3
- package/src/components/modules/toolbar/index.ts +72 -14
- package/src/components/modules/toolbar/plus-button.ts +24 -3
- package/src/components/modules/toolbar/settings-toggler.ts +3 -5
- package/src/components/modules/ui.ts +46 -68
- package/src/components/modules/uiControllers/controllers/blockHover.ts +49 -61
- package/src/components/modules/uiControllers/controllers/keyboard.ts +17 -11
- package/src/components/modules/uiControllers/handlers/click.ts +0 -12
- package/src/components/modules/yjs/index.ts +23 -0
- package/src/components/ui/toolbox.ts +41 -6
- package/src/components/utils/placeholder.ts +16 -0
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +2 -1
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +6 -1
- package/src/components/utils/popover/index.ts +1 -0
- package/src/components/utils/popover/popover-abstract.ts +11 -1
- package/src/components/utils/popover/popover-desktop.ts +27 -8
- package/src/components/utils/popover/popover-registry.ts +188 -0
- package/src/components/utils/sanitizer.ts +23 -2
- package/src/components/utils/tooltip.ts +2 -24
- package/src/styles/main.css +22 -0
- package/src/tools/paragraph/index.ts +12 -4
- package/src/tools/table/data-normalizer.ts +1 -0
- package/src/tools/table/index.ts +283 -346
- package/src/tools/table/table-add-controls.ts +353 -47
- package/src/tools/table/table-cell-blocks.ts +95 -7
- package/src/tools/table/table-cell-selection.ts +648 -0
- package/src/tools/table/table-core.ts +21 -32
- package/src/tools/table/table-grip-visuals.ts +96 -0
- package/src/tools/table/table-heading-toggle.ts +127 -0
- package/src/tools/table/table-operations.ts +475 -0
- package/src/tools/table/table-resize.ts +27 -6
- package/src/tools/table/table-restrictions.ts +64 -0
- package/src/tools/table/table-row-col-action-handler.ts +190 -0
- package/src/tools/table/table-row-col-controls.ts +265 -211
- package/src/tools/table/table-row-col-drag.ts +4 -4
- package/src/tools/table/table-row-col-popover.ts +225 -0
- package/src/tools/table/types.ts +4 -0
- package/src/types-internal/blok-modules.d.ts +2 -0
- package/types/api/blocks.d.ts +8 -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 +10 -0
- package/types/tools/table.d.ts +67 -0
- package/types/tools-entry.d.ts +4 -0
- package/types/utils/popover/popover-item.d.ts +6 -0
- package/types/utils/popover/popover.d.ts +7 -0
- package/dist/chunks/messages-CySyfkMU.mjs +0 -48
- package/dist/messages-CySyfkMU.mjs +0 -48
|
@@ -191,6 +191,7 @@ export class BlockOperations {
|
|
|
191
191
|
replace = false,
|
|
192
192
|
tunes,
|
|
193
193
|
skipYjsSync = false,
|
|
194
|
+
appendToWorkingArea = false,
|
|
194
195
|
} = options;
|
|
195
196
|
|
|
196
197
|
const targetIndex = index ?? this.currentBlockIndex + (replace ? 0 : 1);
|
|
@@ -235,7 +236,7 @@ export class BlockOperations {
|
|
|
235
236
|
});
|
|
236
237
|
}
|
|
237
238
|
|
|
238
|
-
blocksStore.insert(targetIndex, block, replace);
|
|
239
|
+
blocksStore.insert(targetIndex, block, replace, appendToWorkingArea);
|
|
239
240
|
|
|
240
241
|
/**
|
|
241
242
|
* Force call of didMutated event on Block insertion
|
|
@@ -298,7 +299,7 @@ export class BlockOperations {
|
|
|
298
299
|
public insertAtEnd(blocksStore: BlocksStore): Block {
|
|
299
300
|
this.currentBlockIndexValue = this.repository.length - 1;
|
|
300
301
|
|
|
301
|
-
return this.insert({}, blocksStore);
|
|
302
|
+
return this.insert({ appendToWorkingArea: true }, blocksStore);
|
|
302
303
|
}
|
|
303
304
|
|
|
304
305
|
/**
|
|
@@ -48,6 +48,8 @@ export interface InsertBlockOptions {
|
|
|
48
48
|
tunes?: { [name: string]: BlockTuneData };
|
|
49
49
|
/** Skip syncing to Yjs (caller handles sync separately) */
|
|
50
50
|
skipYjsSync?: boolean;
|
|
51
|
+
/** When true, append block to workingArea instead of positioning relative to adjacent blocks */
|
|
52
|
+
appendToWorkingArea?: boolean;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
/**
|
|
@@ -105,7 +107,7 @@ export interface ConvertBlockOptions {
|
|
|
105
107
|
*/
|
|
106
108
|
export type BlocksStore = Blocks & {
|
|
107
109
|
[index: number]: Block | undefined;
|
|
108
|
-
insert(index: number, block: Block, replace?: boolean): void;
|
|
110
|
+
insert(index: number, block: Block, replace?: boolean, appendToWorkingArea?: boolean): void;
|
|
109
111
|
remove(index: number): void;
|
|
110
112
|
move(toIndex: number, fromIndex: number, skipDOM?: boolean): void;
|
|
111
113
|
};
|
|
@@ -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,
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { generateBlockId } from '../utils/id-generator';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Minimal block shape expected by the normalizer.
|
|
5
|
+
* Matches the SaverValidatedData shape from the saver pipeline.
|
|
6
|
+
*/
|
|
7
|
+
interface NormalizableBlock {
|
|
8
|
+
id?: string;
|
|
9
|
+
tool?: string;
|
|
10
|
+
data?: Record<string, unknown>;
|
|
11
|
+
isValid: boolean;
|
|
12
|
+
parentId?: string | null;
|
|
13
|
+
contentIds?: string[];
|
|
14
|
+
tunes?: Record<string, unknown>;
|
|
15
|
+
time?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Shape of a table cell within the table's content data.
|
|
20
|
+
*/
|
|
21
|
+
interface TableCell {
|
|
22
|
+
blocks: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Tracking info for a paragraph whose inline images need extraction.
|
|
27
|
+
*/
|
|
28
|
+
interface ExtractionInfo {
|
|
29
|
+
parentTableId: string;
|
|
30
|
+
imgSrcs: string[];
|
|
31
|
+
cleanedText: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Regex to match <img> tags and capture their src attribute.
|
|
36
|
+
* Handles both single and double quotes around src value.
|
|
37
|
+
*/
|
|
38
|
+
const IMG_TAG_REGEX = /<img\s+[^>]*src=["']([^"']+)["'][^>]*>/g;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Normalizes inline images in table cell paragraphs by extracting `<img>` tags
|
|
42
|
+
* into standalone image blocks.
|
|
43
|
+
*
|
|
44
|
+
* For each paragraph block whose parent is a table:
|
|
45
|
+
* 1. Extracts all `<img>` tags from the paragraph's text
|
|
46
|
+
* 2. Creates a new image block for each extracted `<img>`
|
|
47
|
+
* 3. Removes the `<img>` tags from the paragraph text
|
|
48
|
+
* 4. Inserts the new image block IDs before the paragraph in the table cell's blocks array
|
|
49
|
+
* 5. Adds the new image block IDs to the table's contentIds
|
|
50
|
+
*
|
|
51
|
+
* @param blocks - array of saved block data
|
|
52
|
+
* @returns new array with inline images extracted into standalone blocks
|
|
53
|
+
*/
|
|
54
|
+
export const normalizeInlineImages = <T extends NormalizableBlock>(blocks: T[]): T[] => {
|
|
55
|
+
/**
|
|
56
|
+
* Build a lookup of block id → block for quick parent resolution.
|
|
57
|
+
*/
|
|
58
|
+
const blockById = new Map<string, T>();
|
|
59
|
+
|
|
60
|
+
for (const block of blocks) {
|
|
61
|
+
if (block.id !== undefined) {
|
|
62
|
+
blockById.set(block.id, block);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check if there are any table blocks at all. If not, return input unchanged.
|
|
68
|
+
*/
|
|
69
|
+
const hasTable = blocks.some((b) => b.tool === 'table');
|
|
70
|
+
|
|
71
|
+
if (!hasTable) {
|
|
72
|
+
return blocks;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const extractionMap = new Map<string, ExtractionInfo>();
|
|
76
|
+
|
|
77
|
+
for (const block of blocks) {
|
|
78
|
+
if (block.tool !== 'paragraph' || block.parentId === undefined || block.parentId === null) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const parent = blockById.get(block.parentId);
|
|
83
|
+
|
|
84
|
+
if (parent === undefined || parent.tool !== 'table') {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const text = block.data?.text;
|
|
89
|
+
|
|
90
|
+
if (typeof text !== 'string') {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const imgSrcs = Array.from(text.matchAll(IMG_TAG_REGEX), (m) => m[1]);
|
|
95
|
+
|
|
96
|
+
if (imgSrcs.length === 0) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Remove all <img> tags from text.
|
|
102
|
+
*/
|
|
103
|
+
IMG_TAG_REGEX.lastIndex = 0;
|
|
104
|
+
const cleanedText = text.replace(IMG_TAG_REGEX, '');
|
|
105
|
+
|
|
106
|
+
if (block.id !== undefined) {
|
|
107
|
+
extractionMap.set(block.id, {
|
|
108
|
+
parentTableId: block.parentId,
|
|
109
|
+
imgSrcs,
|
|
110
|
+
cleanedText,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* If no paragraphs need extraction, return input unchanged.
|
|
117
|
+
*/
|
|
118
|
+
if (extractionMap.size === 0) {
|
|
119
|
+
return blocks;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Generate image block IDs and build new image blocks.
|
|
124
|
+
* Maps paragraph id → array of new image block entries.
|
|
125
|
+
*/
|
|
126
|
+
const newImageBlocksPerParagraph = new Map<string, T[]>();
|
|
127
|
+
|
|
128
|
+
for (const [paragraphId, info] of extractionMap) {
|
|
129
|
+
const imageBlocks: T[] = [];
|
|
130
|
+
|
|
131
|
+
for (const src of info.imgSrcs) {
|
|
132
|
+
const imageBlock = {
|
|
133
|
+
id: generateBlockId(),
|
|
134
|
+
tool: 'image',
|
|
135
|
+
data: { url: src },
|
|
136
|
+
isValid: true,
|
|
137
|
+
parentId: info.parentTableId,
|
|
138
|
+
} as unknown as T;
|
|
139
|
+
|
|
140
|
+
imageBlocks.push(imageBlock);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
newImageBlocksPerParagraph.set(paragraphId, imageBlocks);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Clone table blocks and update their content/contentIds with new image block references.
|
|
148
|
+
*/
|
|
149
|
+
const updatedTableIds = new Set<string>();
|
|
150
|
+
|
|
151
|
+
for (const info of extractionMap.values()) {
|
|
152
|
+
updatedTableIds.add(info.parentTableId);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const clonedTables = new Map<string, T>();
|
|
156
|
+
|
|
157
|
+
for (const tableId of updatedTableIds) {
|
|
158
|
+
const original = blockById.get(tableId);
|
|
159
|
+
|
|
160
|
+
if (original === undefined) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const cloned = { ...original };
|
|
165
|
+
const originalData = original.data as { content: TableCell[][] } | undefined;
|
|
166
|
+
|
|
167
|
+
if (originalData?.content !== undefined) {
|
|
168
|
+
/**
|
|
169
|
+
* Deep clone the content array so we can mutate cell blocks arrays.
|
|
170
|
+
*/
|
|
171
|
+
const clonedContent: TableCell[][] = originalData.content.map(
|
|
172
|
+
(row) => row.map((cell) => ({ ...cell, blocks: [...cell.blocks] }))
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
cloned.data = { ...original.data, content: clonedContent };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
cloned.contentIds = original.contentIds !== undefined ? [...original.contentIds] : [];
|
|
179
|
+
clonedTables.set(tableId, cloned);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Update cloned table cell blocks arrays and contentIds.
|
|
184
|
+
*/
|
|
185
|
+
for (const [paragraphId, imageBlocks] of newImageBlocksPerParagraph) {
|
|
186
|
+
const info = extractionMap.get(paragraphId);
|
|
187
|
+
|
|
188
|
+
if (info === undefined) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const clonedTable = clonedTables.get(info.parentTableId);
|
|
193
|
+
|
|
194
|
+
if (clonedTable === undefined) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const tableData = clonedTable.data as { content: TableCell[][] } | undefined;
|
|
199
|
+
|
|
200
|
+
if (tableData?.content === undefined) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const imageBlockIds = imageBlocks.map((b) => b.id ?? '');
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Find the cell containing this paragraph and insert image IDs before the paragraph.
|
|
208
|
+
*/
|
|
209
|
+
tableData.content.flat().forEach((cell) => {
|
|
210
|
+
const paragraphIndex = cell.blocks.indexOf(paragraphId);
|
|
211
|
+
|
|
212
|
+
if (paragraphIndex !== -1) {
|
|
213
|
+
cell.blocks.splice(paragraphIndex, 0, ...imageBlockIds);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Add image block IDs to the table's contentIds.
|
|
219
|
+
*/
|
|
220
|
+
if (clonedTable.contentIds !== undefined) {
|
|
221
|
+
clonedTable.contentIds.push(...imageBlockIds);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Build the result array:
|
|
227
|
+
* - Replace table blocks with cloned versions
|
|
228
|
+
* - Replace paragraph blocks with cleaned text versions
|
|
229
|
+
* - Insert image blocks before their source paragraph
|
|
230
|
+
*/
|
|
231
|
+
const result: T[] = [];
|
|
232
|
+
|
|
233
|
+
for (const block of blocks) {
|
|
234
|
+
/**
|
|
235
|
+
* If this is a table that was updated, use the cloned version.
|
|
236
|
+
*/
|
|
237
|
+
if (block.id !== undefined && clonedTables.has(block.id)) {
|
|
238
|
+
result.push(clonedTables.get(block.id) as T);
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* If this is a paragraph with images to extract, insert image blocks before it
|
|
244
|
+
* and update its text.
|
|
245
|
+
*/
|
|
246
|
+
if (block.id !== undefined && extractionMap.has(block.id)) {
|
|
247
|
+
result.push(...(newImageBlocksPerParagraph.get(block.id) ?? []));
|
|
248
|
+
|
|
249
|
+
const info = extractionMap.get(block.id);
|
|
250
|
+
const updatedParagraph = {
|
|
251
|
+
...block,
|
|
252
|
+
data: { ...block.data, text: info?.cleanedText ?? '' },
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
result.push(updatedParagraph);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
result.push(block);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return result;
|
|
263
|
+
};
|
|
@@ -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
|
*/
|
|
@@ -140,11 +140,14 @@ export class RectangleSelection extends Module {
|
|
|
140
140
|
const pointerX = pageX - scrollLeft;
|
|
141
141
|
|
|
142
142
|
/**
|
|
143
|
-
* Check if pointer is within
|
|
143
|
+
* Check if pointer is within the content area's horizontal bounds.
|
|
144
144
|
* This determines whether we should close the toolbar when starting selection.
|
|
145
|
-
* Clicks outside the
|
|
145
|
+
* Clicks outside the content area (to the left or right, in the margin/toolbar zone)
|
|
146
|
+
* should NOT close the toolbar. Uses UI.contentRect which queries the first block's
|
|
147
|
+
* content element and caches the result.
|
|
146
148
|
*/
|
|
147
|
-
const
|
|
149
|
+
const contentRect = this.Blok.UI.contentRect;
|
|
150
|
+
const withinEditorHorizontally = pointerX >= contentRect.left && pointerX <= contentRect.right;
|
|
148
151
|
|
|
149
152
|
const elemWhereSelectionStart = document.elementFromPoint(pageX - scrollLeft, pointerY);
|
|
150
153
|
|
|
@@ -224,6 +227,19 @@ export class RectangleSelection extends Module {
|
|
|
224
227
|
this.isRectSelectionActivated = false;
|
|
225
228
|
}
|
|
226
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Cancel active rectangle selection.
|
|
232
|
+
* Used when another selection system (e.g., table cell selection) takes priority.
|
|
233
|
+
*/
|
|
234
|
+
public cancelActiveSelection(): void {
|
|
235
|
+
if (!this.mousedown && !this.isRectSelectionActivated) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
this.clearSelection();
|
|
240
|
+
this.endSelection();
|
|
241
|
+
}
|
|
242
|
+
|
|
227
243
|
/**
|
|
228
244
|
* Sets Module necessary event handlers
|
|
229
245
|
*/
|
|
@@ -12,6 +12,7 @@ import type { Block } from '../block';
|
|
|
12
12
|
import { getBlokVersion, isEmpty, isObject, log, logLabeled } from '../utils';
|
|
13
13
|
import { collapseToLegacy, shouldCollapseToLegacy } from '../utils/data-model-transform';
|
|
14
14
|
import { sanitizeBlocks } from '../utils/sanitizer';
|
|
15
|
+
import { normalizeInlineImages } from './normalizeInlineImages';
|
|
15
16
|
|
|
16
17
|
type SaverValidatedData = ValidatedData & {
|
|
17
18
|
tunes?: Record<string, BlockTuneData>;
|
|
@@ -75,7 +76,9 @@ export class Saver extends Module {
|
|
|
75
76
|
this.config.sanitizer as SanitizerConfig
|
|
76
77
|
);
|
|
77
78
|
|
|
78
|
-
|
|
79
|
+
const normalizedData = normalizeInlineImages(sanitizedData);
|
|
80
|
+
|
|
81
|
+
return this.makeOutput(normalizedData);
|
|
79
82
|
} catch (error: unknown) {
|
|
80
83
|
this.lastSaveError = error;
|
|
81
84
|
|
|
@@ -125,7 +128,9 @@ export class Saver extends Module {
|
|
|
125
128
|
const extractedBlocks: OutputData['blocks'] = [];
|
|
126
129
|
|
|
127
130
|
allExtractedData.forEach(({ id, tool, data, tunes, isValid, parentId, contentIds }) => {
|
|
128
|
-
|
|
131
|
+
const hasParent = parentId !== undefined && parentId !== null;
|
|
132
|
+
|
|
133
|
+
if (!isValid && !hasParent) {
|
|
129
134
|
log(`Block «${tool}» skipped because saved data is invalid`);
|
|
130
135
|
|
|
131
136
|
return;
|
|
@@ -151,7 +156,6 @@ export class Saver extends Module {
|
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
const isTunesEmpty = tunes === undefined || isEmpty(tunes);
|
|
154
|
-
const hasParent = parentId !== undefined && parentId !== null;
|
|
155
159
|
const hasContent = contentIds !== undefined && contentIds.length > 0;
|
|
156
160
|
|
|
157
161
|
const output: OutputData['blocks'][number] = {
|
|
@@ -5,7 +5,7 @@ import { BlockAPI } from '../../block/api';
|
|
|
5
5
|
import { Dom as $ } from '../../dom';
|
|
6
6
|
import { BlockSettingsClosed, BlockSettingsOpened, BlokMobileLayoutToggled } from '../../events';
|
|
7
7
|
import { Flipper } from '../../flipper';
|
|
8
|
-
import { IconReplace,
|
|
8
|
+
import { IconReplace, IconTrash } from '../../icons';
|
|
9
9
|
import { SelectionUtils } from '../../selection/index';
|
|
10
10
|
import type { BlockToolAdapter } from '../../tools/block';
|
|
11
11
|
import { isMobileScreen, keyCodes } from '../../utils';
|
|
@@ -187,7 +187,6 @@ export class BlockSettings extends Module<BlockSettingsNodes> {
|
|
|
187
187
|
trigger: trigger || this.nodes.wrapper,
|
|
188
188
|
items: await this.getTunesItems(block, commonTunes, toolTunes),
|
|
189
189
|
scopeElement: this.Blok.API.methods.ui.nodes.redactor,
|
|
190
|
-
width: 'auto',
|
|
191
190
|
messages: {
|
|
192
191
|
nothingFound: this.Blok.I18n.t('popover.nothingFound'),
|
|
193
192
|
search: this.Blok.I18n.t('popover.search'),
|
|
@@ -375,9 +374,10 @@ export class BlockSettings extends Module<BlockSettingsNodes> {
|
|
|
375
374
|
items.push(...commonTunes);
|
|
376
375
|
} else {
|
|
377
376
|
items.push({
|
|
378
|
-
icon:
|
|
377
|
+
icon: IconTrash,
|
|
379
378
|
title: this.Blok.I18n.t('blockSettings.delete'),
|
|
380
379
|
name: 'delete',
|
|
380
|
+
isDestructive: true,
|
|
381
381
|
closeOnActivate: true,
|
|
382
382
|
onActivate: () => {
|
|
383
383
|
const { BlockManager, Caret, Toolbar } = this.Blok;
|
|
@@ -85,6 +85,13 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
85
85
|
*/
|
|
86
86
|
private explicitlyClosed: boolean = false;
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Flag to track if the current hovered block was resolved from a table cell block.
|
|
90
|
+
* When true, the toolbar suppresses plus button, settings toggler, and
|
|
91
|
+
* prevents overriding the current block when the toolbox opens.
|
|
92
|
+
*/
|
|
93
|
+
private hoveredBlockIsFromTableCell: boolean = false;
|
|
94
|
+
|
|
88
95
|
/**
|
|
89
96
|
* Toolbox class instance
|
|
90
97
|
* It will be created in requestIdleCallback so it can be null in some period of time
|
|
@@ -215,8 +222,10 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
215
222
|
|
|
216
223
|
/**
|
|
217
224
|
* Set current block to cover the case when the Toolbar showed near hovered Block but caret is set to another Block.
|
|
225
|
+
* Skip this when the hovered block was resolved from a table cell, so the toolbox
|
|
226
|
+
* can detect the original cell block and hide restricted tools (e.g., table, header).
|
|
218
227
|
*/
|
|
219
|
-
if (this.hoveredBlock) {
|
|
228
|
+
if (this.hoveredBlock && !this.hoveredBlockIsFromTableCell) {
|
|
220
229
|
this.Blok.BlockManager.currentBlock = this.hoveredBlock;
|
|
221
230
|
}
|
|
222
231
|
|
|
@@ -320,21 +329,20 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
320
329
|
/**
|
|
321
330
|
* If no one Block selected as a Current
|
|
322
331
|
*/
|
|
323
|
-
const
|
|
332
|
+
const unresolvedBlock = block ?? this.Blok.BlockManager.currentBlock;
|
|
324
333
|
|
|
325
|
-
if (!
|
|
334
|
+
if (!unresolvedBlock) {
|
|
326
335
|
return;
|
|
327
336
|
}
|
|
328
337
|
|
|
329
338
|
/**
|
|
330
|
-
*
|
|
331
|
-
*
|
|
339
|
+
* Track whether the original block is inside a table cell.
|
|
340
|
+
* Check the DOM directly rather than relying on resolution success,
|
|
341
|
+
* so that the flag is correct even when resolution falls back to the original block.
|
|
332
342
|
*/
|
|
333
|
-
|
|
334
|
-
this.close();
|
|
343
|
+
this.hoveredBlockIsFromTableCell = unresolvedBlock.holder.closest('[data-blok-table-cell-blocks]') !== null;
|
|
335
344
|
|
|
336
|
-
|
|
337
|
-
}
|
|
345
|
+
const targetBlock = this.resolveTableCellBlock(unresolvedBlock);
|
|
338
346
|
|
|
339
347
|
/** Clean up draggable on previous block if any */
|
|
340
348
|
if (this.hoveredBlock && this.hoveredBlock !== targetBlock) {
|
|
@@ -353,6 +361,19 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
353
361
|
return;
|
|
354
362
|
}
|
|
355
363
|
|
|
364
|
+
/**
|
|
365
|
+
* Suppress toolbar buttons when the block is inside a table cell.
|
|
366
|
+
* The toolbar still positions itself for toolbox/slash-search purposes,
|
|
367
|
+
* but plus button and settings toggler remain hidden.
|
|
368
|
+
*/
|
|
369
|
+
const displayValue = this.hoveredBlockIsFromTableCell ? 'none' : '';
|
|
370
|
+
|
|
371
|
+
plusButton.style.display = displayValue;
|
|
372
|
+
|
|
373
|
+
if (settingsToggler) {
|
|
374
|
+
settingsToggler.style.display = displayValue;
|
|
375
|
+
}
|
|
376
|
+
|
|
356
377
|
const targetBlockHolder = targetBlock.holder;
|
|
357
378
|
const { isMobile } = this.Blok.UI;
|
|
358
379
|
|
|
@@ -458,12 +479,22 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
458
479
|
this.positioner.setHoveredTarget(null); // No target for multi-block selection
|
|
459
480
|
this.positioner.resetCachedPosition(); // Reset cached position when moving to a new block
|
|
460
481
|
|
|
461
|
-
const { wrapper, plusButton } = this.nodes;
|
|
482
|
+
const { wrapper, plusButton, settingsToggler } = this.nodes;
|
|
462
483
|
|
|
463
484
|
if (!wrapper || !plusButton) {
|
|
464
485
|
return;
|
|
465
486
|
}
|
|
466
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Restore plus button and settings toggler visibility for multi-block selection,
|
|
490
|
+
* in case they were hidden for table cell blocks.
|
|
491
|
+
*/
|
|
492
|
+
plusButton.style.display = '';
|
|
493
|
+
|
|
494
|
+
if (settingsToggler) {
|
|
495
|
+
settingsToggler.style.display = '';
|
|
496
|
+
}
|
|
497
|
+
|
|
467
498
|
const targetBlockHolder = targetBlock.holder;
|
|
468
499
|
|
|
469
500
|
const toolbarY = this.positioner.calculateToolbarY(
|
|
@@ -478,9 +509,6 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
478
509
|
this.positioner.moveToY(this.nodes, toolbarY);
|
|
479
510
|
targetBlockHolder.appendChild(wrapper);
|
|
480
511
|
|
|
481
|
-
/** Set up draggable on the target block using the settings toggler as drag handle */
|
|
482
|
-
const { settingsToggler } = this.nodes;
|
|
483
|
-
|
|
484
512
|
if (settingsToggler && !this.Blok.ReadOnly.isEnabled) {
|
|
485
513
|
targetBlock.setupDraggable(settingsToggler, this.Blok.DragManager);
|
|
486
514
|
}
|
|
@@ -523,18 +551,24 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
523
551
|
* to prevent toolbar from reopening on subsequent block-hovered events
|
|
524
552
|
*/
|
|
525
553
|
this.hoveredBlock = null;
|
|
554
|
+
this.hoveredBlockIsFromTableCell = false;
|
|
526
555
|
// Only set explicitlyClosed if not explicitly disabled (e.g., when called from toolbox after block insertion)
|
|
527
556
|
if (options?.setExplicitlyClosed !== false) {
|
|
528
557
|
this.explicitlyClosed = true;
|
|
529
558
|
}
|
|
530
559
|
|
|
531
560
|
/**
|
|
532
|
-
* Restore plus button
|
|
561
|
+
* Restore plus button and settings toggler visibility
|
|
562
|
+
* in case they were hidden for table cell blocks
|
|
533
563
|
*/
|
|
534
564
|
if (this.nodes.plusButton) {
|
|
535
565
|
this.nodes.plusButton.style.display = '';
|
|
536
566
|
}
|
|
537
567
|
|
|
568
|
+
if (this.nodes.settingsToggler) {
|
|
569
|
+
this.nodes.settingsToggler.style.display = '';
|
|
570
|
+
}
|
|
571
|
+
|
|
538
572
|
/**
|
|
539
573
|
* Reset the content offset transform
|
|
540
574
|
*/
|
|
@@ -562,6 +596,30 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
562
596
|
this.explicitlyClosed = false;
|
|
563
597
|
}
|
|
564
598
|
|
|
599
|
+
/**
|
|
600
|
+
* If the block is inside a table cell, resolve to the parent table block.
|
|
601
|
+
* This ensures the toolbar shows for the table when clicking/focusing inside cells.
|
|
602
|
+
* Uses the DOM attribute directly to avoid cross-module dependency on the table tool.
|
|
603
|
+
*
|
|
604
|
+
* @param block - the block to resolve
|
|
605
|
+
* @returns the parent table block if inside a cell, the original block otherwise
|
|
606
|
+
*/
|
|
607
|
+
private resolveTableCellBlock(block: Block): Block {
|
|
608
|
+
const cellBlocksContainer = block.holder.closest('[data-blok-table-cell-blocks]');
|
|
609
|
+
|
|
610
|
+
if (!cellBlocksContainer) {
|
|
611
|
+
return block;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
const tableBlockHolder = cellBlocksContainer.closest('[data-blok-testid="block-wrapper"]');
|
|
615
|
+
|
|
616
|
+
if (!tableBlockHolder) {
|
|
617
|
+
return block;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
return this.Blok.BlockManager.getBlockByChildNode(tableBlockHolder) ?? block;
|
|
621
|
+
}
|
|
622
|
+
|
|
565
623
|
/**
|
|
566
624
|
* Reset the Toolbar position to prevent DOM height growth, for example after blocks deletion
|
|
567
625
|
*/
|