@jackuait/blok 0.13.0 → 0.13.2
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/codemod/migrate-editorjs-to-blok.js +7 -2
- package/codemod/test.js +22 -2
- package/dist/blok.cjs +1 -1
- package/dist/blok.iife.js +29 -29
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-Cy7bijNZ.mjs → blok-Du6vYONn.mjs} +2166 -2182
- package/dist/chunks/{blok-DsB9tzWP.cjs → blok-Xu27QC2G.cjs} +13 -13
- package/dist/chunks/constants-DDTVRO2H.cjs +457 -0
- package/dist/chunks/{constants-CnxI96Oy.mjs → constants-DUuYY64n.mjs} +451 -246
- package/dist/chunks/{i18next-loader-BObGIOaH.cjs → i18next-loader-DC1uN-wc.cjs} +1 -1
- package/dist/chunks/{i18next-loader-BrDbxldT.mjs → i18next-loader-GIrBCFrC.mjs} +1 -1
- package/dist/chunks/{lightweight-i18n-Bw9zJMpT.cjs → lightweight-i18n-Bbl1cNYK.cjs} +1 -1
- package/dist/chunks/{lightweight-i18n-CFXiOjGR.mjs → lightweight-i18n-DF9Pupws.mjs} +2 -0
- package/dist/chunks/{messages-DLaesq4h2.cjs → messages-1qYt6EhZ2.cjs} +1 -1
- package/dist/chunks/{messages-BzCMWDCa.cjs → messages-2fxvN3Nb.cjs} +1 -1
- package/dist/chunks/{messages-CloQj-t82.mjs → messages-5AxgjKgf2.mjs} +2 -0
- package/dist/{messages-ByaREXXn.mjs → chunks/messages-AgmrT2Id.mjs} +2 -0
- package/dist/{messages-DV7zSwcU2.mjs → chunks/messages-AtUsRyWK2.mjs} +2 -0
- package/dist/chunks/{messages-23LJg97F.cjs → messages-B1Vs2HmR.cjs} +1 -1
- package/dist/{messages-Bgub7yIr.mjs → chunks/messages-B1k4DgVe.mjs} +4 -2
- package/dist/chunks/{messages-CyNE9mfW.cjs → messages-B1xgsCNQ.cjs} +1 -1
- package/dist/chunks/{messages-CK6NQlei2.mjs → messages-B2zrJyAc2.mjs} +2 -0
- package/dist/chunks/{messages-D9KllT5S.mjs → messages-B5CFhyI8.mjs} +2 -0
- package/dist/chunks/{messages-BFPJInnK.mjs → messages-B6You-RA.mjs} +7 -5
- package/dist/{messages-B8Ps9X7Q.mjs → chunks/messages-B6t1xShv.mjs} +2 -0
- package/dist/chunks/{messages-B5P29HKO2.cjs → messages-B780gS332.cjs} +1 -1
- package/dist/chunks/{messages-BBD0GeAN.mjs → messages-B7KbtBAE.mjs} +5 -3
- package/dist/chunks/{messages-CG1tpK3F.cjs → messages-B7T5Notn.cjs} +1 -1
- package/dist/{messages-DemkV5oa2.mjs → chunks/messages-BA2sVGrR2.mjs} +2 -0
- package/dist/chunks/{messages-B9q8LdZT.cjs → messages-BE9aZQ1Q.cjs} +1 -1
- package/dist/chunks/{messages-CPTia1Ip.cjs → messages-BIQpTYfm.cjs} +1 -1
- package/dist/chunks/{messages-BT-EUB5N.cjs → messages-BIRvUJ0t.cjs} +1 -1
- package/dist/chunks/{messages-BEkcSJKV.cjs → messages-BIodfkjv.cjs} +1 -1
- package/dist/chunks/{messages-_ysQiWQr.cjs → messages-BL-zBcuM.cjs} +1 -1
- package/dist/chunks/{messages-CSZTOxAh.mjs → messages-BNxTGhHu.mjs} +2 -0
- package/dist/chunks/{messages-CzG5xDaO.mjs → messages-BP77P9ER.mjs} +2 -0
- package/dist/chunks/{messages-BEM-ySlb2.cjs → messages-BQr0zpmu2.cjs} +1 -1
- package/dist/chunks/{messages-D4P5aWos2.cjs → messages-BTHi6rVW2.cjs} +1 -1
- package/dist/chunks/{messages-KTUVKXJd.mjs → messages-BVZONUH9.mjs} +3 -1
- package/dist/{messages-BvHpSkAX2.mjs → chunks/messages-BVarbXYD2.mjs} +2 -0
- package/dist/{messages-DiOm0iFp.mjs → chunks/messages-BWGqOZ9J.mjs} +2 -0
- package/dist/{messages-DIBytW9u.mjs → chunks/messages-BZ4d5yNH.mjs} +2 -0
- package/dist/chunks/{messages-WUvriTcu2.cjs → messages-BZOAdcmO2.cjs} +1 -1
- package/dist/chunks/{messages-CN9LNhoS2.mjs → messages-B_U10evN2.mjs} +4 -2
- package/dist/chunks/{messages-DPrZ8Z6d2.cjs → messages-BbsGeVs_2.cjs} +1 -1
- package/dist/chunks/{messages-3_7JWqT0.cjs → messages-Bc1NYJVS.cjs} +1 -1
- package/dist/chunks/{messages-D3EU-LRS.cjs → messages-BdORNG8X.cjs} +1 -1
- package/dist/chunks/{messages-BIOk-aTQ.cjs → messages-Bg2kheTv.cjs} +1 -1
- package/dist/chunks/{messages-DsAkJt8M.cjs → messages-Bj1eQtQw.cjs} +1 -1
- package/dist/chunks/{messages-CD6xvMw1.cjs → messages-BkJJCHNK.cjs} +1 -1
- package/dist/chunks/{messages-BIN5-zeZ.cjs → messages-BkdGQfIX.cjs} +1 -1
- package/dist/chunks/{messages-pKpKbxTh2.cjs → messages-BkgsB-cj2.cjs} +1 -1
- package/dist/{messages-DXCKUB0_.mjs → chunks/messages-BmdkDNYv.mjs} +4 -2
- package/dist/{messages-B66o_tQ42.mjs → chunks/messages-BmiN0JGP2.mjs} +2 -0
- package/dist/chunks/{messages-BG17trOF.cjs → messages-Bn0vGFEP.cjs} +1 -1
- package/dist/{messages-BpJopIVL2.mjs → chunks/messages-BoCUgrkI.mjs} +2 -0
- package/dist/chunks/{messages-B7dSyfsy.cjs → messages-BoIUXwWe.cjs} +1 -1
- package/dist/chunks/{messages-7oeFTHO4.cjs → messages-BpDEh8rW.cjs} +1 -1
- package/dist/{messages-DVSJBYhD.mjs → chunks/messages-BuYnNUtU2.mjs} +3 -1
- package/dist/{messages-D8SUKrMB.mjs → chunks/messages-BvuEffoe.mjs} +4 -2
- package/dist/{messages-DvIwCnTR.mjs → chunks/messages-BvupGuDw2.mjs} +2 -0
- package/dist/chunks/{messages-BZr0xR7X.cjs → messages-BwknPZJ8.cjs} +1 -1
- package/dist/{messages-5s1gGSm4.mjs → chunks/messages-BxKobpJ22.mjs} +2 -0
- package/dist/chunks/{messages-D_OfKMtO2.cjs → messages-ByicRCge2.cjs} +1 -1
- package/dist/{messages-DNDonN-x.mjs → chunks/messages-C03LZxma.mjs} +2 -0
- package/dist/{messages-CqrBLC_P.mjs → chunks/messages-C24IC_eR.mjs} +2 -0
- package/dist/chunks/{messages-CucO-8OV.cjs → messages-C2oBmyTn.cjs} +1 -1
- package/dist/chunks/{messages-CXZtG3Xs2.mjs → messages-C4bHKGnB2.mjs} +4 -2
- package/dist/chunks/{messages-DTceHV5d2.mjs → messages-C4sIqArW2.mjs} +2 -0
- package/dist/chunks/{messages-Ds1jRRkJ2.cjs → messages-C9wBMmxr2.cjs} +1 -1
- package/dist/chunks/{messages-DdMhxYfW.cjs → messages-CDK5-8vW.cjs} +1 -1
- package/dist/chunks/{messages-CP3f0qkN.cjs → messages-CKHbPcfh.cjs} +1 -1
- package/dist/{messages-Dt4Cw2PN2.mjs → chunks/messages-CMRjQYxi2.mjs} +3 -1
- package/dist/chunks/{messages-BJVhJhdz.cjs → messages-CNFfwTfw.cjs} +1 -1
- package/dist/chunks/{messages-C99hDoeM2.cjs → messages-CNiuofck2.cjs} +1 -1
- package/dist/chunks/{messages-CjgjbJ1H2.mjs → messages-COMdnGQV2.mjs} +4 -2
- package/dist/{messages-BfsTqQCr2.mjs → chunks/messages-CQg2_vmm.mjs} +2 -0
- package/dist/{messages-_OjohrXs.mjs → chunks/messages-CTWXEx_o.mjs} +6 -4
- package/dist/{messages-BJBdgowf.mjs → chunks/messages-CWTFEPbA2.mjs} +2 -0
- package/dist/chunks/{messages-l73qDsKl.cjs → messages-CWszAGkF.cjs} +1 -1
- package/dist/chunks/{messages-BGcdiqDM2.cjs → messages-CWzQNagc2.cjs} +1 -1
- package/dist/{messages-CaC0BVP72.mjs → chunks/messages-CXxz5HYQ.mjs} +2 -0
- package/dist/chunks/{messages-BvJTJwoq2.cjs → messages-CYf1gv722.cjs} +1 -1
- package/dist/{messages-DN_N2jK1.mjs → chunks/messages-CcboYTP8.mjs} +2 -0
- package/dist/{messages-DdGG7T30.mjs → chunks/messages-CdWXgq_r.mjs} +2 -0
- package/dist/chunks/{messages-pZC8rTng.cjs → messages-CfcCwbQo.cjs} +1 -1
- package/dist/chunks/{messages-DFJTssY7.cjs → messages-CkvqOnAR.cjs} +1 -1
- package/dist/chunks/{messages-BzbW5tIB2.cjs → messages-Cnrug7nz2.cjs} +1 -1
- package/dist/chunks/{messages-BUp0i-9G.cjs → messages-Cr51zCHy.cjs} +1 -1
- package/dist/chunks/{messages-Cz63p8bt2.cjs → messages-CsLvvl2F2.cjs} +1 -1
- package/dist/chunks/{messages-DrIzpqee.cjs → messages-CuO-Rx4g.cjs} +1 -1
- package/dist/chunks/messages-Cv4I3k1W2.cjs +1 -0
- package/dist/chunks/{messages-BScbCwsN.cjs → messages-CwHRv6g8.cjs} +1 -1
- package/dist/chunks/{messages-EUS1-T0-.mjs → messages-CyCl8la6.mjs} +2 -0
- package/dist/chunks/{messages-DOUT2sT62.cjs → messages-CzXnHfGb2.cjs} +1 -1
- package/dist/chunks/{messages-ndFXaPuJ.cjs → messages-D2QxLx1a.cjs} +1 -1
- package/dist/chunks/{messages-CDLJmxWA.cjs → messages-D4LUPpX_.cjs} +1 -1
- package/dist/{messages-DpQjOxzP.mjs → chunks/messages-D7YPlNAK.mjs} +2 -0
- package/dist/{messages-S0krg7sB.mjs → chunks/messages-DGHTTk1S2.mjs} +3 -1
- package/dist/chunks/{messages-wZhc9mFF2.mjs → messages-DHdoaaFq2.mjs} +6 -4
- package/dist/chunks/{messages-C0BMFvdy.mjs → messages-DI9Ifrgt.mjs} +2 -0
- package/dist/chunks/messages-DJFL-bxd2.cjs +1 -0
- package/dist/chunks/messages-DLEeNpMi2.cjs +1 -0
- package/dist/chunks/{messages-BpI1875E.mjs → messages-DNqFlfOd.mjs} +3 -1
- package/dist/chunks/{messages-mtoLIsYL.cjs → messages-DTNU_cq0.cjs} +1 -1
- package/dist/chunks/{messages-BxXGCWit.cjs → messages-DVKsYqpJ.cjs} +1 -1
- package/dist/chunks/{messages-BJNTs8dY.cjs → messages-DXlfz-nC.cjs} +1 -1
- package/dist/chunks/{messages-DKdgRSvy.cjs → messages-DbA_Zja3.cjs} +1 -1
- package/dist/chunks/{messages-CZ2th1UV2.cjs → messages-Dc2TTEx_2.cjs} +1 -1
- package/dist/chunks/{messages-Bh-GPq0T2.mjs → messages-Dd4nzvLj2.mjs} +2 -0
- package/dist/chunks/{messages-BISkpo37.cjs → messages-DeDMMmRC.cjs} +1 -1
- package/dist/chunks/{messages-C0Fr1grN.mjs → messages-DefZ3ihx.mjs} +2 -0
- package/dist/{messages-DC1fWdjB2.mjs → chunks/messages-DhZwMl9x2.mjs} +2 -0
- package/dist/chunks/{messages-BYT844Pj.mjs → messages-DiGsu5XN.mjs} +6 -4
- package/dist/chunks/{messages-xeJ5eVFo.cjs → messages-DlQNXqzr.cjs} +1 -1
- package/dist/{messages-CZYocA-2.mjs → chunks/messages-DlcI-0Sy.mjs} +2 -0
- package/dist/{messages-ZJE9VNzB2.mjs → chunks/messages-DmErSGPk2.mjs} +2 -0
- package/dist/chunks/{messages-h9Zi_9Gr.cjs → messages-DqMqZLcn.cjs} +1 -1
- package/dist/chunks/{messages-D_w-pjpG2.cjs → messages-DqqDuEE22.cjs} +1 -1
- package/dist/chunks/{messages-DW0CNDiw.mjs → messages-DsyO86r3.mjs} +2 -0
- package/dist/chunks/{messages-DgdjQ2JT.mjs → messages-DzY53I67.mjs} +2 -0
- package/dist/chunks/{messages-PeAC6FL2.cjs → messages-DzppdmWe.cjs} +1 -1
- package/dist/chunks/{messages-CkCgWAJW2.mjs → messages-GHsufIGi2.mjs} +4 -2
- package/dist/chunks/{messages-Diinl7nA2.cjs → messages-HzLF-BQL2.cjs} +1 -1
- package/dist/chunks/{messages-CoWmNHyu2.cjs → messages-Jb9n97oP2.cjs} +1 -1
- package/dist/chunks/{messages-2sqZ51ZE2.cjs → messages-K_vSdSoF2.cjs} +1 -1
- package/dist/{messages-D-K9TXl02.mjs → chunks/messages-LTkIIrSe2.mjs} +6 -4
- package/dist/chunks/{messages-zqNVwsuv.mjs → messages-MPF8o3EP.mjs} +2 -0
- package/dist/chunks/{messages-5HoTbob5.cjs → messages-Nh7wrRdm.cjs} +1 -1
- package/dist/chunks/{messages-B6ALGrrK2.mjs → messages-OSIAf0Wk2.mjs} +5 -3
- package/dist/chunks/{messages-P9sjeERx.mjs → messages-OYoN_rp1.mjs} +4 -2
- package/dist/chunks/messages-QHS-Ydg_.cjs +1 -0
- package/dist/chunks/{messages-DLphNjiM2.cjs → messages-SpiG5vT-2.cjs} +1 -1
- package/dist/chunks/{messages-RumMLtL32.mjs → messages-Uc3Uc2862.mjs} +3 -1
- package/dist/chunks/{messages-BP9zsQtc.mjs → messages-V8K7-1l2.mjs} +2 -0
- package/dist/chunks/{messages-BR1Rd5-u2.cjs → messages-XFaJzdhP2.cjs} +1 -1
- package/dist/{messages-B3GO2TNx2.mjs → chunks/messages-Z9mDYT3w.mjs} +2 -0
- package/dist/chunks/{messages-CEroCDzi.mjs → messages-ZHNvKiIX.mjs} +2 -0
- package/dist/chunks/{messages-C2irZQlh.mjs → messages-bSVgJ1cu.mjs} +3 -1
- package/dist/chunks/{messages-DlNTalkx2.mjs → messages-bjSJwsXK2.mjs} +2 -0
- package/dist/{messages-D_jk0Apm.mjs → chunks/messages-eyGOcbhV.mjs} +2 -0
- package/dist/chunks/{messages-DlvmJJK6.mjs → messages-fSeXd6-z.mjs} +3 -1
- package/dist/{messages-BYooY4mP2.mjs → chunks/messages-l5xHQb_m.mjs} +7 -5
- package/dist/{messages-D_pfhYg5.mjs → chunks/messages-rEsI_fAk.mjs} +5 -3
- package/dist/chunks/{messages-MxqZVywa2.mjs → messages-sqdfYuVj2.mjs} +2 -0
- package/dist/chunks/{messages-C-D80jVE.mjs → messages-vQ5kblO8.mjs} +2 -0
- package/dist/chunks/{messages-BwNXKlvA2.cjs → messages-y03BGg692.cjs} +1 -1
- package/dist/chunks/tools-DOuVjow8.cjs +116 -0
- package/dist/chunks/{tools-1xd7TPfu.mjs → tools-Tt-NXbRZ.mjs} +1816 -1637
- package/dist/full.cjs +1 -1
- package/dist/full.mjs +3 -3
- package/dist/locales.mjs +69 -67
- package/dist/{chunks/messages-CkdgHogc2.mjs → messages-1ufJbdRv2.mjs} +3 -1
- package/dist/{messages-cBA8dKoi.mjs → messages-3j4yi-DF.mjs} +5 -3
- package/dist/{chunks/messages-BGCpxpgG.mjs → messages-5USazVPA2.mjs} +2 -0
- package/dist/{chunks/messages-Cf9wwoye2.mjs → messages-7fwJIrld2.mjs} +2 -0
- package/dist/{messages-hVVP_eZE.mjs → messages-AycxTjmw.mjs} +2 -0
- package/dist/{messages-Bg5tERmS.mjs → messages-B3PWaMcw.mjs} +6 -4
- package/dist/{chunks/messages-Diozu4lJ.mjs → messages-B3oFjWq3.mjs} +4 -2
- package/dist/{chunks/messages-ByJ-nSXK.mjs → messages-B8Tq9Txy.mjs} +2 -0
- package/dist/{messages-CDJP_fbb2.mjs → messages-BDwU9rYR2.mjs} +4 -2
- package/dist/{messages-6ukS6d5Z.mjs → messages-BGzpwNrz.mjs} +2 -0
- package/dist/{chunks/messages-CHXG6lEA2.mjs → messages-BKCuCTFM.mjs} +2 -0
- package/dist/{chunks/messages-aGEPK1g12.mjs → messages-BSHFypGE2.mjs} +2 -0
- package/dist/{chunks/messages-OMGVF8X52.mjs → messages-BcD7xtJA.mjs} +3 -1
- package/dist/{messages-DA2x_UvX2.mjs → messages-Bj03XD-02.mjs} +6 -4
- package/dist/{chunks/messages-C3NrnRWC.mjs → messages-BkTBwYet.mjs} +2 -0
- package/dist/{messages-ZjCwxd3_2.mjs → messages-BmWP4vpV2.mjs} +2 -0
- package/dist/{chunks/messages-DDtwOfXf.mjs → messages-Bt4TLGth.mjs} +2 -0
- package/dist/{chunks/messages-Bly_2YUk.mjs → messages-BtDz-sw92.mjs} +2 -0
- package/dist/{messages-CTcNzaJJ2.mjs → messages-C2TRJroV2.mjs} +2 -0
- package/dist/{messages-CDRUbL17.mjs → messages-C31VIrlL.mjs} +2 -0
- package/dist/{messages-Yg8Y6PlG.mjs → messages-C8RMjnBe.mjs} +2 -0
- package/dist/{chunks/messages-BciKgfP4.mjs → messages-C9GFRcVj.mjs} +6 -4
- package/dist/{chunks/messages-0cSP25RB.mjs → messages-CAGQtm7T.mjs} +5 -3
- package/dist/{messages-_6tu8F-N.mjs → messages-CITYhXUz.mjs} +2 -0
- package/dist/{messages-BbaS2xgR2.mjs → messages-CIjSE2_O2.mjs} +5 -3
- package/dist/{messages-BQ7jJt9m.mjs → messages-CRR1VRO6.mjs} +2 -0
- package/dist/{chunks/messages-Da-9fv3U.mjs → messages-CTzO11jz.mjs} +2 -0
- package/dist/{messages-DaSzBuLF2.mjs → messages-CX8egsiA2.mjs} +2 -0
- package/dist/{messages-DccIq7002.mjs → messages-C_gdsU952.mjs} +4 -2
- package/dist/{messages-CXXQC9Vz.mjs → messages-C_mN4lx0.mjs} +3 -1
- package/dist/{chunks/messages-BI7NfKFe.mjs → messages-CacRpQpm.mjs} +4 -2
- package/dist/{chunks/messages-BCRpttn3.mjs → messages-Cdgz3urh.mjs} +2 -0
- package/dist/{messages-BaC-sNb4.mjs → messages-CgVEHCQ-.mjs} +3 -1
- package/dist/{chunks/messages-D_24p8E62.mjs → messages-CgaGkQi32.mjs} +2 -0
- package/dist/{chunks/messages-D3AyiRbO.mjs → messages-CmN2OfuB.mjs} +2 -0
- package/dist/{chunks/messages-CSierpa_2.mjs → messages-CntTlSE22.mjs} +2 -0
- package/dist/{messages-BK1sXq7X.mjs → messages-Cp0fjsey.mjs} +3 -1
- package/dist/{messages-DHOj5syv2.mjs → messages-Cx7sqvx02.mjs} +2 -0
- package/dist/{messages-CQUbgCd62.mjs → messages-CxX23Jsk2.mjs} +4 -2
- package/dist/{chunks/messages-DTqb7T61.mjs → messages-D-rvoUSJ.mjs} +2 -0
- package/dist/{messages-Bkbhk9kJ2.mjs → messages-D1Fjr4OK2.mjs} +2 -0
- package/dist/{chunks/messages-CSkYL3AP.mjs → messages-D4U4wkYM.mjs} +2 -0
- package/dist/{chunks/messages-DwuvQpsD.mjs → messages-D5qgCWmB2.mjs} +7 -5
- package/dist/{chunks/messages-a_XmI-x5.mjs → messages-D788KtGe.mjs} +2 -0
- package/dist/{chunks/messages-B4-oaYBZ.mjs → messages-DFfhoDWZ2.mjs} +2 -0
- package/dist/{messages-BgcWyc4R.mjs → messages-DKsyrVp5.mjs} +2 -0
- package/dist/{messages-B_Js-HRK.mjs → messages-DL7JAwpC.mjs} +2 -0
- package/dist/{chunks/messages-CSioKJVK2.mjs → messages-DNlrcG5Z.mjs} +2 -0
- package/dist/{chunks/messages-vGRE1OPk2.mjs → messages-DPqFBtJR.mjs} +2 -0
- package/dist/{chunks/messages-BTKAxpmi.mjs → messages-DQik3_xv2.mjs} +2 -0
- package/dist/{messages-BUksRT7Q.mjs → messages-DTkd9ND8.mjs} +7 -5
- package/dist/{messages-Br4tspi_2.mjs → messages-DXCyNanc2.mjs} +2 -0
- package/dist/{chunks/messages-CdJq8h3E.mjs → messages-D_WzyzUt.mjs} +2 -0
- package/dist/{chunks/messages-DC0r7l8x2.mjs → messages-Ddz6eH0-2.mjs} +2 -0
- package/dist/{messages-BqCRuWLo.mjs → messages-DiL61awK.mjs} +2 -0
- package/dist/{chunks/messages-DXaps_uI.mjs → messages-Dq2WEsEu.mjs} +2 -0
- package/dist/{chunks/messages-8qsQ7qZX2.mjs → messages-DqXJJPx9.mjs} +3 -1
- package/dist/{messages-jh3qE8dL.mjs → messages-Duk7VVeY.mjs} +3 -1
- package/dist/{messages-DQHRgl_P.mjs → messages-DzkZ434Z.mjs} +4 -2
- package/dist/{messages-DUdZKtlE.mjs → messages-JKXCsFKZ.mjs} +2 -0
- package/dist/{chunks/messages-C9-UAJuq.mjs → messages-NVepzgE3.mjs} +4 -2
- package/dist/{messages-omcUe0Za.mjs → messages-PQVh93mt.mjs} +2 -0
- package/dist/{chunks/messages-xRQMQj4w2.mjs → messages-ftPYsH6d2.mjs} +6 -4
- package/dist/{chunks/messages-Ddb_L6gp2.mjs → messages-gQ5PFa2t2.mjs} +2 -0
- package/dist/{messages-DzqQWiFx.mjs → messages-oIa8wahx.mjs} +2 -0
- package/dist/{messages-DO62ugjy2.mjs → messages-rpO1POP02.mjs} +3 -1
- package/dist/{messages-63r3O0932.mjs → messages-uy3FE24_2.mjs} +4 -2
- package/dist/react.cjs +1 -1
- package/dist/react.mjs +1 -1
- package/dist/tools.cjs +1 -1
- package/dist/tools.mjs +2 -2
- package/package.json +1 -1
- package/src/blok.ts +2 -0
- package/src/cli/commands/convert-html/block-builder.ts +13 -3
- package/src/components/i18n/locales/am/messages.json +2 -1
- package/src/components/i18n/locales/ar/messages.json +2 -1
- package/src/components/i18n/locales/az/messages.json +3 -2
- package/src/components/i18n/locales/bg/messages.json +2 -1
- package/src/components/i18n/locales/bn/messages.json +2 -1
- package/src/components/i18n/locales/bs/messages.json +6 -5
- package/src/components/i18n/locales/cs/messages.json +4 -3
- package/src/components/i18n/locales/da/messages.json +6 -5
- package/src/components/i18n/locales/de/messages.json +4 -3
- package/src/components/i18n/locales/dv/messages.json +2 -1
- package/src/components/i18n/locales/el/messages.json +2 -1
- package/src/components/i18n/locales/en/messages.json +2 -0
- package/src/components/i18n/locales/es/messages.json +3 -2
- package/src/components/i18n/locales/et/messages.json +3 -2
- package/src/components/i18n/locales/fa/messages.json +2 -1
- package/src/components/i18n/locales/fi/messages.json +3 -2
- package/src/components/i18n/locales/fil/messages.json +7 -6
- package/src/components/i18n/locales/fr/messages.json +4 -3
- package/src/components/i18n/locales/gu/messages.json +2 -1
- package/src/components/i18n/locales/he/messages.json +2 -1
- package/src/components/i18n/locales/hi/messages.json +2 -1
- package/src/components/i18n/locales/hr/messages.json +5 -4
- package/src/components/i18n/locales/hu/messages.json +4 -3
- package/src/components/i18n/locales/hy/messages.json +2 -1
- package/src/components/i18n/locales/id/messages.json +2 -1
- package/src/components/i18n/locales/it/messages.json +5 -4
- package/src/components/i18n/locales/ja/messages.json +2 -1
- package/src/components/i18n/locales/ka/messages.json +2 -1
- package/src/components/i18n/locales/km/messages.json +2 -1
- package/src/components/i18n/locales/kn/messages.json +2 -1
- package/src/components/i18n/locales/ko/messages.json +2 -1
- package/src/components/i18n/locales/ku/messages.json +2 -1
- package/src/components/i18n/locales/lo/messages.json +2 -1
- package/src/components/i18n/locales/lt/messages.json +3 -2
- package/src/components/i18n/locales/lv/messages.json +3 -2
- package/src/components/i18n/locales/mk/messages.json +2 -1
- package/src/components/i18n/locales/ml/messages.json +2 -1
- package/src/components/i18n/locales/mn/messages.json +2 -1
- package/src/components/i18n/locales/mr/messages.json +2 -1
- package/src/components/i18n/locales/ms/messages.json +4 -3
- package/src/components/i18n/locales/my/messages.json +2 -1
- package/src/components/i18n/locales/ne/messages.json +2 -1
- package/src/components/i18n/locales/nl/messages.json +4 -3
- package/src/components/i18n/locales/no/messages.json +4 -3
- package/src/components/i18n/locales/pa/messages.json +2 -1
- package/src/components/i18n/locales/pl/messages.json +4 -3
- package/src/components/i18n/locales/ps/messages.json +2 -1
- package/src/components/i18n/locales/pt/messages.json +6 -5
- package/src/components/i18n/locales/ro/messages.json +3 -2
- package/src/components/i18n/locales/ru/messages.json +2 -1
- package/src/components/i18n/locales/sd/messages.json +2 -1
- package/src/components/i18n/locales/si/messages.json +2 -1
- package/src/components/i18n/locales/sk/messages.json +6 -5
- package/src/components/i18n/locales/sl/messages.json +5 -4
- package/src/components/i18n/locales/sq/messages.json +3 -2
- package/src/components/i18n/locales/sr/messages.json +2 -1
- package/src/components/i18n/locales/sv/messages.json +7 -6
- package/src/components/i18n/locales/sw/messages.json +2 -1
- package/src/components/i18n/locales/ta/messages.json +2 -1
- package/src/components/i18n/locales/te/messages.json +2 -1
- package/src/components/i18n/locales/th/messages.json +2 -1
- package/src/components/i18n/locales/tr/messages.json +2 -1
- package/src/components/i18n/locales/ug/messages.json +2 -1
- package/src/components/i18n/locales/uk/messages.json +2 -1
- package/src/components/i18n/locales/ur/messages.json +2 -1
- package/src/components/i18n/locales/vi/messages.json +2 -1
- package/src/components/i18n/locales/yi/messages.json +2 -1
- package/src/components/i18n/locales/zh/messages.json +2 -1
- package/src/components/icons/index.ts +6 -3
- package/src/components/inline-tools/inline-tool-marker.ts +12 -0
- package/src/components/modules/api/blocks.ts +3 -0
- package/src/components/modules/paste/google-docs-preprocessor.ts +64 -28
- package/src/components/modules/paste/sanitizer-config.ts +10 -1
- package/src/components/modules/renderer.ts +7 -1
- package/src/components/modules/toolbar/blockSettings.ts +54 -7
- package/src/components/modules/toolbar/content-alignment.ts +89 -0
- package/src/components/modules/toolbar/index.ts +85 -61
- package/src/components/modules/ui.ts +28 -6
- package/src/components/modules/uiControllers/controllers/blockHover.ts +20 -0
- package/src/components/utils/color-mapping.ts +15 -0
- package/src/components/utils/color-migration.ts +10 -0
- package/src/components/utils/data-model-transform.ts +200 -0
- package/src/components/utils/default-page-colors.ts +130 -0
- package/src/components/utils/highlight-block-arrival.ts +50 -0
- package/src/components/utils/popover/popover-desktop.ts +23 -1
- package/src/styles/image.css +86 -0
- package/src/styles/keyframes.css +6 -0
- package/src/styles/main.css +17 -0
- package/src/tools/database/index.ts +3 -4
- package/src/tools/image/dimensions-from-svg.ts +53 -0
- package/src/tools/image/dimensions-from-url.ts +87 -0
- package/src/tools/image/error-state.ts +7 -2
- package/src/tools/image/index.ts +81 -7
- package/src/tools/image/probe-dimensions.ts +36 -0
- package/src/tools/image/ui.ts +46 -2
- package/src/tools/image/uploader.ts +12 -8
- package/src/tools/table/table-cell-clipboard.ts +17 -3
- package/types/tools/image.d.ts +16 -2
- package/dist/chunks/constants-JFG5JxhI.cjs +0 -457
- package/dist/chunks/messages-C-FUK4Ki2.cjs +0 -1
- package/dist/chunks/messages-CLkrVqVp.cjs +0 -1
- package/dist/chunks/messages-D9qYuzOY2.cjs +0 -1
- package/dist/chunks/messages-DEdX7dXt2.cjs +0 -1
- package/dist/chunks/tools-Cnlc1TxG.cjs +0 -116
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { DATA_ATTR } from '../../constants';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Horizontal alignment helpers for the toolbar.
|
|
5
|
+
*
|
|
6
|
+
* The toolbar's inner content wrapper (holding the plus button + drag handle)
|
|
7
|
+
* must align with the block's visible content column. Two layouts exist:
|
|
8
|
+
*
|
|
9
|
+
* 1. Non-stretched block — `[data-blok-element-content]` is centered inside
|
|
10
|
+
* the holder via `mx-auto` + `max-w-blok-content`. The gap between holder
|
|
11
|
+
* left and content left IS the offset we want.
|
|
12
|
+
*
|
|
13
|
+
* 2. Stretched block (e.g. `database`) — the content element fills the holder
|
|
14
|
+
* (max-width removed), so the raw gap is 0. The tool may still re-center
|
|
15
|
+
* its visible content via internal CSS padding. In this case we fall back
|
|
16
|
+
* to the editor's canonical content-column width (`--max-width-content`)
|
|
17
|
+
* and center that inside the holder. Without this the toolbar snaps to
|
|
18
|
+
* the holder's far-left edge, far from the visible content.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Compute the horizontal offset between the holder's left edge and the block's
|
|
23
|
+
* visible content column. See module doc for the two layout cases.
|
|
24
|
+
* @param targetBlockHolder - Block holder element (has `data-blok-stretched` when stretched)
|
|
25
|
+
* @param contentRect - bounding rect of the block's `[data-blok-element-content]`
|
|
26
|
+
* @param wrapperRect - bounding rect of the toolbar wrapper (co-located with holder)
|
|
27
|
+
*/
|
|
28
|
+
export function computeVisualContentOffset(
|
|
29
|
+
targetBlockHolder: HTMLElement,
|
|
30
|
+
contentRect: DOMRect,
|
|
31
|
+
wrapperRect: DOMRect | undefined
|
|
32
|
+
): number {
|
|
33
|
+
if (wrapperRect === undefined) {
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const stretched = targetBlockHolder.getAttribute(DATA_ATTR.stretched) === 'true';
|
|
38
|
+
|
|
39
|
+
if (stretched) {
|
|
40
|
+
const maxContent = readMaxContentWidth(targetBlockHolder);
|
|
41
|
+
|
|
42
|
+
if (maxContent !== null && wrapperRect.width > maxContent) {
|
|
43
|
+
return (wrapperRect.width - maxContent) / 2;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return Math.max(0, contentRect.left - wrapperRect.left);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Resolve the visible content width used to clamp the toolbar wrapper's
|
|
52
|
+
* max-width. Stretched blocks still size their visible content to the
|
|
53
|
+
* canonical content column (`--max-width-content`), so clamp to that
|
|
54
|
+
* instead of the full holder width — otherwise the toolbar hover target
|
|
55
|
+
* would span the whole viewport.
|
|
56
|
+
* @param targetBlockHolder - Block holder element
|
|
57
|
+
* @param contentRect - bounding rect of the block's `[data-blok-element-content]`
|
|
58
|
+
* @param wrapperRect - bounding rect of the toolbar wrapper (co-located with holder)
|
|
59
|
+
*/
|
|
60
|
+
export function resolveVisualContentWidth(
|
|
61
|
+
targetBlockHolder: HTMLElement,
|
|
62
|
+
contentRect: DOMRect,
|
|
63
|
+
wrapperRect: DOMRect | undefined
|
|
64
|
+
): number {
|
|
65
|
+
const stretched = targetBlockHolder.getAttribute(DATA_ATTR.stretched) === 'true';
|
|
66
|
+
|
|
67
|
+
if (stretched && wrapperRect !== undefined) {
|
|
68
|
+
const maxContent = readMaxContentWidth(targetBlockHolder);
|
|
69
|
+
|
|
70
|
+
if (maxContent !== null && wrapperRect.width > maxContent) {
|
|
71
|
+
return maxContent;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return contentRect.width;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Read the `--max-width-content` CSS custom property off the given element
|
|
80
|
+
* (inherited from `:root`/`@theme`). Returns `null` if the token is absent
|
|
81
|
+
* or not a positive finite number.
|
|
82
|
+
* @param element - element whose computed style supplies the CSS var
|
|
83
|
+
*/
|
|
84
|
+
function readMaxContentWidth(element: HTMLElement): number | null {
|
|
85
|
+
const raw = getComputedStyle(element).getPropertyValue('--max-width-content').trim();
|
|
86
|
+
const value = parseFloat(raw);
|
|
87
|
+
|
|
88
|
+
return Number.isFinite(value) && value > 0 ? value : null;
|
|
89
|
+
}
|
|
@@ -17,6 +17,7 @@ import { hide } from '../../utils/tooltip';
|
|
|
17
17
|
* Refactored Toolbar module components
|
|
18
18
|
*/
|
|
19
19
|
import { ClickDragHandler } from './click-handler';
|
|
20
|
+
import { computeVisualContentOffset, resolveVisualContentWidth } from './content-alignment';
|
|
20
21
|
import { PlusButtonHandler } from './plus-button';
|
|
21
22
|
import { ToolbarPositioner } from './positioning';
|
|
22
23
|
import { SettingsTogglerHandler } from './settings-toggler';
|
|
@@ -360,20 +361,47 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
360
361
|
|
|
361
362
|
|
|
362
363
|
/**
|
|
363
|
-
* Toggles read-only mode
|
|
364
|
+
* Toggles read-only mode.
|
|
365
|
+
*
|
|
366
|
+
* Read-only (Notion-style): the toolbar and block settings stay alive so the
|
|
367
|
+
* user can still hover a block and copy a link to it. The plus button is
|
|
368
|
+
* hidden and the drag gesture is suppressed (see moveAndOpen + plus-button
|
|
369
|
+
* handler).
|
|
364
370
|
* @param {boolean} readOnlyEnabled - read-only mode
|
|
365
371
|
*/
|
|
366
372
|
public toggleReadOnly(readOnlyEnabled: boolean): void {
|
|
367
|
-
|
|
373
|
+
/**
|
|
374
|
+
* Draw the toolbar the first time we need it. Previously the toolbar DOM
|
|
375
|
+
* was only built on the readOnly=false path; now read-only also hosts a
|
|
376
|
+
* (restricted) block settings popover, so ensure the DOM exists in both
|
|
377
|
+
* modes. Subsequent toggles just flip plus-button visibility.
|
|
378
|
+
*/
|
|
379
|
+
if (this.nodes.wrapper === undefined) {
|
|
368
380
|
window.requestIdleCallback(async () => {
|
|
369
381
|
await this.drawUI();
|
|
370
382
|
this.enableModuleBindings();
|
|
383
|
+
this.applyReadOnlyToPlusButton(readOnlyEnabled);
|
|
371
384
|
}, { timeout: 2000 });
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
this.Blok.BlockSettings.destroy();
|
|
375
|
-
this.disableModuleBindings();
|
|
385
|
+
|
|
386
|
+
return;
|
|
376
387
|
}
|
|
388
|
+
|
|
389
|
+
this.applyReadOnlyToPlusButton(readOnlyEnabled);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Hides the plus button in read-only mode, restores its visibility otherwise.
|
|
394
|
+
* Uses inline display:none because the button element already uses inline
|
|
395
|
+
* style toggling elsewhere (moveAndOpen, close, moveAndOpenForMultipleBlocks).
|
|
396
|
+
*/
|
|
397
|
+
private applyReadOnlyToPlusButton(readOnlyEnabled: boolean): void {
|
|
398
|
+
const { plusButton } = this.nodes;
|
|
399
|
+
|
|
400
|
+
if (plusButton === undefined) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
plusButton.style.display = readOnlyEnabled ? 'none' : '';
|
|
377
405
|
}
|
|
378
406
|
|
|
379
407
|
/**
|
|
@@ -476,8 +504,9 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
476
504
|
* whole table undraggable while the user edits cell text.
|
|
477
505
|
*/
|
|
478
506
|
const isCalloutFirstChild = this.isFirstChildOfCallout(targetBlock);
|
|
507
|
+
const hidePlusButton = isCalloutFirstChild || this.Blok.ReadOnly.isEnabled;
|
|
479
508
|
|
|
480
|
-
plusButton.style.display =
|
|
509
|
+
plusButton.style.display = hidePlusButton ? 'none' : '';
|
|
481
510
|
|
|
482
511
|
if (settingsToggler) {
|
|
483
512
|
settingsToggler.style.display = isCalloutFirstChild ? 'none' : '';
|
|
@@ -594,38 +623,41 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
594
623
|
this.restoreSettingsTogglerForLeftEdgeBlock(targetBlock);
|
|
595
624
|
}
|
|
596
625
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
* so toolbar buttons align with the block content edge regardless of whether
|
|
600
|
-
* the consumer uses CSS margin or overrides max-width (e.g. wide-mode).
|
|
601
|
-
*
|
|
602
|
-
* Uses getBoundingClientRect to get the actual visual offset rather than reading
|
|
603
|
-
* CSS marginLeft, which does not account for cases where max-width is removed
|
|
604
|
-
* and the content fills the full container width.
|
|
605
|
-
*
|
|
606
|
-
* Uses Math.max to guarantee the actions container (positioned via right:100%)
|
|
607
|
-
* never extends beyond the left edge of the viewport, which would make the
|
|
608
|
-
* drag handle unreachable by pointer events.
|
|
609
|
-
*
|
|
610
|
-
* For nested blocks (e.g. children inside a callout), the holder is already
|
|
611
|
-
* offset from the viewport left by the parent's indentation. In that case we
|
|
612
|
-
* only need to ensure the actions don't extend beyond the viewport left edge
|
|
613
|
-
* (holderLeft px are available to the left), so the minimum margin is
|
|
614
|
-
* max(0, actionsWidth - holderLeft) rather than a flat actionsWidth clamp.
|
|
615
|
-
*/
|
|
616
|
-
if (blockContentElement && this.nodes.content) {
|
|
617
|
-
const holderRect = this.nodes.wrapper?.getBoundingClientRect();
|
|
618
|
-
const contentRect = blockContentElement.getBoundingClientRect();
|
|
619
|
-
const visualOffset = holderRect ? Math.max(0, contentRect.left - holderRect.left) : 0;
|
|
620
|
-
const actionsWidth = this.nodes.actions?.offsetWidth ?? 0;
|
|
621
|
-
const holderLeft = holderRect ? Math.max(0, holderRect.left) : 0;
|
|
622
|
-
const minMarginLeft = Math.max(0, actionsWidth - holderLeft);
|
|
623
|
-
|
|
624
|
-
this.nodes.content.style.marginLeft = `${Math.max(visualOffset, minMarginLeft)}px`;
|
|
625
|
-
this.nodes.content.style.maxWidth = `${contentRect.width}px`;
|
|
626
|
+
if (blockContentElement) {
|
|
627
|
+
this.syncContentToBlock(targetBlockHolder, blockContentElement);
|
|
626
628
|
}
|
|
627
629
|
}
|
|
628
630
|
|
|
631
|
+
/**
|
|
632
|
+
* Align the toolbar's inner content wrapper with the block's visible content column.
|
|
633
|
+
* See `content-alignment.ts` for the two-case reasoning (non-stretched vs stretched).
|
|
634
|
+
*
|
|
635
|
+
* `Math.max` with `actionsWidth - holderLeft` guarantees the actions bar
|
|
636
|
+
* (positioned at `right:100%`) never extends past the viewport's left edge,
|
|
637
|
+
* which would make the drag handle unreachable by pointer events. For nested
|
|
638
|
+
* blocks already offset from the viewport, `holderLeft` px-of-slack relax the
|
|
639
|
+
* minimum so buttons aren't pushed into the text content.
|
|
640
|
+
* @param targetBlockHolder - Block holder element
|
|
641
|
+
* @param blockContentElement - `[data-blok-element-content]` element inside the holder
|
|
642
|
+
*/
|
|
643
|
+
private syncContentToBlock(targetBlockHolder: HTMLElement, blockContentElement: HTMLElement): void {
|
|
644
|
+
if (this.nodes.content === undefined) {
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
const wrapperRect = this.nodes.wrapper?.getBoundingClientRect();
|
|
649
|
+
const contentRect = blockContentElement.getBoundingClientRect();
|
|
650
|
+
const visualOffset = computeVisualContentOffset(targetBlockHolder, contentRect, wrapperRect);
|
|
651
|
+
const actionsWidth = this.nodes.actions?.offsetWidth ?? 0;
|
|
652
|
+
const holderLeft = wrapperRect ? Math.max(0, wrapperRect.left) : 0;
|
|
653
|
+
const minMarginLeft = Math.max(0, actionsWidth - holderLeft);
|
|
654
|
+
const effectiveOffset = Math.max(visualOffset, minMarginLeft);
|
|
655
|
+
const contentWidth = resolveVisualContentWidth(targetBlockHolder, contentRect, wrapperRect);
|
|
656
|
+
|
|
657
|
+
this.nodes.content.style.marginLeft = `${effectiveOffset}px`;
|
|
658
|
+
this.nodes.content.style.maxWidth = `${contentWidth}px`;
|
|
659
|
+
}
|
|
660
|
+
|
|
629
661
|
/**
|
|
630
662
|
* Move Toolbar to the specified block (or first selected block) and open it for multi-block selection.
|
|
631
663
|
* Keeps the add button visible so users can still insert blocks while multiple are selected.
|
|
@@ -697,8 +729,9 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
697
729
|
/**
|
|
698
730
|
* Restore plus button and settings toggler visibility for multi-block selection,
|
|
699
731
|
* in case they were hidden for table cell blocks.
|
|
732
|
+
* In read-only mode, keep the plus button hidden.
|
|
700
733
|
*/
|
|
701
|
-
plusButton.style.display = '';
|
|
734
|
+
plusButton.style.display = this.Blok.ReadOnly.isEnabled ? 'none' : '';
|
|
702
735
|
plusButton.style.color = '';
|
|
703
736
|
|
|
704
737
|
if (settingsToggler) {
|
|
@@ -742,23 +775,8 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
742
775
|
|
|
743
776
|
this.open();
|
|
744
777
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
* Uses getBoundingClientRect so wide-mode content (max-width: none) is handled correctly.
|
|
748
|
-
* Clamp to max(0, actionsWidth - holderLeft) so actions never extend beyond the left
|
|
749
|
-
* viewport edge. For nested blocks already offset from the left, a smaller clamp is
|
|
750
|
-
* used so buttons are not pushed into the text content.
|
|
751
|
-
*/
|
|
752
|
-
if (blockContentElement && this.nodes.content) {
|
|
753
|
-
const holderRect = this.nodes.wrapper?.getBoundingClientRect();
|
|
754
|
-
const contentRect = blockContentElement.getBoundingClientRect();
|
|
755
|
-
const visualOffset = holderRect ? Math.max(0, contentRect.left - holderRect.left) : 0;
|
|
756
|
-
const actionsWidth = this.nodes.actions?.offsetWidth ?? 0;
|
|
757
|
-
const holderLeft = holderRect ? Math.max(0, holderRect.left) : 0;
|
|
758
|
-
const minMarginLeft = Math.max(0, actionsWidth - holderLeft);
|
|
759
|
-
|
|
760
|
-
this.nodes.content.style.marginLeft = `${Math.max(visualOffset, minMarginLeft)}px`;
|
|
761
|
-
this.nodes.content.style.maxWidth = `${contentRect.width}px`;
|
|
778
|
+
if (blockContentElement) {
|
|
779
|
+
this.syncContentToBlock(targetBlockHolder, blockContentElement);
|
|
762
780
|
}
|
|
763
781
|
}
|
|
764
782
|
|
|
@@ -767,10 +785,6 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
767
785
|
* @param options - Optional configuration
|
|
768
786
|
*/
|
|
769
787
|
public close(options?: ToolbarCloseOptions): void {
|
|
770
|
-
if (this.Blok.ReadOnly.isEnabled) {
|
|
771
|
-
return;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
788
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
775
789
|
this.nodes.wrapper?.classList.remove(this.CSS.toolbarOpened);
|
|
776
790
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
@@ -804,10 +818,11 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
804
818
|
|
|
805
819
|
/**
|
|
806
820
|
* Restore plus button and settings toggler visibility
|
|
807
|
-
* in case they were hidden for table cell blocks
|
|
821
|
+
* in case they were hidden for table cell blocks.
|
|
822
|
+
* In read-only mode, keep the plus button hidden.
|
|
808
823
|
*/
|
|
809
824
|
if (this.nodes.plusButton) {
|
|
810
|
-
this.nodes.plusButton.style.display = '';
|
|
825
|
+
this.nodes.plusButton.style.display = this.Blok.ReadOnly.isEnabled ? 'none' : '';
|
|
811
826
|
this.nodes.plusButton.style.color = '';
|
|
812
827
|
}
|
|
813
828
|
|
|
@@ -948,8 +963,9 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
948
963
|
}
|
|
949
964
|
|
|
950
965
|
const isCalloutFirstChild = this.hoveredBlock !== null && this.isFirstChildOfCallout(this.hoveredBlock);
|
|
966
|
+
const hidePlusButton = isCalloutFirstChild || this.Blok.ReadOnly.isEnabled;
|
|
951
967
|
|
|
952
|
-
plusButton.style.display =
|
|
968
|
+
plusButton.style.display = hidePlusButton ? 'none' : '';
|
|
953
969
|
|
|
954
970
|
if (settingsToggler) {
|
|
955
971
|
settingsToggler.style.display = isCalloutFirstChild ? 'none' : '';
|
|
@@ -1244,6 +1260,14 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
1244
1260
|
|
|
1245
1261
|
if (plusButton) {
|
|
1246
1262
|
this.readOnlyMutableListeners.on(plusButton, 'mousedown', (e) => {
|
|
1263
|
+
/**
|
|
1264
|
+
* Plus button is inert in read-only mode. It is also visually hidden
|
|
1265
|
+
* (see toggleReadOnly), but guard here too in case of programmatic clicks.
|
|
1266
|
+
*/
|
|
1267
|
+
if (this.Blok.ReadOnly.isEnabled) {
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1247
1271
|
/**
|
|
1248
1272
|
* Prevent focus from moving away from the currently-active contenteditable block.
|
|
1249
1273
|
* Without this, clicking the plus button steals DOM focus, causing subsequent
|
|
@@ -256,15 +256,32 @@ export class UI extends Module<UINodes> {
|
|
|
256
256
|
* @param {boolean} readOnlyEnabled - "read only" state
|
|
257
257
|
*/
|
|
258
258
|
public toggleReadOnly(readOnlyEnabled: boolean): void {
|
|
259
|
+
/**
|
|
260
|
+
* Collapse the bottom zone in read-only mode. Its only purpose is to act as
|
|
261
|
+
* a clickable area below the last block for adding/focusing a block, which is
|
|
262
|
+
* disabled in read-only mode. Restore the configured min-height when editing.
|
|
263
|
+
*/
|
|
264
|
+
if (this.nodes.bottomZone) {
|
|
265
|
+
this.nodes.bottomZone.style.minHeight = readOnlyEnabled ? '0px' : `${this.config.minHeight}px`;
|
|
266
|
+
}
|
|
267
|
+
|
|
259
268
|
/**
|
|
260
269
|
* Prepare components based on read-only state
|
|
261
270
|
*/
|
|
262
271
|
if (readOnlyEnabled) {
|
|
263
272
|
/**
|
|
264
|
-
* Unbind
|
|
265
|
-
*
|
|
273
|
+
* Unbind editing-only events but keep block hover active so the toolbar
|
|
274
|
+
* can still appear on hover (used by the read-only "copy link to block"
|
|
275
|
+
* popover; see Toolbar.toggleReadOnly).
|
|
266
276
|
*/
|
|
267
|
-
this.unbindReadOnlySensitiveListeners();
|
|
277
|
+
this.unbindReadOnlySensitiveListeners({ keepBlockHover: true });
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Ensure block hover detection is active even when the editor starts in
|
|
281
|
+
* read-only mode — bindReadOnlySensitiveListeners() was never called in
|
|
282
|
+
* that path.
|
|
283
|
+
*/
|
|
284
|
+
this.blockHoverController?.enable();
|
|
268
285
|
|
|
269
286
|
/**
|
|
270
287
|
* Set contenteditable="false" on all block content elements
|
|
@@ -672,8 +689,11 @@ export class UI extends Module<UINodes> {
|
|
|
672
689
|
|
|
673
690
|
/**
|
|
674
691
|
* Unbind events that should work only in read-only mode
|
|
692
|
+
* @param options - when keepBlockHover is true, the block-hover controller
|
|
693
|
+
* stays enabled so the toolbar can still appear on hover. Used when entering
|
|
694
|
+
* read-only mode; editor destroy still disables everything.
|
|
675
695
|
*/
|
|
676
|
-
private unbindReadOnlySensitiveListeners(): void {
|
|
696
|
+
private unbindReadOnlySensitiveListeners(options?: { keepBlockHover?: boolean }): void {
|
|
677
697
|
this.readOnlyMutableListeners.clearAll();
|
|
678
698
|
|
|
679
699
|
/**
|
|
@@ -682,9 +702,11 @@ export class UI extends Module<UINodes> {
|
|
|
682
702
|
this.keyboardController?.disable();
|
|
683
703
|
|
|
684
704
|
/**
|
|
685
|
-
* Disable block hover controller
|
|
705
|
+
* Disable block hover controller unless the caller opted to keep it alive.
|
|
686
706
|
*/
|
|
687
|
-
|
|
707
|
+
if (options?.keepBlockHover !== true) {
|
|
708
|
+
this.blockHoverController?.disable();
|
|
709
|
+
}
|
|
688
710
|
}
|
|
689
711
|
|
|
690
712
|
/**
|
|
@@ -48,10 +48,22 @@ export class BlockHoverController extends Controller {
|
|
|
48
48
|
super(options);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Whether the controller's listeners are currently bound. Used to make
|
|
53
|
+
* enable() idempotent so repeated calls (e.g. during read-only toggling)
|
|
54
|
+
* do not register the mousemove handler multiple times.
|
|
55
|
+
*/
|
|
56
|
+
private isEnabled: boolean = false;
|
|
57
|
+
|
|
51
58
|
/**
|
|
52
59
|
* Enable block hover detection
|
|
53
60
|
*/
|
|
54
61
|
public override enable(): void {
|
|
62
|
+
if (this.isEnabled) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.isEnabled = true;
|
|
55
67
|
/**
|
|
56
68
|
* Local function that handles block hover detection
|
|
57
69
|
* Bound to 'this' to preserve context when passed to throttle
|
|
@@ -252,6 +264,14 @@ export class BlockHoverController extends Controller {
|
|
|
252
264
|
return result.block;
|
|
253
265
|
}
|
|
254
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Disable the controller and clear its listeners.
|
|
269
|
+
*/
|
|
270
|
+
public override disable(): void {
|
|
271
|
+
super.disable();
|
|
272
|
+
this.isEnabled = false;
|
|
273
|
+
}
|
|
274
|
+
|
|
255
275
|
/**
|
|
256
276
|
* Reset the last hovered block (useful for testing or state reset)
|
|
257
277
|
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { COLOR_PRESETS, COLOR_PRESETS_DARK } from '../shared/color-presets';
|
|
2
|
+
import { isDefaultDarkBackground, isDefaultWhiteBackground } from './default-page-colors';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Convert an HSL color (H in degrees, S and L as 0-100 percentages) to an RGB tuple.
|
|
@@ -214,6 +215,13 @@ function hslDistance(
|
|
|
214
215
|
* @returns the nearest preset hex color, or the input unchanged if unparseable
|
|
215
216
|
*/
|
|
216
217
|
export function mapToNearestPresetColor(cssColor: string, mode: 'text' | 'bg'): string {
|
|
218
|
+
/* Defense-in-depth: default page backgrounds (white / near-black) would otherwise
|
|
219
|
+
* collapse onto the gray bg preset since gray is the only achromatic bg color.
|
|
220
|
+
* Return the input unchanged so callers preserve the page-default rendering. */
|
|
221
|
+
if (mode === 'bg' && (isDefaultWhiteBackground(cssColor) || isDefaultDarkBackground(cssColor))) {
|
|
222
|
+
return cssColor;
|
|
223
|
+
}
|
|
224
|
+
|
|
217
225
|
const rgb = parseColor(cssColor);
|
|
218
226
|
|
|
219
227
|
if (rgb === null) {
|
|
@@ -251,6 +259,13 @@ export function mapToNearestPresetColor(cssColor: string, mode: 'text' | 'bg'):
|
|
|
251
259
|
* @returns the nearest preset name (e.g. 'red'), or null if unparseable
|
|
252
260
|
*/
|
|
253
261
|
export function mapToNearestPresetName(cssColor: string, mode: 'text' | 'bg'): string | null {
|
|
262
|
+
/* Defense-in-depth: default page backgrounds (white / near-black) would otherwise
|
|
263
|
+
* collapse onto the gray bg preset since gray is the only achromatic bg color.
|
|
264
|
+
* Return null so callers leave the original styling untouched. */
|
|
265
|
+
if (mode === 'bg' && (isDefaultWhiteBackground(cssColor) || isDefaultDarkBackground(cssColor))) {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
|
|
254
269
|
const rgb = parseColor(cssColor);
|
|
255
270
|
|
|
256
271
|
if (rgb === null) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { colorVarName } from '../shared/color-presets';
|
|
2
2
|
import { mapToNearestPresetName } from './color-mapping';
|
|
3
|
+
import { isDefaultDarkBackground, isDefaultWhiteBackground } from './default-page-colors';
|
|
3
4
|
|
|
4
5
|
const PROPS = ['color', 'background-color'] as const;
|
|
5
6
|
type Prop = typeof PROPS[number];
|
|
@@ -27,6 +28,15 @@ export function migrateMarkColors(container: Element): void {
|
|
|
27
28
|
continue;
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
/* Strip default page background-colors so persisted defaults don't render
|
|
32
|
+
* as a styled <mark>. mapToNearestPresetName already returns null for
|
|
33
|
+
* these inputs, but null only blocks substitution — it does not remove
|
|
34
|
+
* the existing inline value. */
|
|
35
|
+
if (prop === 'background-color' && (isDefaultWhiteBackground(value) || isDefaultDarkBackground(value))) {
|
|
36
|
+
el.style.removeProperty(prop);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
const name = mapToNearestPresetName(value, PROP_MODE[prop]);
|
|
31
41
|
|
|
32
42
|
if (name !== null) {
|
|
@@ -1238,6 +1238,206 @@ export const normalizeTableChildParents = (blocks: OutputBlockData[]): OutputBlo
|
|
|
1238
1238
|
});
|
|
1239
1239
|
};
|
|
1240
1240
|
|
|
1241
|
+
/**
|
|
1242
|
+
* Positional cell-child id minted by the HTML→blok migration: `cell-<row>-<col>`
|
|
1243
|
+
* with 1-based row/col (e.g. `cell-2-1` = row 2, column 1). See the migration
|
|
1244
|
+
* system prompt (EditorJsHtmlConversionSystemPrompt) which instructs the model
|
|
1245
|
+
* to emit one paragraph per non-empty cell with exactly this id.
|
|
1246
|
+
*/
|
|
1247
|
+
const DETACHED_CELL_ID_PATTERN = /^cell-([1-9]\d*)-([1-9]\d*)$/;
|
|
1248
|
+
|
|
1249
|
+
interface CellPosition {
|
|
1250
|
+
row: number;
|
|
1251
|
+
col: number;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
const parseDetachedCellPosition = (id: BlockId | undefined): CellPosition | null => {
|
|
1255
|
+
if (typeof id !== 'string') {
|
|
1256
|
+
return null;
|
|
1257
|
+
}
|
|
1258
|
+
const match = DETACHED_CELL_ID_PATTERN.exec(id);
|
|
1259
|
+
|
|
1260
|
+
if (match === null) {
|
|
1261
|
+
return null;
|
|
1262
|
+
}
|
|
1263
|
+
const row = Number(match[1]) - 1;
|
|
1264
|
+
const col = Number(match[2]) - 1;
|
|
1265
|
+
|
|
1266
|
+
if (row < 0 || col < 0) {
|
|
1267
|
+
return null;
|
|
1268
|
+
}
|
|
1269
|
+
return { row, col };
|
|
1270
|
+
};
|
|
1271
|
+
|
|
1272
|
+
const tableCellIsEmptyAt = (tableBlock: OutputBlockData, row: number, col: number): boolean => {
|
|
1273
|
+
const rows = getTableContentRows(tableBlock.data);
|
|
1274
|
+
|
|
1275
|
+
if (rows === null) {
|
|
1276
|
+
return false;
|
|
1277
|
+
}
|
|
1278
|
+
const rowCells = rows[row];
|
|
1279
|
+
|
|
1280
|
+
if (!Array.isArray(rowCells)) {
|
|
1281
|
+
return false;
|
|
1282
|
+
}
|
|
1283
|
+
const cell = rowCells[col];
|
|
1284
|
+
|
|
1285
|
+
return isCellWithBlockRefs(cell) && cell.blocks.length === 0;
|
|
1286
|
+
};
|
|
1287
|
+
|
|
1288
|
+
const collectReferencedCellChildIds = (blocks: OutputBlockData[]): Set<string> => {
|
|
1289
|
+
const referenced = new Set<string>();
|
|
1290
|
+
|
|
1291
|
+
blocks
|
|
1292
|
+
.filter(block => block.type === 'table')
|
|
1293
|
+
.forEach(tableBlock => {
|
|
1294
|
+
const rows = getTableContentRows(tableBlock.data);
|
|
1295
|
+
|
|
1296
|
+
rows?.forEach(row => {
|
|
1297
|
+
if (!Array.isArray(row)) {
|
|
1298
|
+
return;
|
|
1299
|
+
}
|
|
1300
|
+
row.forEach(cell => {
|
|
1301
|
+
if (!isCellWithBlockRefs(cell)) {
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
cell.blocks.forEach(id => {
|
|
1305
|
+
if (typeof id === 'string') {
|
|
1306
|
+
referenced.add(id);
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
1309
|
+
});
|
|
1310
|
+
});
|
|
1311
|
+
});
|
|
1312
|
+
|
|
1313
|
+
return referenced;
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
/**
|
|
1317
|
+
* Recover migrated table cells whose text was detached by a pre-fix save.
|
|
1318
|
+
*
|
|
1319
|
+
* The "migration table content loss" bug worked like this: a migrated table
|
|
1320
|
+
* references its cell text via `data.content[r][c].blocks = [<childId>]`, but the
|
|
1321
|
+
* child paragraph lacked `parent === tableId`. A save on an unfixed editor filtered
|
|
1322
|
+
* that child out of the cell (Table.save() keeps only `parentId === tableId`) and
|
|
1323
|
+
* the saver emitted it as a root-level block. The text is NOT lost — it survives
|
|
1324
|
+
* as a detached top-level paragraph — but the cell now reads `{ blocks: [] }`.
|
|
1325
|
+
*
|
|
1326
|
+
* Crucially, the migration minted that paragraph with a POSITIONAL id
|
|
1327
|
+
* (`cell-<row>-<col>`, 1-based) that still encodes which cell it came from. This
|
|
1328
|
+
* pass walks every root-level block whose id matches that pattern and is no longer
|
|
1329
|
+
* referenced by any cell, and — when exactly one table has a matching EMPTY cell at
|
|
1330
|
+
* that position — re-attaches it: the id is restored to `content[row][col].blocks`
|
|
1331
|
+
* and the block's `parent` is set to that table.
|
|
1332
|
+
*
|
|
1333
|
+
* Safety: only empty cells are filled (occupied cells are never overwritten), only
|
|
1334
|
+
* `cell-R-C`-id root blocks are consumed (user-authored blocks never match), blocks
|
|
1335
|
+
* that already carry a `parent` are skipped, and reclamation is skipped entirely
|
|
1336
|
+
* when two or more tables share the matching empty cell (ambiguous — never guess).
|
|
1337
|
+
* The function is non-mutating and returns the same array reference when there is
|
|
1338
|
+
* nothing to reclaim.
|
|
1339
|
+
* @param blocks - flat block array potentially containing detached migrated cells
|
|
1340
|
+
*/
|
|
1341
|
+
export const reclaimDetachedTableCells = (blocks: OutputBlockData[]): OutputBlockData[] => {
|
|
1342
|
+
const tableBlocks = blocks.filter(
|
|
1343
|
+
(block): block is OutputBlockData => block.type === 'table' && block.id !== undefined && block.id !== null
|
|
1344
|
+
);
|
|
1345
|
+
|
|
1346
|
+
// The positional id `cell-<row>-<col>` encodes the cell but NOT which table.
|
|
1347
|
+
// With two or more tables the owning table is unidentifiable, so re-attaching
|
|
1348
|
+
// could silently drop text into the wrong table. Only single-table documents
|
|
1349
|
+
// are unambiguous; anything else is left untouched (never guess).
|
|
1350
|
+
if (tableBlocks.length !== 1) {
|
|
1351
|
+
return blocks;
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
const referenced = collectReferencedCellChildIds(blocks);
|
|
1355
|
+
|
|
1356
|
+
// Count id occurrences: a duplicated id is ambiguous and would be regenerated
|
|
1357
|
+
// by the renderer's dedup pass after reclaim (leaving a dangling cell ref), so
|
|
1358
|
+
// such ids must never be reclaimed.
|
|
1359
|
+
const idCounts = new Map<string, number>();
|
|
1360
|
+
|
|
1361
|
+
for (const block of blocks) {
|
|
1362
|
+
if (block.id !== undefined && block.id !== null) {
|
|
1363
|
+
idCounts.set(block.id, (idCounts.get(block.id) ?? 0) + 1);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
const reclaimedParent = new Map<BlockId, BlockId>();
|
|
1368
|
+
const cellAdditions = new Map<BlockId, Array<CellPosition & { id: BlockId }>>();
|
|
1369
|
+
|
|
1370
|
+
for (const block of blocks) {
|
|
1371
|
+
if (block.id === undefined || block.id === null) {
|
|
1372
|
+
continue;
|
|
1373
|
+
}
|
|
1374
|
+
if (block.parent !== undefined && block.parent !== null) {
|
|
1375
|
+
continue;
|
|
1376
|
+
}
|
|
1377
|
+
if (referenced.has(block.id)) {
|
|
1378
|
+
continue;
|
|
1379
|
+
}
|
|
1380
|
+
if ((idCounts.get(block.id) ?? 0) > 1) {
|
|
1381
|
+
continue;
|
|
1382
|
+
}
|
|
1383
|
+
const position = parseDetachedCellPosition(block.id);
|
|
1384
|
+
|
|
1385
|
+
if (position === null) {
|
|
1386
|
+
continue;
|
|
1387
|
+
}
|
|
1388
|
+
const matchingTables = tableBlocks.filter(table =>
|
|
1389
|
+
tableCellIsEmptyAt(table, position.row, position.col)
|
|
1390
|
+
);
|
|
1391
|
+
|
|
1392
|
+
if (matchingTables.length !== 1) {
|
|
1393
|
+
continue;
|
|
1394
|
+
}
|
|
1395
|
+
const tableId = matchingTables[0].id as BlockId;
|
|
1396
|
+
|
|
1397
|
+
reclaimedParent.set(block.id, tableId);
|
|
1398
|
+
const additions = cellAdditions.get(tableId) ?? [];
|
|
1399
|
+
|
|
1400
|
+
additions.push({ ...position, id: block.id });
|
|
1401
|
+
cellAdditions.set(tableId, additions);
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
if (reclaimedParent.size === 0) {
|
|
1405
|
+
return blocks;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
return blocks.map(block => {
|
|
1409
|
+
if (block.id !== undefined && block.id !== null && reclaimedParent.has(block.id)) {
|
|
1410
|
+
return { ...block, parent: reclaimedParent.get(block.id) };
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
if (block.type === 'table' && block.id !== undefined && block.id !== null && cellAdditions.has(block.id)) {
|
|
1414
|
+
const additions = cellAdditions.get(block.id) ?? [];
|
|
1415
|
+
const rows = getTableContentRows(block.data);
|
|
1416
|
+
|
|
1417
|
+
if (rows === null) {
|
|
1418
|
+
return block;
|
|
1419
|
+
}
|
|
1420
|
+
const newContent = rows.map((row, rowIndex) => {
|
|
1421
|
+
if (!Array.isArray(row)) {
|
|
1422
|
+
return row;
|
|
1423
|
+
}
|
|
1424
|
+
return row.map((cell, colIndex) => {
|
|
1425
|
+
const addition = additions.find(a => a.row === rowIndex && a.col === colIndex);
|
|
1426
|
+
|
|
1427
|
+
if (addition === undefined || !isCellWithBlockRefs(cell)) {
|
|
1428
|
+
return cell;
|
|
1429
|
+
}
|
|
1430
|
+
return { ...cell, blocks: [...cell.blocks, addition.id] };
|
|
1431
|
+
});
|
|
1432
|
+
});
|
|
1433
|
+
|
|
1434
|
+
return { ...block, data: { ...(block.data as Record<string, unknown>), content: newContent } } as OutputBlockData;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
return block;
|
|
1438
|
+
});
|
|
1439
|
+
};
|
|
1440
|
+
|
|
1241
1441
|
/**
|
|
1242
1442
|
* Check if transformation is needed based on config and detected format
|
|
1243
1443
|
*/
|