@jackuait/blok 0.4.1-beta.4 → 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.
Files changed (400) hide show
  1. package/README.md +136 -17
  2. package/codemod/README.md +16 -0
  3. package/codemod/migrate-editorjs-to-blok.js +868 -92
  4. package/codemod/test.js +682 -77
  5. package/dist/blok.mjs +5 -2
  6. package/dist/chunks/blok-B5qs7C5l.mjs +12838 -0
  7. package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
  8. package/dist/chunks/i18next-loader-CTrK3HzG.mjs +43 -0
  9. package/dist/{index-XWGz4gev.mjs → chunks/index-DDpzQn-0.mjs} +2 -2
  10. package/dist/chunks/inline-tool-convert-RBcopmCh.mjs +1988 -0
  11. package/dist/chunks/messages-2434tVOK.mjs +47 -0
  12. package/dist/chunks/messages-3DcCwXMF.mjs +47 -0
  13. package/dist/chunks/messages-4kMwVAKY.mjs +47 -0
  14. package/dist/chunks/messages-57uL5htT.mjs +47 -0
  15. package/dist/chunks/messages-76-iJV9Q.mjs +47 -0
  16. package/dist/chunks/messages-8p86Eyf2.mjs +47 -0
  17. package/dist/chunks/messages-BBX0p0Pi.mjs +47 -0
  18. package/dist/chunks/messages-BCm2eudQ.mjs +47 -0
  19. package/dist/chunks/messages-BFiUomgG.mjs +47 -0
  20. package/dist/chunks/messages-BIPNHHAV.mjs +47 -0
  21. package/dist/chunks/messages-BUlwu9mo.mjs +47 -0
  22. package/dist/chunks/messages-BX-DPa-z.mjs +47 -0
  23. package/dist/chunks/messages-BextV3Qh.mjs +47 -0
  24. package/dist/chunks/messages-BiPSFlUG.mjs +47 -0
  25. package/dist/chunks/messages-BiXe9G-O.mjs +47 -0
  26. package/dist/chunks/messages-Bl5z_Igo.mjs +47 -0
  27. package/dist/chunks/messages-BnsE97ku.mjs +47 -0
  28. package/dist/chunks/messages-BoO8gsVD.mjs +47 -0
  29. package/dist/chunks/messages-BqWaOGMn.mjs +47 -0
  30. package/dist/chunks/messages-BqkL2_Ro.mjs +47 -0
  31. package/dist/chunks/messages-BvCkXKX-.mjs +47 -0
  32. package/dist/chunks/messages-C6tbPLoj.mjs +47 -0
  33. package/dist/chunks/messages-CA6T3-gQ.mjs +47 -0
  34. package/dist/chunks/messages-CFFPFdWP.mjs +47 -0
  35. package/dist/chunks/messages-CFrKE-TN.mjs +47 -0
  36. package/dist/chunks/messages-CHz8VlG-.mjs +47 -0
  37. package/dist/chunks/messages-CLixzySl.mjs +47 -0
  38. package/dist/chunks/messages-CV7OM_qk.mjs +47 -0
  39. package/dist/chunks/messages-CXHt3eCC.mjs +47 -0
  40. package/dist/chunks/messages-CbmsBrB0.mjs +47 -0
  41. package/dist/chunks/messages-Ceo1KtFx.mjs +47 -0
  42. package/dist/chunks/messages-Cm0LJLtB.mjs +47 -0
  43. package/dist/chunks/messages-CmymP_Ar.mjs +47 -0
  44. package/dist/chunks/messages-D0ohMB5H.mjs +47 -0
  45. package/dist/chunks/messages-D3GrDwXh.mjs +47 -0
  46. package/dist/chunks/messages-D3vTzIpL.mjs +47 -0
  47. package/dist/chunks/messages-D5WeksbV.mjs +47 -0
  48. package/dist/chunks/messages-DGaab4EP.mjs +47 -0
  49. package/dist/chunks/messages-DKha57ZU.mjs +47 -0
  50. package/dist/chunks/messages-DOaujgMW.mjs +47 -0
  51. package/dist/chunks/messages-DVbPLd_0.mjs +47 -0
  52. package/dist/chunks/messages-D_FCyfW6.mjs +47 -0
  53. package/dist/chunks/messages-Dd5iZN3c.mjs +47 -0
  54. package/dist/chunks/messages-DehM7135.mjs +47 -0
  55. package/dist/chunks/messages-Dg1OHftD.mjs +47 -0
  56. package/dist/chunks/messages-Di6Flq-b.mjs +47 -0
  57. package/dist/chunks/messages-Dqhhex6e.mjs +47 -0
  58. package/dist/chunks/messages-DueVe0F1.mjs +47 -0
  59. package/dist/chunks/messages-Dx3eFwI0.mjs +47 -0
  60. package/dist/chunks/messages-FOtiUoKl.mjs +47 -0
  61. package/dist/chunks/messages-FTOZNhRD.mjs +47 -0
  62. package/dist/chunks/messages-IQxGfQIV.mjs +47 -0
  63. package/dist/chunks/messages-JF2fzCkK.mjs +47 -0
  64. package/dist/chunks/messages-MOGl7I5v.mjs +47 -0
  65. package/dist/chunks/messages-QgYhPL-3.mjs +47 -0
  66. package/dist/chunks/messages-WYWIbQwo.mjs +47 -0
  67. package/dist/chunks/messages-a6A_LgDv.mjs +47 -0
  68. package/dist/chunks/messages-bSf31LJi.mjs +47 -0
  69. package/dist/chunks/messages-diGozhTn.mjs +47 -0
  70. package/dist/chunks/messages-er-kd-VO.mjs +47 -0
  71. package/dist/chunks/messages-ez3w5NBn.mjs +47 -0
  72. package/dist/chunks/messages-f3uXjegd.mjs +47 -0
  73. package/dist/chunks/messages-ohwI1UGv.mjs +47 -0
  74. package/dist/chunks/messages-p9BZJaFV.mjs +47 -0
  75. package/dist/chunks/messages-qIQ4L4rw.mjs +47 -0
  76. package/dist/chunks/messages-qWkXPggi.mjs +47 -0
  77. package/dist/chunks/messages-w5foGze_.mjs +47 -0
  78. package/dist/full.mjs +50 -0
  79. package/dist/locales.mjs +227 -0
  80. package/dist/messages-2434tVOK.mjs +47 -0
  81. package/dist/messages-3DcCwXMF.mjs +47 -0
  82. package/dist/messages-4kMwVAKY.mjs +47 -0
  83. package/dist/messages-57uL5htT.mjs +47 -0
  84. package/dist/messages-76-iJV9Q.mjs +47 -0
  85. package/dist/messages-8p86Eyf2.mjs +47 -0
  86. package/dist/messages-BBX0p0Pi.mjs +47 -0
  87. package/dist/messages-BCm2eudQ.mjs +47 -0
  88. package/dist/messages-BFiUomgG.mjs +47 -0
  89. package/dist/messages-BIPNHHAV.mjs +47 -0
  90. package/dist/messages-BUlwu9mo.mjs +47 -0
  91. package/dist/messages-BX-DPa-z.mjs +47 -0
  92. package/dist/messages-BextV3Qh.mjs +47 -0
  93. package/dist/messages-BiPSFlUG.mjs +47 -0
  94. package/dist/messages-BiXe9G-O.mjs +47 -0
  95. package/dist/messages-Bl5z_Igo.mjs +47 -0
  96. package/dist/messages-BnsE97ku.mjs +47 -0
  97. package/dist/messages-BoO8gsVD.mjs +47 -0
  98. package/dist/messages-BqWaOGMn.mjs +47 -0
  99. package/dist/messages-BqkL2_Ro.mjs +47 -0
  100. package/dist/messages-BvCkXKX-.mjs +47 -0
  101. package/dist/messages-C6tbPLoj.mjs +47 -0
  102. package/dist/messages-CA6T3-gQ.mjs +47 -0
  103. package/dist/messages-CFFPFdWP.mjs +47 -0
  104. package/dist/messages-CFrKE-TN.mjs +47 -0
  105. package/dist/messages-CHz8VlG-.mjs +47 -0
  106. package/dist/messages-CLixzySl.mjs +47 -0
  107. package/dist/messages-CV7OM_qk.mjs +47 -0
  108. package/dist/messages-CXHt3eCC.mjs +47 -0
  109. package/dist/messages-CbmsBrB0.mjs +47 -0
  110. package/dist/messages-Ceo1KtFx.mjs +47 -0
  111. package/dist/messages-Cm0LJLtB.mjs +47 -0
  112. package/dist/messages-CmymP_Ar.mjs +47 -0
  113. package/dist/messages-D0ohMB5H.mjs +47 -0
  114. package/dist/messages-D3GrDwXh.mjs +47 -0
  115. package/dist/messages-D3vTzIpL.mjs +47 -0
  116. package/dist/messages-D5WeksbV.mjs +47 -0
  117. package/dist/messages-DGaab4EP.mjs +47 -0
  118. package/dist/messages-DKha57ZU.mjs +47 -0
  119. package/dist/messages-DOaujgMW.mjs +47 -0
  120. package/dist/messages-DVbPLd_0.mjs +47 -0
  121. package/dist/messages-D_FCyfW6.mjs +47 -0
  122. package/dist/messages-Dd5iZN3c.mjs +47 -0
  123. package/dist/messages-DehM7135.mjs +47 -0
  124. package/dist/messages-Dg1OHftD.mjs +47 -0
  125. package/dist/messages-Di6Flq-b.mjs +47 -0
  126. package/dist/messages-Dqhhex6e.mjs +47 -0
  127. package/dist/messages-DueVe0F1.mjs +47 -0
  128. package/dist/messages-Dx3eFwI0.mjs +47 -0
  129. package/dist/messages-FOtiUoKl.mjs +47 -0
  130. package/dist/messages-FTOZNhRD.mjs +47 -0
  131. package/dist/messages-IQxGfQIV.mjs +47 -0
  132. package/dist/messages-JF2fzCkK.mjs +47 -0
  133. package/dist/messages-MOGl7I5v.mjs +47 -0
  134. package/dist/messages-QgYhPL-3.mjs +47 -0
  135. package/dist/messages-WYWIbQwo.mjs +47 -0
  136. package/dist/messages-a6A_LgDv.mjs +47 -0
  137. package/dist/messages-bSf31LJi.mjs +47 -0
  138. package/dist/messages-diGozhTn.mjs +47 -0
  139. package/dist/messages-er-kd-VO.mjs +47 -0
  140. package/dist/messages-ez3w5NBn.mjs +47 -0
  141. package/dist/messages-f3uXjegd.mjs +47 -0
  142. package/dist/messages-ohwI1UGv.mjs +47 -0
  143. package/dist/messages-p9BZJaFV.mjs +47 -0
  144. package/dist/messages-qIQ4L4rw.mjs +47 -0
  145. package/dist/messages-qWkXPggi.mjs +47 -0
  146. package/dist/messages-w5foGze_.mjs +47 -0
  147. package/dist/tools.mjs +3073 -0
  148. package/dist/vendor.LICENSE.txt +26 -225
  149. package/package.json +49 -23
  150. package/src/blok.ts +267 -0
  151. package/src/components/__module.ts +139 -0
  152. package/src/components/block/api.ts +155 -0
  153. package/src/components/block/index.ts +1427 -0
  154. package/src/components/block-tunes/block-tune-delete.ts +51 -0
  155. package/src/components/blocks.ts +338 -0
  156. package/src/components/constants/data-attributes.ts +342 -0
  157. package/src/components/constants.ts +76 -0
  158. package/src/components/core.ts +392 -0
  159. package/src/components/dom.ts +773 -0
  160. package/src/components/domIterator.ts +189 -0
  161. package/src/components/errors/critical.ts +5 -0
  162. package/src/components/events/BlockChanged.ts +16 -0
  163. package/src/components/events/BlockHovered.ts +21 -0
  164. package/src/components/events/BlockSettingsClosed.ts +12 -0
  165. package/src/components/events/BlockSettingsOpened.ts +12 -0
  166. package/src/components/events/BlokMobileLayoutToggled.ts +15 -0
  167. package/src/components/events/FakeCursorAboutToBeToggled.ts +17 -0
  168. package/src/components/events/FakeCursorHaveBeenSet.ts +17 -0
  169. package/src/components/events/HistoryStateChanged.ts +19 -0
  170. package/src/components/events/RedactorDomChanged.ts +14 -0
  171. package/src/components/events/index.ts +46 -0
  172. package/src/components/flipper.ts +481 -0
  173. package/src/components/i18n/i18next-loader.ts +84 -0
  174. package/src/components/i18n/lightweight-i18n.ts +86 -0
  175. package/src/components/i18n/locales/TRANSLATION_GUIDELINES.md +113 -0
  176. package/src/components/i18n/locales/am/messages.json +44 -0
  177. package/src/components/i18n/locales/ar/messages.json +44 -0
  178. package/src/components/i18n/locales/az/messages.json +44 -0
  179. package/src/components/i18n/locales/bg/messages.json +44 -0
  180. package/src/components/i18n/locales/bn/messages.json +44 -0
  181. package/src/components/i18n/locales/bs/messages.json +44 -0
  182. package/src/components/i18n/locales/cs/messages.json +44 -0
  183. package/src/components/i18n/locales/da/messages.json +44 -0
  184. package/src/components/i18n/locales/de/messages.json +44 -0
  185. package/src/components/i18n/locales/dv/messages.json +44 -0
  186. package/src/components/i18n/locales/el/messages.json +44 -0
  187. package/src/components/i18n/locales/en/messages.json +44 -0
  188. package/src/components/i18n/locales/es/messages.json +44 -0
  189. package/src/components/i18n/locales/et/messages.json +44 -0
  190. package/src/components/i18n/locales/fa/messages.json +44 -0
  191. package/src/components/i18n/locales/fi/messages.json +44 -0
  192. package/src/components/i18n/locales/fil/messages.json +44 -0
  193. package/src/components/i18n/locales/fr/messages.json +44 -0
  194. package/src/components/i18n/locales/gu/messages.json +44 -0
  195. package/src/components/i18n/locales/he/messages.json +44 -0
  196. package/src/components/i18n/locales/hi/messages.json +44 -0
  197. package/src/components/i18n/locales/hr/messages.json +44 -0
  198. package/src/components/i18n/locales/hu/messages.json +44 -0
  199. package/src/components/i18n/locales/hy/messages.json +44 -0
  200. package/src/components/i18n/locales/id/messages.json +44 -0
  201. package/src/components/i18n/locales/index.ts +225 -0
  202. package/src/components/i18n/locales/it/messages.json +44 -0
  203. package/src/components/i18n/locales/ja/messages.json +44 -0
  204. package/src/components/i18n/locales/ka/messages.json +44 -0
  205. package/src/components/i18n/locales/km/messages.json +44 -0
  206. package/src/components/i18n/locales/kn/messages.json +44 -0
  207. package/src/components/i18n/locales/ko/messages.json +44 -0
  208. package/src/components/i18n/locales/ku/messages.json +44 -0
  209. package/src/components/i18n/locales/lo/messages.json +44 -0
  210. package/src/components/i18n/locales/lt/messages.json +44 -0
  211. package/src/components/i18n/locales/lv/messages.json +44 -0
  212. package/src/components/i18n/locales/mk/messages.json +44 -0
  213. package/src/components/i18n/locales/ml/messages.json +44 -0
  214. package/src/components/i18n/locales/mn/messages.json +44 -0
  215. package/src/components/i18n/locales/mr/messages.json +44 -0
  216. package/src/components/i18n/locales/ms/messages.json +44 -0
  217. package/src/components/i18n/locales/my/messages.json +44 -0
  218. package/src/components/i18n/locales/ne/messages.json +44 -0
  219. package/src/components/i18n/locales/nl/messages.json +44 -0
  220. package/src/components/i18n/locales/no/messages.json +44 -0
  221. package/src/components/i18n/locales/pa/messages.json +44 -0
  222. package/src/components/i18n/locales/pl/messages.json +44 -0
  223. package/src/components/i18n/locales/ps/messages.json +44 -0
  224. package/src/components/i18n/locales/pt/messages.json +44 -0
  225. package/src/components/i18n/locales/ro/messages.json +44 -0
  226. package/src/components/i18n/locales/ru/messages.json +44 -0
  227. package/src/components/i18n/locales/sd/messages.json +44 -0
  228. package/src/components/i18n/locales/si/messages.json +44 -0
  229. package/src/components/i18n/locales/sk/messages.json +44 -0
  230. package/src/components/i18n/locales/sl/messages.json +44 -0
  231. package/src/components/i18n/locales/sq/messages.json +44 -0
  232. package/src/components/i18n/locales/sr/messages.json +44 -0
  233. package/src/components/i18n/locales/sv/messages.json +44 -0
  234. package/src/components/i18n/locales/sw/messages.json +44 -0
  235. package/src/components/i18n/locales/ta/messages.json +44 -0
  236. package/src/components/i18n/locales/te/messages.json +44 -0
  237. package/src/components/i18n/locales/th/messages.json +44 -0
  238. package/src/components/i18n/locales/tr/messages.json +44 -0
  239. package/src/components/i18n/locales/ug/messages.json +44 -0
  240. package/src/components/i18n/locales/uk/messages.json +44 -0
  241. package/src/components/i18n/locales/ur/messages.json +44 -0
  242. package/src/components/i18n/locales/vi/messages.json +44 -0
  243. package/src/components/i18n/locales/yi/messages.json +44 -0
  244. package/src/components/i18n/locales/zh/messages.json +44 -0
  245. package/src/components/icons/index.ts +242 -0
  246. package/src/components/inline-tools/inline-tool-bold.ts +2213 -0
  247. package/src/components/inline-tools/inline-tool-convert.ts +141 -0
  248. package/src/components/inline-tools/inline-tool-italic.ts +500 -0
  249. package/src/components/inline-tools/inline-tool-link.ts +539 -0
  250. package/src/components/modules/api/blocks.ts +363 -0
  251. package/src/components/modules/api/caret.ts +125 -0
  252. package/src/components/modules/api/events.ts +51 -0
  253. package/src/components/modules/api/history.ts +73 -0
  254. package/src/components/modules/api/i18n.ts +33 -0
  255. package/src/components/modules/api/index.ts +39 -0
  256. package/src/components/modules/api/inlineToolbar.ts +33 -0
  257. package/src/components/modules/api/listeners.ts +56 -0
  258. package/src/components/modules/api/notifier.ts +46 -0
  259. package/src/components/modules/api/readonly.ts +39 -0
  260. package/src/components/modules/api/sanitizer.ts +30 -0
  261. package/src/components/modules/api/saver.ts +52 -0
  262. package/src/components/modules/api/selection.ts +48 -0
  263. package/src/components/modules/api/styles.ts +72 -0
  264. package/src/components/modules/api/toolbar.ts +79 -0
  265. package/src/components/modules/api/tools.ts +16 -0
  266. package/src/components/modules/api/tooltip.ts +67 -0
  267. package/src/components/modules/api/ui.ts +36 -0
  268. package/src/components/modules/blockEvents.ts +1375 -0
  269. package/src/components/modules/blockManager.ts +1348 -0
  270. package/src/components/modules/blockSelection.ts +708 -0
  271. package/src/components/modules/caret.ts +853 -0
  272. package/src/components/modules/crossBlockSelection.ts +329 -0
  273. package/src/components/modules/dragManager.ts +1141 -0
  274. package/src/components/modules/history.ts +1098 -0
  275. package/src/components/modules/i18n.ts +325 -0
  276. package/src/components/modules/index.ts +139 -0
  277. package/src/components/modules/modificationsObserver.ts +147 -0
  278. package/src/components/modules/paste.ts +1092 -0
  279. package/src/components/modules/readonly.ts +136 -0
  280. package/src/components/modules/rectangleSelection.ts +668 -0
  281. package/src/components/modules/renderer.ts +155 -0
  282. package/src/components/modules/saver.ts +283 -0
  283. package/src/components/modules/toolbar/blockSettings.ts +776 -0
  284. package/src/components/modules/toolbar/index.ts +1311 -0
  285. package/src/components/modules/toolbar/inline.ts +956 -0
  286. package/src/components/modules/tools.ts +589 -0
  287. package/src/components/modules/ui.ts +1179 -0
  288. package/src/components/polyfills.ts +113 -0
  289. package/src/components/selection.ts +1189 -0
  290. package/src/components/tools/base.ts +274 -0
  291. package/src/components/tools/block.ts +291 -0
  292. package/src/components/tools/collection.ts +67 -0
  293. package/src/components/tools/factory.ts +85 -0
  294. package/src/components/tools/inline.ts +71 -0
  295. package/src/components/tools/tune.ts +33 -0
  296. package/src/components/ui/toolbox.ts +497 -0
  297. package/src/components/utils/announcer.ts +205 -0
  298. package/src/components/utils/api.ts +20 -0
  299. package/src/components/utils/bem.ts +26 -0
  300. package/src/components/utils/blocks.ts +284 -0
  301. package/src/components/utils/caret.ts +1067 -0
  302. package/src/components/utils/data-model-transform.ts +382 -0
  303. package/src/components/utils/events.ts +117 -0
  304. package/src/components/utils/keyboard.ts +60 -0
  305. package/src/components/utils/listeners.ts +296 -0
  306. package/src/components/utils/mutations.ts +39 -0
  307. package/src/components/utils/notifier/draw.ts +190 -0
  308. package/src/components/utils/notifier/index.ts +66 -0
  309. package/src/components/utils/notifier/types.ts +1 -0
  310. package/src/components/utils/notifier.ts +77 -0
  311. package/src/components/utils/placeholder.ts +140 -0
  312. package/src/components/utils/popover/components/hint/hint.const.ts +10 -0
  313. package/src/components/utils/popover/components/hint/hint.ts +46 -0
  314. package/src/components/utils/popover/components/hint/index.ts +6 -0
  315. package/src/components/utils/popover/components/popover-header/index.ts +2 -0
  316. package/src/components/utils/popover/components/popover-header/popover-header.const.ts +8 -0
  317. package/src/components/utils/popover/components/popover-header/popover-header.ts +80 -0
  318. package/src/components/utils/popover/components/popover-header/popover-header.types.ts +14 -0
  319. package/src/components/utils/popover/components/popover-item/index.ts +13 -0
  320. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +50 -0
  321. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +666 -0
  322. package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.const.ts +14 -0
  323. package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.ts +136 -0
  324. package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts +20 -0
  325. package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.ts +117 -0
  326. package/src/components/utils/popover/components/popover-item/popover-item.ts +187 -0
  327. package/src/components/utils/popover/components/search-input/index.ts +2 -0
  328. package/src/components/utils/popover/components/search-input/search-input.const.ts +8 -0
  329. package/src/components/utils/popover/components/search-input/search-input.ts +181 -0
  330. package/src/components/utils/popover/components/search-input/search-input.types.ts +30 -0
  331. package/src/components/utils/popover/index.ts +13 -0
  332. package/src/components/utils/popover/popover-abstract.ts +448 -0
  333. package/src/components/utils/popover/popover-desktop.ts +643 -0
  334. package/src/components/utils/popover/popover-inline.ts +338 -0
  335. package/src/components/utils/popover/popover-mobile.ts +201 -0
  336. package/src/components/utils/popover/popover.const.ts +81 -0
  337. package/src/components/utils/popover/utils/popover-states-history.ts +72 -0
  338. package/src/components/utils/promise-queue.ts +43 -0
  339. package/src/components/utils/sanitizer.ts +537 -0
  340. package/src/components/utils/scroll-locker.ts +87 -0
  341. package/src/components/utils/shortcut.ts +231 -0
  342. package/src/components/utils/shortcuts.ts +113 -0
  343. package/src/components/utils/tools.ts +105 -0
  344. package/src/components/utils/tooltip.ts +642 -0
  345. package/src/components/utils/tw.ts +241 -0
  346. package/src/components/utils.ts +1081 -0
  347. package/src/env.d.ts +13 -0
  348. package/src/full.ts +69 -0
  349. package/src/locales.ts +51 -0
  350. package/src/stories/Block.stories.ts +498 -0
  351. package/src/stories/EditorModes.stories.ts +505 -0
  352. package/src/stories/Header.stories.ts +137 -0
  353. package/src/stories/InlineToolbar.stories.ts +498 -0
  354. package/src/stories/List.stories.ts +259 -0
  355. package/src/stories/Notifier.stories.ts +340 -0
  356. package/src/stories/Paragraph.stories.ts +112 -0
  357. package/src/stories/Placeholder.stories.ts +319 -0
  358. package/src/stories/Popover.stories.ts +844 -0
  359. package/src/stories/Selection.stories.ts +250 -0
  360. package/src/stories/StubBlock.stories.ts +156 -0
  361. package/src/stories/Toolbar.stories.ts +223 -0
  362. package/src/stories/Toolbox.stories.ts +166 -0
  363. package/src/stories/Tooltip.stories.ts +198 -0
  364. package/src/stories/helpers.ts +463 -0
  365. package/src/styles/main.css +123 -0
  366. package/src/tools/header/index.ts +570 -0
  367. package/src/tools/index.ts +38 -0
  368. package/src/tools/list/index.ts +1803 -0
  369. package/src/tools/paragraph/index.ts +411 -0
  370. package/src/tools/stub/index.ts +107 -0
  371. package/src/types-internal/blok-modules.d.ts +87 -0
  372. package/src/types-internal/html-janitor.d.ts +28 -0
  373. package/src/types-internal/module-config.d.ts +11 -0
  374. package/src/variants/all-locales.ts +155 -0
  375. package/src/variants/blok-maximum.ts +20 -0
  376. package/src/variants/blok-minimum.ts +243 -0
  377. package/types/api/blocks.d.ts +1 -1
  378. package/types/api/i18n.d.ts +5 -3
  379. package/types/api/selection.d.ts +6 -0
  380. package/types/api/styles.d.ts +23 -10
  381. package/types/configs/blok-config.d.ts +29 -0
  382. package/types/configs/i18n-config.d.ts +52 -2
  383. package/types/configs/i18n-dictionary.d.ts +16 -90
  384. package/types/data-attributes.d.ts +169 -0
  385. package/types/data-formats/output-data.d.ts +15 -0
  386. package/types/full.d.ts +80 -0
  387. package/types/index.d.ts +9 -12
  388. package/types/locales.d.ts +59 -0
  389. package/types/tools/adapters/inline-tool-adapter.d.ts +10 -0
  390. package/types/tools/block-tool.d.ts +9 -0
  391. package/types/tools/header.d.ts +18 -0
  392. package/types/tools/index.d.ts +1 -0
  393. package/types/tools/list.d.ts +91 -0
  394. package/types/tools/paragraph.d.ts +71 -0
  395. package/types/tools/tool-settings.d.ts +16 -2
  396. package/types/tools/tool.d.ts +6 -0
  397. package/types/tools-entry.d.ts +49 -0
  398. package/types/utils/popover/popover-item.d.ts +6 -5
  399. package/dist/blok-B870U2fw.mjs +0 -25803
  400. package/dist/blok.umd.js +0 -181
