@blokkli/editor 2.0.0-alpha.35 → 2.0.0-alpha.37

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 (320) hide show
  1. package/dist/global/types/blockOptions.d.ts +10 -2
  2. package/dist/global/types/definitions.d.ts +12 -5
  3. package/dist/module.d.mts +2 -2
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +126 -7
  6. package/dist/modules/agent/index.d.mts +1 -1
  7. package/dist/modules/agent/index.mjs +273 -25
  8. package/dist/modules/agent/runtime/app/composables/agentProvider.d.ts +2 -2
  9. package/dist/modules/agent/runtime/app/composables/agentProvider.js +34 -17
  10. package/dist/modules/agent/runtime/app/composables/defineBlokkliAgentTool.d.ts +2 -20
  11. package/dist/modules/agent/runtime/app/composables/defineBlokkliAgentTool.js +0 -3
  12. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/Assistant/index.vue +2 -2
  13. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/User/index.vue +1 -2
  14. package/dist/modules/agent/runtime/app/features/agent/Panel/DebugGallery/index.vue +1 -2
  15. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/Actions/index.d.vue.ts +1 -0
  16. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/Actions/index.vue +67 -86
  17. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/Actions/index.vue.d.ts +1 -0
  18. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/index.vue +10 -12
  19. package/dist/modules/agent/runtime/app/features/agent/Panel/Welcome/de.md +2 -2
  20. package/dist/modules/agent/runtime/app/features/agent/Panel/Welcome/en.md +2 -2
  21. package/dist/modules/agent/runtime/app/features/agent/Panel/index.vue +1 -5
  22. package/dist/modules/agent/runtime/app/features/agent/Transcript/index.d.vue.ts +8 -0
  23. package/dist/modules/agent/runtime/app/features/agent/Transcript/index.vue +138 -0
  24. package/dist/modules/agent/runtime/app/features/agent/Transcript/index.vue.d.ts +8 -0
  25. package/dist/modules/agent/runtime/app/features/agent/index.vue +94 -38
  26. package/dist/modules/agent/runtime/app/helpers/index.d.ts +16 -19
  27. package/dist/modules/agent/runtime/app/helpers/index.js +22 -46
  28. package/dist/modules/agent/runtime/app/helpers/pageStructure.js +1 -1
  29. package/dist/modules/agent/runtime/app/tools/add_content_search_paragraph/index.js +5 -9
  30. package/dist/modules/agent/runtime/app/tools/add_fragment/index.js +2 -6
  31. package/dist/modules/agent/runtime/app/tools/add_media_paragraph/index.js +2 -6
  32. package/dist/modules/agent/runtime/app/tools/add_paragraphs/index.js +2 -3
  33. package/dist/modules/agent/runtime/app/tools/add_reusable_paragraph/index.js +2 -6
  34. package/dist/modules/agent/runtime/app/tools/add_template/index.js +2 -6
  35. package/dist/modules/agent/runtime/app/tools/analyze_content/index.js +120 -0
  36. package/dist/modules/agent/runtime/app/tools/check_readability/index.d.ts +2 -0
  37. package/dist/modules/agent/runtime/app/tools/check_readability/index.js +57 -0
  38. package/dist/modules/agent/runtime/app/tools/duplicate_paragraphs/index.js +2 -6
  39. package/dist/modules/agent/runtime/app/tools/get_all_page_content/index.js +1 -1
  40. package/dist/modules/agent/runtime/app/tools/get_bundle_info/index.d.ts +2 -0
  41. package/dist/modules/agent/runtime/app/tools/get_bundle_info/index.js +176 -0
  42. package/dist/modules/agent/runtime/app/tools/get_content_fields/index.js +1 -1
  43. package/dist/modules/agent/runtime/app/tools/get_paragraph_context/index.js +7 -5
  44. package/dist/modules/agent/runtime/app/tools/get_paragraph_options/index.js +2 -1
  45. package/dist/modules/agent/runtime/app/tools/get_selected_paragraphs/index.js +2 -3
  46. package/dist/modules/agent/runtime/app/tools/helpers.d.ts +53 -0
  47. package/dist/modules/agent/runtime/app/tools/helpers.js +187 -0
  48. package/dist/modules/agent/runtime/app/tools/move_paragraphs/index.js +2 -6
  49. package/dist/modules/agent/runtime/app/tools/schemas.d.ts +1 -44
  50. package/dist/modules/agent/runtime/app/tools/schemas.js +0 -174
  51. package/dist/modules/agent/runtime/app/tools/search_content/index.js +40 -47
  52. package/dist/modules/agent/runtime/app/tools/set_paragraph_options/index.js +2 -5
  53. package/dist/modules/agent/runtime/app/types/index.d.ts +0 -61
  54. package/dist/modules/agent/runtime/server/Session.d.ts +29 -8
  55. package/dist/modules/agent/runtime/server/Session.js +168 -85
  56. package/dist/modules/agent/runtime/server/SessionManager.d.ts +3 -0
  57. package/dist/modules/agent/runtime/server/SessionManager.js +4 -1
  58. package/dist/modules/agent/runtime/server/agent.js +3 -2
  59. package/dist/modules/agent/runtime/server/agentPrompt.d.ts +9 -1
  60. package/dist/modules/agent/runtime/server/agentPrompt.js +26 -0
  61. package/dist/modules/agent/runtime/server/default-skills/fixReadability.d.ts +2 -0
  62. package/dist/modules/agent/runtime/server/default-skills/fixReadability.js +69 -0
  63. package/dist/modules/agent/runtime/server/default-system-prompts/page-context.js +28 -0
  64. package/dist/modules/agent/runtime/server/server-tools/index.d.ts +10 -2
  65. package/dist/modules/agent/runtime/server/server-tools/index.js +1 -1
  66. package/dist/modules/agent/runtime/server/server-tools/load_tools/index.js +1 -1
  67. package/dist/modules/agent/runtime/shared/types.d.ts +81 -12
  68. package/dist/modules/agent/runtime/shared/types.js +22 -10
  69. package/dist/modules/charts/index.d.mts +35 -0
  70. package/dist/modules/charts/index.mjs +57 -0
  71. package/dist/modules/charts/runtime/blokkli/skills/charts.d.ts +2 -0
  72. package/dist/modules/charts/runtime/blokkli/skills/charts.js +42 -0
  73. package/dist/modules/charts/runtime/blokkli/tools/chart_schemas.d.ts +86 -0
  74. package/dist/modules/charts/runtime/blokkli/tools/chart_schemas.js +136 -0
  75. package/dist/modules/charts/runtime/blokkli/tools/create_chart/index.d.ts +2 -0
  76. package/dist/modules/charts/runtime/blokkli/tools/create_chart/index.js +93 -0
  77. package/dist/modules/charts/runtime/blokkli/tools/get_chart_data/index.d.ts +2 -0
  78. package/dist/modules/charts/runtime/blokkli/tools/get_chart_data/index.js +66 -0
  79. package/dist/modules/charts/runtime/blokkli/tools/get_chart_type_options/index.d.ts +2 -0
  80. package/dist/modules/charts/runtime/blokkli/tools/get_chart_type_options/index.js +40 -0
  81. package/dist/modules/charts/runtime/blokkli/tools/update_chart/index.d.ts +2 -0
  82. package/dist/modules/charts/runtime/blokkli/tools/update_chart/index.js +89 -0
  83. package/dist/modules/charts/runtime/chartTypes/area.d.ts +7 -0
  84. package/dist/modules/charts/runtime/chartTypes/area.js +68 -0
  85. package/dist/modules/charts/runtime/chartTypes/bar.d.ts +8 -0
  86. package/dist/modules/charts/runtime/chartTypes/bar.js +76 -0
  87. package/dist/modules/charts/runtime/chartTypes/define.d.ts +2 -0
  88. package/dist/modules/charts/runtime/chartTypes/define.js +3 -0
  89. package/dist/modules/charts/runtime/chartTypes/donut.d.ts +6 -0
  90. package/dist/modules/charts/runtime/chartTypes/donut.js +45 -0
  91. package/dist/modules/charts/runtime/chartTypes/heatmap.d.ts +4 -0
  92. package/dist/modules/charts/runtime/chartTypes/heatmap.js +54 -0
  93. package/dist/modules/charts/runtime/chartTypes/index.d.ts +39 -0
  94. package/dist/modules/charts/runtime/chartTypes/index.js +47 -0
  95. package/dist/modules/charts/runtime/chartTypes/line.d.ts +7 -0
  96. package/dist/modules/charts/runtime/chartTypes/line.js +68 -0
  97. package/dist/modules/charts/runtime/chartTypes/pie.d.ts +5 -0
  98. package/dist/modules/charts/runtime/chartTypes/pie.js +28 -0
  99. package/dist/modules/charts/runtime/chartTypes/radar.d.ts +7 -0
  100. package/dist/modules/charts/runtime/chartTypes/radar.js +52 -0
  101. package/dist/modules/charts/runtime/chartTypes/radialBar.d.ts +6 -0
  102. package/dist/modules/charts/runtime/chartTypes/radialBar.js +44 -0
  103. package/dist/modules/charts/runtime/chartTypes/shared.d.ts +67 -0
  104. package/dist/modules/charts/runtime/chartTypes/shared.js +103 -0
  105. package/dist/modules/charts/runtime/chartTypes/types.d.ts +29 -0
  106. package/dist/modules/charts/runtime/chartTypes/types.js +0 -0
  107. package/dist/modules/charts/runtime/components/ChartRenderer/index.d.vue.ts +147 -0
  108. package/dist/modules/charts/runtime/components/ChartRenderer/index.vue +120 -0
  109. package/dist/modules/charts/runtime/components/ChartRenderer/index.vue.d.ts +147 -0
  110. package/dist/modules/charts/runtime/components/index.d.ts +1 -0
  111. package/dist/modules/charts/runtime/components/index.js +1 -0
  112. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypeOptions/index.d.vue.ts +16 -0
  113. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypeOptions/index.vue +97 -0
  114. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypeOptions/index.vue.d.ts +16 -0
  115. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypePicker/index.d.vue.ts +11 -0
  116. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypePicker/index.vue +34 -0
  117. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypePicker/index.vue.d.ts +11 -0
  118. package/dist/modules/charts/runtime/features/charts/Editor/ColorDropdown/index.d.vue.ts +12 -0
  119. package/dist/modules/charts/runtime/features/charts/Editor/ColorDropdown/index.vue +49 -0
  120. package/dist/modules/charts/runtime/features/charts/Editor/ColorDropdown/index.vue.d.ts +12 -0
  121. package/dist/modules/charts/runtime/features/charts/Editor/CsvImport/index.d.vue.ts +19 -0
  122. package/dist/modules/charts/runtime/features/charts/Editor/CsvImport/index.vue +89 -0
  123. package/dist/modules/charts/runtime/features/charts/Editor/CsvImport/index.vue.d.ts +19 -0
  124. package/dist/modules/charts/runtime/features/charts/Editor/DataTable/index.d.vue.ts +23 -0
  125. package/dist/modules/charts/runtime/features/charts/Editor/DataTable/index.vue +224 -0
  126. package/dist/modules/charts/runtime/features/charts/Editor/DataTable/index.vue.d.ts +23 -0
  127. package/dist/{runtime/editor/features/clipboard/List → modules/charts/runtime/features/charts/Editor/FootnoteEditor}/index.d.vue.ts +4 -5
  128. package/dist/modules/charts/runtime/features/charts/Editor/FootnoteEditor/index.vue +61 -0
  129. package/dist/{runtime/editor/features/clipboard/List → modules/charts/runtime/features/charts/Editor/FootnoteEditor}/index.vue.d.ts +4 -5
  130. package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.d.vue.ts +10 -0
  131. package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.vue +45 -0
  132. package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.vue.d.ts +10 -0
  133. package/dist/modules/charts/runtime/features/charts/Editor/index.d.vue.ts +11 -0
  134. package/dist/modules/charts/runtime/features/charts/Editor/index.vue +249 -0
  135. package/dist/modules/charts/runtime/features/charts/Editor/index.vue.d.ts +11 -0
  136. package/dist/modules/charts/runtime/features/charts/Editor/useChartEditorState.d.ts +17 -0
  137. package/dist/modules/charts/runtime/features/charts/Editor/useChartEditorState.js +90 -0
  138. package/dist/modules/charts/runtime/features/charts/index.d.vue.ts +3 -0
  139. package/dist/modules/charts/runtime/features/charts/index.vue +72 -0
  140. package/dist/modules/charts/runtime/features/charts/index.vue.d.ts +3 -0
  141. package/dist/modules/charts/runtime/helpers/index.d.ts +26 -0
  142. package/dist/modules/charts/runtime/helpers/index.js +80 -0
  143. package/dist/modules/charts/runtime/types.d.ts +33 -0
  144. package/dist/modules/charts/runtime/types.js +0 -0
  145. package/dist/modules/drupal/graphql/features/fragments.graphql +2 -0
  146. package/dist/modules/drupal/index.d.mts +1 -1
  147. package/dist/modules/drupal/runtime/adapter/index.d.ts +3 -1
  148. package/dist/modules/drupal/runtime/adapter/index.js +16 -12
  149. package/dist/modules/table-of-contents/index.d.mts +11 -0
  150. package/dist/modules/table-of-contents/index.mjs +24 -0
  151. package/dist/modules/table-of-contents/runtime/components/BlokkliTableOfContents/index.d.vue.ts +44 -0
  152. package/dist/modules/table-of-contents/runtime/components/BlokkliTableOfContents/index.vue +43 -0
  153. package/dist/modules/table-of-contents/runtime/components/BlokkliTableOfContents/index.vue.d.ts +44 -0
  154. package/dist/modules/table-of-contents/runtime/types/index.d.ts +4 -0
  155. package/dist/modules/table-of-contents/runtime/types/index.js +0 -0
  156. package/dist/runtime/components/Blocks/Fragment/index.vue +6 -2
  157. package/dist/runtime/components/BlokkliItem.vue +9 -4
  158. package/dist/runtime/components/BlokkliProvider.d.vue.ts +7 -0
  159. package/dist/runtime/components/BlokkliProvider.vue +7 -1
  160. package/dist/runtime/components/BlokkliProvider.vue.d.ts +7 -0
  161. package/dist/runtime/composables/defineBlokkli.js +1 -1
  162. package/dist/runtime/composables/useBlokkliHelper.js +4 -2
  163. package/dist/runtime/editor/components/AnimationCanvas/index.vue +17 -27
  164. package/dist/runtime/editor/components/Banner/index.d.vue.ts +13 -2
  165. package/dist/runtime/editor/components/Banner/index.vue +4 -2
  166. package/dist/runtime/editor/components/Banner/index.vue.d.ts +13 -2
  167. package/dist/runtime/editor/components/Dropdown/index.d.vue.ts +27 -0
  168. package/dist/runtime/editor/components/Dropdown/index.vue +107 -0
  169. package/dist/runtime/editor/components/Dropdown/index.vue.d.ts +27 -0
  170. package/dist/{modules/agent/runtime/app/features/agent/Panel/Input/Actions → runtime/editor/components}/DropdownItem/index.d.vue.ts +1 -0
  171. package/dist/{modules/agent/runtime/app/features/agent/Panel/Input/Actions → runtime/editor/components}/DropdownItem/index.vue +3 -2
  172. package/dist/{modules/agent/runtime/app/features/agent/Panel/Input/Actions → runtime/editor/components}/DropdownItem/index.vue.d.ts +1 -0
  173. package/dist/runtime/editor/components/EditProvider.d.vue.ts +2 -0
  174. package/dist/runtime/editor/components/EditProvider.vue +11 -7
  175. package/dist/runtime/editor/components/EditProvider.vue.d.ts +2 -0
  176. package/dist/runtime/editor/components/FlexTextarea/index.d.vue.ts +5 -1
  177. package/dist/runtime/editor/components/FlexTextarea/index.vue +24 -101
  178. package/dist/runtime/editor/components/FlexTextarea/index.vue.d.ts +5 -1
  179. package/dist/runtime/editor/components/Form/Radio/index.d.vue.ts +1 -0
  180. package/dist/runtime/editor/components/Form/Radio/index.vue +3 -2
  181. package/dist/runtime/editor/components/Form/Radio/index.vue.d.ts +1 -0
  182. package/dist/runtime/editor/components/ItemIcon/index.vue +10 -2
  183. package/dist/runtime/editor/components/NestedEditorOverlay/index.d.vue.ts +13 -3
  184. package/dist/runtime/editor/components/NestedEditorOverlay/index.vue +43 -16
  185. package/dist/runtime/editor/components/NestedEditorOverlay/index.vue.d.ts +13 -3
  186. package/dist/runtime/editor/components/Popup/index.d.vue.ts +30 -0
  187. package/dist/runtime/editor/components/Popup/index.vue +82 -0
  188. package/dist/runtime/editor/components/Popup/index.vue.d.ts +30 -0
  189. package/dist/runtime/editor/components/PreviewProvider.d.vue.ts +2 -0
  190. package/dist/runtime/editor/components/PreviewProvider.vue +3 -2
  191. package/dist/runtime/editor/components/PreviewProvider.vue.d.ts +2 -0
  192. package/dist/runtime/editor/components/Resizable/index.vue +4 -1
  193. package/dist/runtime/editor/components/ShortcutIndicator/index.vue +1 -1
  194. package/dist/runtime/editor/components/Toolbar/index.vue +107 -6
  195. package/dist/runtime/editor/components/index.d.ts +4 -1
  196. package/dist/runtime/editor/components/index.js +6 -0
  197. package/dist/runtime/editor/composables/defineDropAreas.js +3 -3
  198. package/dist/runtime/editor/composables/defineDropHandler.d.ts +3 -0
  199. package/dist/runtime/editor/composables/defineDropHandler.js +10 -0
  200. package/dist/runtime/editor/composables/index.d.ts +1 -0
  201. package/dist/runtime/editor/composables/index.js +1 -0
  202. package/dist/runtime/editor/composables/onElementResize.js +0 -1
  203. package/dist/runtime/editor/composables/useEditableFieldOverride.js +4 -5
  204. package/dist/runtime/editor/css/output.css +1 -1
  205. package/dist/runtime/editor/events/index.d.ts +16 -0
  206. package/dist/runtime/editor/features/add-list/Help/Item.vue +5 -2
  207. package/dist/runtime/editor/features/add-list/index.vue +58 -1
  208. package/dist/runtime/editor/features/analyze/Main.d.vue.ts +3 -2
  209. package/dist/runtime/editor/features/analyze/Main.vue +28 -44
  210. package/dist/runtime/editor/features/analyze/Main.vue.d.ts +3 -2
  211. package/dist/runtime/editor/features/analyze/analyzers/readability.js +65 -0
  212. package/dist/runtime/editor/features/analyze/analyzers/types.d.ts +19 -0
  213. package/dist/runtime/editor/features/analyze/index.vue +18 -15
  214. package/dist/runtime/editor/features/artboard/Renderer.vue +1 -1
  215. package/dist/runtime/editor/features/clipboard/DropElement/Video.d.vue.ts +8 -0
  216. package/dist/runtime/editor/features/clipboard/{List/Item → DropElement}/Video.vue +1 -5
  217. package/dist/runtime/editor/features/clipboard/DropElement/Video.vue.d.ts +8 -0
  218. package/dist/runtime/editor/features/clipboard/DropElement/helpers.d.ts +1 -0
  219. package/dist/runtime/editor/features/clipboard/DropElement/helpers.js +14 -0
  220. package/dist/runtime/editor/features/clipboard/DropElement/index.d.vue.ts +16 -0
  221. package/dist/runtime/editor/features/clipboard/DropElement/index.vue +97 -0
  222. package/dist/runtime/editor/features/clipboard/DropElement/index.vue.d.ts +16 -0
  223. package/dist/runtime/editor/features/clipboard/helpers.d.ts +15 -0
  224. package/dist/runtime/editor/features/clipboard/helpers.js +62 -0
  225. package/dist/runtime/editor/features/clipboard/index.vue +586 -338
  226. package/dist/runtime/editor/features/clipboard/types.d.ts +14 -2
  227. package/dist/runtime/editor/features/debug/index.vue +1 -1
  228. package/dist/runtime/editor/features/dev-mode/index.vue +86 -2
  229. package/dist/runtime/editor/features/dragging-overlay/DragItems/index.vue +17 -5
  230. package/dist/runtime/editor/features/dragging-overlay/Renderer/index.vue +2 -2
  231. package/dist/runtime/editor/features/dragging-overlay/index.vue +125 -219
  232. package/dist/runtime/editor/features/edit/index.vue +20 -0
  233. package/dist/runtime/editor/features/editable-field/Overlay/Plaintext/index.vue +4 -4
  234. package/dist/runtime/editor/features/editable-field/Overlay/index.vue +6 -0
  235. package/dist/runtime/editor/features/fragments/types.d.ts +1 -0
  236. package/dist/runtime/editor/features/hover/Renderer/index.vue +30 -3
  237. package/dist/runtime/editor/features/hover/index.vue +1 -1
  238. package/dist/runtime/editor/features/library/index.vue +14 -0
  239. package/dist/runtime/editor/features/media-library/index.vue +32 -1
  240. package/dist/runtime/editor/features/options/Form/Checkbox/index.d.vue.ts +2 -2
  241. package/dist/runtime/editor/features/options/Form/Checkbox/index.vue +3 -3
  242. package/dist/runtime/editor/features/options/Form/Checkbox/index.vue.d.ts +2 -2
  243. package/dist/runtime/editor/features/options/Form/Checkboxes/index.d.vue.ts +2 -2
  244. package/dist/runtime/editor/features/options/Form/Checkboxes/index.vue +5 -5
  245. package/dist/runtime/editor/features/options/Form/Checkboxes/index.vue.d.ts +2 -2
  246. package/dist/runtime/editor/features/options/Form/ComplexType/index.d.vue.ts +11 -0
  247. package/dist/runtime/editor/features/options/Form/ComplexType/index.vue +36 -0
  248. package/dist/runtime/editor/features/options/Form/ComplexType/index.vue.d.ts +11 -0
  249. package/dist/runtime/editor/features/options/Form/Item.d.vue.ts +5 -4
  250. package/dist/runtime/editor/features/options/Form/Item.vue +24 -50
  251. package/dist/runtime/editor/features/options/Form/Item.vue.d.ts +5 -4
  252. package/dist/runtime/editor/features/options/Form/Number/index.d.vue.ts +3 -3
  253. package/dist/runtime/editor/features/options/Form/Number/index.vue +7 -17
  254. package/dist/runtime/editor/features/options/Form/Number/index.vue.d.ts +3 -3
  255. package/dist/runtime/editor/features/options/Form/Range/index.d.vue.ts +2 -2
  256. package/dist/runtime/editor/features/options/Form/Range/index.vue +4 -4
  257. package/dist/runtime/editor/features/options/Form/Range/index.vue.d.ts +2 -2
  258. package/dist/runtime/editor/features/options/Form/index.vue +15 -5
  259. package/dist/runtime/editor/features/search/index.vue +25 -1
  260. package/dist/runtime/editor/features/selection/index.vue +2 -2
  261. package/dist/runtime/editor/features/structure/index.vue +25 -1
  262. package/dist/runtime/editor/features/tour/index.vue +22 -12
  263. package/dist/runtime/editor/features/transform/index.vue +1 -3
  264. package/dist/runtime/editor/helpers/clipboardData/index.d.ts +11 -0
  265. package/dist/runtime/editor/helpers/clipboardData/index.js +157 -0
  266. package/dist/runtime/editor/helpers/options/index.js +5 -0
  267. package/dist/runtime/editor/icons/svg/stars.svg +5 -1
  268. package/dist/runtime/editor/plugins/Sidebar/Detached/index.d.vue.ts +1 -1
  269. package/dist/runtime/editor/plugins/Sidebar/Detached/index.vue.d.ts +1 -1
  270. package/dist/runtime/editor/plugins/Sidebar/index.d.vue.ts +15 -4
  271. package/dist/runtime/editor/plugins/Sidebar/index.vue +4 -2
  272. package/dist/runtime/editor/plugins/Sidebar/index.vue.d.ts +15 -4
  273. package/dist/runtime/editor/providers/analyze.d.ts +43 -0
  274. package/dist/runtime/editor/providers/analyze.js +78 -0
  275. package/dist/runtime/editor/providers/animation.d.ts +4 -0
  276. package/dist/runtime/editor/providers/animation.js +6 -0
  277. package/dist/runtime/editor/providers/definition.d.ts +2 -2
  278. package/dist/runtime/editor/providers/definition.js +7 -1
  279. package/dist/runtime/editor/providers/dom.d.ts +5 -0
  280. package/dist/runtime/editor/providers/dom.js +11 -2
  281. package/dist/runtime/editor/providers/dragdrop.d.ts +55 -0
  282. package/dist/runtime/editor/providers/dragdrop.js +37 -0
  283. package/dist/runtime/editor/providers/fields.d.ts +19 -1
  284. package/dist/runtime/editor/providers/fields.js +54 -2
  285. package/dist/runtime/editor/providers/storage.js +15 -0
  286. package/dist/runtime/editor/providers/ui.d.ts +6 -0
  287. package/dist/runtime/editor/providers/ui.js +19 -0
  288. package/dist/runtime/editor/translations/de.json +338 -58
  289. package/dist/runtime/editor/translations/fr.json +331 -51
  290. package/dist/runtime/editor/translations/gsw_CH.json +336 -56
  291. package/dist/runtime/editor/translations/it.json +331 -51
  292. package/dist/runtime/editor/types/app.d.ts +4 -2
  293. package/dist/runtime/editor/types/draggable.d.ts +1 -0
  294. package/dist/runtime/editor/types/ui.d.ts +1 -1
  295. package/dist/runtime/helpers/imports/index.d.ts +8 -1
  296. package/dist/runtime/helpers/imports/index.js +15 -6
  297. package/dist/runtime/helpers/injections.d.ts +6 -2
  298. package/dist/runtime/helpers/injections.js +3 -0
  299. package/dist/runtime/helpers/runtimeHelpers/index.js +14 -0
  300. package/dist/runtime/types/blockOptions.d.ts +2 -1
  301. package/dist/runtime/types/definitions.d.ts +12 -5
  302. package/dist/runtime/types/provider.d.ts +2 -0
  303. package/dist/shared/editor.6D5vApr0.mjs +30 -0
  304. package/dist/shared/{editor.DMFfaLVE.mjs → editor.BFIzNSQM.mjs} +1 -30
  305. package/dist/shared/{editor.Iax3GCvt.d.mts → editor.BdBm1Z7C.d.mts} +34 -0
  306. package/dist/types.d.mts +1 -1
  307. package/package.json +21 -3
  308. package/dist/modules/agent/runtime/app/tools/get_available_bundles/index.js +0 -104
  309. package/dist/runtime/editor/features/clipboard/List/Item/File.d.vue.ts +0 -4
  310. package/dist/runtime/editor/features/clipboard/List/Item/File.vue +0 -60
  311. package/dist/runtime/editor/features/clipboard/List/Item/File.vue.d.ts +0 -4
  312. package/dist/runtime/editor/features/clipboard/List/Item/Video.d.vue.ts +0 -4
  313. package/dist/runtime/editor/features/clipboard/List/Item/Video.vue.d.ts +0 -4
  314. package/dist/runtime/editor/features/clipboard/List/index.vue +0 -72
  315. package/dist/runtime/editor/features/tour/Popup/index.d.vue.ts +0 -9
  316. package/dist/runtime/editor/features/tour/Popup/index.vue +0 -34
  317. package/dist/runtime/editor/features/tour/Popup/index.vue.d.ts +0 -9
  318. package/dist/runtime/editor/providers/dropArea.d.ts +0 -48
  319. package/dist/runtime/editor/providers/dropArea.js +0 -22
  320. /package/dist/modules/agent/runtime/app/tools/{get_available_bundles → analyze_content}/index.d.ts +0 -0
