@blokkli/editor 2.0.0-alpha.4 → 2.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "blokkli",
3
3
  "configKey": "blokkli",
4
- "version": "2.0.0-alpha.4",
4
+ "version": "2.0.0-alpha.5",
5
5
  "compatibility": {
6
6
  "nuxt": "^3.15.0"
7
7
  },
package/dist/module.mjs CHANGED
@@ -13,7 +13,7 @@ import { BK_VISIBLE_LANGUAGES, BK_HIDDEN_GLOBALLY } from '../dist/runtime/helper
13
13
  import fs from 'node:fs';
14
14
  import { defu, createDefu } from 'defu';
15
15
 
16
- const version = "2.0.0-alpha.4";
16
+ const version = "2.0.0-alpha.5";
17
17
 
18
18
  function sortObjectKeys(obj) {
19
19
  if (Array.isArray(obj)) {
@@ -6345,6 +6345,9 @@ declare const adapter: BlokkliAdapterFactory<any>
6345
6345
 
6346
6346
  export default adapter
6347
6347
  `;
6348
+ },
6349
+ {
6350
+ write: true
6348
6351
  }
6349
6352
  );
6350
6353
 
@@ -23,7 +23,9 @@ import {
23
23
  provide,
24
24
  useRuntimeConfig,
25
25
  inject,
26
- defineAsyncComponent
26
+ defineAsyncComponent,
27
+ getCurrentInstance,
28
+ onMounted
27
29
  } from "#imports";
28
30
  import { getComponent } from "#blokkli/helpers/imports";
29
31
  import {
@@ -45,6 +47,7 @@ const componentProps = defineProps({
45
47
  parentType: { type: String, required: false, default: "" },
46
48
  isEditing: { type: Boolean, required: false, default: false }
47
49
  });
50
+ const instance = componentProps.isEditing ? getCurrentInstance() : null;
48
51
  const isProxyMode = inject(INJECT_FIELD_PROXY_MODE, false);
49
52
  const fieldUsesProxy = inject(INJECT_FIELD_USES_PROXY, false);
50
53
  const isGlobalProxyMode = inject(
@@ -75,7 +75,7 @@ import {
75
75
  import { onlyUnique, findIdealRectPosition, falsy } from "#blokkli/helpers";
76
76
  import { ItemIcon, Icon } from "#blokkli/components";
77
77
  import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
78
- const { selection, $t, types, state, ui, dom, definitions } = useBlokkli();
78
+ const { selection, $t, types, state, ui, dom, definitions, debug } = useBlokkli();
79
79
  const editingEnabled = computed(
80
80
  () => state.editMode.value === "editing" || state.editMode.value === "translating"
81
81
  );
@@ -100,6 +100,9 @@ const title = computed(() => {
100
100
  if (ui.transformLabel.value) {
101
101
  return ui.transformLabel.value;
102
102
  }
103
+ if (debug.isEnabled.value && selection.uuids.value.length === 1) {
104
+ return selection.uuids.value[0];
105
+ }
103
106
  if (itemBundle.value) {
104
107
  if (itemBundle.value.id === "blokkli_fragment") {
105
108
  const fragments = selection.uuids.value.map((uuid) => {
@@ -34,6 +34,7 @@ import { computed, useBlokkli, ref } from "#imports";
34
34
  import { getBlokkliItemProxyComponent } from "#blokkli/helpers/editComponents";
35
35
  import { ItemIcon } from "#blokkli/components";
36
36
  import { buildAttributesForLibraryItem, falsy } from "#blokkli/helpers";
37
+ import { useBlockRegistration } from "#blokkli/helpers/composables/useBlockRegistration";
37
38
  const props = defineProps({
38
39
  uuid: { type: String, required: true },
39
40
  bundle: { type: String, required: true },
@@ -63,7 +64,7 @@ const rootProps = computed(() => {
63
64
  const proxyBundle = computed(
64
65
  () => libraryItemProps.value?.block?.bundle || props.bundle
65
66
  );
66
- const { types, runtimeConfig, definitions } = useBlokkli();
67
+ const { types, runtimeConfig, definitions, dom } = useBlokkli();
67
68
  const root = ref(null);
68
69
  const type = computed(() => types.getBlockBundleDefinition(proxyBundle.value));
69
70
  const proxyComponent = getBlokkliItemProxyComponent(proxyBundle.value);
@@ -89,4 +90,5 @@ const fieldLayout = computed(() => {
89
90
  }
90
91
  return types.fieldConfig.forEntityTypeAndBundle(runtimeConfig.itemEntityType, proxyBundle.value).map((config) => [config]);
91
92
  });
93
+ useBlockRegistration(dom, props.uuid);
92
94
  </script>
@@ -94,6 +94,7 @@ import {
94
94
  INJECT_GLOBAL_PROXY_MODE,
95
95
  INJECT_IS_EDITING
96
96
  } from "#blokkli/helpers/symbols";
97
+ import { useBlockRegistration } from "#blokkli/helpers/composables/useBlockRegistration";
97
98
  const props = defineProps({
98
99
  entity: { type: null, required: false, default: void 0 },
99
100
  entityType: { type: String, required: true },
@@ -184,7 +185,8 @@ provide(INJECT_EDIT_CONTEXT, {
184
185
  eventBus,
185
186
  mutatedOptions: state.mutatedOptions,
186
187
  dom,
187
- definitions
188
+ definitions,
189
+ useBlockRegistration
188
190
  });
189
191
  provide(INJECT_APP, {
190
192
  adapter,
@@ -87,6 +87,9 @@ export function defineBlokkli(arg) {
87
87
  import.meta.hot.accept("#blokkli/helpers/runtimeHelpers", () => {
88
88
  });
89
89
  }
90
+ if (editContext?.useBlockRegistration && editContext.dom && bundle !== "from_library" && bundle !== "blokkli_fragment") {
91
+ editContext.useBlockRegistration(editContext.dom, uuid);
92
+ }
90
93
  return {
91
94
  uuid,
92
95
  index,
@@ -1,4 +1,7 @@
1
- import { INJECT_FRAGMENT_CONTEXT } from "../helpers/symbols.js";
1
+ import {
2
+ INJECT_EDIT_CONTEXT,
3
+ INJECT_FRAGMENT_CONTEXT
4
+ } from "../helpers/symbols.js";
2
5
  import { inject, computed } from "#imports";
3
6
  export function defineBlokkliFragment(_config) {
4
7
  const ctx = inject(
@@ -18,5 +21,9 @@ export function defineBlokkliFragment(_config) {
18
21
  provider: computed(() => null)
19
22
  };
20
23
  }
24
+ const editContext = inject(INJECT_EDIT_CONTEXT, null);
25
+ if (editContext?.dom && editContext.useBlockRegistration) {
26
+ editContext.useBlockRegistration(editContext.dom, ctx.uuid);
27
+ }
21
28
  return ctx;
22
29
  }
@@ -0,0 +1,5 @@
1
+ import type { DomProvider } from '../domProvider.js';
2
+ /**
3
+ * Helper composable to handle registering the block in the DOM provider.
4
+ */
5
+ export declare function useBlockRegistration(dom: DomProvider, uuid: string): void;
@@ -0,0 +1,23 @@
1
+ import {
2
+ getCurrentInstance,
3
+ onBeforeUnmount,
4
+ onMounted,
5
+ onUpdated
6
+ } from "#imports";
7
+ export function useBlockRegistration(dom, uuid) {
8
+ const instance = getCurrentInstance();
9
+ const key = uuid + Math.round(Math.random() * 1e10).toString() + Date.now().toString();
10
+ let rootElement = null;
11
+ function setRootElement() {
12
+ const newElement = instance?.proxy?.$el;
13
+ if (newElement && rootElement !== newElement) {
14
+ rootElement = newElement;
15
+ dom.registerBlock(key, uuid, newElement);
16
+ }
17
+ }
18
+ onMounted(setRootElement);
19
+ onUpdated(setRootElement);
20
+ onBeforeUnmount(() => {
21
+ dom.unregisterBlock(key, uuid);
22
+ });
23
+ }
@@ -20,6 +20,8 @@ export type DomProvider = {
20
20
  */
21
21
  getDropElementMarkup(item: DraggableItem, checkSize?: boolean): string;
22
22
  findField(entityUuid: string, fieldName: string): BlokkliFieldElement | undefined;
23
+ registerBlock: (key: string, uuid: string, el: HTMLElement | null) => void;
24
+ unregisterBlock: (key: string, uuid: string) => void;
23
25
  registerField: (entity: EntityContext, fieldName: string, instance: HTMLElement) => void;
24
26
  updateFieldElement: (entity: EntityContext, fieldName: string, element: HTMLElement) => void;
25
27
  unregisterField: (entity: EntityContext, fieldName: string) => void;
@@ -49,7 +49,6 @@ function rectWithTime(rect, time) {
49
49
  };
50
50
  }
51
51
  export default function(ui, debug, definitions) {
52
- const artboardElement = ui.artboardElement();
53
52
  const logger = debug.createLogger("DomProvider");
54
53
  const mutationsReady = ref(true);
55
54
  const intersectionReady = ref(false);
@@ -57,6 +56,7 @@ export default function(ui, debug, definitions) {
57
56
  const visibleFields = /* @__PURE__ */ new Set();
58
57
  const blockRects = {};
59
58
  const fieldRects = {};
59
+ const blockUuidCurrentKey = {};
60
60
  let draggableBlockCache = {};
61
61
  const resizeObserver = new ResizeObserver(function(entries) {
62
62
  for (const entry of entries) {
@@ -360,66 +360,6 @@ export default function(ui, debug, definitions) {
360
360
  }
361
361
  const dragElementUuidMap = /* @__PURE__ */ new WeakMap();
362
362
  const dragElementCache = /* @__PURE__ */ new Map();
363
- function handleNodeAdded(node) {
364
- if (!(node instanceof HTMLElement)) {
365
- return;
366
- }
367
- if (node.dataset.uuid) {
368
- const item = buildDraggableItem(node);
369
- if (item && item.itemType === "existing") {
370
- const observableElement = getElementToObserve(
371
- node,
372
- item.itemBundle,
373
- item.hostFieldListType,
374
- item.hostBundle
375
- );
376
- intersectionObserver.observe(observableElement);
377
- resizeObserver.observe(observableElement);
378
- registeredBlocks[item.uuid] = node;
379
- }
380
- } else if (node.dataset.fieldName && node.dataset.fieldKey && node.dataset.fieldCardinality) {
381
- const blocks = node.querySelectorAll('[data-element-type="existing"]');
382
- for (const block of blocks) {
383
- handleNodeAdded(block);
384
- }
385
- }
386
- }
387
- function handleNodeRemoved(node) {
388
- if (node instanceof HTMLElement && node.dataset.uuid) {
389
- const uuid = node.dataset.uuid;
390
- const el = registeredBlocks[uuid];
391
- if (el !== node) {
392
- return;
393
- }
394
- if (el) {
395
- intersectionObserver.unobserve(el);
396
- resizeObserver.unobserve(el);
397
- dragElementUuidMap.delete(el);
398
- }
399
- dragElementUuidMap.delete(node);
400
- dragElementCache.delete(uuid);
401
- registeredBlocks[uuid] = void 0;
402
- delete blockRects[uuid];
403
- visibleBlocks.delete(uuid);
404
- }
405
- }
406
- const mutationObserverCallback = function(mutationsList) {
407
- for (const mutation of mutationsList) {
408
- if (mutation.type === "childList") {
409
- for (const node of mutation.removedNodes) {
410
- handleNodeRemoved(node);
411
- }
412
- for (const node of mutation.addedNodes) {
413
- handleNodeAdded(node);
414
- }
415
- }
416
- }
417
- };
418
- const mutationObserver = new MutationObserver(mutationObserverCallback);
419
- mutationObserver.observe(artboardElement, {
420
- subtree: true,
421
- childList: true
422
- });
423
363
  function getDragElement(block) {
424
364
  const cached = dragElementCache.get(block.uuid);
425
365
  if (cached && document.body.contains(cached)) {
@@ -429,9 +369,6 @@ export default function(ui, debug, definitions) {
429
369
  if (!el) {
430
370
  return;
431
371
  }
432
- if (el.parentNode) {
433
- mutationObserver.observe(el.parentNode, { childList: true });
434
- }
435
372
  dragElementUuidMap.set(el, block.uuid);
436
373
  dragElementCache.set(block.uuid, el);
437
374
  return el;
@@ -439,6 +376,52 @@ export default function(ui, debug, definitions) {
439
376
  function isBlockVisible(uuid) {
440
377
  return visibleBlocks.has(uuid);
441
378
  }
379
+ function registerBlock(key, uuid, el) {
380
+ logger.log("registerBlock: " + uuid);
381
+ blockUuidCurrentKey[uuid] = key;
382
+ if (!el) {
383
+ logger.log("registerBlock call unregisterBlock because no element", uuid);
384
+ unregisterBlock(key, uuid);
385
+ return;
386
+ }
387
+ if (registeredBlocks[uuid]) {
388
+ logger.log(
389
+ "registerBlock call unregisterBlock because already registered",
390
+ uuid
391
+ );
392
+ unregisterBlock(key, uuid);
393
+ }
394
+ const item = buildDraggableItem(el);
395
+ if (item && item.itemType === "existing") {
396
+ const observableElement = getElementToObserve(
397
+ el,
398
+ item.itemBundle,
399
+ item.hostFieldListType,
400
+ item.hostBundle
401
+ );
402
+ intersectionObserver.observe(observableElement);
403
+ resizeObserver.observe(observableElement);
404
+ registeredBlocks[item.uuid] = el;
405
+ }
406
+ }
407
+ function unregisterBlock(key, uuid) {
408
+ const currentKey = blockUuidCurrentKey[uuid];
409
+ if (currentKey && currentKey !== key) {
410
+ return;
411
+ }
412
+ logger.log("unregisterBlock: " + uuid);
413
+ const el = registeredBlocks[uuid];
414
+ if (el) {
415
+ intersectionObserver.unobserve(el);
416
+ resizeObserver.unobserve(el);
417
+ dragElementUuidMap.delete(el);
418
+ dragElementUuidMap.delete(el);
419
+ }
420
+ dragElementCache.delete(uuid);
421
+ registeredBlocks[uuid] = void 0;
422
+ delete blockRects[uuid];
423
+ visibleBlocks.delete(uuid);
424
+ }
442
425
  return {
443
426
  findBlock,
444
427
  getAllBlocks,
@@ -462,6 +445,8 @@ export default function(ui, debug, definitions) {
462
445
  init,
463
446
  getDragElement,
464
447
  updateVisibleRects,
465
- registeredFieldTypes
448
+ registeredFieldTypes,
449
+ registerBlock,
450
+ unregisterBlock
466
451
  };
467
452
  }
@@ -936,6 +936,7 @@ export type ItemEditContext = {
936
936
  mutatedOptions: MutatedOptions;
937
937
  dom?: DomProvider;
938
938
  definitions: DefinitionProvider;
939
+ useBlockRegistration?: (dom: DomProvider, uuid: string) => void;
939
940
  };
940
941
  export interface BlokkliApp {
941
942
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blokkli/editor",
3
- "version": "2.0.0-alpha.4",
3
+ "version": "2.0.0-alpha.5",
4
4
  "description": "Interactive page building experience for Nuxt",
5
5
  "repository": "blokkli/editor",
6
6
  "type": "module",