@jackuait/blok 0.4.1-beta.5 → 0.4.1-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +136 -17
- package/codemod/README.md +16 -0
- package/codemod/migrate-editorjs-to-blok.js +868 -92
- package/codemod/test.js +682 -77
- package/dist/blok.mjs +5 -2
- package/dist/chunks/blok-B5qs7C5l.mjs +12838 -0
- package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
- package/dist/chunks/i18next-loader-CTrK3HzG.mjs +43 -0
- package/dist/{index-Cl_5rkKS.mjs → chunks/index-DDpzQn-0.mjs} +2 -2
- package/dist/chunks/inline-tool-convert-RBcopmCh.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 +48 -16
- 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 -12
- 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/header.d.ts +18 -0
- package/types/tools/index.d.ts +1 -0
- package/types/tools/list.d.ts +91 -0
- package/types/tools/paragraph.d.ts +71 -0
- package/types/tools/tool-settings.d.ts +16 -2
- 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-DvN73wsH.mjs +0 -19922
- package/dist/blok.umd.js +0 -166
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Model Transformation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles conversion between legacy nested format and hierarchical flat-with-references format.
|
|
5
|
+
* Used for automatic detection and transformation when dataModel config is 'auto'.
|
|
6
|
+
*/
|
|
7
|
+
import type { OutputBlockData, BlockId } from '../../../types';
|
|
8
|
+
import { generateBlockId } from '../utils';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Legacy list item structure for data model transformation.
|
|
12
|
+
* Used internally for transforming legacy nested list data to the hierarchical model.
|
|
13
|
+
*/
|
|
14
|
+
interface LegacyListItem {
|
|
15
|
+
content: string;
|
|
16
|
+
checked?: boolean;
|
|
17
|
+
items?: LegacyListItem[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Legacy list data structure for data model transformation.
|
|
22
|
+
* Used internally for transforming legacy nested list data to the hierarchical model.
|
|
23
|
+
*/
|
|
24
|
+
interface LegacyListData {
|
|
25
|
+
style: 'unordered' | 'ordered' | 'checklist';
|
|
26
|
+
items: LegacyListItem[];
|
|
27
|
+
start?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Result of analyzing the input data format
|
|
32
|
+
*/
|
|
33
|
+
export interface DataFormatAnalysis {
|
|
34
|
+
/**
|
|
35
|
+
* Detected format: 'legacy' if any block has nested items, 'hierarchical' if any block has parent/content
|
|
36
|
+
*/
|
|
37
|
+
format: 'legacy' | 'hierarchical' | 'flat';
|
|
38
|
+
/**
|
|
39
|
+
* Whether the data contains any hierarchical relationships
|
|
40
|
+
*/
|
|
41
|
+
hasHierarchy: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Recursively check if any list item has nested items
|
|
46
|
+
*/
|
|
47
|
+
const hasNestedListItems = (items: LegacyListItem[]): boolean => {
|
|
48
|
+
return items.some(item => item.items !== undefined && item.items.length > 0);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if a block contains legacy nested items structure
|
|
53
|
+
* Currently supports: List tool with nested items[]
|
|
54
|
+
*/
|
|
55
|
+
const hasNestedItems = (block: OutputBlockData): boolean => {
|
|
56
|
+
const isListWithItems = block.type === 'list' && block.data?.items;
|
|
57
|
+
|
|
58
|
+
if (!isListWithItems) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return hasNestedListItems(block.data.items as LegacyListItem[]);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Check if block has hierarchical references
|
|
67
|
+
*/
|
|
68
|
+
const hasHierarchicalRefs = (block: OutputBlockData): boolean => {
|
|
69
|
+
return block.parent !== undefined || (block.content !== undefined && block.content.length > 0);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Analyze the input data to detect its format
|
|
74
|
+
* @param blocks - array of output block data
|
|
75
|
+
* @returns analysis result with detected format
|
|
76
|
+
*/
|
|
77
|
+
export const analyzeDataFormat = (blocks: OutputBlockData[]): DataFormatAnalysis => {
|
|
78
|
+
const foundHierarchicalRefs = blocks.some(hasHierarchicalRefs);
|
|
79
|
+
|
|
80
|
+
if (foundHierarchicalRefs) {
|
|
81
|
+
return { format: 'hierarchical', hasHierarchy: true };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const foundLegacyNested = blocks.some(hasNestedItems);
|
|
85
|
+
|
|
86
|
+
if (foundLegacyNested) {
|
|
87
|
+
return { format: 'legacy', hasHierarchy: true };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return { format: 'flat', hasHierarchy: false };
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Expand list items recursively, collecting child IDs
|
|
95
|
+
*/
|
|
96
|
+
const expandListItems = (
|
|
97
|
+
items: LegacyListItem[],
|
|
98
|
+
parentId: BlockId | undefined,
|
|
99
|
+
depth: number,
|
|
100
|
+
style: string,
|
|
101
|
+
start: number | undefined,
|
|
102
|
+
tunes: OutputBlockData['tunes'],
|
|
103
|
+
blocks: OutputBlockData[]
|
|
104
|
+
): BlockId[] => {
|
|
105
|
+
const childIds: BlockId[] = [];
|
|
106
|
+
|
|
107
|
+
items.forEach((item, index) => {
|
|
108
|
+
const itemId = generateBlockId();
|
|
109
|
+
|
|
110
|
+
childIds.push(itemId);
|
|
111
|
+
|
|
112
|
+
// Recursively expand nested items first to get their IDs
|
|
113
|
+
const nestedChildIds = item.items && item.items.length > 0
|
|
114
|
+
? expandListItems(item.items, itemId, depth + 1, style, undefined, tunes, blocks)
|
|
115
|
+
: [];
|
|
116
|
+
|
|
117
|
+
// Determine if we should include start (only for first root item of ordered lists)
|
|
118
|
+
const includeStart = style === 'ordered' && depth === 0 && index === 0 && start !== undefined && start !== 1;
|
|
119
|
+
|
|
120
|
+
// Create the list_item block
|
|
121
|
+
const itemBlock: OutputBlockData = {
|
|
122
|
+
id: itemId,
|
|
123
|
+
type: 'list_item',
|
|
124
|
+
data: {
|
|
125
|
+
text: item.content,
|
|
126
|
+
checked: item.checked,
|
|
127
|
+
style,
|
|
128
|
+
...(includeStart ? { start } : {}),
|
|
129
|
+
},
|
|
130
|
+
...(tunes !== undefined ? { tunes } : {}),
|
|
131
|
+
...(parentId !== undefined ? { parent: parentId } : {}),
|
|
132
|
+
...(nestedChildIds.length > 0 ? { content: nestedChildIds } : {}),
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
blocks.push(itemBlock);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
return childIds;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Expand a List block with nested items into flat list_item blocks
|
|
143
|
+
*/
|
|
144
|
+
const expandListToHierarchical = (
|
|
145
|
+
listData: LegacyListData,
|
|
146
|
+
tunes?: OutputBlockData['tunes']
|
|
147
|
+
): OutputBlockData[] => {
|
|
148
|
+
const blocks: OutputBlockData[] = [];
|
|
149
|
+
const style = listData.style;
|
|
150
|
+
const start = listData.start;
|
|
151
|
+
|
|
152
|
+
// Start expansion from root items (no parent)
|
|
153
|
+
expandListItems(listData.items, undefined, 0, style, start, tunes, blocks);
|
|
154
|
+
|
|
155
|
+
return blocks;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Expand legacy nested format to hierarchical flat-with-references format
|
|
160
|
+
* @param blocks - array of blocks potentially containing nested structures
|
|
161
|
+
* @returns expanded array of flat blocks with parent/content references
|
|
162
|
+
*/
|
|
163
|
+
export const expandToHierarchical = (blocks: OutputBlockData[]): OutputBlockData[] => {
|
|
164
|
+
const expandedBlocks: OutputBlockData[] = [];
|
|
165
|
+
|
|
166
|
+
for (const block of blocks) {
|
|
167
|
+
// Ensure block has an ID
|
|
168
|
+
const blockId = block.id ?? generateBlockId();
|
|
169
|
+
|
|
170
|
+
const isListBlock = block.type === 'list' && block.data?.items;
|
|
171
|
+
|
|
172
|
+
if (isListBlock) {
|
|
173
|
+
// Expand List tool nested items to flat blocks
|
|
174
|
+
const listData = block.data as LegacyListData;
|
|
175
|
+
const expanded = expandListToHierarchical(listData, block.tunes);
|
|
176
|
+
|
|
177
|
+
expandedBlocks.push(...expanded);
|
|
178
|
+
} else {
|
|
179
|
+
// Non-list blocks pass through unchanged (with guaranteed ID)
|
|
180
|
+
expandedBlocks.push({
|
|
181
|
+
...block,
|
|
182
|
+
id: blockId,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return expandedBlocks;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Mark a block ID as processed if it exists
|
|
192
|
+
*/
|
|
193
|
+
const markBlockAsProcessed = (id: BlockId | undefined, processedIds: Set<BlockId>): void => {
|
|
194
|
+
if (id) {
|
|
195
|
+
processedIds.add(id);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Remove hierarchy fields from a block, returning a clean copy
|
|
201
|
+
*/
|
|
202
|
+
const stripHierarchyFields = (block: OutputBlockData): OutputBlockData => {
|
|
203
|
+
const { parent: _parent, content: _content, ...rest } = block;
|
|
204
|
+
|
|
205
|
+
return rest;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Collect child items from content IDs
|
|
210
|
+
*/
|
|
211
|
+
const collectChildItems = (
|
|
212
|
+
contentIds: BlockId[],
|
|
213
|
+
blockMap: Map<BlockId, OutputBlockData>,
|
|
214
|
+
processedIds: Set<BlockId>
|
|
215
|
+
): LegacyListItem[] => {
|
|
216
|
+
const childItems: LegacyListItem[] = [];
|
|
217
|
+
|
|
218
|
+
for (const childId of contentIds) {
|
|
219
|
+
const childBlock = blockMap.get(childId);
|
|
220
|
+
const isListItem = childBlock && childBlock.type === 'list_item';
|
|
221
|
+
|
|
222
|
+
if (isListItem) {
|
|
223
|
+
const items = collectListItems(childBlock, blockMap, processedIds);
|
|
224
|
+
|
|
225
|
+
childItems.push(...items);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return childItems;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Recursively collect list items and their nested children into ListItem structure
|
|
234
|
+
*/
|
|
235
|
+
const collectListItems = (
|
|
236
|
+
block: OutputBlockData,
|
|
237
|
+
blockMap: Map<BlockId, OutputBlockData>,
|
|
238
|
+
processedIds: Set<BlockId>
|
|
239
|
+
): LegacyListItem[] => {
|
|
240
|
+
const items: LegacyListItem[] = [];
|
|
241
|
+
|
|
242
|
+
// Mark this block as processed
|
|
243
|
+
if (block.id) {
|
|
244
|
+
processedIds.add(block.id);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const item: LegacyListItem = {
|
|
248
|
+
content: block.data?.text || '',
|
|
249
|
+
checked: block.data?.checked,
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// Recursively process children
|
|
253
|
+
const hasChildren = block.content && block.content.length > 0;
|
|
254
|
+
|
|
255
|
+
if (hasChildren) {
|
|
256
|
+
item.items = collectChildItems(block.content!, blockMap, processedIds);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Clean up empty items array
|
|
260
|
+
const shouldRemoveItems = item.items !== undefined && item.items.length === 0;
|
|
261
|
+
|
|
262
|
+
if (shouldRemoveItems) {
|
|
263
|
+
delete item.items;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
items.push(item);
|
|
267
|
+
|
|
268
|
+
return items;
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Process a root list_item block and convert to a legacy List block
|
|
273
|
+
*/
|
|
274
|
+
const processRootListItem = (
|
|
275
|
+
block: OutputBlockData,
|
|
276
|
+
blockMap: Map<BlockId, OutputBlockData>,
|
|
277
|
+
processedIds: Set<BlockId>
|
|
278
|
+
): OutputBlockData => {
|
|
279
|
+
const listItems = collectListItems(block, blockMap, processedIds);
|
|
280
|
+
const style = block.data?.style || 'unordered';
|
|
281
|
+
const start = block.data?.start;
|
|
282
|
+
|
|
283
|
+
const listBlock: OutputBlockData = {
|
|
284
|
+
id: block.id,
|
|
285
|
+
type: 'list',
|
|
286
|
+
data: {
|
|
287
|
+
style,
|
|
288
|
+
items: listItems,
|
|
289
|
+
...(style === 'ordered' && start !== undefined && start !== 1 ? { start } : {}),
|
|
290
|
+
} as LegacyListData,
|
|
291
|
+
...(block.tunes !== undefined ? { tunes: block.tunes } : {}),
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
return listBlock;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Collapse hierarchical flat-with-references format back to legacy nested format
|
|
299
|
+
* @param blocks - array of flat blocks with parent/content references
|
|
300
|
+
* @returns collapsed array with nested structures
|
|
301
|
+
*/
|
|
302
|
+
export const collapseToLegacy = (blocks: OutputBlockData[]): OutputBlockData[] => {
|
|
303
|
+
// Build a map of blocks by ID for quick lookup
|
|
304
|
+
const blockMap = new Map<BlockId, OutputBlockData>();
|
|
305
|
+
const listItemBlocks: OutputBlockData[] = [];
|
|
306
|
+
|
|
307
|
+
for (const block of blocks) {
|
|
308
|
+
if (block.id) {
|
|
309
|
+
blockMap.set(block.id, block);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (block.type === 'list_item') {
|
|
313
|
+
listItemBlocks.push(block);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// If no list_item blocks, just strip hierarchy fields and return
|
|
318
|
+
if (listItemBlocks.length === 0) {
|
|
319
|
+
return blocks.map(stripHierarchyFields);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Process blocks, converting root list_items to List blocks
|
|
323
|
+
const result: OutputBlockData[] = [];
|
|
324
|
+
const processedIds = new Set<BlockId>();
|
|
325
|
+
|
|
326
|
+
for (const block of blocks) {
|
|
327
|
+
const alreadyProcessed = block.id && processedIds.has(block.id);
|
|
328
|
+
|
|
329
|
+
if (alreadyProcessed) {
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const isRootListItem = block.type === 'list_item' && !block.parent;
|
|
334
|
+
const isNonListItem = block.type !== 'list_item';
|
|
335
|
+
|
|
336
|
+
if (isRootListItem) {
|
|
337
|
+
const listBlock = processRootListItem(block, blockMap, processedIds);
|
|
338
|
+
|
|
339
|
+
result.push(listBlock);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (isNonListItem) {
|
|
343
|
+
result.push(stripHierarchyFields(block));
|
|
344
|
+
markBlockAsProcessed(block.id, processedIds);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return result;
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Check if transformation is needed based on config and detected format
|
|
353
|
+
*/
|
|
354
|
+
export const shouldExpandToHierarchical = (
|
|
355
|
+
dataModelConfig: 'legacy' | 'hierarchical' | 'auto',
|
|
356
|
+
detectedFormat: DataFormatAnalysis['format']
|
|
357
|
+
): boolean => {
|
|
358
|
+
if (dataModelConfig === 'hierarchical') {
|
|
359
|
+
return detectedFormat === 'legacy';
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// For 'auto' and 'legacy', don't expand
|
|
363
|
+
return false;
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Check if transformation is needed for output based on config and detected format
|
|
368
|
+
*/
|
|
369
|
+
export const shouldCollapseToLegacy = (
|
|
370
|
+
dataModelConfig: 'legacy' | 'hierarchical' | 'auto',
|
|
371
|
+
inputFormat: DataFormatAnalysis['format']
|
|
372
|
+
): boolean => {
|
|
373
|
+
if (dataModelConfig === 'legacy') {
|
|
374
|
+
return true;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (dataModelConfig === 'auto' && inputFormat === 'legacy') {
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return false;
|
|
382
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { isEmpty } from '../utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Event Dispatcher event listener
|
|
5
|
+
*/
|
|
6
|
+
type Listener<Data> = (data: Data) => void;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Mapped type with subscriptions list
|
|
10
|
+
*
|
|
11
|
+
* event name -> array of callbacks
|
|
12
|
+
*/
|
|
13
|
+
type Subscriptions<EventMap> = {
|
|
14
|
+
[Key in keyof EventMap]: Listener<EventMap[Key]>[];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Provides methods for working with Event Bus:
|
|
19
|
+
* - {Function} on - appends subscriber to the event. If event doesn't exist - creates new one
|
|
20
|
+
* - {Function} emit - fires all subscribers with data
|
|
21
|
+
* - {Function off - unsubscribes callback
|
|
22
|
+
*/
|
|
23
|
+
export class EventsDispatcher<EventMap> {
|
|
24
|
+
/**
|
|
25
|
+
* All subscribers grouped by event name
|
|
26
|
+
* Object with events` names as key and array of callback functions as value
|
|
27
|
+
*/
|
|
28
|
+
private subscribers = <Subscriptions<EventMap>>{};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Subscribe any event on callback
|
|
32
|
+
* @param eventName - event name
|
|
33
|
+
* @param callback - subscriber
|
|
34
|
+
*/
|
|
35
|
+
public on<Name extends keyof EventMap>(eventName: Name, callback: Listener<EventMap[Name]>): void {
|
|
36
|
+
if (!(eventName in this.subscribers)) {
|
|
37
|
+
this.subscribers[eventName] = [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// group by events
|
|
41
|
+
this.subscribers[eventName].push(callback);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Subscribe any event on callback. Callback will be called once and be removed from subscribers array after call.
|
|
46
|
+
* @param eventName - event name
|
|
47
|
+
* @param callback - subscriber
|
|
48
|
+
*/
|
|
49
|
+
public once<Name extends keyof EventMap>(eventName: Name, callback: Listener<EventMap[Name]>): void {
|
|
50
|
+
if (!(eventName in this.subscribers)) {
|
|
51
|
+
this.subscribers[eventName] = [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const wrappedCallback = (data: EventMap[typeof eventName]): void => {
|
|
55
|
+
const result = callback(data);
|
|
56
|
+
|
|
57
|
+
const indexOfHandler = this.subscribers[eventName].indexOf(wrappedCallback);
|
|
58
|
+
|
|
59
|
+
if (indexOfHandler !== -1) {
|
|
60
|
+
this.subscribers[eventName].splice(indexOfHandler, 1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return result;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// group by events
|
|
67
|
+
this.subscribers[eventName].push(wrappedCallback);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Emit callbacks with passed data
|
|
72
|
+
* @param eventName - event name
|
|
73
|
+
* @param data - subscribers get this data when they were fired
|
|
74
|
+
*/
|
|
75
|
+
public emit<Name extends keyof EventMap>(eventName: Name, data?: EventMap[Name]): void {
|
|
76
|
+
if (isEmpty(this.subscribers) || !this.subscribers[eventName]) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this.subscribers[eventName].reduce<EventMap[Name] | undefined>((previousData, currentHandler) => {
|
|
81
|
+
const newData = currentHandler(previousData as EventMap[Name]);
|
|
82
|
+
|
|
83
|
+
return newData !== undefined ? newData : previousData;
|
|
84
|
+
}, data);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Unsubscribe callback from event
|
|
89
|
+
* @param eventName - event name
|
|
90
|
+
* @param callback - event handler
|
|
91
|
+
*/
|
|
92
|
+
public off<Name extends keyof EventMap>(eventName: Name, callback: Listener<EventMap[Name]>): void {
|
|
93
|
+
const subscribers = this.subscribers[eventName];
|
|
94
|
+
|
|
95
|
+
if (subscribers === undefined) {
|
|
96
|
+
console.warn(`EventDispatcher .off(): there is no subscribers for event "${eventName.toString()}". Probably, .off() called before .on()`);
|
|
97
|
+
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const indexOfCallback = subscribers.indexOf(callback);
|
|
102
|
+
|
|
103
|
+
if (indexOfCallback === -1) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
subscribers.splice(indexOfCallback, 1);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Destroyer
|
|
112
|
+
* clears subscribers list
|
|
113
|
+
*/
|
|
114
|
+
public destroy(): void {
|
|
115
|
+
this.subscribers = {} as Subscriptions<EventMap>;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
/**
|
|
3
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/KeyboardLayoutMap
|
|
4
|
+
*/
|
|
5
|
+
interface KeyboardLayoutMap {
|
|
6
|
+
get(key: string): string | undefined;
|
|
7
|
+
has(key: string): boolean;
|
|
8
|
+
size: number;
|
|
9
|
+
entries(): IterableIterator<[string, string]>;
|
|
10
|
+
keys(): IterableIterator<string>;
|
|
11
|
+
values(): IterableIterator<string>;
|
|
12
|
+
forEach(callbackfn: (value: string, key: string, map: KeyboardLayoutMap) => void, thisArg?: unknown): void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The getLayoutMap() method of the Keyboard interface returns a Promise
|
|
17
|
+
* that resolves with an instance of KeyboardLayoutMap which is a map-like object
|
|
18
|
+
* with functions for retrieving the strings associated with specific physical keys.
|
|
19
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/getLayoutMap
|
|
20
|
+
*/
|
|
21
|
+
interface Keyboard {
|
|
22
|
+
getLayoutMap(): Promise<KeyboardLayoutMap>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface Navigator {
|
|
26
|
+
/**
|
|
27
|
+
* Keyboard API. Not supported by Firefox and Safari.
|
|
28
|
+
*/
|
|
29
|
+
keyboard?: Keyboard;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns real layout-related keyboard key for a given key code.
|
|
35
|
+
* For example, for "Slash" it will return "/" on US keyboard and "-" on Spanish keyboard.
|
|
36
|
+
*
|
|
37
|
+
* Works with Keyboard API which is not supported by Firefox and Safari. So fallback is used for these browsers.
|
|
38
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Keyboard
|
|
39
|
+
* @param code - {@link https://www.w3.org/TR/uievents-code/#key-alphanumeric-writing-system}
|
|
40
|
+
* @param fallback - fallback value to be returned if Keyboard API is not supported (Safari, Firefox)
|
|
41
|
+
*/
|
|
42
|
+
export const getKeyboardKeyForCode = async (code: string, fallback: string): Promise<string> => {
|
|
43
|
+
const keyboard = navigator.keyboard;
|
|
44
|
+
|
|
45
|
+
if (!keyboard) {
|
|
46
|
+
return fallback;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const map = await keyboard.getLayoutMap();
|
|
51
|
+
|
|
52
|
+
const key = map.get(code);
|
|
53
|
+
|
|
54
|
+
return key || fallback;
|
|
55
|
+
} catch (e) {
|
|
56
|
+
console.error(e);
|
|
57
|
+
|
|
58
|
+
return fallback;
|
|
59
|
+
}
|
|
60
|
+
};
|