@@ -1,68 +1,13 @@
1
1
  <template>
2
- <PluginSidebar
3
- v-if="adapter.addBlockFromClipboardItem"
4
- id="clipboard"
5
- ref="plugin"
6
- :title="$t('clipboard', 'Clipboard')"
7
- :tour-text="
8
- $t(
9
- 'clipboardTourText',
10
- 'Drag and drop content pasted from your clipboard into the page to create a matching block.'
11
- )
12
- "
13
- edit-only
14
- icon="bk_mdi_content_paste"
15
- weight="-30"
16
- >
17
- <div class="bk bk-clipboard bk-control">
18
- <div
19
- v-if="!pastedItems.length"
20
- class="bk-clipboard-info bk-sidebar-padding"
21
- >
22
- <h4>{{ $t("clipboardEmpty", "No items in the clipboard") }}</h4>
23
- <div
24
- v-if="!ui.isMobile.value"
25
- v-html="
26
- $t(
27
- 'clipboardExplanation',
28
- `<p>
29
- Use Ctrl-V on the page to paste content. These
30
- will then be displayed here.
31
- </p>
32
- <p>
33
- Use Ctrl-F to search for existing content and paste it into
34
- the clipboard.
35
- </p>`
36
- )
37
- "
38
- />
39
- </div>
40
- <ClipboardList
41
- v-if="pastedItems.length"
42
- :items="pastedItems"
43
- @remove="remove"
2
+ <Teleport :to="ui.mainLayoutElement.value">
3
+ <div class="bk-clipboard-drop-element-wrapper">
4
+ <DropElement
5
+ ref="dropElementRef"
6
+ :bundles="directDropBundles"
7
+ :items="dropItems"
44
8
  />
