@jackuait/blok 0.6.0-beta.8 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-bzxy6Olq.mjs → blok-BAh1rvUC.mjs} +3410 -2927
- package/dist/chunks/i18next-B47TKgbU.mjs +1303 -0
- package/dist/chunks/{i18next-loader-CzL6YHyQ.mjs → i18next-loader-CHtGO6IK.mjs} +2 -2
- package/dist/chunks/{index-DSSrx_Co.mjs → index-DBWWKrDe.mjs} +12 -12
- package/dist/chunks/{inline-tool-convert-D4SXxjDd.mjs → inline-tool-convert-DduRc0fF.mjs} +1467 -951
- package/dist/chunks/{messages-BogRq8lt.mjs → messages-0AbcLMLm.mjs} +6 -0
- package/dist/chunks/{messages-DJDG55Vq.mjs → messages-0E0AkrNu.mjs} +6 -0
- package/dist/{messages-DnXLrlHh.mjs → chunks/messages-4v4MuVEc.mjs} +6 -0
- package/dist/chunks/{messages-DnIhyAJk.mjs → messages-62v-CLC-.mjs} +6 -0
- package/dist/chunks/{messages-Dzwxv9v1.mjs → messages-8DeO60Oo.mjs} +6 -0
- package/dist/chunks/{messages-B1Aww8q7.mjs → messages-8IPXkrDl.mjs} +6 -0
- package/dist/{messages-uKX8WBaD.mjs → chunks/messages-96kNZDll.mjs} +6 -0
- package/dist/chunks/{messages-BL0tXcDf.mjs → messages-B1FZ8lxU.mjs} +6 -0
- package/dist/{messages-DBn76jVV.mjs → chunks/messages-B217znr-.mjs} +8 -2
- package/dist/{messages-DT4dP5uK.mjs → chunks/messages-B8WNljW3.mjs} +6 -0
- package/dist/chunks/{messages-BdeLo0N9.mjs → messages-BC8IN4Bf.mjs} +6 -0
- package/dist/{messages-CZygwLwM.mjs → chunks/messages-BI43k_BD.mjs} +6 -0
- package/dist/{messages-CzTufCHu.mjs → chunks/messages-BJ6zrz2j.mjs} +6 -0
- package/dist/{messages-BoJc_p1r.mjs → chunks/messages-BUl_Rcnj.mjs} +6 -0
- package/dist/chunks/{messages-CnwibSvh.mjs → messages-BZlmVRwn.mjs} +6 -0
- package/dist/{messages-C2htQ_3F.mjs → chunks/messages-BcpCubnC.mjs} +6 -0
- package/dist/{messages-D5C3J9qr.mjs → chunks/messages-Bm-E4iRC.mjs} +6 -0
- package/dist/chunks/{messages-BELRf6DU.mjs → messages-C4jL-90N.mjs} +6 -0
- package/dist/chunks/{messages-1fC8IMyX.mjs → messages-CDBLbUOQ.mjs} +6 -0
- package/dist/chunks/{messages-7QoX8DkW.mjs → messages-CH4hrauY.mjs} +6 -0
- package/dist/{messages-Dz9L52ol.mjs → chunks/messages-CRJ_mchV.mjs} +6 -0
- package/dist/chunks/{messages-JELdtT6E.mjs → messages-CW4c4cRk.mjs} +6 -0
- package/dist/chunks/{messages-CKI54h6O.mjs → messages-C_4otP7U.mjs} +6 -0
- package/dist/{messages-R3hUSvr3.mjs → chunks/messages-CfiyT2Wi.mjs} +6 -0
- package/dist/{messages-CJdUsQ-c.mjs → chunks/messages-CgTq3QhU.mjs} +6 -0
- package/dist/chunks/{messages-D1Hv8XGo.mjs → messages-Chb7k3Rg.mjs} +6 -0
- package/dist/{messages-Q7AO_FLv.mjs → chunks/messages-Cjjo7yHR.mjs} +6 -0
- package/dist/{messages-C99mq906.mjs → chunks/messages-Cl6ayUaq.mjs} +6 -0
- package/dist/chunks/{messages-Diu6jAaR.mjs → messages-CmR9ftc_.mjs} +6 -0
- package/dist/chunks/{messages-LPVfA-8K.mjs → messages-Cr49Nt3U.mjs} +6 -0
- package/dist/chunks/{messages-DqM1LFg5.mjs → messages-Cr94GzbX.mjs} +6 -0
- package/dist/{messages-BWF-zUpY.mjs → chunks/messages-CrCYPCk3.mjs} +6 -0
- package/dist/{messages-D-ZtY5v0.mjs → chunks/messages-Cs8zmZ3L.mjs} +6 -0
- package/dist/{messages-DprmQg6V.mjs → chunks/messages-CzK0LEhb.mjs} +6 -0
- package/dist/chunks/{messages-BSbjsyHY.mjs → messages-D00x4S8o.mjs} +6 -0
- package/dist/chunks/{messages-Xq8UmkVs.mjs → messages-D1mn7Zd5.mjs} +6 -0
- package/dist/chunks/{messages-BC86qLvI.mjs → messages-D2NOpHn9.mjs} +6 -0
- package/dist/{messages-kep5wtm4.mjs → chunks/messages-D4qqwVgQ.mjs} +6 -0
- package/dist/chunks/{messages-7W4d0DwD.mjs → messages-D5S1Dnpm.mjs} +6 -0
- package/dist/{messages-CY8_RyFE.mjs → chunks/messages-D7u2bmP2.mjs} +6 -0
- package/dist/chunks/{messages-BFG6Wlgy.mjs → messages-D85FqxgY.mjs} +6 -0
- package/dist/{messages-DLfR5bMd.mjs → chunks/messages-D9ndgBnU.mjs} +6 -0
- package/dist/{messages-CVw84KdI.mjs → chunks/messages-DDTQgImT.mjs} +6 -0
- package/dist/{messages-_ErNTNhk.mjs → chunks/messages-DH_jBeED.mjs} +6 -0
- package/dist/chunks/{messages-CMkNSDTo.mjs → messages-DRXWF0PV.mjs} +6 -0
- package/dist/chunks/{messages-BYyy6Wqf.mjs → messages-DVQvl8Qj.mjs} +6 -0
- package/dist/chunks/{messages-CznZadDf.mjs → messages-DXktiao_.mjs} +6 -0
- package/dist/chunks/{messages-DhLKYm2j.mjs → messages-DdK-nFGm.mjs} +6 -0
- package/dist/chunks/{messages-BMXCuEKO.mjs → messages-DlJbPF2T.mjs} +6 -0
- package/dist/chunks/{messages-CvGLfqmV.mjs → messages-DnVlmiNT.mjs} +6 -0
- package/dist/{messages-Z9nEU2xK.mjs → chunks/messages-DviiFSv2.mjs} +6 -0
- package/dist/chunks/{messages-BB5z9Uba.mjs → messages-DzqM3Fel.mjs} +6 -0
- package/dist/{messages-w7v1GNaE.mjs → chunks/messages-Dzzn6XoD.mjs} +6 -0
- package/dist/{messages-CqWJcCbY.mjs → chunks/messages-GSByFygY.mjs} +6 -0
- package/dist/chunks/{messages-_ncGrKHh.mjs → messages-L_kl2Qvh.mjs} +6 -0
- package/dist/chunks/{messages-BrPFGbM-.mjs → messages-Phkd7XmE.mjs} +6 -0
- package/dist/{messages-BU2nlrLK.mjs → chunks/messages-RonBBCnh.mjs} +6 -0
- package/dist/{messages-Bmu_S7GM.mjs → chunks/messages-VDriF5Qy.mjs} +6 -0
- package/dist/{messages-CLhcMlTc.mjs → chunks/messages-ZjUAIWb1.mjs} +6 -0
- package/dist/{messages-9SihnaXQ.mjs → chunks/messages-b1EdvUm0.mjs} +6 -0
- package/dist/{messages-DvFLX36Q.mjs → chunks/messages-begYOTgC.mjs} +6 -0
- package/dist/{messages-BMv4xwIr.mjs → chunks/messages-jrncnb-H.mjs} +6 -0
- package/dist/{messages-D5iv1Kox.mjs → chunks/messages-nefz1S71.mjs} +6 -0
- package/dist/{messages-CQwpzUFp.mjs → chunks/messages-ucTVgS5G.mjs} +6 -0
- package/dist/chunks/{messages-DBRw-7Zc.mjs → messages-v3GipbFl.mjs} +6 -0
- package/dist/{messages-C9eaarcK.mjs → chunks/messages-wmi-iFkH.mjs} +6 -0
- package/dist/chunks/{messages-O5tQus_0.mjs → messages-yHcs38yI.mjs} +6 -0
- package/dist/full.mjs +2 -2
- package/dist/locales.mjs +90 -84
- package/dist/{messages-BogRq8lt.mjs → messages-0AbcLMLm.mjs} +6 -0
- package/dist/{messages-DJDG55Vq.mjs → messages-0E0AkrNu.mjs} +6 -0
- package/dist/{chunks/messages-DnXLrlHh.mjs → messages-4v4MuVEc.mjs} +6 -0
- package/dist/{messages-DnIhyAJk.mjs → messages-62v-CLC-.mjs} +6 -0
- package/dist/{messages-Dzwxv9v1.mjs → messages-8DeO60Oo.mjs} +6 -0
- package/dist/{messages-B1Aww8q7.mjs → messages-8IPXkrDl.mjs} +6 -0
- package/dist/{chunks/messages-uKX8WBaD.mjs → messages-96kNZDll.mjs} +6 -0
- package/dist/{messages-BL0tXcDf.mjs → messages-B1FZ8lxU.mjs} +6 -0
- package/dist/{chunks/messages-DBn76jVV.mjs → messages-B217znr-.mjs} +8 -2
- package/dist/{chunks/messages-DT4dP5uK.mjs → messages-B8WNljW3.mjs} +6 -0
- package/dist/{messages-BdeLo0N9.mjs → messages-BC8IN4Bf.mjs} +6 -0
- package/dist/{chunks/messages-CZygwLwM.mjs → messages-BI43k_BD.mjs} +6 -0
- package/dist/{chunks/messages-CzTufCHu.mjs → messages-BJ6zrz2j.mjs} +6 -0
- package/dist/{chunks/messages-BoJc_p1r.mjs → messages-BUl_Rcnj.mjs} +6 -0
- package/dist/{messages-CnwibSvh.mjs → messages-BZlmVRwn.mjs} +6 -0
- package/dist/{chunks/messages-C2htQ_3F.mjs → messages-BcpCubnC.mjs} +6 -0
- package/dist/{chunks/messages-D5C3J9qr.mjs → messages-Bm-E4iRC.mjs} +6 -0
- package/dist/{messages-BELRf6DU.mjs → messages-C4jL-90N.mjs} +6 -0
- package/dist/{messages-1fC8IMyX.mjs → messages-CDBLbUOQ.mjs} +6 -0
- package/dist/{messages-7QoX8DkW.mjs → messages-CH4hrauY.mjs} +6 -0
- package/dist/{chunks/messages-Dz9L52ol.mjs → messages-CRJ_mchV.mjs} +6 -0
- package/dist/{messages-JELdtT6E.mjs → messages-CW4c4cRk.mjs} +6 -0
- package/dist/{messages-CKI54h6O.mjs → messages-C_4otP7U.mjs} +6 -0
- package/dist/{chunks/messages-R3hUSvr3.mjs → messages-CfiyT2Wi.mjs} +6 -0
- package/dist/{chunks/messages-CJdUsQ-c.mjs → messages-CgTq3QhU.mjs} +6 -0
- package/dist/{messages-D1Hv8XGo.mjs → messages-Chb7k3Rg.mjs} +6 -0
- package/dist/{chunks/messages-Q7AO_FLv.mjs → messages-Cjjo7yHR.mjs} +6 -0
- package/dist/{chunks/messages-C99mq906.mjs → messages-Cl6ayUaq.mjs} +6 -0
- package/dist/{messages-Diu6jAaR.mjs → messages-CmR9ftc_.mjs} +6 -0
- package/dist/{messages-LPVfA-8K.mjs → messages-Cr49Nt3U.mjs} +6 -0
- package/dist/{messages-DqM1LFg5.mjs → messages-Cr94GzbX.mjs} +6 -0
- package/dist/{chunks/messages-BWF-zUpY.mjs → messages-CrCYPCk3.mjs} +6 -0
- package/dist/{chunks/messages-D-ZtY5v0.mjs → messages-Cs8zmZ3L.mjs} +6 -0
- package/dist/{chunks/messages-DprmQg6V.mjs → messages-CzK0LEhb.mjs} +6 -0
- package/dist/{messages-BSbjsyHY.mjs → messages-D00x4S8o.mjs} +6 -0
- package/dist/{messages-Xq8UmkVs.mjs → messages-D1mn7Zd5.mjs} +6 -0
- package/dist/{messages-BC86qLvI.mjs → messages-D2NOpHn9.mjs} +6 -0
- package/dist/{chunks/messages-kep5wtm4.mjs → messages-D4qqwVgQ.mjs} +6 -0
- package/dist/{messages-7W4d0DwD.mjs → messages-D5S1Dnpm.mjs} +6 -0
- package/dist/{chunks/messages-CY8_RyFE.mjs → messages-D7u2bmP2.mjs} +6 -0
- package/dist/{messages-BFG6Wlgy.mjs → messages-D85FqxgY.mjs} +6 -0
- package/dist/{chunks/messages-DLfR5bMd.mjs → messages-D9ndgBnU.mjs} +6 -0
- package/dist/{chunks/messages-CVw84KdI.mjs → messages-DDTQgImT.mjs} +6 -0
- package/dist/{chunks/messages-_ErNTNhk.mjs → messages-DH_jBeED.mjs} +6 -0
- package/dist/{messages-CMkNSDTo.mjs → messages-DRXWF0PV.mjs} +6 -0
- package/dist/{messages-BYyy6Wqf.mjs → messages-DVQvl8Qj.mjs} +6 -0
- package/dist/{messages-CznZadDf.mjs → messages-DXktiao_.mjs} +6 -0
- package/dist/{messages-DhLKYm2j.mjs → messages-DdK-nFGm.mjs} +6 -0
- package/dist/{messages-BMXCuEKO.mjs → messages-DlJbPF2T.mjs} +6 -0
- package/dist/{messages-CvGLfqmV.mjs → messages-DnVlmiNT.mjs} +6 -0
- package/dist/{chunks/messages-Z9nEU2xK.mjs → messages-DviiFSv2.mjs} +6 -0
- package/dist/{messages-BB5z9Uba.mjs → messages-DzqM3Fel.mjs} +6 -0
- package/dist/{chunks/messages-w7v1GNaE.mjs → messages-Dzzn6XoD.mjs} +6 -0
- package/dist/{chunks/messages-CqWJcCbY.mjs → messages-GSByFygY.mjs} +6 -0
- package/dist/{messages-_ncGrKHh.mjs → messages-L_kl2Qvh.mjs} +6 -0
- package/dist/{messages-BrPFGbM-.mjs → messages-Phkd7XmE.mjs} +6 -0
- package/dist/{chunks/messages-BU2nlrLK.mjs → messages-RonBBCnh.mjs} +6 -0
- package/dist/{chunks/messages-Bmu_S7GM.mjs → messages-VDriF5Qy.mjs} +6 -0
- package/dist/{chunks/messages-CLhcMlTc.mjs → messages-ZjUAIWb1.mjs} +6 -0
- package/dist/{chunks/messages-9SihnaXQ.mjs → messages-b1EdvUm0.mjs} +6 -0
- package/dist/{chunks/messages-DvFLX36Q.mjs → messages-begYOTgC.mjs} +6 -0
- package/dist/{chunks/messages-BMv4xwIr.mjs → messages-jrncnb-H.mjs} +6 -0
- package/dist/{chunks/messages-D5iv1Kox.mjs → messages-nefz1S71.mjs} +6 -0
- package/dist/{chunks/messages-CQwpzUFp.mjs → messages-ucTVgS5G.mjs} +6 -0
- package/dist/{messages-DBRw-7Zc.mjs → messages-v3GipbFl.mjs} +6 -0
- package/dist/{chunks/messages-C9eaarcK.mjs → messages-wmi-iFkH.mjs} +6 -0
- package/dist/{messages-O5tQus_0.mjs → messages-yHcs38yI.mjs} +6 -0
- package/dist/tools.mjs +3194 -1690
- package/dist/vendor.LICENSE.txt +109 -109
- package/package.json +43 -57
- package/src/blok.ts +12 -0
- package/src/components/__module.ts +21 -0
- package/src/components/block/api.ts +17 -0
- package/src/components/block/style-manager.ts +6 -2
- package/src/components/block/tool-renderer.ts +33 -30
- package/src/components/blocks.ts +132 -15
- package/src/components/i18n/locales/am/messages.json +6 -0
- package/src/components/i18n/locales/ar/messages.json +6 -0
- package/src/components/i18n/locales/az/messages.json +6 -0
- package/src/components/i18n/locales/bg/messages.json +6 -0
- package/src/components/i18n/locales/bn/messages.json +6 -0
- package/src/components/i18n/locales/bs/messages.json +6 -0
- package/src/components/i18n/locales/cs/messages.json +6 -0
- package/src/components/i18n/locales/da/messages.json +6 -0
- package/src/components/i18n/locales/de/messages.json +6 -0
- package/src/components/i18n/locales/dv/messages.json +6 -0
- package/src/components/i18n/locales/el/messages.json +6 -0
- package/src/components/i18n/locales/en/messages.json +6 -0
- package/src/components/i18n/locales/es/messages.json +6 -0
- package/src/components/i18n/locales/et/messages.json +6 -0
- package/src/components/i18n/locales/fa/messages.json +6 -0
- package/src/components/i18n/locales/fi/messages.json +6 -0
- package/src/components/i18n/locales/fil/messages.json +6 -0
- package/src/components/i18n/locales/fr/messages.json +6 -0
- package/src/components/i18n/locales/gu/messages.json +6 -0
- package/src/components/i18n/locales/he/messages.json +6 -0
- package/src/components/i18n/locales/hi/messages.json +6 -0
- package/src/components/i18n/locales/hr/messages.json +6 -0
- package/src/components/i18n/locales/hu/messages.json +6 -0
- package/src/components/i18n/locales/hy/messages.json +6 -0
- package/src/components/i18n/locales/id/messages.json +6 -0
- package/src/components/i18n/locales/it/messages.json +6 -0
- package/src/components/i18n/locales/ja/messages.json +6 -0
- package/src/components/i18n/locales/ka/messages.json +6 -0
- package/src/components/i18n/locales/km/messages.json +6 -0
- package/src/components/i18n/locales/kn/messages.json +6 -0
- package/src/components/i18n/locales/ko/messages.json +6 -0
- package/src/components/i18n/locales/ku/messages.json +6 -0
- package/src/components/i18n/locales/lo/messages.json +6 -0
- package/src/components/i18n/locales/lt/messages.json +6 -0
- package/src/components/i18n/locales/lv/messages.json +6 -0
- package/src/components/i18n/locales/mk/messages.json +6 -0
- package/src/components/i18n/locales/ml/messages.json +6 -0
- package/src/components/i18n/locales/mn/messages.json +6 -0
- package/src/components/i18n/locales/mr/messages.json +6 -0
- package/src/components/i18n/locales/ms/messages.json +6 -0
- package/src/components/i18n/locales/my/messages.json +6 -0
- package/src/components/i18n/locales/ne/messages.json +6 -0
- package/src/components/i18n/locales/nl/messages.json +6 -0
- package/src/components/i18n/locales/no/messages.json +6 -0
- package/src/components/i18n/locales/pa/messages.json +6 -0
- package/src/components/i18n/locales/pl/messages.json +6 -0
- package/src/components/i18n/locales/ps/messages.json +6 -0
- package/src/components/i18n/locales/pt/messages.json +6 -0
- package/src/components/i18n/locales/ro/messages.json +6 -0
- package/src/components/i18n/locales/ru/messages.json +6 -0
- package/src/components/i18n/locales/sd/messages.json +6 -0
- package/src/components/i18n/locales/si/messages.json +6 -0
- package/src/components/i18n/locales/sk/messages.json +6 -0
- package/src/components/i18n/locales/sl/messages.json +6 -0
- package/src/components/i18n/locales/sq/messages.json +6 -0
- package/src/components/i18n/locales/sr/messages.json +6 -0
- package/src/components/i18n/locales/sv/messages.json +6 -0
- package/src/components/i18n/locales/sw/messages.json +6 -0
- package/src/components/i18n/locales/ta/messages.json +6 -0
- package/src/components/i18n/locales/te/messages.json +6 -0
- package/src/components/i18n/locales/th/messages.json +6 -0
- package/src/components/i18n/locales/tr/messages.json +6 -0
- package/src/components/i18n/locales/ug/messages.json +6 -0
- package/src/components/i18n/locales/uk/messages.json +6 -0
- package/src/components/i18n/locales/ur/messages.json +6 -0
- package/src/components/i18n/locales/vi/messages.json +6 -0
- package/src/components/i18n/locales/yi/messages.json +6 -0
- package/src/components/i18n/locales/zh/messages.json +6 -0
- package/src/components/icons/index.ts +17 -0
- package/src/components/inline-tools/inline-tool-link.ts +1 -1
- package/src/components/inline-tools/inline-tool-marker.ts +737 -0
- package/src/components/inline-tools/utils/formatting-range-utils.ts +6 -3
- package/src/components/inline-tools/utils/marker-dom-utils.ts +17 -0
- package/src/components/modules/api/blocks.ts +34 -9
- package/src/components/modules/blockEvents/composers/keyboardNavigation.ts +75 -29
- package/src/components/modules/blockEvents/index.ts +13 -5
- package/src/components/modules/blockManager/blockManager.ts +81 -2
- package/src/components/modules/blockManager/hierarchy.ts +20 -2
- package/src/components/modules/blockManager/operations.ts +70 -35
- package/src/components/modules/blockManager/repository.ts +22 -0
- package/src/components/modules/blockManager/types.ts +3 -1
- package/src/components/modules/blockManager/yjs-sync.ts +173 -39
- package/src/components/modules/blockSelection.ts +3 -0
- package/src/components/modules/crossBlockSelection.ts +11 -3
- package/src/components/modules/drag/preview/DragPreview.ts +10 -2
- package/src/components/modules/drag/target/DropTargetDetector.ts +100 -11
- package/src/components/modules/drag/utils/drag.constants.ts +1 -1
- package/src/components/modules/normalizeInlineImages.ts +263 -0
- package/src/components/modules/paste/google-docs-preprocessor.ts +197 -0
- package/src/components/modules/paste/handlers/base.ts +43 -2
- package/src/components/modules/paste/handlers/html-handler.ts +1 -1
- package/src/components/modules/paste/handlers/index.ts +1 -0
- package/src/components/modules/paste/handlers/table-cells-handler.ts +104 -0
- package/src/components/modules/paste/index.ts +20 -3
- package/src/components/modules/readonly.ts +8 -2
- package/src/components/modules/rectangleSelection.ts +5 -2
- package/src/components/modules/renderer.ts +35 -0
- package/src/components/modules/saver.ts +52 -2
- package/src/components/modules/toolbar/blockSettings.ts +52 -44
- package/src/components/modules/toolbar/index.ts +124 -17
- package/src/components/modules/toolbar/inline/index.ts +4 -4
- package/src/components/modules/toolbar/plus-button.ts +3 -3
- package/src/components/modules/toolbar/settings-toggler.ts +3 -3
- package/src/components/modules/toolbar/styles.ts +7 -7
- package/src/components/modules/ui.ts +6 -6
- package/src/components/modules/uiControllers/controllers/blockHover.ts +16 -2
- package/src/components/modules/uiControllers/handlers/touch.ts +83 -10
- package/src/components/modules/yjs/block-observer.ts +9 -3
- package/src/components/modules/yjs/document-store.ts +10 -7
- package/src/components/modules/yjs/types.ts +8 -6
- package/src/components/modules/yjs/undo-history.ts +90 -11
- package/src/components/selection/fake-background/shadows.ts +1 -1
- package/src/components/shared/color-picker.ts +211 -0
- package/src/components/shared/color-presets.ts +25 -0
- package/src/components/ui/toolbox.ts +19 -11
- package/src/components/utils/color-mapping.ts +241 -0
- package/src/components/utils/notifier/draw.ts +9 -9
- package/src/components/utils/placeholder.ts +24 -8
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +2 -2
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +14 -12
- package/src/components/utils/popover/components/search-input/search-input.const.ts +2 -2
- package/src/components/utils/popover/popover-abstract.ts +27 -3
- package/src/components/utils/popover/popover-desktop.ts +26 -3
- package/src/components/utils/popover/popover-inline.ts +14 -1
- package/src/components/utils/popover/popover-mobile.ts +4 -4
- package/src/components/utils/popover/popover.const.ts +2 -2
- package/src/components/utils/sanitizer.ts +24 -3
- package/src/components/utils/tw.ts +17 -5
- package/src/stories/Header.stories.ts +106 -0
- package/src/stories/MarkerColors.stories.ts +730 -0
- package/src/stories/Popover.stories.ts +1 -3
- package/src/stories/Table.stories.ts +1662 -0
- package/src/styles/main.css +207 -37
- package/src/tools/header/index.ts +1 -1
- package/src/tools/index.ts +3 -1
- package/src/tools/list/caret-manager.ts +28 -10
- package/src/tools/list/constants.ts +2 -2
- package/src/tools/list/dom-builder.ts +3 -3
- package/src/tools/list/static-configs.ts +0 -1
- package/src/tools/paragraph/index.ts +15 -7
- package/src/tools/table/core/table-commands.ts +99 -0
- package/src/tools/table/core/table-controller.ts +231 -0
- package/src/tools/table/core/table-events.ts +102 -0
- package/src/tools/table/index.ts +1070 -174
- package/src/tools/table/ownership/table-event-broker.ts +74 -0
- package/src/tools/table/ownership/table-ownership-registry.ts +126 -0
- package/src/tools/table/table-add-controls.ts +85 -15
- package/src/tools/table/table-cell-blocks.ts +336 -38
- package/src/tools/table/table-cell-clipboard.ts +415 -0
- package/src/tools/table/table-cell-color-picker.ts +34 -0
- package/src/tools/table/table-cell-selection.ts +264 -15
- package/src/tools/table/table-core.ts +3 -42
- package/src/tools/table/table-heading-toggle.ts +2 -2
- package/src/tools/table/table-model.ts +623 -0
- package/src/tools/table/table-operations.ts +59 -78
- package/src/tools/table/table-resize.ts +15 -11
- package/src/tools/table/table-restrictions.ts +69 -3
- package/src/tools/table/table-row-col-action-handler.ts +22 -7
- package/src/tools/table/table-row-col-controls.ts +129 -12
- package/src/tools/table/table-row-col-drag.ts +14 -0
- package/src/tools/table/table-scroll-haze.ts +152 -0
- package/src/tools/table/types.ts +22 -1
- package/src/tools/table/view/table-cell-blocks-adapter.ts +47 -0
- package/src/variants/blok-minimum.ts +13 -0
- package/types/api/block.d.ts +13 -0
- package/types/api/blocks.d.ts +16 -0
- package/types/tools/table.d.ts +2 -0
- package/dist/chunks/i18next-CugVlwWp.mjs +0 -1292
- package/src/tools/table/data-normalizer.ts +0 -32
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { API } from '../../../types';
|
|
2
2
|
|
|
3
3
|
import { CELL_ATTR, ROW_ATTR } from './table-core';
|
|
4
|
+
import type { TableModel } from './table-model';
|
|
4
5
|
import type { LegacyCellContent, CellContent } from './types';
|
|
5
6
|
import { isCellWithBlocks } from './types';
|
|
6
7
|
|
|
@@ -35,7 +36,10 @@ interface TableCellBlocksOptions {
|
|
|
35
36
|
api: API;
|
|
36
37
|
gridElement: HTMLElement;
|
|
37
38
|
tableBlockId: string;
|
|
39
|
+
model: TableModel;
|
|
38
40
|
onNavigateToCell?: CellNavigationCallback;
|
|
41
|
+
/** When true, handleBlockMutation defers events instead of processing immediately. */
|
|
42
|
+
isStructuralOpActive?: () => boolean;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
/**
|
|
@@ -46,6 +50,7 @@ export class TableCellBlocks {
|
|
|
46
50
|
private api: API;
|
|
47
51
|
private gridElement: HTMLElement;
|
|
48
52
|
private tableBlockId: string;
|
|
53
|
+
private model: TableModel;
|
|
49
54
|
private _activeCellWithBlocks: CellPosition | null = null;
|
|
50
55
|
private onNavigateToCell?: CellNavigationCallback;
|
|
51
56
|
|
|
@@ -59,18 +64,35 @@ export class TableCellBlocks {
|
|
|
59
64
|
private pendingCheckScheduled = false;
|
|
60
65
|
|
|
61
66
|
/**
|
|
62
|
-
* Maps a
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
67
|
+
* Maps a removed block's ID to the cell it was in and its flat-list index
|
|
68
|
+
* when block-removed fired.
|
|
69
|
+
*
|
|
70
|
+
* Used during replace operations: block-removed fires while the holder is
|
|
71
|
+
* still in the cell DOM, then block-added fires at the same index after the
|
|
72
|
+
* holder has been removed. This map lets the block-added handler find the
|
|
73
|
+
* correct cell.
|
|
74
|
+
*
|
|
75
|
+
* Keyed by block ID (not flat index) to prevent two classes of bugs:
|
|
76
|
+
* - Non-replace deletion + coincidental same-index insertion claiming the
|
|
77
|
+
* wrong cell.
|
|
78
|
+
* - Cross-table interference when two TableCellBlocks instances both
|
|
79
|
+
* subscribe to the global "block changed" event.
|
|
66
80
|
*/
|
|
67
|
-
private removedBlockCells = new Map<
|
|
81
|
+
private removedBlockCells = new Map<string, { cell: HTMLElement; index: number }>();
|
|
82
|
+
|
|
83
|
+
/** Callback to check if a structural operation is active on the parent Table. */
|
|
84
|
+
private isStructuralOpActive: () => boolean;
|
|
85
|
+
|
|
86
|
+
/** Events deferred during structural operations, replayed or discarded afterward. */
|
|
87
|
+
private deferredEvents: Array<unknown> = [];
|
|
68
88
|
|
|
69
89
|
constructor(options: TableCellBlocksOptions) {
|
|
70
90
|
this.api = options.api;
|
|
71
91
|
this.gridElement = options.gridElement;
|
|
72
92
|
this.tableBlockId = options.tableBlockId;
|
|
93
|
+
this.model = options.model;
|
|
73
94
|
this.onNavigateToCell = options.onNavigateToCell;
|
|
95
|
+
this.isStructuralOpActive = options.isStructuralOpActive ?? (() => false);
|
|
74
96
|
|
|
75
97
|
this.api.events.on('block changed', this.handleBlockMutation);
|
|
76
98
|
this.gridElement.addEventListener('click', this.handleCellBlankSpaceClick);
|
|
@@ -260,19 +282,48 @@ export class TableCellBlocks {
|
|
|
260
282
|
return;
|
|
261
283
|
}
|
|
262
284
|
|
|
263
|
-
const
|
|
264
|
-
?
|
|
285
|
+
const referencedBlockIds = isCellWithBlocks(cellContent) && cellContent.blocks.length > 0
|
|
286
|
+
? [...cellContent.blocks]
|
|
287
|
+
: null;
|
|
288
|
+
const mountedIds = referencedBlockIds
|
|
289
|
+
? this.mountBlocksInCell(container, referencedBlockIds)
|
|
265
290
|
: [];
|
|
266
291
|
|
|
292
|
+
const cellColorProps: Pick<CellContent, 'color' | 'textColor'> = {};
|
|
293
|
+
|
|
294
|
+
if (isCellWithBlocks(cellContent)) {
|
|
295
|
+
if (cellContent.color !== undefined) {
|
|
296
|
+
cellColorProps.color = cellContent.color;
|
|
297
|
+
}
|
|
298
|
+
if (cellContent.textColor !== undefined) {
|
|
299
|
+
cellColorProps.textColor = cellContent.textColor;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
267
303
|
if (mountedIds.length > 0) {
|
|
268
|
-
normalizedRow.push({ blocks: mountedIds });
|
|
304
|
+
normalizedRow.push({ blocks: referencedBlockIds ?? mountedIds, ...cellColorProps });
|
|
269
305
|
} else {
|
|
270
|
-
const text = typeof cellContent === 'string'
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
306
|
+
const text = typeof cellContent === 'string'
|
|
307
|
+
? cellContent
|
|
308
|
+
: (cellContent.text ?? '');
|
|
309
|
+
const segments = text.split(/<br\s*\/?>/i).map(s => s.trim()).filter(Boolean);
|
|
310
|
+
const textsToInsert = segments.length > 0 ? segments : [text];
|
|
311
|
+
const ids: string[] = [];
|
|
312
|
+
|
|
313
|
+
for (const segmentText of textsToInsert) {
|
|
314
|
+
const block = this.api.blocks.insert('paragraph', { text: segmentText }, {}, this.api.blocks.getBlocksCount(), false);
|
|
315
|
+
|
|
316
|
+
container.appendChild(block.holder);
|
|
317
|
+
this.api.blocks.setBlockParent(block.id, this.tableBlockId);
|
|
318
|
+
ids.push(block.id);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
normalizedRow.push({
|
|
322
|
+
blocks: referencedBlockIds === null
|
|
323
|
+
? ids
|
|
324
|
+
: [...referencedBlockIds, ...ids],
|
|
325
|
+
...cellColorProps,
|
|
326
|
+
});
|
|
276
327
|
}
|
|
277
328
|
|
|
278
329
|
this.stripPlaceholders(container);
|
|
@@ -347,6 +398,12 @@ export class TableCellBlocks {
|
|
|
347
398
|
return;
|
|
348
399
|
}
|
|
349
400
|
|
|
401
|
+
// Guard against circular DOM: never append the table block's own holder
|
|
402
|
+
// into one of its descendant cell containers.
|
|
403
|
+
if (block.holder.contains(container)) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
350
407
|
container.appendChild(block.holder);
|
|
351
408
|
this.api.blocks.setBlockParent(blockId, this.tableBlockId);
|
|
352
409
|
this.stripPlaceholders(container);
|
|
@@ -408,6 +465,7 @@ export class TableCellBlocks {
|
|
|
408
465
|
|
|
409
466
|
container.appendChild(block.holder);
|
|
410
467
|
this.api.blocks.setBlockParent(block.id, this.tableBlockId);
|
|
468
|
+
this.syncBlockToModel(cell, block.id);
|
|
411
469
|
this.stripPlaceholders(container);
|
|
412
470
|
}
|
|
413
471
|
|
|
@@ -417,6 +475,12 @@ export class TableCellBlocks {
|
|
|
417
475
|
* When a block is removed, ensure no cell is left empty.
|
|
418
476
|
*/
|
|
419
477
|
private handleBlockMutation = (data: unknown): void => {
|
|
478
|
+
if (this.isStructuralOpActive()) {
|
|
479
|
+
this.deferredEvents.push(data);
|
|
480
|
+
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
|
|
420
484
|
if (!this.isBlockMutationEvent(data)) {
|
|
421
485
|
return;
|
|
422
486
|
}
|
|
@@ -424,22 +488,7 @@ export class TableCellBlocks {
|
|
|
424
488
|
const { type, detail } = data.event;
|
|
425
489
|
|
|
426
490
|
if (type === 'block-removed') {
|
|
427
|
-
|
|
428
|
-
// at this point during a replace operation). This lets the subsequent
|
|
429
|
-
// block-added handler find the correct cell even when no adjacent block
|
|
430
|
-
// remains in the cell.
|
|
431
|
-
this.recordRemovedBlockCell(detail);
|
|
432
|
-
|
|
433
|
-
// Schedule deferred empty-cell checks instead of running immediately.
|
|
434
|
-
// This avoids creating spurious paragraphs during BlockManager.replace(),
|
|
435
|
-
// where block-removed is immediately followed by block-added.
|
|
436
|
-
const cells = this.gridElement.querySelectorAll<HTMLElement>(`[${CELL_ATTR}]`);
|
|
437
|
-
|
|
438
|
-
cells.forEach(cell => {
|
|
439
|
-
this.cellsPendingCheck.add(cell);
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
this.schedulePendingCellCheck();
|
|
491
|
+
this.handleBlockRemoved(detail);
|
|
443
492
|
|
|
444
493
|
return;
|
|
445
494
|
}
|
|
@@ -448,6 +497,13 @@ export class TableCellBlocks {
|
|
|
448
497
|
return;
|
|
449
498
|
}
|
|
450
499
|
|
|
500
|
+
// Never claim the table block itself as a cell content block.
|
|
501
|
+
// This can happen when rendered() creates cell blocks synchronously,
|
|
502
|
+
// polluting currentBlockIndex before the table's own block-added fires.
|
|
503
|
+
if (detail.target.id === this.tableBlockId) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
451
507
|
const blockIndex = detail.index;
|
|
452
508
|
|
|
453
509
|
if (blockIndex === undefined) {
|
|
@@ -456,16 +512,20 @@ export class TableCellBlocks {
|
|
|
456
512
|
|
|
457
513
|
// Check if a block was just removed at this index (replace operation).
|
|
458
514
|
// Use the recorded cell so the replacement lands in the correct cell.
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
this.
|
|
515
|
+
// The map is keyed by the removed block's ID, so we iterate to find an
|
|
516
|
+
// entry whose stored index matches the newly added block's index.
|
|
517
|
+
const removedEntry = this.findRemovedEntryForIndex(blockIndex);
|
|
462
518
|
|
|
463
519
|
// For replace operations, always move the block to the recorded cell.
|
|
464
520
|
// blocksStore.insert() places the holder adjacent to the previous block
|
|
465
521
|
// in the DOM, which may be inside a different cell.
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
522
|
+
// Guard: verify the new block actually belongs to this table by checking
|
|
523
|
+
// that an adjacent block is either the table block itself or a block
|
|
524
|
+
// mounted inside this table's grid.
|
|
525
|
+
if (removedEntry && this.isAdjacentToThisTable(blockIndex)) {
|
|
526
|
+
this.claimBlockForCell(removedEntry.cell, detail.target.id);
|
|
527
|
+
this.syncBlockToModel(removedEntry.cell, detail.target.id);
|
|
528
|
+
this.cellsPendingCheck.delete(removedEntry.cell);
|
|
469
529
|
|
|
470
530
|
return;
|
|
471
531
|
}
|
|
@@ -477,6 +537,50 @@ export class TableCellBlocks {
|
|
|
477
537
|
|
|
478
538
|
if (existingContainer) {
|
|
479
539
|
this.stripPlaceholders(existingContainer);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Sync to model if holder landed in a cell but isn't tracked yet (e.g. toolbox conversion)
|
|
543
|
+
const untrackedCell = existingContainer && !this.model.findCellForBlock(detail.target.id)
|
|
544
|
+
? existingContainer.closest<HTMLElement>(`[${CELL_ATTR}]`)
|
|
545
|
+
: null;
|
|
546
|
+
|
|
547
|
+
if (untrackedCell) {
|
|
548
|
+
this.syncBlockToModel(untrackedCell, detail.target.id);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if (existingContainer) {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// Only claim blocks whose holder is inside this table's grid.
|
|
556
|
+
// Blocks placed outside the grid (e.g., via undo/restore or API inserts)
|
|
557
|
+
// should not be pulled into a cell by adjacency alone.
|
|
558
|
+
//
|
|
559
|
+
// However, blocks created while the editor's focus is inside this table
|
|
560
|
+
// (e.g., via Enter key or paste in a cell) land outside the grid because
|
|
561
|
+
// insertToDOM walks up from cell blocks to the table holder level.
|
|
562
|
+
// For those, check that the current block at the time of insertion belongs
|
|
563
|
+
// to this table — indicating the user was editing inside a cell.
|
|
564
|
+
if (!this.gridElement.contains(holder)) {
|
|
565
|
+
const currentIndex = this.api.blocks.getCurrentBlockIndex();
|
|
566
|
+
const currentBlock = currentIndex >= 0
|
|
567
|
+
? this.api.blocks.getBlockByIndex(currentIndex)
|
|
568
|
+
: null;
|
|
569
|
+
const currentBlockInOurTable = currentBlock !== null
|
|
570
|
+
&& currentBlock !== undefined
|
|
571
|
+
&& this.getOwnedCellForBlock(currentBlock.id) !== null;
|
|
572
|
+
|
|
573
|
+
if (!currentBlockInOurTable) {
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
const cell = this.findCellForNewBlock(blockIndex);
|
|
578
|
+
|
|
579
|
+
if (cell) {
|
|
580
|
+
this.claimBlockForCell(cell, detail.target.id);
|
|
581
|
+
this.syncBlockToModel(cell, detail.target.id);
|
|
582
|
+
this.cellsPendingCheck.delete(cell);
|
|
583
|
+
}
|
|
480
584
|
|
|
481
585
|
return;
|
|
482
586
|
}
|
|
@@ -486,16 +590,79 @@ export class TableCellBlocks {
|
|
|
486
590
|
|
|
487
591
|
if (cell) {
|
|
488
592
|
this.claimBlockForCell(cell, detail.target.id);
|
|
593
|
+
this.syncBlockToModel(cell, detail.target.id);
|
|
489
594
|
this.cellsPendingCheck.delete(cell);
|
|
490
595
|
}
|
|
491
596
|
};
|
|
492
597
|
|
|
598
|
+
/**
|
|
599
|
+
* Handle a block-removed event: update the model and schedule an empty-cell check.
|
|
600
|
+
*/
|
|
601
|
+
private handleBlockRemoved(detail: { target: { id: string; holder: HTMLElement }; index?: number }): void {
|
|
602
|
+
this.recordRemovedBlockCell(detail);
|
|
603
|
+
const blockId = detail.target.id;
|
|
604
|
+
const cellPos = this.model.findCellForBlock(blockId);
|
|
605
|
+
|
|
606
|
+
if (!cellPos) {
|
|
607
|
+
this.schedulePendingCellCheck();
|
|
608
|
+
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
this.model.removeBlockFromCell(cellPos.row, cellPos.col, blockId);
|
|
613
|
+
const affectedCell = this.getCell(cellPos.row, cellPos.col);
|
|
614
|
+
|
|
615
|
+
if (affectedCell) {
|
|
616
|
+
this.cellsPendingCheck.add(affectedCell);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
this.schedulePendingCellCheck();
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Find the DOM cell's row/col position and add the block to the model.
|
|
624
|
+
*/
|
|
625
|
+
private syncBlockToModel(cell: HTMLElement, blockId: string): void {
|
|
626
|
+
const pos = this.getCellPosition(cell);
|
|
627
|
+
|
|
628
|
+
if (pos) {
|
|
629
|
+
this.model.addBlockToCell(pos.row, pos.col, blockId);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Get the row/col position of a cell element within the grid.
|
|
635
|
+
*/
|
|
636
|
+
private getCellPosition(cell: HTMLElement): { row: number; col: number } | null {
|
|
637
|
+
const row = cell.closest<HTMLElement>(`[${ROW_ATTR}]`);
|
|
638
|
+
|
|
639
|
+
if (!row) {
|
|
640
|
+
return null;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
const rows = Array.from(this.gridElement.querySelectorAll(`[${ROW_ATTR}]`));
|
|
644
|
+
const rowIndex = rows.indexOf(row);
|
|
645
|
+
|
|
646
|
+
if (rowIndex < 0) {
|
|
647
|
+
return null;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
const cells = Array.from(row.querySelectorAll(`[${CELL_ATTR}]`));
|
|
651
|
+
const colIndex = cells.indexOf(cell);
|
|
652
|
+
|
|
653
|
+
if (colIndex < 0) {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
return { row: rowIndex, col: colIndex };
|
|
658
|
+
}
|
|
659
|
+
|
|
493
660
|
/**
|
|
494
661
|
* If the removed block's holder is currently inside a cell of this table,
|
|
495
662
|
* record the mapping so a subsequent block-added at the same index can
|
|
496
663
|
* find the correct cell.
|
|
497
664
|
*/
|
|
498
|
-
private recordRemovedBlockCell(detail: { target: { holder: HTMLElement }; index?: number }): void {
|
|
665
|
+
private recordRemovedBlockCell(detail: { target: { id: string; holder: HTMLElement }; index?: number }): void {
|
|
499
666
|
if (detail.index === undefined) {
|
|
500
667
|
return;
|
|
501
668
|
}
|
|
@@ -503,10 +670,118 @@ export class TableCellBlocks {
|
|
|
503
670
|
const cell = detail.target.holder.closest<HTMLElement>(`[${CELL_ATTR}]`);
|
|
504
671
|
|
|
505
672
|
if (cell && this.gridElement.contains(cell)) {
|
|
506
|
-
this.removedBlockCells.set(detail.
|
|
673
|
+
this.removedBlockCells.set(detail.target.id, { cell, index: detail.index });
|
|
507
674
|
}
|
|
508
675
|
}
|
|
509
676
|
|
|
677
|
+
/**
|
|
678
|
+
* Find a removedBlockCells entry whose stored index matches the given block index.
|
|
679
|
+
* Removes and returns the first match, or null if none found.
|
|
680
|
+
*/
|
|
681
|
+
private findRemovedEntryForIndex(blockIndex: number): { cell: HTMLElement; index: number } | null {
|
|
682
|
+
for (const [removedId, entry] of this.removedBlockCells) {
|
|
683
|
+
if (entry.index === blockIndex) {
|
|
684
|
+
this.removedBlockCells.delete(removedId);
|
|
685
|
+
|
|
686
|
+
return entry;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
return null;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Resolve a block id to a cell only when this table model explicitly tracks
|
|
695
|
+
* that block in one of this table's cells.
|
|
696
|
+
*/
|
|
697
|
+
private getOwnedCellForBlock(blockId: string): HTMLElement | null {
|
|
698
|
+
const cellPos = this.model.findCellForBlock(blockId);
|
|
699
|
+
|
|
700
|
+
if (!cellPos) {
|
|
701
|
+
return null;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
const cell = this.getCell(cellPos.row, cellPos.col);
|
|
705
|
+
|
|
706
|
+
return cell && this.gridElement.contains(cell) ? cell : null;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Check whether a block at the given flat-list index belongs to this table's
|
|
711
|
+
* block range. Used to prevent cross-table interference when two
|
|
712
|
+
* TableCellBlocks instances both subscribe to the global "block changed" event.
|
|
713
|
+
*
|
|
714
|
+
* Returns true if:
|
|
715
|
+
* - An adjacent block (index-1 or index+1) is mounted inside a cell of this
|
|
716
|
+
* table's grid, OR
|
|
717
|
+
* - The table block is immediately before this index AND either the index
|
|
718
|
+
* after is also within this table (block in a cell) or does not exist
|
|
719
|
+
* (the new block is the last in the flat list).
|
|
720
|
+
*
|
|
721
|
+
* The table block alone being adjacent is NOT sufficient — a second table
|
|
722
|
+
* could immediately follow this one in the flat list, making the table
|
|
723
|
+
* block adjacent to BOTH tables' blocks.
|
|
724
|
+
*/
|
|
725
|
+
private isAdjacentToThisTable(blockIndex: number): boolean {
|
|
726
|
+
const blocksCount = this.api.blocks.getBlocksCount();
|
|
727
|
+
|
|
728
|
+
// Check if any adjacent block is explicitly tracked by this table model.
|
|
729
|
+
for (const offset of [-1, 1]) {
|
|
730
|
+
const adjacentIndex = blockIndex + offset;
|
|
731
|
+
|
|
732
|
+
if (adjacentIndex < 0 || adjacentIndex >= blocksCount) {
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const block = this.api.blocks.getBlockByIndex(adjacentIndex);
|
|
737
|
+
|
|
738
|
+
if (!block) {
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
if (this.getOwnedCellForBlock(block.id)) {
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// For single-block-in-cell tables: the table block is at index-1 and
|
|
748
|
+
// either (a) no block follows at index+1, or (b) the block at index+1
|
|
749
|
+
// is inside this table's grid. This avoids matching blocks that belong
|
|
750
|
+
// to a different table immediately following this one.
|
|
751
|
+
if (!this.isTableBlockAtPrevIndex(blockIndex)) {
|
|
752
|
+
return false;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
const nextIndex = blockIndex + 1;
|
|
756
|
+
|
|
757
|
+
if (nextIndex >= blocksCount) {
|
|
758
|
+
return true;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const nextBlock = this.api.blocks.getBlockByIndex(nextIndex);
|
|
762
|
+
|
|
763
|
+
if (!nextBlock) {
|
|
764
|
+
return true;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
return this.getOwnedCellForBlock(nextBlock.id) !== null;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Check if this table's block is at the index immediately before the given index.
|
|
772
|
+
*/
|
|
773
|
+
private isTableBlockAtPrevIndex(blockIndex: number): boolean {
|
|
774
|
+
const prevIndex = blockIndex - 1;
|
|
775
|
+
|
|
776
|
+
if (prevIndex < 0) {
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
const prevBlock = this.api.blocks.getBlockByIndex(prevIndex);
|
|
781
|
+
|
|
782
|
+
return prevBlock?.id === this.tableBlockId;
|
|
783
|
+
}
|
|
784
|
+
|
|
510
785
|
/**
|
|
511
786
|
* Schedule a microtask to run ensureCellHasBlock for all cells still pending.
|
|
512
787
|
* If a block-added event removes a cell from the pending set before the microtask runs,
|
|
@@ -661,5 +936,28 @@ export class TableCellBlocks {
|
|
|
661
936
|
this._activeCellWithBlocks = null;
|
|
662
937
|
this.cellsPendingCheck.clear();
|
|
663
938
|
this.removedBlockCells.clear();
|
|
939
|
+
this.deferredEvents.length = 0;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* Replay all deferred events. Called after interactive structural ops
|
|
944
|
+
* (add/delete/move row/col) complete so block lifecycle events are processed.
|
|
945
|
+
*/
|
|
946
|
+
public flushDeferredEvents(): void {
|
|
947
|
+
const events = [...this.deferredEvents];
|
|
948
|
+
|
|
949
|
+
this.deferredEvents.length = 0;
|
|
950
|
+
|
|
951
|
+
for (const data of events) {
|
|
952
|
+
this.handleBlockMutation(data);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Discard all deferred events. Called after full-rebuild ops (setData, onPaste)
|
|
958
|
+
* where the entire grid is replaced and old events are meaningless.
|
|
959
|
+
*/
|
|
960
|
+
public discardDeferredEvents(): void {
|
|
961
|
+
this.deferredEvents.length = 0;
|
|
664
962
|
}
|
|
665
963
|
}
|