@@ -0,0 +1,539 @@
1
+ import { SelectionUtils } from '../selection';
2
+ import { log } from '../utils';
3
+ import type {
4
+ InlineTool,
5
+ InlineToolConstructorOptions,
6
+ SanitizerConfig
7
+ } from '../../../types';
8
+ import { PopoverItemType } from '../utils/popover';
9
+ import type { Notifier, Toolbar, I18n, InlineToolbar } from '../../../types/api';
10
+ import type { MenuConfig } from '../../../types/tools';
11
+ import { IconLink } from '../icons';
12
+ import { DATA_ATTR, createSelector, INLINE_TOOLBAR_INTERFACE_VALUE } from '../constants';
13
+ import { twMerge } from '../utils/tw';
14
+
15
+ /**
16
+ * Link Tool
17
+ *
18
+ * Inline Toolbar Tool
19
+ *
20
+ * Wrap selected text with <a> tag
21
+ */
22
+ export class LinkInlineTool implements InlineTool {
23
+ /**
24
+ * Specifies Tool as Inline Toolbar Tool
25
+ * @returns {boolean}
26
+ */
27
+ public static isInline = true;
28
+
29
+ /**
30
+ * Title for the Inline Tool
31
+ */
32
+ public static title = 'Link';
33
+
34
+ /**
35
+ * Translation key for i18n
36
+ */
37
+ public static titleKey = 'link';
38
+
39
+ /**
40
+ * Sanitizer Rule
41
+ * Leave <a> tags
42
+ * @returns {object}
43
+ */
44
+ public static get sanitize(): SanitizerConfig {
45
+ return {
46
+ a: {
47
+ href: true,
48
+ target: '_blank',
49
+ rel: 'nofollow',
50
+ },
51
+ } as SanitizerConfig;
52
+ }
53
+
54
+ /**
55
+ * Tailwind classes for input
56
+ */
57
+ private readonly INPUT_BASE_CLASSES = 'hidden w-full m-0 px-2 py-1 text-sm leading-[22px] font-medium bg-item-hover-bg border border-[rgba(226,226,229,0.2)] rounded-md outline-none box-border appearance-none font-[inherit] placeholder:text-gray-text mobile:text-[15px] mobile:font-medium';
58
+
59
+ /**
60
+ * Data attributes for e2e selectors
61
+ */
62
+ private readonly DATA_ATTRIBUTES = {
63
+ buttonActive: 'data-blok-link-tool-active',
64
+ buttonUnlink: 'data-blok-link-tool-unlink',
65
+ inputOpened: 'data-blok-link-tool-input-opened',
66
+ } as const;
67
+
68
+ /**
69
+ * Elements
70
+ */
71
+ private nodes: {
72
+ input: HTMLInputElement | null;
73
+ button: HTMLButtonElement | null;
74
+ } = {
75
+ input: null,
76
+ button: null,
77
+ };
78
+
79
+ /**
80
+ * SelectionUtils instance
81
+ */
82
+ private selection: SelectionUtils;
83
+
84
+ /**
85
+ * Input opening state
86
+ */
87
+ private inputOpened = false;
88
+
89
+ /**
90
+ * Tracks whether unlink action is available via toolbar button toggle
91
+ */
92
+ private unlinkAvailable = false;
93
+
94
+ /**
95
+ * Available Toolbar methods (open/close)
96
+ */
97
+ private toolbar: Toolbar;
98
+
99
+ /**
100
+ * Available inline toolbar methods (open/close)
101
+ */
102
+ private inlineToolbar: InlineToolbar;
103
+
104
+ /**
105
+ * Notifier API methods
106
+ */
107
+ private notifier: Notifier;
108
+
109
+ /**
110
+ * I18n API
111
+ */
112
+ private i18n: I18n;
113
+
114
+ /**
115
+ * @param api - Blok API
116
+ */
117
+ constructor({ api }: InlineToolConstructorOptions) {
118
+ this.toolbar = api.toolbar;
119
+ this.inlineToolbar = api.inlineToolbar;
120
+ this.notifier = api.notifier;
121
+ this.i18n = api.i18n;
122
+ this.selection = new SelectionUtils();
123
+ this.nodes.input = this.createInput();
124
+ }
125
+
126
+ /**
127
+ * Create button for Inline Toolbar
128
+ */
129
+ public render(): MenuConfig {
130
+ return {
131
+ icon: IconLink,
132
+ name: 'link',
133
+ isActive: () => !!this.selection.findParentTag('A'),
134
+ children: {
135
+ hideChevron: true,
136
+ items: [
137
+ {
138
+ type: PopoverItemType.Html,
139
+ element: this.nodes.input!,
140
+ },
141
+ ],
142
+ onOpen: () => {
143
+ this.openActions(true);
144
+ },
145
+ onClose: () => {
146
+ this.closeActions();
147
+ },
148
+ },
149
+ };
150
+ }
151
+
152
+ /**
153
+ * Input for the link
154
+ */
155
+ private createInput(): HTMLInputElement {
156
+ const input = document.createElement('input') as HTMLInputElement;
157
+
158
+ input.placeholder = this.i18n.t('tools.link.addLink');
159
+ input.enterKeyHint = 'done';
160
+ input.className = this.INPUT_BASE_CLASSES;
161
+ input.setAttribute('data-blok-testid', 'inline-tool-input');
162
+ this.setBooleanStateAttribute(input, this.DATA_ATTRIBUTES.inputOpened, false);
163
+ input.addEventListener('keydown', (event: KeyboardEvent) => {
164
+ if (event.key === 'Enter') {
165
+ this.enterPressed(event);
166
+ }
167
+ });
168
+
169
+ return input;
170
+ }
171
+
172
+ /**
173
+ * Shortcut for the link tool
174
+ */
175
+ public static shortcut = 'CMD+K';
176
+
177
+ /**
178
+ * @param {boolean} needFocus - on link creation we need to focus input. On editing - nope.
179
+ */
180
+ private openActions(needFocus = false): void {
181
+ if (!this.nodes.input) {
182
+ return;
183
+ }
184
+
185
+ const anchorTag = this.selection.findParentTag('A');
186
+
187
+ const hasAnchor = Boolean(anchorTag);
188
+
189
+ this.updateButtonStateAttributes(hasAnchor);
190
+ this.unlinkAvailable = hasAnchor;
191
+
192
+ if (anchorTag) {
193
+ /**
194
+ * Fill input value with link href
195
+ */
196
+ const hrefAttr = anchorTag.getAttribute('href');
197
+
198
+ this.nodes.input.value = hrefAttr !== null ? hrefAttr : '';
199
+ } else {
200
+ this.nodes.input.value = '';
201
+ }
202
+
203
+ this.nodes.input.className = twMerge(this.INPUT_BASE_CLASSES, 'block');
204
+ this.setBooleanStateAttribute(this.nodes.input, this.DATA_ATTRIBUTES.inputOpened, true);
205
+
206
+ /**
207
+ * Set fake background to visually indicate selection when focus moves to input
208
+ */
209
+ this.selection.setFakeBackground();
210
+ this.selection.save();
211
+
212
+ if (needFocus) {
213
+ this.focusInputWithRetry();
214
+ }
215
+ this.inputOpened = true;
216
+ }
217
+ /**
218
+ * Ensures the link input receives focus even if other listeners steal it
219
+ */
220
+ private focusInputWithRetry(): void {
221
+ if (!this.nodes.input) {
222
+ return;
223
+ }
224
+
225
+ this.nodes.input.focus();
226
+
227
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
228
+ return;
229
+ }
230
+
231
+ window.setTimeout(() => {
232
+ if (document.activeElement !== this.nodes.input) {
233
+ this.nodes.input?.focus();
234
+ }
235
+ }, 0);
236
+ }
237
+
238
+ /**
239
+ * Resolve the current inline toolbar button element
240
+ */
241
+ private getButtonElement(): HTMLButtonElement | null {
242
+ // Always query fresh to ensure we have the latest DOM element
243
+ const button = document.querySelector<HTMLButtonElement>(
244
+ `${createSelector(DATA_ATTR.interface, INLINE_TOOLBAR_INTERFACE_VALUE)} [data-blok-item-name="link"]`
245
+ );
246
+
247
+ // Only add click listener if this is a new button element
248
+ if (button && button !== this.nodes.button) {
249
+ button.addEventListener('click', this.handleButtonClick, true);
250
+ this.nodes.button = button;
251
+ }
252
+
253
+ return button;
254
+ }
255
+
256
+ /**
257
+ * Update button state attributes for e2e hooks
258
+ * @param hasAnchor - Optional override for anchor presence
259
+ */
260
+ private updateButtonStateAttributes(hasAnchor?: boolean): void {
261
+ const button = this.getButtonElement();
262
+
263
+ if (!button) {
264
+ return;
265
+ }
266
+
267
+ const anchorPresent = typeof hasAnchor === 'boolean' ? hasAnchor : Boolean(this.selection.findParentTag('A'));
268
+
269
+ this.setBooleanStateAttribute(button, this.DATA_ATTRIBUTES.buttonActive, anchorPresent);
270
+ this.setBooleanStateAttribute(button, this.DATA_ATTRIBUTES.buttonUnlink, anchorPresent);
271
+ }
272
+
273
+ /**
274
+ * Handles toggling the inline tool button while actions menu is open
275
+ * @param event - Click event emitted by the inline tool button
276
+ */
277
+ private handleButtonClick = (event: MouseEvent): void => {
278
+ if (!this.inputOpened || !this.unlinkAvailable) {
279
+ return;
280
+ }
281
+
282
+ event.preventDefault();
283
+ event.stopPropagation();
284
+ event.stopImmediatePropagation();
285
+
286
+ this.restoreSelection();
287
+ this.unlink();
288
+ this.inlineToolbar.close();
289
+ };
290
+
291
+
292
+ /**
293
+ * Close input
294
+ * @param {boolean} clearSavedSelection — we don't need to clear saved selection
295
+ * on toggle-clicks on the icon of opened Toolbar
296
+ */
297
+ private closeActions(clearSavedSelection = true): void {
298
+ const shouldRestoreSelection = this.selection.isFakeBackgroundEnabled ||
299
+ (clearSavedSelection && !!this.selection.savedSelectionRange);
300
+
301
+ if (shouldRestoreSelection) {
302
+ this.restoreSelection();
303
+ }
304
+
305
+ if (!this.nodes.input) {
306
+ return;
307
+ }
308
+ this.nodes.input.className = this.INPUT_BASE_CLASSES;
309
+ this.setBooleanStateAttribute(this.nodes.input, this.DATA_ATTRIBUTES.inputOpened, false);
310
+ this.nodes.input.value = '';
311
+ this.updateButtonStateAttributes(false);
312
+ this.unlinkAvailable = false;
313
+ if (clearSavedSelection) {
314
+ this.selection.clearSaved();
315
+ }
316
+ this.inputOpened = false;
317
+ }
318
+
319
+ /**
320
+ * Restore selection after closing actions
321
+ */
322
+ private restoreSelection(): void {
323
+ // if actions is broken by other selection We need to save new selection
324
+ const currentSelection = new SelectionUtils();
325
+ const isSelectionInBlok = SelectionUtils.isAtBlok;
326
+
327
+ if (isSelectionInBlok) {
328
+ currentSelection.save();
329
+ }
330
+
331
+ this.selection.removeFakeBackground();
332
+ this.selection.restore();
333
+
334
+ // and recover new selection after removing fake background
335
+ if (!isSelectionInBlok && this.selection.savedSelectionRange) {
336
+ const range = this.selection.savedSelectionRange;
337
+ const container = range.commonAncestorContainer;
338
+ const element = container.nodeType === Node.ELEMENT_NODE ? container as HTMLElement : container.parentElement;
339
+
340
+ element?.focus();
341
+ }
342
+
343
+ if (!isSelectionInBlok) {
344
+ return;
345
+ }
346
+
347
+ currentSelection.restore();
348
+
349
+ const range = currentSelection.savedSelectionRange;
350
+
351
+ if (range) {
352
+ const container = range.commonAncestorContainer;
353
+ const element = container.nodeType === Node.ELEMENT_NODE ? container as HTMLElement : container.parentElement;
354
+
355
+ element?.focus();
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Enter pressed on input
361
+ * @param {KeyboardEvent} event - enter keydown event
362
+ */
363
+ private enterPressed(event: KeyboardEvent): void {
364
+ if (!this.nodes.input) {
365
+ return;
366
+ }
367
+ const value = this.nodes.input.value || '';
368
+
369
+ if (!value.trim()) {
370
+ this.selection.restore();
371
+ this.unlink();
372
+ event.preventDefault();
373
+ this.closeActions();
374
+ // Explicitly close inline toolbar as well, similar to legacy behavior
375
+ this.inlineToolbar.close();
376
+
377
+ return;
378
+ }
379
+
380
+ if (!this.validateURL(value)) {
381
+ this.notifier.show({
382
+ message: this.i18n.t('tools.link.invalidLink'),
383
+ style: 'error',
384
+ });
385
+
386
+ log('Incorrect Link pasted', 'warn', value);
387
+
388
+ return;
389
+ }
390
+
391
+ const preparedValue = this.prepareLink(value);
392
+
393
+ this.selection.removeFakeBackground();
394
+ this.selection.restore();
395
+
396
+ this.insertLink(preparedValue);
397
+
398
+ /**
399
+ * Preventing events that will be able to happen
400
+ */
401
+ event.preventDefault();
402
+ event.stopPropagation();
403
+ event.stopImmediatePropagation();
404
+ this.selection.collapseToEnd();
405
+ this.inlineToolbar.close();
406
+ }
407
+
408
+ /**
409
+ * Detects if passed string is URL
410
+ * @param {string} str - string to validate
411
+ * @returns {boolean}
412
+ */
413
+ private validateURL(str: string): boolean {
414
+ /**
415
+ * Don't allow spaces
416
+ */
417
+ return !/\s/.test(str);
418
+ }
419
+
420
+ /**
421
+ * Process link before injection
422
+ * - sanitize
423
+ * - add protocol for links like 'google.com'
424
+ * @param {string} link - raw user input
425
+ */
426
+ private prepareLink(link: string): string {
427
+ return this.addProtocol(link.trim());
428
+ }
429
+
430
+ /**
431
+ * Add 'http' protocol to the links like 'vc.ru', 'google.com'
432
+ * @param {string} link - string to process
433
+ */
434
+ private addProtocol(link: string): string {
435
+ /**
436
+ * If protocol already exists, do nothing
437
+ */
438
+ if (/^(\w+):(\/\/)?/.test(link)) {
439
+ return link;
440
+ }
441
+
442
+ /**
443
+ * We need to add missed HTTP protocol to the link, but skip 2 cases:
444
+ * 1) Internal links like "/general"
445
+ * 2) Anchors looks like "#results"
446
+ * 3) Protocol-relative URLs like "//google.com"
447
+ */
448
+ const isInternal = /^\/[^/\s]/.test(link);
449
+ const isAnchor = link.substring(0, 1) === '#';
450
+ const isProtocolRelative = /^\/\/[^/\s]/.test(link);
451
+
452
+ if (!isInternal && !isAnchor && !isProtocolRelative) {
453
+ return 'http://' + link;
454
+ }
455
+
456
+ return link;
457
+ }
458
+
459
+ /**
460
+ * Inserts <a> tag with "href"
461
+ * @param {string} link - "href" value
462
+ */
463
+ private insertLink(link: string): void {
464
+ /**
465
+ * Edit all link, not selected part
466
+ */
467
+ const anchorTag = this.selection.findParentTag('A') as HTMLAnchorElement;
468
+
469
+ if (anchorTag) {
470
+ this.selection.expandToTag(anchorTag);
471
+
472
+ anchorTag.href = link;
473
+ anchorTag.target = '_blank';
474
+ anchorTag.rel = 'nofollow';
475
+
476
+ return;
477
+ }
478
+
479
+ const range = SelectionUtils.range;
480
+
481
+ if (!range) {
482
+ return;
483
+ }
484
+
485
+ const anchor = document.createElement('a');
486
+
487
+ anchor.href = link;
488
+ anchor.target = '_blank';
489
+ anchor.rel = 'nofollow';
490
+
491
+ anchor.appendChild(range.extractContents());
492
+
493
+ range.insertNode(anchor);
494
+
495
+ this.selection.expandToTag(anchor);
496
+ }
497
+
498
+ /**
499
+ * Removes <a> tag
500
+ */
501
+ private unlink(): void {
502
+ const anchorTag = this.selection.findParentTag('A');
503
+
504
+ if (anchorTag) {
505
+ this.unwrap(anchorTag);
506
+ this.updateButtonStateAttributes(false);
507
+ this.unlinkAvailable = false;
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Unwrap passed node
513
+ * @param term - node to unwrap
514
+ */
515
+ private unwrap(term: HTMLElement): void {
516
+ const docFrag = document.createDocumentFragment();
517
+
518
+ while (term.firstChild) {
519
+ docFrag.appendChild(term.firstChild);
520
+ }
521
+
522
+ term.parentNode?.replaceChild(docFrag, term);
523
+ }
524
+
525
+ /**
526
+ * Persist state as data attributes for testing hooks
527
+ * @param element - The HTML element to set the attribute on, or null
528
+ * @param attributeName - The name of the attribute to set
529
+ * @param state - The boolean state value to persist
530
+ */
531
+ private setBooleanStateAttribute(element: HTMLElement | null, attributeName: string, state: boolean): void {
532
+ if (!element) {
533
+ return;
534
+ }
535
+
536
+ element.setAttribute(attributeName, state ? 'true' : 'false');
537
+ }
538
+ };
539
+