45
- <div class="bk-clipboard-form bk-sidebar-padding">
46
- <div class="bk-clipboard-input">
47
- <input
48
- type="text"
49
- class="bk-form-input"
50
- :placeholder="
51
- $t('clipboardPastePlaceholder', 'Paste text or media here')
52
- "
53
- @paste.stop.prevent="onManualPaste"
54
- @keydown.stop
55
- />
56
- </div>
57
- <div class="bk-clipboard-upload">
58
- <input type="file" @change="onFileInput" />
59
- <div class="bk-button bk-is-primary">
60
- <Icon name="bk_mdi_upload" />
61
- </div>
62
- </div>
63
- </div>
64
9
  </div>
65
- </PluginSidebar>
10
+ </Teleport>
66
11
  </template>
67
12
 
68
13
  <script setup>
@@ -75,38 +20,200 @@ import {
75
20
  computed,
76
21
  useTemplateRef
77
22
  } from "#imports";
78
- import { PluginSidebar } from "#blokkli/editor/plugins";
79
- import ClipboardList from "./List/index.vue";
80
23
  import { falsy, getFieldKey } from "#blokkli/helpers";
81
24
  import { generateUUID } from "#blokkli/editor/helpers/uuid";
82
- import { Icon } from "#blokkli/editor/components";
83
25
  import getVideoId from "get-video-id";
