@jackuait/blok 0.4.1 → 0.4.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +136 -17
- package/codemod/README.md +45 -7
- package/codemod/migrate-editorjs-to-blok.js +951 -92
- package/codemod/test.js +780 -77
- package/dist/blok.mjs +5 -2
- package/dist/chunks/blok-8ptWuVZC.mjs +12838 -0
- package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
- package/dist/chunks/i18next-loader-bLawSYRV.mjs +43 -0
- package/dist/{index-CBkApZKo.mjs → chunks/index-5nYtWZD2.mjs} +2 -2
- package/dist/chunks/inline-tool-convert-CvMDAIzb.mjs +1988 -0
- package/dist/chunks/messages-2434tVOK.mjs +47 -0
- package/dist/chunks/messages-3DcCwXMF.mjs +47 -0
- package/dist/chunks/messages-4kMwVAKY.mjs +47 -0
- package/dist/chunks/messages-57uL5htT.mjs +47 -0
- package/dist/chunks/messages-76-iJV9Q.mjs +47 -0
- package/dist/chunks/messages-8p86Eyf2.mjs +47 -0
- package/dist/chunks/messages-BBX0p0Pi.mjs +47 -0
- package/dist/chunks/messages-BCm2eudQ.mjs +47 -0
- package/dist/chunks/messages-BFiUomgG.mjs +47 -0
- package/dist/chunks/messages-BIPNHHAV.mjs +47 -0
- package/dist/chunks/messages-BUlwu9mo.mjs +47 -0
- package/dist/chunks/messages-BX-DPa-z.mjs +47 -0
- package/dist/chunks/messages-BextV3Qh.mjs +47 -0
- package/dist/chunks/messages-BiPSFlUG.mjs +47 -0
- package/dist/chunks/messages-BiXe9G-O.mjs +47 -0
- package/dist/chunks/messages-Bl5z_Igo.mjs +47 -0
- package/dist/chunks/messages-BnsE97ku.mjs +47 -0
- package/dist/chunks/messages-BoO8gsVD.mjs +47 -0
- package/dist/chunks/messages-BqWaOGMn.mjs +47 -0
- package/dist/chunks/messages-BqkL2_Ro.mjs +47 -0
- package/dist/chunks/messages-BvCkXKX-.mjs +47 -0
- package/dist/chunks/messages-C6tbPLoj.mjs +47 -0
- package/dist/chunks/messages-CA6T3-gQ.mjs +47 -0
- package/dist/chunks/messages-CFFPFdWP.mjs +47 -0
- package/dist/chunks/messages-CFrKE-TN.mjs +47 -0
- package/dist/chunks/messages-CHz8VlG-.mjs +47 -0
- package/dist/chunks/messages-CLixzySl.mjs +47 -0
- package/dist/chunks/messages-CV7OM_qk.mjs +47 -0
- package/dist/chunks/messages-CXHt3eCC.mjs +47 -0
- package/dist/chunks/messages-CbmsBrB0.mjs +47 -0
- package/dist/chunks/messages-Ceo1KtFx.mjs +47 -0
- package/dist/chunks/messages-Cm0LJLtB.mjs +47 -0
- package/dist/chunks/messages-CmymP_Ar.mjs +47 -0
- package/dist/chunks/messages-D0ohMB5H.mjs +47 -0
- package/dist/chunks/messages-D3GrDwXh.mjs +47 -0
- package/dist/chunks/messages-D3vTzIpL.mjs +47 -0
- package/dist/chunks/messages-D5WeksbV.mjs +47 -0
- package/dist/chunks/messages-DGaab4EP.mjs +47 -0
- package/dist/chunks/messages-DKha57ZU.mjs +47 -0
- package/dist/chunks/messages-DOaujgMW.mjs +47 -0
- package/dist/chunks/messages-DVbPLd_0.mjs +47 -0
- package/dist/chunks/messages-D_FCyfW6.mjs +47 -0
- package/dist/chunks/messages-Dd5iZN3c.mjs +47 -0
- package/dist/chunks/messages-DehM7135.mjs +47 -0
- package/dist/chunks/messages-Dg1OHftD.mjs +47 -0
- package/dist/chunks/messages-Di6Flq-b.mjs +47 -0
- package/dist/chunks/messages-Dqhhex6e.mjs +47 -0
- package/dist/chunks/messages-DueVe0F1.mjs +47 -0
- package/dist/chunks/messages-Dx3eFwI0.mjs +47 -0
- package/dist/chunks/messages-FOtiUoKl.mjs +47 -0
- package/dist/chunks/messages-FTOZNhRD.mjs +47 -0
- package/dist/chunks/messages-IQxGfQIV.mjs +47 -0
- package/dist/chunks/messages-JF2fzCkK.mjs +47 -0
- package/dist/chunks/messages-MOGl7I5v.mjs +47 -0
- package/dist/chunks/messages-QgYhPL-3.mjs +47 -0
- package/dist/chunks/messages-WYWIbQwo.mjs +47 -0
- package/dist/chunks/messages-a6A_LgDv.mjs +47 -0
- package/dist/chunks/messages-bSf31LJi.mjs +47 -0
- package/dist/chunks/messages-diGozhTn.mjs +47 -0
- package/dist/chunks/messages-er-kd-VO.mjs +47 -0
- package/dist/chunks/messages-ez3w5NBn.mjs +47 -0
- package/dist/chunks/messages-f3uXjegd.mjs +47 -0
- package/dist/chunks/messages-ohwI1UGv.mjs +47 -0
- package/dist/chunks/messages-p9BZJaFV.mjs +47 -0
- package/dist/chunks/messages-qIQ4L4rw.mjs +47 -0
- package/dist/chunks/messages-qWkXPggi.mjs +47 -0
- package/dist/chunks/messages-w5foGze_.mjs +47 -0
- package/dist/full.mjs +50 -0
- package/dist/locales.mjs +227 -0
- package/dist/messages-2434tVOK.mjs +47 -0
- package/dist/messages-3DcCwXMF.mjs +47 -0
- package/dist/messages-4kMwVAKY.mjs +47 -0
- package/dist/messages-57uL5htT.mjs +47 -0
- package/dist/messages-76-iJV9Q.mjs +47 -0
- package/dist/messages-8p86Eyf2.mjs +47 -0
- package/dist/messages-BBX0p0Pi.mjs +47 -0
- package/dist/messages-BCm2eudQ.mjs +47 -0
- package/dist/messages-BFiUomgG.mjs +47 -0
- package/dist/messages-BIPNHHAV.mjs +47 -0
- package/dist/messages-BUlwu9mo.mjs +47 -0
- package/dist/messages-BX-DPa-z.mjs +47 -0
- package/dist/messages-BextV3Qh.mjs +47 -0
- package/dist/messages-BiPSFlUG.mjs +47 -0
- package/dist/messages-BiXe9G-O.mjs +47 -0
- package/dist/messages-Bl5z_Igo.mjs +47 -0
- package/dist/messages-BnsE97ku.mjs +47 -0
- package/dist/messages-BoO8gsVD.mjs +47 -0
- package/dist/messages-BqWaOGMn.mjs +47 -0
- package/dist/messages-BqkL2_Ro.mjs +47 -0
- package/dist/messages-BvCkXKX-.mjs +47 -0
- package/dist/messages-C6tbPLoj.mjs +47 -0
- package/dist/messages-CA6T3-gQ.mjs +47 -0
- package/dist/messages-CFFPFdWP.mjs +47 -0
- package/dist/messages-CFrKE-TN.mjs +47 -0
- package/dist/messages-CHz8VlG-.mjs +47 -0
- package/dist/messages-CLixzySl.mjs +47 -0
- package/dist/messages-CV7OM_qk.mjs +47 -0
- package/dist/messages-CXHt3eCC.mjs +47 -0
- package/dist/messages-CbmsBrB0.mjs +47 -0
- package/dist/messages-Ceo1KtFx.mjs +47 -0
- package/dist/messages-Cm0LJLtB.mjs +47 -0
- package/dist/messages-CmymP_Ar.mjs +47 -0
- package/dist/messages-D0ohMB5H.mjs +47 -0
- package/dist/messages-D3GrDwXh.mjs +47 -0
- package/dist/messages-D3vTzIpL.mjs +47 -0
- package/dist/messages-D5WeksbV.mjs +47 -0
- package/dist/messages-DGaab4EP.mjs +47 -0
- package/dist/messages-DKha57ZU.mjs +47 -0
- package/dist/messages-DOaujgMW.mjs +47 -0
- package/dist/messages-DVbPLd_0.mjs +47 -0
- package/dist/messages-D_FCyfW6.mjs +47 -0
- package/dist/messages-Dd5iZN3c.mjs +47 -0
- package/dist/messages-DehM7135.mjs +47 -0
- package/dist/messages-Dg1OHftD.mjs +47 -0
- package/dist/messages-Di6Flq-b.mjs +47 -0
- package/dist/messages-Dqhhex6e.mjs +47 -0
- package/dist/messages-DueVe0F1.mjs +47 -0
- package/dist/messages-Dx3eFwI0.mjs +47 -0
- package/dist/messages-FOtiUoKl.mjs +47 -0
- package/dist/messages-FTOZNhRD.mjs +47 -0
- package/dist/messages-IQxGfQIV.mjs +47 -0
- package/dist/messages-JF2fzCkK.mjs +47 -0
- package/dist/messages-MOGl7I5v.mjs +47 -0
- package/dist/messages-QgYhPL-3.mjs +47 -0
- package/dist/messages-WYWIbQwo.mjs +47 -0
- package/dist/messages-a6A_LgDv.mjs +47 -0
- package/dist/messages-bSf31LJi.mjs +47 -0
- package/dist/messages-diGozhTn.mjs +47 -0
- package/dist/messages-er-kd-VO.mjs +47 -0
- package/dist/messages-ez3w5NBn.mjs +47 -0
- package/dist/messages-f3uXjegd.mjs +47 -0
- package/dist/messages-ohwI1UGv.mjs +47 -0
- package/dist/messages-p9BZJaFV.mjs +47 -0
- package/dist/messages-qIQ4L4rw.mjs +47 -0
- package/dist/messages-qWkXPggi.mjs +47 -0
- package/dist/messages-w5foGze_.mjs +47 -0
- package/dist/tools.mjs +3073 -0
- package/dist/vendor.LICENSE.txt +59 -156
- package/package.json +60 -15
- package/src/blok.ts +267 -0
- package/src/components/__module.ts +139 -0
- package/src/components/block/api.ts +155 -0
- package/src/components/block/index.ts +1427 -0
- package/src/components/block-tunes/block-tune-delete.ts +51 -0
- package/src/components/blocks.ts +338 -0
- package/src/components/constants/data-attributes.ts +342 -0
- package/src/components/constants.ts +76 -0
- package/src/components/core.ts +392 -0
- package/src/components/dom.ts +773 -0
- package/src/components/domIterator.ts +189 -0
- package/src/components/errors/critical.ts +5 -0
- package/src/components/events/BlockChanged.ts +16 -0
- package/src/components/events/BlockHovered.ts +21 -0
- package/src/components/events/BlockSettingsClosed.ts +12 -0
- package/src/components/events/BlockSettingsOpened.ts +12 -0
- package/src/components/events/BlokMobileLayoutToggled.ts +15 -0
- package/src/components/events/FakeCursorAboutToBeToggled.ts +17 -0
- package/src/components/events/FakeCursorHaveBeenSet.ts +17 -0
- package/src/components/events/HistoryStateChanged.ts +19 -0
- package/src/components/events/RedactorDomChanged.ts +14 -0
- package/src/components/events/index.ts +46 -0
- package/src/components/flipper.ts +481 -0
- package/src/components/i18n/i18next-loader.ts +84 -0
- package/src/components/i18n/lightweight-i18n.ts +86 -0
- package/src/components/i18n/locales/TRANSLATION_GUIDELINES.md +113 -0
- package/src/components/i18n/locales/am/messages.json +44 -0
- package/src/components/i18n/locales/ar/messages.json +44 -0
- package/src/components/i18n/locales/az/messages.json +44 -0
- package/src/components/i18n/locales/bg/messages.json +44 -0
- package/src/components/i18n/locales/bn/messages.json +44 -0
- package/src/components/i18n/locales/bs/messages.json +44 -0
- package/src/components/i18n/locales/cs/messages.json +44 -0
- package/src/components/i18n/locales/da/messages.json +44 -0
- package/src/components/i18n/locales/de/messages.json +44 -0
- package/src/components/i18n/locales/dv/messages.json +44 -0
- package/src/components/i18n/locales/el/messages.json +44 -0
- package/src/components/i18n/locales/en/messages.json +44 -0
- package/src/components/i18n/locales/es/messages.json +44 -0
- package/src/components/i18n/locales/et/messages.json +44 -0
- package/src/components/i18n/locales/fa/messages.json +44 -0
- package/src/components/i18n/locales/fi/messages.json +44 -0
- package/src/components/i18n/locales/fil/messages.json +44 -0
- package/src/components/i18n/locales/fr/messages.json +44 -0
- package/src/components/i18n/locales/gu/messages.json +44 -0
- package/src/components/i18n/locales/he/messages.json +44 -0
- package/src/components/i18n/locales/hi/messages.json +44 -0
- package/src/components/i18n/locales/hr/messages.json +44 -0
- package/src/components/i18n/locales/hu/messages.json +44 -0
- package/src/components/i18n/locales/hy/messages.json +44 -0
- package/src/components/i18n/locales/id/messages.json +44 -0
- package/src/components/i18n/locales/index.ts +225 -0
- package/src/components/i18n/locales/it/messages.json +44 -0
- package/src/components/i18n/locales/ja/messages.json +44 -0
- package/src/components/i18n/locales/ka/messages.json +44 -0
- package/src/components/i18n/locales/km/messages.json +44 -0
- package/src/components/i18n/locales/kn/messages.json +44 -0
- package/src/components/i18n/locales/ko/messages.json +44 -0
- package/src/components/i18n/locales/ku/messages.json +44 -0
- package/src/components/i18n/locales/lo/messages.json +44 -0
- package/src/components/i18n/locales/lt/messages.json +44 -0
- package/src/components/i18n/locales/lv/messages.json +44 -0
- package/src/components/i18n/locales/mk/messages.json +44 -0
- package/src/components/i18n/locales/ml/messages.json +44 -0
- package/src/components/i18n/locales/mn/messages.json +44 -0
- package/src/components/i18n/locales/mr/messages.json +44 -0
- package/src/components/i18n/locales/ms/messages.json +44 -0
- package/src/components/i18n/locales/my/messages.json +44 -0
- package/src/components/i18n/locales/ne/messages.json +44 -0
- package/src/components/i18n/locales/nl/messages.json +44 -0
- package/src/components/i18n/locales/no/messages.json +44 -0
- package/src/components/i18n/locales/pa/messages.json +44 -0
- package/src/components/i18n/locales/pl/messages.json +44 -0
- package/src/components/i18n/locales/ps/messages.json +44 -0
- package/src/components/i18n/locales/pt/messages.json +44 -0
- package/src/components/i18n/locales/ro/messages.json +44 -0
- package/src/components/i18n/locales/ru/messages.json +44 -0
- package/src/components/i18n/locales/sd/messages.json +44 -0
- package/src/components/i18n/locales/si/messages.json +44 -0
- package/src/components/i18n/locales/sk/messages.json +44 -0
- package/src/components/i18n/locales/sl/messages.json +44 -0
- package/src/components/i18n/locales/sq/messages.json +44 -0
- package/src/components/i18n/locales/sr/messages.json +44 -0
- package/src/components/i18n/locales/sv/messages.json +44 -0
- package/src/components/i18n/locales/sw/messages.json +44 -0
- package/src/components/i18n/locales/ta/messages.json +44 -0
- package/src/components/i18n/locales/te/messages.json +44 -0
- package/src/components/i18n/locales/th/messages.json +44 -0
- package/src/components/i18n/locales/tr/messages.json +44 -0
- package/src/components/i18n/locales/ug/messages.json +44 -0
- package/src/components/i18n/locales/uk/messages.json +44 -0
- package/src/components/i18n/locales/ur/messages.json +44 -0
- package/src/components/i18n/locales/vi/messages.json +44 -0
- package/src/components/i18n/locales/yi/messages.json +44 -0
- package/src/components/i18n/locales/zh/messages.json +44 -0
- package/src/components/icons/index.ts +242 -0
- package/src/components/inline-tools/inline-tool-bold.ts +2213 -0
- package/src/components/inline-tools/inline-tool-convert.ts +141 -0
- package/src/components/inline-tools/inline-tool-italic.ts +500 -0
- package/src/components/inline-tools/inline-tool-link.ts +539 -0
- package/src/components/modules/api/blocks.ts +363 -0
- package/src/components/modules/api/caret.ts +125 -0
- package/src/components/modules/api/events.ts +51 -0
- package/src/components/modules/api/history.ts +73 -0
- package/src/components/modules/api/i18n.ts +33 -0
- package/src/components/modules/api/index.ts +39 -0
- package/src/components/modules/api/inlineToolbar.ts +33 -0
- package/src/components/modules/api/listeners.ts +56 -0
- package/src/components/modules/api/notifier.ts +46 -0
- package/src/components/modules/api/readonly.ts +39 -0
- package/src/components/modules/api/sanitizer.ts +30 -0
- package/src/components/modules/api/saver.ts +52 -0
- package/src/components/modules/api/selection.ts +48 -0
- package/src/components/modules/api/styles.ts +72 -0
- package/src/components/modules/api/toolbar.ts +79 -0
- package/src/components/modules/api/tools.ts +16 -0
- package/src/components/modules/api/tooltip.ts +67 -0
- package/src/components/modules/api/ui.ts +36 -0
- package/src/components/modules/blockEvents.ts +1375 -0
- package/src/components/modules/blockManager.ts +1348 -0
- package/src/components/modules/blockSelection.ts +708 -0
- package/src/components/modules/caret.ts +853 -0
- package/src/components/modules/crossBlockSelection.ts +329 -0
- package/src/components/modules/dragManager.ts +1141 -0
- package/src/components/modules/history.ts +1098 -0
- package/src/components/modules/i18n.ts +325 -0
- package/src/components/modules/index.ts +139 -0
- package/src/components/modules/modificationsObserver.ts +147 -0
- package/src/components/modules/paste.ts +1092 -0
- package/src/components/modules/readonly.ts +136 -0
- package/src/components/modules/rectangleSelection.ts +668 -0
- package/src/components/modules/renderer.ts +155 -0
- package/src/components/modules/saver.ts +283 -0
- package/src/components/modules/toolbar/blockSettings.ts +776 -0
- package/src/components/modules/toolbar/index.ts +1311 -0
- package/src/components/modules/toolbar/inline.ts +956 -0
- package/src/components/modules/tools.ts +589 -0
- package/src/components/modules/ui.ts +1179 -0
- package/src/components/polyfills.ts +113 -0
- package/src/components/selection.ts +1189 -0
- package/src/components/tools/base.ts +274 -0
- package/src/components/tools/block.ts +291 -0
- package/src/components/tools/collection.ts +67 -0
- package/src/components/tools/factory.ts +85 -0
- package/src/components/tools/inline.ts +71 -0
- package/src/components/tools/tune.ts +33 -0
- package/src/components/ui/toolbox.ts +497 -0
- package/src/components/utils/announcer.ts +205 -0
- package/src/components/utils/api.ts +20 -0
- package/src/components/utils/bem.ts +26 -0
- package/src/components/utils/blocks.ts +284 -0
- package/src/components/utils/caret.ts +1067 -0
- package/src/components/utils/data-model-transform.ts +382 -0
- package/src/components/utils/events.ts +117 -0
- package/src/components/utils/keyboard.ts +60 -0
- package/src/components/utils/listeners.ts +296 -0
- package/src/components/utils/mutations.ts +39 -0
- package/src/components/utils/notifier/draw.ts +190 -0
- package/src/components/utils/notifier/index.ts +66 -0
- package/src/components/utils/notifier/types.ts +1 -0
- package/src/components/utils/notifier.ts +77 -0
- package/src/components/utils/placeholder.ts +140 -0
- package/src/components/utils/popover/components/hint/hint.const.ts +10 -0
- package/src/components/utils/popover/components/hint/hint.ts +46 -0
- package/src/components/utils/popover/components/hint/index.ts +6 -0
- package/src/components/utils/popover/components/popover-header/index.ts +2 -0
- package/src/components/utils/popover/components/popover-header/popover-header.const.ts +8 -0
- package/src/components/utils/popover/components/popover-header/popover-header.ts +80 -0
- package/src/components/utils/popover/components/popover-header/popover-header.types.ts +14 -0
- package/src/components/utils/popover/components/popover-item/index.ts +13 -0
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +50 -0
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +666 -0
- package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.const.ts +14 -0
- package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.ts +136 -0
- package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts +20 -0
- package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.ts +117 -0
- package/src/components/utils/popover/components/popover-item/popover-item.ts +187 -0
- package/src/components/utils/popover/components/search-input/index.ts +2 -0
- package/src/components/utils/popover/components/search-input/search-input.const.ts +8 -0
- package/src/components/utils/popover/components/search-input/search-input.ts +181 -0
- package/src/components/utils/popover/components/search-input/search-input.types.ts +30 -0
- package/src/components/utils/popover/index.ts +13 -0
- package/src/components/utils/popover/popover-abstract.ts +448 -0
- package/src/components/utils/popover/popover-desktop.ts +643 -0
- package/src/components/utils/popover/popover-inline.ts +338 -0
- package/src/components/utils/popover/popover-mobile.ts +201 -0
- package/src/components/utils/popover/popover.const.ts +81 -0
- package/src/components/utils/popover/utils/popover-states-history.ts +72 -0
- package/src/components/utils/promise-queue.ts +43 -0
- package/src/components/utils/sanitizer.ts +537 -0
- package/src/components/utils/scroll-locker.ts +87 -0
- package/src/components/utils/shortcut.ts +231 -0
- package/src/components/utils/shortcuts.ts +113 -0
- package/src/components/utils/tools.ts +105 -0
- package/src/components/utils/tooltip.ts +642 -0
- package/src/components/utils/tw.ts +241 -0
- package/src/components/utils.ts +1081 -0
- package/src/env.d.ts +13 -0
- package/src/full.ts +69 -0
- package/src/locales.ts +51 -0
- package/src/stories/Block.stories.ts +498 -0
- package/src/stories/EditorModes.stories.ts +505 -0
- package/src/stories/Header.stories.ts +137 -0
- package/src/stories/InlineToolbar.stories.ts +498 -0
- package/src/stories/List.stories.ts +259 -0
- package/src/stories/Notifier.stories.ts +340 -0
- package/src/stories/Paragraph.stories.ts +112 -0
- package/src/stories/Placeholder.stories.ts +319 -0
- package/src/stories/Popover.stories.ts +844 -0
- package/src/stories/Selection.stories.ts +250 -0
- package/src/stories/StubBlock.stories.ts +156 -0
- package/src/stories/Toolbar.stories.ts +223 -0
- package/src/stories/Toolbox.stories.ts +166 -0
- package/src/stories/Tooltip.stories.ts +198 -0
- package/src/stories/helpers.ts +463 -0
- package/src/styles/main.css +123 -0
- package/src/tools/header/index.ts +570 -0
- package/src/tools/index.ts +38 -0
- package/src/tools/list/index.ts +1803 -0
- package/src/tools/paragraph/index.ts +411 -0
- package/src/tools/stub/index.ts +107 -0
- package/src/types-internal/blok-modules.d.ts +87 -0
- package/src/types-internal/html-janitor.d.ts +28 -0
- package/src/types-internal/module-config.d.ts +11 -0
- package/src/variants/all-locales.ts +155 -0
- package/src/variants/blok-maximum.ts +20 -0
- package/src/variants/blok-minimum.ts +243 -0
- package/types/api/blocks.d.ts +1 -1
- package/types/api/i18n.d.ts +5 -3
- package/types/api/selection.d.ts +6 -0
- package/types/api/styles.d.ts +0 -5
- package/types/configs/blok-config.d.ts +21 -0
- package/types/configs/i18n-config.d.ts +52 -2
- package/types/configs/i18n-dictionary.d.ts +16 -90
- package/types/data-attributes.d.ts +169 -0
- package/types/data-formats/output-data.d.ts +15 -0
- package/types/full.d.ts +80 -0
- package/types/index.d.ts +9 -24
- package/types/locales.d.ts +59 -0
- package/types/tools/adapters/inline-tool-adapter.d.ts +10 -0
- package/types/tools/block-tool.d.ts +9 -0
- package/types/tools/list.d.ts +25 -18
- package/types/tools/tool-settings.d.ts +8 -1
- package/types/tools/tool.d.ts +6 -0
- package/types/tools-entry.d.ts +49 -0
- package/types/utils/popover/popover-item.d.ts +0 -5
- package/dist/blok-BwPfU8ro.mjs +0 -21510
- package/dist/blok.umd.js +0 -198
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { Module } from '../__module';
|
|
2
|
+
import type { I18nDictionary } from '../../../types/configs';
|
|
3
|
+
import type { SupportedLocale } from '../../../types/configs/i18n-config';
|
|
4
|
+
import {
|
|
5
|
+
DEFAULT_LOCALE,
|
|
6
|
+
loadLocale,
|
|
7
|
+
getDirection,
|
|
8
|
+
ALL_LOCALE_CODES,
|
|
9
|
+
} from '../i18n/locales';
|
|
10
|
+
import { LightweightI18n } from '../i18n/lightweight-i18n';
|
|
11
|
+
import type { I18nextInitResult } from '../i18n/i18next-loader';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* I18n module - handles translations and locale management.
|
|
15
|
+
*
|
|
16
|
+
* Uses a lightweight implementation for English (default) and dynamically
|
|
17
|
+
* loads i18next only when non-English locales are needed.
|
|
18
|
+
*
|
|
19
|
+
* This lazy-loading approach saves ~18 KB gzipped for English-only users.
|
|
20
|
+
*
|
|
21
|
+
* Instance-based module that provides:
|
|
22
|
+
* - Translation lookup with interpolation
|
|
23
|
+
* - Lazy locale loading
|
|
24
|
+
* - Browser locale detection
|
|
25
|
+
* - RTL support
|
|
26
|
+
* - Pluralization support (via i18next when loaded)
|
|
27
|
+
*/
|
|
28
|
+
export class I18n extends Module {
|
|
29
|
+
/**
|
|
30
|
+
* Lightweight i18n for English (synchronous, no dependencies)
|
|
31
|
+
*/
|
|
32
|
+
private lightweightI18n: LightweightI18n;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Full i18next instance (loaded dynamically for non-English locales)
|
|
36
|
+
*/
|
|
37
|
+
private i18nextWrapper: I18nextInitResult | null = null;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Current locale code
|
|
41
|
+
*/
|
|
42
|
+
private locale: SupportedLocale = DEFAULT_LOCALE;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Default locale to fall back to
|
|
46
|
+
*/
|
|
47
|
+
private defaultLocale: SupportedLocale = DEFAULT_LOCALE;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Whether we're using the full i18next implementation
|
|
51
|
+
*/
|
|
52
|
+
private usingI18next = false;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Constructor - creates lightweight i18n instance
|
|
56
|
+
*/
|
|
57
|
+
constructor(...args: ConstructorParameters<typeof Module>) {
|
|
58
|
+
super(...args);
|
|
59
|
+
this.lightweightI18n = new LightweightI18n();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Translate a key with optional interpolation.
|
|
64
|
+
*
|
|
65
|
+
* @param key - Translation key (e.g., 'blockSettings.delete')
|
|
66
|
+
* @param vars - Optional variables to interpolate (e.g., { count: 5 })
|
|
67
|
+
* @returns Translated string, or the key if not found
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // Simple translation
|
|
71
|
+
* this.Blok.I18n.t('blockSettings.delete')
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* // With interpolation
|
|
75
|
+
* this.Blok.I18n.t('a11y.blockMoved', { position: 3, total: 10 })
|
|
76
|
+
*/
|
|
77
|
+
public t(key: string, vars?: Record<string, string | number>): string {
|
|
78
|
+
if (this.usingI18next && this.i18nextWrapper !== null) {
|
|
79
|
+
return this.i18nextWrapper.t(key, vars);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return this.lightweightI18n.t(key, vars);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Check if a translation exists for the given key
|
|
87
|
+
*
|
|
88
|
+
* @param key - Translation key to check
|
|
89
|
+
* @returns True if translation exists
|
|
90
|
+
*/
|
|
91
|
+
public has(key: string): boolean {
|
|
92
|
+
if (this.usingI18next && this.i18nextWrapper !== null) {
|
|
93
|
+
return this.i18nextWrapper.has(key);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return this.lightweightI18n.has(key);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Set the active locale, loading it if necessary.
|
|
101
|
+
* All 68 supported locales are available for loading.
|
|
102
|
+
*
|
|
103
|
+
* @param locale - Locale code to set
|
|
104
|
+
* @returns Promise that resolves when locale is loaded and set
|
|
105
|
+
*/
|
|
106
|
+
public async setLocale(locale: SupportedLocale): Promise<void> {
|
|
107
|
+
try {
|
|
108
|
+
// For English, use lightweight implementation
|
|
109
|
+
if (locale === 'en') {
|
|
110
|
+
this.locale = 'en';
|
|
111
|
+
this.usingI18next = false;
|
|
112
|
+
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// For non-English, load i18next dynamically
|
|
117
|
+
const localeConfig = await loadLocale(locale);
|
|
118
|
+
|
|
119
|
+
await this.ensureI18nextLoaded(locale, localeConfig);
|
|
120
|
+
|
|
121
|
+
if (this.i18nextWrapper === null) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// If locale was already loaded, just change language
|
|
126
|
+
const needsBundle = !this.i18nextWrapper.instance.hasResourceBundle(locale, 'translation');
|
|
127
|
+
|
|
128
|
+
if (needsBundle) {
|
|
129
|
+
this.i18nextWrapper.instance.addResourceBundle(locale, 'translation', localeConfig.dictionary);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await this.i18nextWrapper.changeLanguage(locale);
|
|
133
|
+
|
|
134
|
+
this.locale = locale;
|
|
135
|
+
this.usingI18next = true;
|
|
136
|
+
} catch (error) {
|
|
137
|
+
// Log warning but don't throw - graceful degradation to default locale
|
|
138
|
+
console.warn(`Failed to load locale "${locale}". Falling back to "${this.defaultLocale}".`, error);
|
|
139
|
+
this.locale = this.defaultLocale;
|
|
140
|
+
|
|
141
|
+
if (this.defaultLocale === 'en') {
|
|
142
|
+
this.usingI18next = false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Detect browser locale and set it.
|
|
149
|
+
*
|
|
150
|
+
* @returns The detected and set locale code
|
|
151
|
+
*/
|
|
152
|
+
public async detectAndSetLocale(): Promise<SupportedLocale> {
|
|
153
|
+
const detected = this.detectBrowserLocale();
|
|
154
|
+
|
|
155
|
+
await this.setLocale(detected);
|
|
156
|
+
|
|
157
|
+
return this.locale;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Set a custom dictionary directly.
|
|
162
|
+
* Useful for custom translations or testing.
|
|
163
|
+
*
|
|
164
|
+
* @param dictionary - Custom translation dictionary
|
|
165
|
+
*/
|
|
166
|
+
public setDictionary(dictionary: I18nDictionary): void {
|
|
167
|
+
if (this.usingI18next && this.i18nextWrapper !== null) {
|
|
168
|
+
this.i18nextWrapper.setDictionary(dictionary);
|
|
169
|
+
} else {
|
|
170
|
+
this.lightweightI18n.setDictionary(dictionary);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get the current locale code
|
|
176
|
+
*/
|
|
177
|
+
public getLocale(): SupportedLocale {
|
|
178
|
+
return this.locale;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get the text direction for the current locale
|
|
183
|
+
*/
|
|
184
|
+
public getDirection(): 'ltr' | 'rtl' {
|
|
185
|
+
return getDirection(this.locale);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Get the text direction for any locale code
|
|
190
|
+
*
|
|
191
|
+
* @param locale - Locale code to check
|
|
192
|
+
*/
|
|
193
|
+
public getDirectionForLocale(locale: SupportedLocale): 'ltr' | 'rtl' {
|
|
194
|
+
return getDirection(locale);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Module preparation - called during editor initialization.
|
|
199
|
+
* Uses lightweight i18n for English, loads i18next only for other locales.
|
|
200
|
+
*/
|
|
201
|
+
public async prepare(): Promise<void> {
|
|
202
|
+
const i18nConfig = this.config.i18n;
|
|
203
|
+
|
|
204
|
+
// Set default locale if configured
|
|
205
|
+
this.applyDefaultLocale(i18nConfig?.defaultLocale);
|
|
206
|
+
|
|
207
|
+
// Handle custom messages (highest priority)
|
|
208
|
+
if (i18nConfig?.messages !== undefined) {
|
|
209
|
+
// For custom messages, use lightweight implementation with overrides
|
|
210
|
+
this.lightweightI18n.setDictionary(i18nConfig.messages);
|
|
211
|
+
this.usingI18next = false;
|
|
212
|
+
// Set direction from config or default to 'ltr' for custom messages
|
|
213
|
+
this.updateConfigDirection(i18nConfig.direction ?? 'ltr');
|
|
214
|
+
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const requestedLocale = i18nConfig?.locale;
|
|
219
|
+
|
|
220
|
+
if (requestedLocale === undefined || requestedLocale === 'auto') {
|
|
221
|
+
await this.detectAndSetLocale();
|
|
222
|
+
} else {
|
|
223
|
+
await this.setLocale(requestedLocale);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Update config.i18n.direction so other modules can access it via isRtl getter
|
|
227
|
+
this.updateConfigDirection(i18nConfig?.direction ?? this.getDirection());
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Dynamically load i18next when needed for non-English locales
|
|
232
|
+
*/
|
|
233
|
+
private async ensureI18nextLoaded(
|
|
234
|
+
locale: SupportedLocale,
|
|
235
|
+
localeConfig: { dictionary: I18nDictionary }
|
|
236
|
+
): Promise<void> {
|
|
237
|
+
if (this.i18nextWrapper !== null) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Dynamic import of the i18next loader
|
|
242
|
+
const { loadI18next } = await import('../i18n/i18next-loader');
|
|
243
|
+
|
|
244
|
+
this.i18nextWrapper = await loadI18next(locale, localeConfig);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Update the config.i18n.direction value
|
|
249
|
+
*/
|
|
250
|
+
private updateConfigDirection(direction: 'ltr' | 'rtl'): void {
|
|
251
|
+
if (this.config.i18n === undefined) {
|
|
252
|
+
this.config.i18n = {};
|
|
253
|
+
}
|
|
254
|
+
this.config.i18n.direction = direction;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Apply default locale from config if valid.
|
|
259
|
+
* The locale is type-checked at compile time via SupportedLocale type.
|
|
260
|
+
*/
|
|
261
|
+
private applyDefaultLocale(defaultLocale: SupportedLocale | undefined): void {
|
|
262
|
+
if (defaultLocale === undefined) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
this.defaultLocale = defaultLocale;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Check if a locale code is supported.
|
|
271
|
+
* All 68 locales in ALL_LOCALE_CODES are supported.
|
|
272
|
+
*/
|
|
273
|
+
private isLocaleSupported(locale: string): locale is SupportedLocale {
|
|
274
|
+
return ALL_LOCALE_CODES.includes(locale as SupportedLocale);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Detect best matching locale from browser settings
|
|
279
|
+
*/
|
|
280
|
+
private detectBrowserLocale(): SupportedLocale {
|
|
281
|
+
if (typeof navigator === 'undefined') {
|
|
282
|
+
return this.defaultLocale;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const browserLanguages = navigator.languages ?? [navigator.language];
|
|
286
|
+
|
|
287
|
+
for (const lang of browserLanguages) {
|
|
288
|
+
if (!lang) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const matched = this.matchLanguageTag(lang);
|
|
293
|
+
|
|
294
|
+
if (matched !== null) {
|
|
295
|
+
return matched;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return this.defaultLocale;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Match a browser language tag to a supported locale.
|
|
304
|
+
* All 68 locales are supported.
|
|
305
|
+
*
|
|
306
|
+
* @param languageTag - BCP 47 language tag (e.g., 'en-US', 'ru')
|
|
307
|
+
*/
|
|
308
|
+
private matchLanguageTag(languageTag: string): SupportedLocale | null {
|
|
309
|
+
const normalized = languageTag.toLowerCase();
|
|
310
|
+
|
|
311
|
+
// Try exact match (e.g., 'ru')
|
|
312
|
+
if (this.isLocaleSupported(normalized)) {
|
|
313
|
+
return normalized as SupportedLocale;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Try base language (e.g., 'en-US' -> 'en')
|
|
317
|
+
const baseLang = normalized.split('-')[0];
|
|
318
|
+
|
|
319
|
+
if (baseLang !== undefined && this.isLocaleSupported(baseLang)) {
|
|
320
|
+
return baseLang as SupportedLocale;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/** ./api */
|
|
2
|
+
import { BlocksAPI } from './api/blocks';
|
|
3
|
+
import { CaretAPI } from './api/caret';
|
|
4
|
+
import { EventsAPI } from './api/events';
|
|
5
|
+
import { I18nAPI } from './api/i18n';
|
|
6
|
+
import { API } from './api/index';
|
|
7
|
+
import { InlineToolbarAPI } from './api/inlineToolbar';
|
|
8
|
+
import { ListenersAPI } from './api/listeners';
|
|
9
|
+
import { NotifierAPI } from './api/notifier';
|
|
10
|
+
import { ReadOnlyAPI } from './api/readonly';
|
|
11
|
+
import { SanitizerAPI } from './api/sanitizer';
|
|
12
|
+
import { SaverAPI } from './api/saver';
|
|
13
|
+
import { SelectionAPI } from './api/selection';
|
|
14
|
+
import { ToolsAPI } from './api/tools';
|
|
15
|
+
import { StylesAPI } from './api/styles';
|
|
16
|
+
import { ToolbarAPI } from './api/toolbar';
|
|
17
|
+
import { TooltipAPI } from './api/tooltip';
|
|
18
|
+
import { UiAPI } from './api/ui';
|
|
19
|
+
import { HistoryAPI } from './api/history';
|
|
20
|
+
|
|
21
|
+
/** ./toolbar */
|
|
22
|
+
import { BlockSettings } from './toolbar/blockSettings';
|
|
23
|
+
import { Toolbar } from './toolbar/index';
|
|
24
|
+
import { InlineToolbar } from './toolbar/inline';
|
|
25
|
+
|
|
26
|
+
/** . */
|
|
27
|
+
import { I18n } from './i18n';
|
|
28
|
+
import { BlockEvents } from './blockEvents';
|
|
29
|
+
import { BlockManager } from './blockManager';
|
|
30
|
+
import { BlockSelection } from './blockSelection';
|
|
31
|
+
import { Caret } from './caret';
|
|
32
|
+
import { CrossBlockSelection } from './crossBlockSelection';
|
|
33
|
+
import { DragManager } from './dragManager';
|
|
34
|
+
import { ModificationsObserver } from './modificationsObserver';
|
|
35
|
+
import { Paste } from './paste';
|
|
36
|
+
import { ReadOnly } from './readonly';
|
|
37
|
+
import { RectangleSelection } from './rectangleSelection';
|
|
38
|
+
import { Renderer } from './renderer';
|
|
39
|
+
import { Saver } from './saver';
|
|
40
|
+
import { Tools } from './tools';
|
|
41
|
+
import { UI } from './ui';
|
|
42
|
+
import { History } from './history';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Named exports for better tree-shaking.
|
|
46
|
+
* Consumers can import only the modules they need.
|
|
47
|
+
*/
|
|
48
|
+
export {
|
|
49
|
+
// API Modules
|
|
50
|
+
BlocksAPI,
|
|
51
|
+
CaretAPI,
|
|
52
|
+
EventsAPI,
|
|
53
|
+
I18nAPI,
|
|
54
|
+
API,
|
|
55
|
+
InlineToolbarAPI,
|
|
56
|
+
ListenersAPI,
|
|
57
|
+
NotifierAPI,
|
|
58
|
+
ReadOnlyAPI,
|
|
59
|
+
SanitizerAPI,
|
|
60
|
+
SaverAPI,
|
|
61
|
+
SelectionAPI,
|
|
62
|
+
ToolsAPI,
|
|
63
|
+
StylesAPI,
|
|
64
|
+
ToolbarAPI,
|
|
65
|
+
TooltipAPI,
|
|
66
|
+
UiAPI,
|
|
67
|
+
HistoryAPI,
|
|
68
|
+
|
|
69
|
+
// Toolbar Modules
|
|
70
|
+
BlockSettings,
|
|
71
|
+
Toolbar,
|
|
72
|
+
InlineToolbar,
|
|
73
|
+
|
|
74
|
+
// Modules
|
|
75
|
+
I18n,
|
|
76
|
+
BlockEvents,
|
|
77
|
+
BlockManager,
|
|
78
|
+
BlockSelection,
|
|
79
|
+
Caret,
|
|
80
|
+
CrossBlockSelection,
|
|
81
|
+
DragManager,
|
|
82
|
+
ModificationsObserver,
|
|
83
|
+
Paste,
|
|
84
|
+
ReadOnly,
|
|
85
|
+
RectangleSelection,
|
|
86
|
+
Renderer,
|
|
87
|
+
Saver,
|
|
88
|
+
Tools,
|
|
89
|
+
UI,
|
|
90
|
+
History,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Default export for backwards compatibility and internal use.
|
|
95
|
+
*/
|
|
96
|
+
export const Modules = {
|
|
97
|
+
// API Modules
|
|
98
|
+
BlocksAPI,
|
|
99
|
+
CaretAPI,
|
|
100
|
+
EventsAPI,
|
|
101
|
+
I18nAPI,
|
|
102
|
+
API,
|
|
103
|
+
InlineToolbarAPI,
|
|
104
|
+
ListenersAPI,
|
|
105
|
+
NotifierAPI,
|
|
106
|
+
ReadOnlyAPI,
|
|
107
|
+
SanitizerAPI,
|
|
108
|
+
SaverAPI,
|
|
109
|
+
SelectionAPI,
|
|
110
|
+
ToolsAPI,
|
|
111
|
+
StylesAPI,
|
|
112
|
+
ToolbarAPI,
|
|
113
|
+
TooltipAPI,
|
|
114
|
+
UiAPI,
|
|
115
|
+
HistoryAPI,
|
|
116
|
+
|
|
117
|
+
// Toolbar Modules
|
|
118
|
+
BlockSettings,
|
|
119
|
+
Toolbar,
|
|
120
|
+
InlineToolbar,
|
|
121
|
+
|
|
122
|
+
// Modules
|
|
123
|
+
I18n,
|
|
124
|
+
BlockEvents,
|
|
125
|
+
BlockManager,
|
|
126
|
+
BlockSelection,
|
|
127
|
+
Caret,
|
|
128
|
+
CrossBlockSelection,
|
|
129
|
+
DragManager,
|
|
130
|
+
ModificationsObserver,
|
|
131
|
+
Paste,
|
|
132
|
+
ReadOnly,
|
|
133
|
+
RectangleSelection,
|
|
134
|
+
Renderer,
|
|
135
|
+
Saver,
|
|
136
|
+
Tools,
|
|
137
|
+
UI,
|
|
138
|
+
History,
|
|
139
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { BlockId } from '../../../types';
|
|
2
|
+
import type { BlockMutationEvent, BlockMutationType } from '../../../types/events/block';
|
|
3
|
+
import type { ModuleConfig } from '../../types-internal/module-config';
|
|
4
|
+
import { Module } from '../__module';
|
|
5
|
+
import { modificationsObserverBatchTimeout } from '../constants';
|
|
6
|
+
import { BlockChanged, FakeCursorAboutToBeToggled, FakeCursorHaveBeenSet, RedactorDomChanged } from '../events';
|
|
7
|
+
import { isFunction } from '../utils';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* We use map of block mutations to filter only unique events
|
|
11
|
+
*/
|
|
12
|
+
type UniqueBlockMutationKey = `block:${BlockId}:event:${BlockMutationType}`;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Single entry point for Block mutation events
|
|
16
|
+
*/
|
|
17
|
+
export class ModificationsObserver extends Module {
|
|
18
|
+
/**
|
|
19
|
+
* Flag shows onChange event is disabled
|
|
20
|
+
*/
|
|
21
|
+
private disabled = false;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Blocks wrapper mutation observer instance
|
|
25
|
+
*/
|
|
26
|
+
private readonly mutationObserver: MutationObserver;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Timeout used to batched several events in a single onChange call
|
|
30
|
+
*/
|
|
31
|
+
private batchingTimeout: null | ReturnType<typeof setTimeout> = null;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Array of onChange events used to batch them
|
|
35
|
+
*
|
|
36
|
+
* Map is used to filter duplicated events related to the same block
|
|
37
|
+
*/
|
|
38
|
+
private batchingOnChangeQueue = new Map<UniqueBlockMutationKey, BlockMutationEvent>();
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Fired onChange events will be batched by this time
|
|
42
|
+
*/
|
|
43
|
+
private readonly batchTime = modificationsObserverBatchTimeout;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Prepare the module
|
|
47
|
+
* @param options - options used by the modification observer module
|
|
48
|
+
* @param options.config - Blok configuration object
|
|
49
|
+
* @param options.eventsDispatcher - common Blok event bus
|
|
50
|
+
*/
|
|
51
|
+
constructor({ config, eventsDispatcher }: ModuleConfig) {
|
|
52
|
+
super({
|
|
53
|
+
config,
|
|
54
|
+
eventsDispatcher,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
this.mutationObserver = new MutationObserver((mutations) => {
|
|
58
|
+
this.redactorChanged(mutations);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
this.eventsDispatcher.on(BlockChanged, (payload) => {
|
|
62
|
+
this.particularBlockChanged(payload.event);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Mutex for fake cursor setting/removing operation
|
|
67
|
+
*/
|
|
68
|
+
this.eventsDispatcher.on(FakeCursorAboutToBeToggled, () => {
|
|
69
|
+
this.disable();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
this.eventsDispatcher.on(FakeCursorHaveBeenSet, () => {
|
|
73
|
+
this.enable();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Enables onChange event
|
|
79
|
+
*/
|
|
80
|
+
public enable(): void {
|
|
81
|
+
this.mutationObserver.observe(
|
|
82
|
+
this.Blok.UI.nodes.redactor,
|
|
83
|
+
{
|
|
84
|
+
childList: true,
|
|
85
|
+
subtree: true,
|
|
86
|
+
characterData: true,
|
|
87
|
+
attributes: true,
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
this.disabled = false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Disables onChange event
|
|
95
|
+
*/
|
|
96
|
+
public disable(): void {
|
|
97
|
+
this.mutationObserver.disconnect();
|
|
98
|
+
this.disabled = true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Call onChange event passed to Blok configuration
|
|
103
|
+
* @param event - some of our custom change events
|
|
104
|
+
*/
|
|
105
|
+
private particularBlockChanged(event: BlockMutationEvent): void {
|
|
106
|
+
if (this.disabled || !isFunction(this.config.onChange)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
this.batchingOnChangeQueue.set(`block:${event.detail.target.id}:event:${event.type as BlockMutationType}`, event);
|
|
111
|
+
|
|
112
|
+
if (this.batchingTimeout) {
|
|
113
|
+
clearTimeout(this.batchingTimeout);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.batchingTimeout = setTimeout(() => {
|
|
117
|
+
const queuedEvents = Array.from(this.batchingOnChangeQueue.values());
|
|
118
|
+
|
|
119
|
+
if (queuedEvents.length === 0) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* If we have only 1 event in a queue, unwrap it
|
|
125
|
+
*/
|
|
126
|
+
const eventsToEmit = queuedEvents.length === 1
|
|
127
|
+
? queuedEvents[0]
|
|
128
|
+
: queuedEvents;
|
|
129
|
+
|
|
130
|
+
if (this.config.onChange) {
|
|
131
|
+
this.config.onChange(this.Blok.API.methods, eventsToEmit);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
this.batchingOnChangeQueue.clear();
|
|
135
|
+
}, this.batchTime);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Fired on every blocks wrapper dom change
|
|
140
|
+
* @param mutations - mutations happened
|
|
141
|
+
*/
|
|
142
|
+
private redactorChanged(mutations: MutationRecord[]): void {
|
|
143
|
+
this.eventsDispatcher.emit(RedactorDomChanged, {
|
|
144
|
+
mutations,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|