@blokkli/editor 2.0.0-alpha.19 → 2.0.0-alpha.20

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.
@@ -48,7 +48,11 @@ export default function(ui, storage, selection, element) {
48
48
  const maxCanvasWidth = ref(16384);
49
49
  const maxCanvasHeight = ref(16384);
50
50
  let webglLimitsQueried = false;
51
+ let canvasElement = null;
51
52
  function getCanvasElement() {
53
+ if (canvasElement) {
54
+ return canvasElement;
55
+ }
52
56
  const el = element.query(
53
57
  document.documentElement,
54
58
  "#bk-animation-canvas-webgl",
@@ -57,6 +61,7 @@ export default function(ui, storage, selection, element) {
57
61
  if (!(el instanceof HTMLCanvasElement)) {
58
62
  throw new TypeError("Failed to locate WebGL canvas.");
59
63
  }
64
+ canvasElement = el;
60
65
  return el;
61
66
  }
62
67
  function gl() {
@@ -14,7 +14,6 @@ type MeasuredBlockRect = Rectangle & {
14
14
  time: number;
15
15
  };
16
16
  export type DomProvider = {
17
- findClosestBlock(el: Element | EventTarget): DraggableExistingBlock | undefined;
18
17
  /**
19
18
  * Return the droppable markup for a draggable item.
20
19
  */
@@ -27,7 +26,6 @@ export type DomProvider = {
27
26
  getRegisteredField: (uuid: string, fieldName: string) => RegisteredField | undefined;
28
27
  registeredFieldTypes: ComputedRef<RegisteredFieldType[]>;
29
28
  registeredBlockUuids: ComputedRef<string[]>;
30
- findClosestEntityContext(el: HTMLElement): EntityContext | undefined;
31
29
  getVisibleBlocks(): string[];
32
30
  getVisibleFields(): string[];
33
31
  isBlockVisible(uuid: string): boolean;
@@ -1,9 +1,5 @@
1
1
  import { reactive, ref, computed } from "#imports";
2
- import {
3
- findClosestBlock,
4
- falsy,
5
- findClosestEntityContext
6
- } from "#blokkli/helpers";
2
+ import { falsy } from "#blokkli/helpers";
7
3
  import { cloneElementWithStyles } from "./dom/index.js";
8
4
  import onBlokkliEvent from "./composables/onBlokkliEvent.js";
9
5
  import useDelayedIntersectionObserver from "./composables/useDelayedIntersectionObserver.js";
@@ -22,6 +18,8 @@ export default function(ui, debug, definitions, state, element) {
22
18
  const registeredFields = reactive({});
23
19
  const visibleBlocks = /* @__PURE__ */ new Set();
24
20
  const visibleFields = /* @__PURE__ */ new Set();
21
+ const fieldElementToFieldKey = /* @__PURE__ */ new WeakMap();
22
+ const blockElementToUuid = /* @__PURE__ */ new WeakMap();
25
23
  const blockRects = {};
26
24
  const fieldRects = {};
27
25
  const blockUuidCurrentKey = {};
@@ -42,7 +40,7 @@ export default function(ui, debug, definitions, state, element) {
42
40
  if (!(entry.target instanceof HTMLElement)) {
43
41
  return;
44
42
  }
45
- const uuid = entry.target.dataset.uuid || entry.target.closest("[data-uuid]")?.dataset.uuid;
43
+ const uuid = blockElementToUuid.get(entry.target);
46
44
  if (!uuid) {
47
45
  return;
48
46
  }
@@ -75,39 +73,43 @@ export default function(ui, debug, definitions, state, element) {
75
73
  const scale = ui.artboardScale.value;
76
74
  const offset = ui.artboardOffset.value;
77
75
  for (const entry of entries) {
78
- if (entry.target instanceof HTMLElement) {
79
- const uuid = entry.target.dataset.uuid || entry.target.closest("[data-uuid]")?.dataset.uuid;
80
- const fieldKey = entry.target.dataset.fieldKey;
81
- const rect = entry.target.getBoundingClientRect();
82
- if (fieldKey) {
83
- if (entry.isIntersecting) {
84
- visibleFields.add(fieldKey);
85
- } else {
86
- visibleFields.delete(fieldKey);
87
- }
88
- fieldRects[fieldKey] = ui.getAbsoluteElementRect(rect, scale, offset);
89
- } else if (uuid) {
90
- if (!registeredBlocks[uuid]) {
91
- continue;
92
- }
93
- const newRect = ui.getAbsoluteElementRect(rect, scale, offset);
94
- const currentRect = blockRects[uuid];
95
- if (currentRect) {
96
- if (currentRect.time > entry.time) {
97
- blockRects[uuid].x = newRect.x;
98
- blockRects[uuid].y = newRect.y;
99
- } else {
100
- blockRects[uuid] = rectWithTime(newRect, entry.time);
101
- }
102
- } else {
103
- blockRects[uuid] = rectWithTime(newRect, entry.time);
104
- }
105
- if (entry.isIntersecting) {
106
- visibleBlocks.add(uuid);
107
- } else {
108
- visibleBlocks.delete(uuid);
109
- }
76
+ if (!(entry.target instanceof HTMLElement)) {
77
+ continue;
78
+ }
79
+ const fieldKey = fieldElementToFieldKey.get(entry.target);
80
+ const rect = entry.target.getBoundingClientRect();
81
+ if (fieldKey) {
82
+ if (entry.isIntersecting) {
83
+ visibleFields.add(fieldKey);
84
+ } else {
85
+ visibleFields.delete(fieldKey);
86
+ }
87
+ fieldRects[fieldKey] = ui.getAbsoluteElementRect(rect, scale, offset);
88
+ continue;
89
+ }
90
+ const uuid = blockElementToUuid.get(entry.target);
91
+ if (!uuid) {
92
+ continue;
93
+ }
94
+ if (!registeredBlocks[uuid]) {
95
+ continue;
96
+ }
97
+ const newRect = ui.getAbsoluteElementRect(rect, scale, offset);
98
+ const currentRect = blockRects[uuid];
99
+ if (currentRect) {
100
+ if (currentRect.time > entry.time) {
101
+ blockRects[uuid].x = newRect.x;
102
+ blockRects[uuid].y = newRect.y;
103
+ } else {
104
+ blockRects[uuid] = rectWithTime(newRect, entry.time);
110
105
  }
106
+ } else {
107
+ blockRects[uuid] = rectWithTime(newRect, entry.time);
108
+ }
109
+ if (entry.isIntersecting) {
110
+ visibleBlocks.add(uuid);
111
+ } else {
112
+ visibleBlocks.delete(uuid);
111
113
  }
112
114
  }
113
115
  }
@@ -146,6 +148,7 @@ export default function(ui, debug, definitions, state, element) {
146
148
  ...data
147
149
  };
148
150
  intersectionObserver.observe(element2);
151
+ fieldElementToFieldKey.set(element2, key);
149
152
  doInitTimeout();
150
153
  };
151
154
  const updateFieldElement = (entity, fieldName, element2, data) => {
@@ -160,6 +163,7 @@ export default function(ui, debug, definitions, state, element) {
160
163
  element: element2,
161
164
  ...data
162
165
  };
166
+ fieldElementToFieldKey.set(element2, key);
163
167
  intersectionObserver.observe(element2);
164
168
  };
165
169
  const unregisterField = (entity, fieldName) => {
@@ -167,6 +171,7 @@ export default function(ui, debug, definitions, state, element) {
167
171
  const el = registeredFields[key]?.element;
168
172
  if (el) {
169
173
  intersectionObserver.unobserve(el);
174
+ fieldElementToFieldKey.delete(el);
170
175
  }
171
176
  visibleFields.delete(key);
172
177
  registeredFields[key] = void 0;
@@ -407,6 +412,7 @@ export default function(ui, debug, definitions, state, element) {
407
412
  fieldListType,
408
413
  parentBundle
409
414
  );
415
+ blockElementToUuid.set(observableElement, uuid);
410
416
  registeredBlocks[uuid] = el;
411
417
  observedElements[uuid] = observableElement;
412
418
  intersectionObserver.observe(observableElement);
@@ -426,6 +432,7 @@ export default function(ui, debug, definitions, state, element) {
426
432
  intersectionObserver.unobserve(observedElement);
427
433
  resizeObserver.unobserve(observedElement);
428
434
  delete observedElements[uuid];
435
+ blockElementToUuid.delete(observedElement);
429
436
  }
430
437
  if (el) {
431
438
  dragElementUuidMap.delete(el);
@@ -507,9 +514,7 @@ export default function(ui, debug, definitions, state, element) {
507
514
  };
508
515
  }
509
516
  return {
510
- findClosestBlock,
511
517
  getDropElementMarkup,
512
- findClosestEntityContext,
513
518
  getVisibleBlocks,
514
519
  getVisibleFields,
515
520
  registerField,
@@ -1,4 +1,4 @@
1
- import type { DraggableItem, Rectangle, DraggableExistingBlock, EntityContext, Coord, LibraryItemProps, Size } from '#blokkli/types';
1
+ import type { DraggableItem, Rectangle, Coord, LibraryItemProps, Size } from '#blokkli/types';
2
2
  import type { RGB } from '#blokkli/types/theme';
3
3
  /**
4
4
  * Type check for falsy values.
@@ -76,12 +76,6 @@ export declare function findIdealRectPosition(blockingRects: Rectangle[], rectTo
76
76
  x: number;
77
77
  y: number;
78
78
  };
79
- export declare const findClosestBlock: (el: Element | EventTarget) => DraggableExistingBlock | undefined;
80
- /**
81
- * Find the closest entity context from a BlokkliProvider.
82
- */
83
- export declare const findClosestEntityContext: (el: HTMLElement) => EntityContext | undefined;
84
- export declare const findParentContext: (el: HTMLElement) => EntityContext | DraggableExistingBlock | undefined;
85
79
  export declare const originatesFromTextInput: (e: Event) => boolean;
86
80
  export declare function getFieldKey(uuid: string, fieldName: string): string;
87
81
  export declare function getInteractionCoordinates(e: MouseEvent | TouchEvent): Coord;
@@ -361,43 +361,6 @@ export function findIdealRectPosition(blockingRects, rectToPlace, viewport, maxO
361
361
  )
362
362
  };
363
363
  }
364
- export const findClosestBlock = (el) => {
365
- if (!(el instanceof Element)) {
366
- return;
367
- }
368
- const closest = el.closest('[data-element-type="existing"]');
369
- if (!closest) {
370
- return;
371
- }
372
- const item = buildDraggableItem(closest);
373
- if (item?.itemType !== "existing") {
374
- return;
375
- }
376
- return item;
377
- };
378
- export const findClosestEntityContext = (el) => {
379
- const provider = el.closest('[data-blokkli-provider-active="true"]');
380
- if (!(provider instanceof HTMLElement)) {
381
- return;
382
- }
383
- const uuid = provider.dataset.providerUuid;
384
- const type = provider.dataset.providerEntityType;
385
- const bundle = provider.dataset.providerEntityBundle;
386
- if (uuid && type && bundle) {
387
- return {
388
- uuid,
389
- type,
390
- bundle
391
- };
392
- }
393
- };
394
- export const findParentContext = (el) => {
395
- const block = findClosestBlock(el);
396
- if (block) {
397
- return block;
398
- }
399
- return findClosestEntityContext(el);
400
- };
401
364
  export const originatesFromTextInput = (e) => e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement;
402
365
  export function getFieldKey(uuid, fieldName) {
403
366
  return uuid + ":" + fieldName;
@@ -1,6 +1,7 @@
1
1
  import type { BlokkliDirectiveType, EntityContext, Rectangle } from '#blokkli/types';
2
2
  import type { UiProvider } from './../uiProvider.js';
3
3
  import { type ComputedRef } from '#imports';
4
+ import type { DebugProvider } from '../debugProvider.js';
4
5
  type EditableFieldData = EntityContext & {
5
6
  key: string;
6
7
  fieldName: string;
@@ -20,5 +21,5 @@ export type DirectiveProvider = {
20
21
  findEditableElement: (fieldName: string, host: EntityContext) => HTMLElement | undefined;
21
22
  isReady: ComputedRef<boolean>;
22
23
  };
23
- export default function (ui: UiProvider): DirectiveProvider;
24
+ export default function (debug: DebugProvider, ui: UiProvider): DirectiveProvider;
24
25
  export {};
@@ -3,7 +3,8 @@ import useDelayedIntersectionObserver from "./../composables/useDelayedIntersect
3
3
  import { computed, onBeforeUnmount, ref } from "#imports";
4
4
  import onBlokkliEvent from "./../composables/onBlokkliEvent.js";
5
5
  import { itemEntityType } from "#blokkli-build/config";
6
- export default function(ui) {
6
+ export default function(debug, ui) {
7
+ const logger = debug.createLogger("DirectiveProvider");
7
8
  let initTimeout = null;
8
9
  const isInitalizing = ref(true);
9
10
  let stateReloadTimeout = null;
@@ -86,10 +87,12 @@ export default function(ui) {
86
87
  editablesByUuid[entity.uuid] ||= {};
87
88
  editablesByUuid[entity.uuid][fieldName] = data;
88
89
  }
90
+ logger.log("Registered directive element", data);
89
91
  doInitTimeout();
90
92
  }
91
93
  function unregisterDirectiveElement(el, fieldName, entity, directiveType) {
92
94
  const key = getEditableKey(fieldName, entity, directiveType);
95
+ logger.log("Unregistered directive element", key);
93
96
  intersectionObserver.unobserve(el);
94
97
  elementMap.delete(el);
95
98
  fieldData.delete(key);
@@ -345,6 +345,7 @@ export type InjectedBlokkliItem = {
345
345
  export type FieldListItem = {
346
346
  uuid: string;
347
347
  bundle: string;
348
+ isVisible: boolean;
348
349
  options?: Record<string, any>;
349
350
  editContext?: BlockEditContext;
350
351
  props?: Record<string, any>;
@@ -1415,5 +1416,6 @@ export type RegisteredField = {
1415
1416
  dropAlignment: FieldDropAlignment | null;
1416
1417
  };
1417
1418
  export type RegisterFieldData = Pick<RegisteredField, 'fieldListType' | 'allowedFragments' | 'isNested' | 'nestingLevel' | 'dropAlignment'>;
1419
+ export type VueClassProp = string | Record<string, boolean> | VueClassProp[];
1418
1420
  declare const _default: {};
1419
1421
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blokkli/editor",
3
- "version": "2.0.0-alpha.19",
3
+ "version": "2.0.0-alpha.20",
4
4
  "description": "Interactive page building experience for Nuxt",
5
5
  "repository": "blokkli/editor",
6
6
  "type": "module",