26
+ import DropElement, {} from "./DropElement/index.vue";
84
27
  import { emitMessage } from "#blokkli/editor/events";
85
28
  import { fragmentBlockBundle, itemEntityType } from "#blokkli-build/config";
86
29
  import {
30
+ defineDropHandler,
87
31
  defineItemDropdownAction,
88
32
  defineShortcut,
89
33
  onBlokkliEvent
90
34
  } from "#blokkli/editor/composables";
91
- const { settings, logger } = defineBlokkliFeature({
35
+ import { buildMapBundleEvent, sanitizeHtml } from "./helpers";
36
+ const { logger } = defineBlokkliFeature({
92
37
  id: "clipboard",
93
38
  label: "Clipboard",
94
39
  icon: "bk_mdi_content_paste",
95
40
  description: "Provides clipboard integration to copy/paste existing blocks or paste supported clipboard content like text or images.",
96
- settings: {
97
- openSidebarOnPaste: {
98
- type: "checkbox",
99
- default: true,
100
- label: "Open sidebar when pasting",
101
- description: "Automatically opens the sidebar when pasting content from the clipboard.",
102
- group: "behavior"
103
- }
104
- },
105
41
  screenshot: "feature-clipboard.jpg"
106
42
  });
107
- const { selection, $t, adapter, state, ui, types, keyboard, blocks, fields } = useBlokkli();
108
- const plugin = useTemplateRef("plugin");
43
+ const {
44
+ selection,
45
+ $t,
46
+ adapter,
47
+ state,
48
+ ui,
49
+ types,
50
+ keyboard,
51
+ blocks,
52
+ fields,
53
+ eventBus,
54
+ animation
55
+ } = useBlokkli();
109
56
  const selectionClipboard = ref([]);
57
+ const isDirectDrop = ref(false);
58
+ const directDropBundles = ref([]);
59
+ const dropItems = ref([]);
60
+ const dropElementRef = useTemplateRef("dropElementRef");
61
+ let dragCounter = 0;
62
+ let nativeDropItem = null;
63
+ function positionDropElement(x, y) {
64
+ const el = dropElementRef.value?.$el;
65
+ const wrapper = el?.parentElement;
66
+ if (wrapper && el) {
67
+ const w = el.offsetWidth;
68
+ const h = el.offsetHeight;
69
+ wrapper.style.left = x - w / 2 + "px";
70
+ wrapper.style.top = y - h / 2 + "px";
71
+ }
72
+ }
73
+ function normalizeBundles(result) {
74
+ if (!result) return null;
75
+ return Array.isArray(result) ? result : [result];
76
+ }
77
+ function startClipboardDrag(item, bundles, allItems) {
78
+ if (!adapter.clipboardMapBundle || !adapter.addBlockFromClipboardItem || state.editMode.value !== "editing" || !dropElementRef.value) {
79
+ return;
80
+ }
81
+ const itemBundles = bundles || [item.itemBundle];
82
+ if (!itemBundles.length) {
83
+ return;
84
+ }
85
+ const items = allItems || [item];
86
+ directDropBundles.value = itemBundles;
87
+ dropItems.value = items.map((v) => ({
88
+ type: v.type,
89
+ data: v.data,
90
+ fileName: "fileName" in v ? v.fileName : void 0,
91
+ fileSize: "fileSize" in v ? v.fileSize : void 0,
92
+ videoId: "videoId" in v ? v.videoId : void 0,
93
+ videoService: "videoService" in v ? v.videoService : void 0
94
+ }));
95
+ const coords = animation.getMouseCoords();
96
+ positionDropElement(coords.x, coords.y);
97
+ const el = dropElementRef.value.$el;
98
+ nativeDropItem = {
99
+ itemType: "native_drop",
100
+ itemBundles,
101
+ dataTransfer: null,
102
+ clipboardItems: allItems || [item],
103
+ element: () => el
104
+ };
105
+ isDirectDrop.value = true;
106
+ eventBus.emit("dragging:start", {
107
+ items: [nativeDropItem],
108
+ coords,
109
+ mode: "mouse"
110
+ });
111
+ }
112
+ function tryStartDirectDrop(e) {
113
+ if (!adapter.clipboardMapBundle || !adapter.addBlockFromClipboardItem || state.editMode.value !== "editing" || !dropElementRef.value) {
114
+ return false;
115
+ }
116
+ const mapEvent = buildMapBundleEvent(e);
117
+ if (!mapEvent) {
118
+ return false;
119
+ }
120
+ const bundles = normalizeBundles(adapter.clipboardMapBundle(mapEvent));
121
+ if (!bundles) {
122
+ return false;
123
+ }
124
+ const itemType = mapEvent.type === "plaintext" ? "text" : mapEvent.type;
125
+ const fileCount = mapEvent.fileCount || 1;
126
+ directDropBundles.value = bundles;
127
+ dropItems.value = Array.from({ length: fileCount }, () => ({
128
+ type: itemType,
129
+ fileName: mapEvent.fileName
130
+ }));
131
+ positionDropElement(e.clientX, e.clientY);
132
+ const el = dropElementRef.value.$el;
133
+ nativeDropItem = {
134
+ itemType: "native_drop",
135
+ itemBundles: bundles,
136
+ dataTransfer: null,
137
+ element: () => el
138
+ };
139
+ isDirectDrop.value = true;
140
+ eventBus.emit("dragging:start", {
141
+ items: [nativeDropItem],
142
+ coords: { x: e.clientX, y: e.clientY },
143
+ mode: "mouse"
144
+ });
145
+ return true;
146
+ }
147
+ function resetDrag() {
148
+ dragCounter = 0;
149
+ isDragFromInput = false;
150
+ if (isDirectDrop.value) {
151
+ eventBus.emit("dragging:end");
152
+ isDirectDrop.value = false;
153
+ nativeDropItem = null;
154
+ directDropBundles.value = [];
155
+ dropItems.value = [];
156
+ }
157
+ }
158
+ let isDragFromInput = false;
159
+ function onDragStart(e) {
160
+ const target = e.target;
161
+ if (target instanceof HTMLTextAreaElement || target instanceof HTMLInputElement || target instanceof HTMLElement && target.isContentEditable) {
162
+ isDragFromInput = true;
163
+ }
164
+ }
165
+ function onDragEnter(e) {
166
+ if (isDragFromInput) {
167
+ return;
168
+ }
169
+ dragCounter++;
170
+ if (dragCounter === 1) {
171
+ tryStartDirectDrop(e);
172
+ }
173
+ }
174
+ function onDragLeave() {
175
+ if (isDragFromInput) {
176
+ return;
177
+ }
178
+ dragCounter--;
179
+ if (dragCounter <= 0) {
180
+ resetDrag();
181
+ }
182
+ }
183
+ function onDragOver(e) {
184
+ e.preventDefault();
185
+ if (isDirectDrop.value) {
186
+ eventBus.emit("dragging:move", { x: e.clientX, y: e.clientY });
187
+ }
188
+ }
189
+ function onNativeDrop(e) {
190
+ e.preventDefault();
191
+ if (isDragFromInput) {
192
+ isDragFromInput = false;
193
+ return;
194
+ }
195
+ if (isDirectDrop.value && nativeDropItem && e.dataTransfer) {
196
+ nativeDropItem.dataTransfer = e.dataTransfer;
197
+ eventBus.emit("mouse:up", {
198
+ type: "mouse",
199
+ x: e.clientX,
200
+ y: e.clientY,
201
+ distance: 100,
202
+ duration: 1e3
203
+ });
204
+ eventBus.emit("dragging:end");
205
+ dragCounter = 0;
206
+ isDirectDrop.value = false;
207
+ nativeDropItem = null;
208
+ directDropBundles.value = [];
209
+ dropItems.value = [];
210
+ return;
211
+ }
212
+ resetDrag();
213
+ if (e.dataTransfer) {
214
+ onDropFallback(e.dataTransfer);
215
+ }
216
+ }
110
217
  const itemDropdownItems = computed(() => {
111
218
  return [
112
219
  {
@@ -134,160 +241,125 @@ function onSelectDropdownItem(item) {
134
241
  handleSelectionPaste(selectionClipboard.value);
135
242
  }
136
243
  }
137
- const ALLOWED_HTML_ATTRIBUTES = ["href"];
138
- const _MOCK = [
139
- {
140
- type: "text",
141
- id: generateUUID(),
142
- itemBundle: "text",
143
- data: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
144
- },
145
- {
146
- type: "file",
147
- id: generateUUID(),
148
- itemBundle: "image",
149
- data: "asdfasdf",
150
- additional: "asdfasdfasdf",
151
- fileName: "my-little-document.pdf",
152
- fileSize: 26624,
153
- fileType: "application/pdf"
154
- },
155
- {
156
- type: "file",
157
- id: generateUUID(),
158
- itemBundle: "image",
159
- data: "asdfasdf",
160
- additional: "asdfasdfasdf",
161
- fileName: "my-little-document.pdf",
162
- fileSize: 36623,
163
- fileType: "application/pdf"
164
- },
165
- {
166
- type: "video",
167
- id: generateUUID(),
168
- itemBundle: "video",
169
- data: "https://vimeo.com/53520224",
170
- videoService: "vimeo",
171
- videoId: "53520224"
172
- },
173
- {
174
- type: "video",
175
- id: generateUUID(),
176
- itemBundle: "video",
177
- data: "https://www.youtube.com/watch?v=zsvYVVRAk0c",
178
- videoService: "youtube",
179
- videoId: "zsvYVVRAk0c"
180
- }
181
- ];
182
- const pastedItems = ref([]);
183
- const onFileInput = (e) => {
184
- e.preventDefault();
185
- if (e.target instanceof HTMLInputElement) {
186
- const files = e.target.files;
187
- if (files) {
188
- handleFiles(files);
189
- }
190
- }
191
- };
192
- function removeAllAttrs(element) {
193
- for (let i = element.attributes.length; i-- > 0; ) {
194
- const attribute = element.attributes[i];
195
- if (!ALLOWED_HTML_ATTRIBUTES.includes(attribute.name)) {
196
- element.removeAttributeNode(attribute);
197
- }
198
- }
244
+ function readFileAsDataURL(file) {
245
+ return new Promise((resolve, reject) => {
246
+ const fr = new FileReader();
247
+ fr.onload = () => {
248
+ if (typeof fr.result === "string") {
249
+ resolve(fr.result);
250
+ } else {
251
+ reject(new Error("FileReader result is not a string"));
252
+ }
253
+ };
254
+ fr.onerror = () => reject(fr.error);
255
+ fr.readAsDataURL(file);
256
+ });
199
257
  }
200
- function removeAttributes(el) {
201
- if (el.tagName === "IMG" || el.tagName === "BR") {
202
- el.remove();
258
+ async function handleFiles(data) {
259
+ if (!FileReader || !adapter.clipboardMapBundle) {
203
260
  return;
204
261
  }
205
- const children = el.children;
206
- for (let i = 0; i < children.length; i++) {
207
- const child = children[i];
208
- removeAllAttrs(child);
209
- if (child.children.length) {
210
- removeAttributes(child);
211
- }
212
- }
213
- }
214
- const onManualPaste = (e) => {
215
- onPaste(e, true);
216
- };
217
- function handleFiles(data) {
218
- if (!FileReader) {
262
+ const files = data instanceof DataTransfer ? [...data.files] : [...data];
263
+ if (!files.length) {
219
264
  return;
220
265
  }
221
- const files = data instanceof DataTransfer ? [...data.files] : [...data];
222
- files.forEach((file) => {
223
- const fr = new FileReader();
224
- fr.onload = function() {
225
- if (!adapter.clipboardMapBundle) {
226
- return;
227
- }
228
- if (typeof fr.result !== "string") {
229
- return;
230
- }
231
- const type = file.type.startsWith("image/") ? "image" : "file";
232
- const itemBundle = adapter.clipboardMapBundle({
266
+ let commonBundles = null;
267
+ for (const file of files) {
268
+ const type = file.type.startsWith("image/") ? "image" : "file";
269
+ const fileBundles = normalizeBundles(
270
+ adapter.clipboardMapBundle({
233
271
  type,
234
272
  fileType: file.type,
235
273
  fileSize: file.size
236
- });
237
- if (!itemBundle) {
238
- return;
239
- }
240
- pastedItems.value.push({
241
- type,
242
- itemBundle,
243
- id: generateUUID(),
244
- data: fr.result,
245
- additional: file.name,
246
- fileSize: file.size,
247
- fileType: file.type,
248
- fileName: file.name
249
- });
250
- showClipboardSidebar();
251
- };
252
- fr.readAsDataURL(file);
253
- });
254
- }
255
- function onDrop(e) {
256
- e.preventDefault();
257
- if (e.dataTransfer?.files.length) {
258
- handleFiles(e.dataTransfer);
274
+ })
275
+ );
276
+ if (!fileBundles) {
277
+ emitPasteError(
278
+ $t("clipboardUnsupportedFileType", "This file type is not supported.")
279
+ );
280
+ return;
281
+ }
282
+ if (commonBundles === null) {
283
+ commonBundles = fileBundles;
284
+ } else {
285
+ commonBundles = commonBundles.filter((b) => fileBundles.includes(b));
286
+ }
259
287
  }
288
+ if (!commonBundles || !commonBundles.length) {
289
+ emitPasteError(
290
+ $t("clipboardNoCommonBundle", "No common block type for these files.")
291
+ );
292
+ return;
293
+ }
294
+ let results;
295
+ try {
296
+ results = await Promise.all(files.map(readFileAsDataURL));
297
+ } catch {
298
+ return;
299
+ }
300
+ const items = [];
301
+ for (let i = 0; i < files.length; i++) {
302
+ const file = files[i];
303
+ const result = results[i];
304
+ const type = file.type.startsWith("image/") ? "image" : "file";
305
+ items.push({
306
+ type,
307
+ itemBundle: commonBundles[0],
308
+ id: generateUUID(),
309
+ data: result,
310
+ additional: file.name,
311
+ fileSize: file.size,
312
+ fileType: file.type,
313
+ fileName: file.name
314
+ });
315
+ }
316
+ startClipboardDrag(items[0], commonBundles, items);
260
317
  }
261
- function onDragOver(e) {
262
- e.preventDefault();
263
- }
264
- const showClipboardSidebar = () => {
265
- if (settings.value.openSidebarOnPaste) {
266
- plugin?.value?.showSidebar();
318
+ function onDropFallback(data) {
319
+ if (data.files.length) {
320
+ handleFiles(data);
321
+ } else {
322
+ const text = data.getData("text/html") || data.getData("text/plain") || data.getData("text");
323
+ if (text) {
324
+ handlePastedText(text);
325
+ }
267
326
  }
268
- };
327
+ }
269
328
  function emitPasteError(message) {
270
329
  const prefix = $t("clipboardPasteError", "Failed to paste:");
271
330
  emitMessage(`${prefix} ${message}`, "error");
272
331
  }
332
+ function startCopyDrag(existingBlocks) {
333
+ const items = existingBlocks.map((block) => ({
334
+ itemType: "existing",
335
+ block,
336
+ isCopy: true
337
+ }));
338
+ const coords = animation.getMouseCoords();
339
+ eventBus.emit("dragging:start", {
340
+ items,
341
+ coords,
342
+ mode: "mouse"
343
+ });
344
+ }
273
345
  const handleSelectionPaste = (pastedUuids) => {
274
346
  if (!adapter.pasteExistingBlocks) {
275
347
  return;
276
348
  }
277
- if (selection.uuids.value.length !== 1) {
278
- emitPasteError(
279
- $t(
280
- "clipboardPasteErrorOneField",
281
- "Pasting is only possible into one field at a time."
282
- )
283
- );
349
+ if (!pastedUuids.length) {
284
350
  return;
285
351
  }
286
- if (!pastedUuids.length) {
352
+ const existingBlocks = pastedUuids.map((uuid) => blocks.getBlock(uuid)).filter((block2) => !!block2);
353
+ if (!existingBlocks.length) {
354
+ return;
355
+ }
356
+ if (selection.uuids.value.length !== 1) {
357
+ startCopyDrag(existingBlocks);
287
358
  return;
288
359
  }
289
360
  const block = selection.items.value[0];
290
361
  if (!block) {
362
+ startCopyDrag(existingBlocks);
291
363
  return;
292
364
  }
293
365
  let targetField = null;
@@ -295,11 +367,10 @@ const handleSelectionPaste = (pastedUuids) => {
295
367
  let targetFieldKey = null;
296
368
  let preceedingUuid = null;
297
369
  if (!keyboard.isPressingShift.value) {
298
- const pastedBundles = pastedUuids.map((uuid) => blocks.getBlock(uuid)?.bundle).filter((bundle) => !!bundle);
299
- const pastedFragments = pastedUuids.map((uuid) => {
300
- const block2 = blocks.getBlock(uuid);
301
- if (block2?.bundle === fragmentBlockBundle && block2.fragment?.name) {
302
- return block2.fragment.name;
370
+ const pastedBundles = existingBlocks.map((b) => b.bundle).filter((bundle) => !!bundle);
371
+ const pastedFragments = existingBlocks.map((b) => {
372
+ if (b.bundle === fragmentBlockBundle && b.fragment?.name) {
373
+ return b.fragment.name;
303
374
  }
304
375
  return null;
305
376
  }).filter(falsy);
@@ -342,83 +413,40 @@ const handleSelectionPaste = (pastedUuids) => {
342
413
  }
343
414
  if (!targetField || !targetFieldElement || !targetFieldKey) {
344
415
  const field = state.getMutatedField(block.host.uuid, block.host.fieldName);
345
- if (!field) {
346
- return;
347
- }
348
- const fieldElement = fields.find(field.entityUuid, field.name);
349
- if (!fieldElement) {
350
- return;
351
- }
352
- targetField = {
353
- entityType: field.entityType,
354
- entityUuid: field.entityUuid,
355
- name: field.name
356
- };
357
- targetFieldElement = fieldElement;
358
- targetFieldKey = getFieldKey(field.entityUuid, field.name);
359
- preceedingUuid = selection.uuids.value[0] ?? null;
360
- }
361
- const pastedBlocks = [];
362
- const notAllowedBundles = [];
363
- const notAllowedFragments = [];
364
- for (let i = 0; i < pastedUuids.length; i++) {
365
- const uuid = pastedUuids[i];
366
- if (!uuid) {
367
- continue;
368
- }
369
- const block2 = blocks.getBlock(uuid);
370
- if (!block2) {
371
- continue;
372
- }
373
- const isAllowed = targetFieldElement.allowedBundles.includes(block2.bundle);
374
- if (!isAllowed) {
375
- notAllowedBundles.push(block2.bundle);
376
- continue;
377
- }
378
- if (block2.bundle === fragmentBlockBundle && block2.fragment?.name && targetFieldElement.allowedFragments.length > 0) {
379
- const fragmentAllowed = targetFieldElement.allowedFragments.includes(
380
- block2.fragment.name
381
- );
382
- if (!fragmentAllowed) {
383
- notAllowedFragments.push(block2.fragment.name);
384
- continue;
416
+ if (field) {
417
+ const fieldElement = fields.find(field.entityUuid, field.name);
418
+ if (fieldElement) {
419
+ targetField = {
420
+ entityType: field.entityType,
421
+ entityUuid: field.entityUuid,
422
+ name: field.name
423
+ };
424
+ targetFieldElement = fieldElement;
425
+ targetFieldKey = getFieldKey(field.entityUuid, field.name);
426
+ preceedingUuid = selection.uuids.value[0] ?? null;
385
427
  }
386
428
  }
387
- pastedBlocks.push(block2);
388
429
  }
389
- if (!pastedBlocks.length) {
390
- if (notAllowedFragments.length) {
391
- const message2 = notAllowedFragments.length === 1 ? $t(
392
- "clipboardPasteErrorAllowedFragmentsSingle",
393
- 'Fragment "@types" is not allowed here.'
394
- ) : $t(
395
- "clipboardPasteErrorAllowedFragmentsMultiple",
396
- "Fragments (@types) are not allowed here."
397
- );
398
- emitPasteError(message2.replace("@types", notAllowedFragments.join(", ")));
399
- return;
430
+ if (!targetField || !targetFieldElement || !targetFieldKey) {
431
+ startCopyDrag(existingBlocks);
432
+ return;
433
+ }
434
+ const pastedBlocks = existingBlocks.filter((b) => {
435
+ if (!targetFieldElement.allowedBundles.includes(b.bundle)) {
436
+ return false;
400
437
  }
401
- const blockTypes = notAllowedBundles.map((bundle) => {
402
- return types.getBlockBundleDefinition(bundle)?.label ?? bundle;
403
- });
404
- const message = blockTypes.length === 1 ? $t(
405
- "clipboardPasteErrorAllowedBundlesSingle",
406
- 'Block type "@types" is not allowed here.'
407
- ) : $t(
408
- "clipboardPasteErrorAllowedBundlesMultiple",
409
- "Block types (@types) are not allowed here."
410
- );
411
- emitPasteError(message.replace("@types", blockTypes.join(", ")));
438
+ if (b.bundle === fragmentBlockBundle && b.fragment?.name && targetFieldElement.allowedFragments.length > 0) {
439
+ return targetFieldElement.allowedFragments.includes(b.fragment.name);
440
+ }
441
+ return true;
442
+ });
443
+ if (!pastedBlocks.length) {
444
+ startCopyDrag(existingBlocks);
412
445
  return;
413
446
  }
414
447
  const count = state.getFieldBlockCount(targetFieldKey);
415
448
  if (targetFieldElement.cardinality !== -1 && count + pastedBlocks.length > targetFieldElement.cardinality) {
416
- emitPasteError(
417
- $t(
418
- "clipboardPasteErrorCardinality",
419
- "This field only allows up to @count blocks."
420
- ).replace("@count", targetFieldElement.cardinality.toString())
421
- );
449
+ startCopyDrag(existingBlocks);
422
450
  return;
423
451
  }
424
452
  state.mutateWithLoadingState(
@@ -433,23 +461,26 @@ const handleSelectionPaste = (pastedUuids) => {
433
461
  })
434
462
  );
435
463
  };
436
- function onPaste(e, fromInput) {
464
+ function onPaste(e) {
437
465
  logger.log("Paste Event", e);
438
466
  if (state.editMode.value !== "editing") {
439
467
  return;
440
468
  }
441
- if (!fromInput && (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement)) {
469
+ if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
442
470
  return;
443
471
  }
444
472
  e.stopPropagation();
445
473
  e.preventDefault();
446
- if (state.isLoading.value) {
474
+ if (state.isLoading.value || selection.isDragging.value) {
447
475
  return;
448
476
  }
449
477
  const clipboardData = e.clipboardData;
450
478
  if (!clipboardData) {
451
479
  return;
452
480
  }
481
+ if (clipboardData.files.length) {
482
+ return handleFiles(clipboardData);
483
+ }
453
484
  const pastedData = clipboardData.getData("text/html") || clipboardData.getData("text/plain") || clipboardData.getData("text");
454
485
  if (pastedData) {
455
486
  if (pastedData.startsWith("{")) {
@@ -464,9 +495,6 @@ function onPaste(e, fromInput) {
464
495
  }
465
496
  handlePastedText(pastedData);
466
497
  }
467
- if (clipboardData.files.length) {
468
- return handleFiles(clipboardData);
469
- }
470
498
  }
471
499
  const handlePastedText = (text) => {
472
500
  if (!adapter.clipboardMapBundle) {
@@ -474,50 +502,279 @@ const handlePastedText = (text) => {
474
502
  }
475
503
  const video = getVideoId(text);
476
504
  if (video.id && video.service) {
477
- const itemBundle = adapter.clipboardMapBundle({
478
- type: "video",
479
- videoService: video.service,
480
- videoId: video.id
481
- });
482
- if (!itemBundle) {
505
+ const itemBundles = normalizeBundles(
506
+ adapter.clipboardMapBundle({
507
+ type: "video",
508
+ videoService: video.service,
509
+ videoId: video.id
510
+ })
511
+ );
512
+ if (!itemBundles) {
483
513
  return;
484
514
  }
485
- pastedItems.value.push({
486
- type: "video",
487
- id: generateUUID(),
488
- itemBundle,
489
- data: text,
490
- videoService: video.service,
491
- videoId: video.id
492
- });
493
- showClipboardSidebar();
515
+ startClipboardDrag(
516
+ {
517
+ type: "video",
518
+ id: generateUUID(),
519
+ itemBundle: itemBundles[0],
520
+ data: text,
521
+ videoService: video.service,
522
+ videoId: video.id
523
+ },
524
+ itemBundles
525
+ );
494
526
  return;
495
527
  }
496
528
  const div = document.createElement("div");
497
529
  div.innerHTML = text.replace(/&nbsp;|<br>/g, "");
498
- removeAttributes(div);
530
+ sanitizeHtml(div);
499
531
  if (div.textContent) {
500
- const itemBundle = adapter.clipboardMapBundle({
501
- type: "plaintext",
502
- text: div.innerHTML
503
- });
504
- if (!itemBundle) {
532
+ const itemBundles = normalizeBundles(
533
+ adapter.clipboardMapBundle({
534
+ type: "plaintext",
535
+ text: div.innerHTML
536
+ })
537
+ );
538
+ if (!itemBundles) {
505
539
  return;
506
540
  }
507
- showClipboardSidebar();
508
- pastedItems.value.push({
509
- type: "text",
510
- id: generateUUID(),
511
- itemBundle,
512
- data: div.innerHTML
513
- });
541
+ startClipboardDrag(
542
+ {
543
+ type: "text",
544
+ id: generateUUID(),
545
+ itemBundle: itemBundles[0],
546
+ data: div.innerHTML
547
+ },
548
+ itemBundles
549
+ );
514
550
  }
515
551
  };
516
- function remove(index) {
517
- pastedItems.value = pastedItems.value.filter((_v, i) => {
518
- return i !== index;
519
- });
552
+ function extractBareUrl(text) {
553
+ const trimmed = text.trim();
554
+ try {
555
+ const url = new URL(trimmed);
556
+ if (url.protocol === "http:" || url.protocol === "https:") {
557
+ return trimmed;
558
+ }
559
+ } catch {
560
+ }
561
+ return null;
520
562
  }
563
+ defineDropHandler("native_drop", {
564
+ resolveBundles({ items, field }) {
565
+ const item = items[0];
566
+ if (!adapter.addBlockFromClipboardItem) {
567
+ return [];
568
+ }
569
+ if (item.clipboardItems?.length) {
570
+ return field.allowedBundles.filter((b) => item.itemBundles.includes(b));
571
+ }
572
+ if (!item.dataTransfer) {
573
+ return field.allowedBundles.filter((b) => item.itemBundles.includes(b));
574
+ }
575
+ const dt = item.dataTransfer;
576
+ if (dt.files.length > 0) {
577
+ if (!adapter.clipboardMapBundle) {
578
+ return field.allowedBundles.filter((b) => item.itemBundles.includes(b));
579
+ }
580
+ const files = [...dt.files];
581
+ let possibleBundles = null;
582
+ for (const file of files) {
583
+ const type = file.type.startsWith("image/") ? "image" : "file";
584
+ const mapped = normalizeBundles(
585
+ adapter.clipboardMapBundle({
586
+ type,
587
+ fileType: file.type,
588
+ fileSize: file.size
589
+ })
590
+ );
591
+ if (!mapped) {
592
+ return [];
593
+ }
594
+ if (possibleBundles === null) {
595
+ possibleBundles = mapped;
596
+ } else {
597
+ possibleBundles = possibleBundles.filter((b) => mapped.includes(b));
598
+ }
599
+ }
600
+ return (possibleBundles || []).filter(
601
+ (b) => field.allowedBundles.includes(b)
602
+ );
603
+ }
604
+ const text = dt.getData("text/html") || dt.getData("text/plain") || dt.getData("text");
605
+ if (!text) {
606
+ return [];
607
+ }
608
+ if (adapter.clipboardMapBundle) {
609
+ const video = getVideoId(text);
610
+ if (video.id && video.service) {
611
+ const mapped2 = normalizeBundles(
612
+ adapter.clipboardMapBundle({
613
+ type: "video",
614
+ videoService: video.service,
615
+ videoId: video.id
616
+ })
617
+ );
618
+ if (mapped2?.length) {
619
+ item.clipboardItems = [
620
+ {
621
+ type: "video",
622
+ id: generateUUID(),
623
+ itemBundle: mapped2[0],
624
+ data: text,
625
+ videoService: video.service,
626
+ videoId: video.id
627
+ }
628
+ ];
629
+ return mapped2.filter((b) => field.allowedBundles.includes(b));
630
+ }
631
+ }
632
+ const bareUrl = extractBareUrl(text);
633
+ if (bareUrl) {
634
+ const mapped2 = normalizeBundles(
635
+ adapter.clipboardMapBundle({ type: "link", url: bareUrl })
636
+ );
637
+ if (mapped2?.length) {
638
+ item.clipboardItems = [
639
+ {
640
+ type: "text",
641
+ id: generateUUID(),
642
+ itemBundle: mapped2[0],
643
+ data: bareUrl
644
+ }
645
+ ];
646
+ return mapped2.filter((b) => field.allowedBundles.includes(b));
647
+ }
648
+ }
649
+ const mapped = normalizeBundles(
650
+ adapter.clipboardMapBundle({ type: "plaintext", text })
651
+ );
652
+ if (mapped?.length) {
653
+ item.clipboardItems = [
654
+ {
655
+ type: "text",
656
+ id: generateUUID(),
657
+ itemBundle: mapped[0],
658
+ data: text
659
+ }
660
+ ];
661
+ return mapped.filter((b) => field.allowedBundles.includes(b));
662
+ }
663
+ }
664
+ item.clipboardItems = [
665
+ {
666
+ type: "text",
667
+ id: generateUUID(),
668
+ itemBundle: item.itemBundles[0],
669
+ data: text
670
+ }
671
+ ];
672
+ return field.allowedBundles.filter((b) => item.itemBundles.includes(b));
673
+ },
674
+ async execute({ items, host, afterUuid, bundle }) {
675
+ if (!adapter.addBlockFromClipboardItem) {
676
+ return;
677
+ }
678
+ const item = items[0];
679
+ if (item.clipboardItems?.length) {
680
+ await state.mutateWithLoadingState(async () => {
681
+ let lastResult;
682
+ for (const clipItem of item.clipboardItems) {
683
+ lastResult = await adapter.addBlockFromClipboardItem({
684
+ item: clipItem,
685
+ blockBundle: bundle,
686
+ host,
687
+ afterUuid
688
+ });
689
+ }
690
+ return lastResult;
691
+ });
692
+ return;
693
+ }
694
+ if (!item.dataTransfer) {
695
+ return;
696
+ }
697
+ const dt = item.dataTransfer;
698
+ if (dt.files.length > 0) {
699
+ const files = [...dt.files];
700
+ if (adapter.clipboardMapBundle) {
701
+ for (const file of files) {
702
+ const type = file.type.startsWith("image/") ? "image" : "file";
703
+ const mapped = adapter.clipboardMapBundle({
704
+ type,
705
+ fileType: file.type,
706
+ fileSize: file.size
707
+ });
708
+ if (!mapped) {
709
+ emitMessage("This file type or size is not supported.", "error");
710
+ return;
711
+ }
712
+ }
713
+ }
714
+ let results;
715
+ try {
716
+ results = await Promise.all(files.map(readFileAsDataURL));
717
+ } catch {
718
+ return;
719
+ }
720
+ const clipboardItems = files.map((file, i) => {
721
+ const type = file.type.startsWith("image/") ? "image" : "file";
722
+ return {
723
+ type,
724
+ id: generateUUID(),
725
+ itemBundle: bundle,
726
+ data: results[i],
727
+ additional: file.name,
728
+ fileName: file.name,
729
+ fileSize: file.size,
730
+ fileType: file.type
731
+ };
732
+ });
733
+ await state.mutateWithLoadingState(async () => {
734
+ let lastResult;
735
+ for (const clipItem of clipboardItems) {
736
+ lastResult = await adapter.addBlockFromClipboardItem({
737
+ item: clipItem,
738
+ blockBundle: bundle,
739
+ host,
740
+ afterUuid
741
+ });
742
+ }
743
+ return lastResult;
744
+ });
745
+ } else {
746
+ const text = dt.getData("text/html") || dt.getData("text/plain") || dt.getData("text");
747
+ if (!text) {
748
+ return;
749
+ }
750
+ const clipboardItem = {
751
+ type: "text",
752
+ id: generateUUID(),
753
+ itemBundle: bundle,
754
+ data: text
755
+ };
756
+ await state.mutateWithLoadingState(
757
+ () => adapter.addBlockFromClipboardItem({
758
+ item: clipboardItem,
759
+ blockBundle: bundle,
760
+ host,
761
+ afterUuid
762
+ })
763
+ );
764
+ }
765
+ }
766
+ });
767
+ defineDropHandler("clipboard", {
768
+ async execute({ items, host, afterUuid }) {
769
+ const item = items[0];
770
+ eventBus.emit("drop:clipboardItem", {
771
+ id: item.clipboardId,
772
+ host,
773
+ blockBundle: item.itemBundle,
774
+ afterUuid
775
+ });
776
+ }
777
+ });
521
778
  function setClipboard(text) {
522
779
  const type = "text/plain";
523
780
  const blob = new Blob([text], { type });
@@ -538,7 +795,7 @@ function copyCurrentSelectionToClipboard() {
538
795
  selectionClipboard.value = selection.uuids.value;
539
796
  }
540
797
  onBlokkliEvent("keyPressed", (e) => {
541
- if (e.code !== "c" || !e.meta || ui.hasDialogOpen.value || !ui.canvasFocused.value) {
798
+ if (e.code !== "c" || !e.meta || ui.hasDialogOpen.value || ui.hasNestedEditorOpen.value || !ui.canvasFocused.value) {
542
799
  return;
543
800
  }
544
801
  copyCurrentSelectionToClipboard();
@@ -574,32 +831,23 @@ defineItemDropdownAction(() => {
574
831
  }));
575
832
  }
576
833
  });
577
- onBlokkliEvent("drop:clipboardItem", async (data) => {
578
- const item = pastedItems.value.find((v) => v.id === data.id);
579
- if (!item) {
580
- return;
581
- }
582
- if (adapter.addBlockFromClipboardItem) {
583
- await state.mutateWithLoadingState(
584
- () => adapter.addBlockFromClipboardItem({
585
- afterUuid: data.afterUuid,
586
- item,
587
- blockBundle: data.blockBundle,
588
- host: data.host
589
- })
590
- );
591
- pastedItems.value = pastedItems.value.filter((v) => v.id !== item.id);
592
- }
593
- });
594
834
  onMounted(() => {
595
835
  document.addEventListener("paste", onPaste);
596
- document.body.addEventListener("drop", onDrop);
836
+ document.addEventListener("dragstart", onDragStart);
837
+ document.addEventListener("dragenter", onDragEnter);
838
+ document.addEventListener("dragleave", onDragLeave);
839
+ document.addEventListener("dragend", resetDrag);
597
840
  document.addEventListener("dragover", onDragOver);
841
+ document.addEventListener("drop", onNativeDrop);
598
842
  });
599
843
  onUnmounted(() => {
600
844
  document.removeEventListener("paste", onPaste);
601
- document.body.removeEventListener("drop", onDrop);
845
+ document.removeEventListener("dragstart", onDragStart);
846
+ document.removeEventListener("dragenter", onDragEnter);
847
+ document.removeEventListener("dragleave", onDragLeave);
848
+ document.removeEventListener("dragend", resetDrag);
602
849
  document.removeEventListener("dragover", onDragOver);
850
+ document.removeEventListener("drop", onNativeDrop);
603
851
  });
604
852
  </script>
605
853