@inditextech/weave-sdk 0.51.0 → 0.52.1

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/sdk.cjs CHANGED
@@ -15665,16 +15665,16 @@ function clearContainerTargets(instance) {
15665
15665
  const containers = instance.getContainerNodes();
15666
15666
  for (const container of containers) container.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, { bubbles: true });
15667
15667
  }
15668
- function containerOverCursor(instance, ignoreNodes) {
15668
+ function containerOverCursor(instance, ignoreNodes, definedCursorPosition) {
15669
15669
  konva.default.hitOnDragEnabled = true;
15670
15670
  const stage = instance.getStage();
15671
- const cursorPosition = stage.getRelativePointerPosition();
15671
+ const cursorPosition = definedCursorPosition ?? stage.getRelativePointerPosition();
15672
15672
  if (!cursorPosition) return void 0;
15673
15673
  const containerUnderPointer = new Set();
15674
15674
  stage.find(".containerCapable").reverse().forEach((node) => {
15675
15675
  if (!node.isVisible()) return;
15676
15676
  if (containsNodeDeep(ignoreNodes, node)) return;
15677
- const shapeRect = node.getClientRect({ relativeTo: stage });
15677
+ const shapeRect = getBoundingBox(stage, [node]);
15678
15678
  if (cursorPosition.x >= shapeRect.x && cursorPosition.x <= shapeRect.x + shapeRect.width && cursorPosition.y >= shapeRect.y && cursorPosition.y <= shapeRect.y + shapeRect.height) {
15679
15679
  if (node?.getAttrs().isContainerPrincipal) containerUnderPointer.add(node);
15680
15680
  }
@@ -15775,7 +15775,10 @@ function getBoundingBox(stage, nodes) {
15775
15775
  let maxX = -Infinity;
15776
15776
  let maxY = -Infinity;
15777
15777
  for (const node of nodes) {
15778
- const box = node.getRealClientRect({ skipTransform: false });
15778
+ const box = node.getRealClientRect({
15779
+ relativeTo: stage,
15780
+ skipTransform: false
15781
+ });
15779
15782
  minX = Math.min(minX, box.x);
15780
15783
  minY = Math.min(minY, box.y);
15781
15784
  maxX = Math.max(maxX, box.x + box.width);
@@ -15903,6 +15906,13 @@ function getVisibleNodesInViewport(stage, referenceLayer) {
15903
15906
  });
15904
15907
  return visibleNodes;
15905
15908
  }
15909
+ function getClosestParentWithId(el) {
15910
+ while (el) {
15911
+ if (el.id) return el;
15912
+ el = el.parentElement;
15913
+ }
15914
+ return null;
15915
+ }
15906
15916
 
15907
15917
  //#endregion
15908
15918
  //#region src/actions/selection-tool/constants.ts
@@ -15978,15 +15988,19 @@ var WeaveContextMenuPlugin = class extends WeavePlugin {
15978
15988
  }
15979
15989
  const containerRect = stage.container().getBoundingClientRect();
15980
15990
  const pointerPos = stage.getPointerPosition();
15981
- if (containerRect && pointerPos) {
15982
- const point = {
15991
+ const relativeClickPoint = stage.getRelativePointerPosition();
15992
+ if (containerRect && pointerPos && relativeClickPoint) {
15993
+ const contextMenuPoint = {
15983
15994
  x: containerRect.left + pointerPos.x + (this.config.xOffset ?? 4),
15984
15995
  y: containerRect.top + pointerPos.y + (this.config.yOffset ?? 4)
15985
15996
  };
15997
+ const stageClickPoint = this.getStageClickPoint(pointerPos);
15986
15998
  this.contextMenuVisible = true;
15987
15999
  this.instance.emitEvent("onNodeContextMenu", {
15988
16000
  selection: nodes,
15989
- point,
16001
+ contextMenuPoint,
16002
+ clickPoint: pointerPos,
16003
+ stageClickPoint,
15990
16004
  visible: true
15991
16005
  });
15992
16006
  }
@@ -15995,7 +16009,15 @@ var WeaveContextMenuPlugin = class extends WeavePlugin {
15995
16009
  this.contextMenuVisible = false;
15996
16010
  this.instance.emitEvent("onNodeContextMenu", {
15997
16011
  selection: [],
15998
- point: {
16012
+ contextMenuPoint: {
16013
+ x: 0,
16014
+ y: 0
16015
+ },
16016
+ clickPoint: {
16017
+ x: 0,
16018
+ y: 0
16019
+ },
16020
+ stageClickPoint: {
15999
16021
  x: 0,
16000
16022
  y: 0
16001
16023
  },
@@ -16040,9 +16062,6 @@ var WeaveContextMenuPlugin = class extends WeavePlugin {
16040
16062
  this.tapHold = false;
16041
16063
  }
16042
16064
  });
16043
- window.addEventListener("contextmenu", (e) => {
16044
- e.preventDefault();
16045
- });
16046
16065
  stage.on("contextmenu", (e) => {
16047
16066
  e.evt.preventDefault();
16048
16067
  if (!this.enabled) return;
@@ -16054,18 +16073,31 @@ var WeaveContextMenuPlugin = class extends WeavePlugin {
16054
16073
  const containerRect = stage.container().getBoundingClientRect();
16055
16074
  const pointerPos = stage.getPointerPosition();
16056
16075
  if (containerRect && pointerPos) {
16057
- const point = {
16076
+ const contextMenuPoint = {
16058
16077
  x: containerRect.left + pointerPos.x + (this.config.xOffset ?? 4),
16059
16078
  y: containerRect.top + pointerPos.y + (this.config.yOffset ?? 4)
16060
16079
  };
16080
+ const stageClickPoint = this.getStageClickPoint(pointerPos);
16061
16081
  this.instance.emitEvent("onNodeContextMenu", {
16062
16082
  selection: [],
16063
- point,
16083
+ contextMenuPoint,
16084
+ clickPoint: pointerPos,
16085
+ stageClickPoint,
16064
16086
  visible: false
16065
16087
  });
16066
16088
  }
16067
16089
  });
16068
16090
  }
16091
+ getStageClickPoint(pointerPos) {
16092
+ const stage = this.instance.getStage();
16093
+ const scale = stage.scale();
16094
+ const position = stage.position();
16095
+ const stageClickPoint = {
16096
+ x: (pointerPos.x - position.x) / scale.x,
16097
+ y: (pointerPos.y - position.y) / scale.y
16098
+ };
16099
+ return stageClickPoint;
16100
+ }
16069
16101
  isContextMenuVisible() {
16070
16102
  return this.contextMenuVisible;
16071
16103
  }
@@ -16269,7 +16301,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16269
16301
  selectionLayer?.add(selectionRectangle);
16270
16302
  const tr = new konva.default.Transformer({
16271
16303
  id: "selectionTransformer",
16272
- ...this.selectionOriginalConfig
16304
+ ...this.selectionOriginalConfig,
16305
+ listening: true
16273
16306
  });
16274
16307
  selectionLayer?.add(tr);
16275
16308
  const trHover = new konva.default.Transformer({
@@ -16281,6 +16314,29 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16281
16314
  listening: false
16282
16315
  });
16283
16316
  selectionLayer?.add(trHover);
16317
+ stage.on("pointermove", () => {
16318
+ if (tr.nodes().length === 1 && tr.nodes()[0].getAttrs().isContainerPrincipal) {
16319
+ const pos = stage.getPointerPosition();
16320
+ if (!pos) return;
16321
+ const shapeUnder = stage.getIntersection(pos);
16322
+ if (!shapeUnder) {
16323
+ tr.setAttrs({ listening: true });
16324
+ tr.forceUpdate();
16325
+ }
16326
+ if (shapeUnder && tr.getChildren().includes(shapeUnder) && shapeUnder.name() === "back") {
16327
+ tr.setAttrs({ listening: false });
16328
+ tr.forceUpdate();
16329
+ }
16330
+ if (shapeUnder && tr.nodes()[0].getChildren().includes(shapeUnder)) {
16331
+ tr.setAttrs({ listening: false });
16332
+ tr.forceUpdate();
16333
+ }
16334
+ if (shapeUnder && !tr.getChildren().includes(shapeUnder) && tr.nodes()[0].getChildren().includes(shapeUnder)) {
16335
+ tr.setAttrs({ listening: true });
16336
+ tr.forceUpdate();
16337
+ }
16338
+ }
16339
+ });
16284
16340
  tr.on("transformstart", () => {
16285
16341
  this.triggerSelectedNodesEvent();
16286
16342
  });
@@ -16370,12 +16426,10 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16370
16426
  const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
16371
16427
  if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(node));
16372
16428
  let containerToMove = this.instance.getMainLayer();
16373
- if (layerToMove) {
16374
- containerToMove = layerToMove;
16375
- containerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, { bubbles: true });
16376
- }
16429
+ if (layerToMove) containerToMove = layerToMove;
16377
16430
  let moved = false;
16378
16431
  if (containerToMove && !selectionContainsFrames) moved = moveNodeToContainer(this.instance, node, containerToMove);
16432
+ if (containerToMove) containerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, { bubbles: true });
16379
16433
  if (!nodeHandler) return resolve();
16380
16434
  toSelect.push(node.getAttrs().id ?? "");
16381
16435
  if (!moved) toUpdate.push(nodeHandler.serialize(node));
@@ -16592,6 +16646,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16592
16646
  };
16593
16647
  stage.on("pointermove", handleMouseMove);
16594
16648
  stage.on("pointerup", (e) => {
16649
+ this.tr.setAttrs({ listening: true });
16595
16650
  const moved = this.checkMoved(e);
16596
16651
  this.checkDoubleTap(e);
16597
16652
  delete this.pointers[e.evt.pointerId];
@@ -16858,6 +16913,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16858
16913
  //#endregion
16859
16914
  //#region src/plugins/copy-paste-nodes/constants.ts
16860
16915
  const WEAVE_COPY_PASTE_NODES_KEY = "copyPasteNodes";
16916
+ const WEAVE_COPY_PASTE_PASTE_CATCHER_ID = "weave-paste-catcher";
16861
16917
  const WEAVE_COPY_PASTE_PASTE_MODES = {
16862
16918
  ["INTERNAL"]: "internal",
16863
16919
  ["EXTERNAL"]: "external",
@@ -16883,18 +16939,6 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
16883
16939
  onInit() {
16884
16940
  this.initEvents();
16885
16941
  }
16886
- readClipboardData() {
16887
- return new Promise((resolve, reject) => {
16888
- setTimeout(async () => {
16889
- if (typeof navigator.clipboard === "undefined") return reject(new Error("Clipboard API not supported"));
16890
- navigator.clipboard.readText().then((text) => {
16891
- resolve(this.isWeaveData(text));
16892
- }).catch((error) => {
16893
- reject(error);
16894
- });
16895
- });
16896
- });
16897
- }
16898
16942
  writeClipboardData(data) {
16899
16943
  return new Promise((resolve, reject) => {
16900
16944
  setTimeout(async () => {
@@ -16907,8 +16951,36 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
16907
16951
  });
16908
16952
  });
16909
16953
  }
16954
+ existsPasteCatcher() {
16955
+ return document.getElementById(WEAVE_COPY_PASTE_PASTE_CATCHER_ID) !== null;
16956
+ }
16957
+ createPasteCatcher() {
16958
+ const stage = this.instance.getStage();
16959
+ if (!this.existsPasteCatcher()) {
16960
+ const catcher = document.createElement("div");
16961
+ catcher.id = WEAVE_COPY_PASTE_PASTE_CATCHER_ID;
16962
+ catcher.contentEditable = "true";
16963
+ catcher.style.position = "absolute";
16964
+ catcher.style.top = "-1px";
16965
+ catcher.style.left = "-1px";
16966
+ catcher.style.width = "1px";
16967
+ catcher.style.height = "1px";
16968
+ catcher.style.zIndex = "-1";
16969
+ catcher.style.outline = "none";
16970
+ catcher.style.opacity = "0";
16971
+ catcher.tabIndex = 0;
16972
+ const stageContainer = stage.container();
16973
+ if (stageContainer?.parentNode) stageContainer.parentNode.appendChild(catcher);
16974
+ }
16975
+ }
16976
+ focusPasteCatcher() {
16977
+ const catcher = document.getElementById(WEAVE_COPY_PASTE_PASTE_CATCHER_ID);
16978
+ catcher?.focus();
16979
+ }
16910
16980
  initEvents() {
16911
16981
  const stage = this.instance.getStage();
16982
+ this.createPasteCatcher();
16983
+ const catcher = document.getElementById(WEAVE_COPY_PASTE_PASTE_CATCHER_ID);
16912
16984
  window.addEventListener("keydown", async (e) => {
16913
16985
  if (stage.isFocused() && e.key === "c" && (e.ctrlKey || e.metaKey)) {
16914
16986
  e.preventDefault();
@@ -16916,49 +16988,49 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
16916
16988
  return;
16917
16989
  }
16918
16990
  if (stage.isFocused() && e.key === "v" && (e.ctrlKey || e.metaKey)) {
16919
- const catcher = document.getElementById("paste-catcher");
16920
- catcher?.focus();
16991
+ this.focusPasteCatcher();
16921
16992
  if (!this.enabled) return;
16922
- try {
16923
- if (this.isClipboardAPIAvailable()) {
16924
- const continueToPaste = await this.readClipboardData();
16925
- if (continueToPaste) {
16926
- this.state = COPY_PASTE_NODES_PLUGIN_STATE.PASTING;
16927
- this.handlePaste();
16928
- e.preventDefault();
16929
- return;
16930
- }
16931
- }
16932
- } catch (ex) {
16933
- this.instance.emitEvent("onPaste", ex);
16934
- }
16935
- e.preventDefault();
16936
- stage.container().focus();
16937
- return;
16938
16993
  }
16939
16994
  });
16940
- document.addEventListener("paste", async (e) => {
16995
+ if (catcher) catcher.addEventListener("paste", async (e) => {
16941
16996
  e.preventDefault();
16942
- const items = e.clipboardData?.items;
16943
- if (!items) return;
16997
+ const dataList = e.clipboardData?.items;
16998
+ let items = void 0;
16999
+ if (!items) {
17000
+ if (this.isClipboardAPIAvailable()) items = await navigator.clipboard.read();
17001
+ }
17002
+ if (!items && !dataList) return;
16944
17003
  let hasWeaveData = false;
16945
17004
  if (this.isClipboardAPIAvailable()) {
16946
- for (const item of items) if (item.type === "text/plain") {
16947
- const text = await this.getTextFromClipboard(item);
16948
- if (this.isWeaveData(text)) {
16949
- hasWeaveData = true;
16950
- this.toPaste = JSON.parse(text);
16951
- }
17005
+ const readText = await navigator.clipboard.readText();
17006
+ const continueToPaste = this.isWeaveData(readText);
17007
+ if (continueToPaste) hasWeaveData = true;
17008
+ } else for (const item of dataList ?? []) if (item.type === "text/plain") {
17009
+ const text = await this.getTextFromClipboard(item);
17010
+ if (this.isWeaveData(text)) {
17011
+ hasWeaveData = true;
17012
+ this.toPaste = JSON.parse(text);
16952
17013
  }
16953
17014
  }
16954
17015
  if (hasWeaveData) {
16955
17016
  this.handlePaste();
16956
17017
  return;
16957
17018
  }
16958
- const position = this.instance.getStage().getRelativePointerPosition();
16959
- if (position) this.instance.emitEvent("onPasteExternal", {
16960
- position,
16961
- dataList: items
17019
+ const container = stage.container();
17020
+ const scale = stage.scale();
17021
+ const position = stage.position();
17022
+ const width = container.clientWidth;
17023
+ const height = container.clientHeight;
17024
+ const centerX = (width / 2 - position.x) / scale.x;
17025
+ const centerY = (height / 2 - position.y) / scale.y;
17026
+ const pastePosition = {
17027
+ x: centerX,
17028
+ y: centerY
17029
+ };
17030
+ this.instance.emitEvent("onPasteExternal", {
17031
+ position: pastePosition,
17032
+ dataList,
17033
+ items
16962
17034
  });
16963
17035
  });
16964
17036
  }
@@ -16984,8 +17056,8 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
16984
17056
  }
16985
17057
  mapToPasteNodes() {
16986
17058
  const nodesSelectionPlugin = this.getNodesSelectionPlugin();
16987
- const selectedNodes = nodesSelectionPlugin.getSelectedNodes();
16988
- return selectedNodes.map((node) => ({
17059
+ const selectedNodes = nodesSelectionPlugin?.getSelectedNodes();
17060
+ return (selectedNodes ?? []).map((node) => ({
16989
17061
  konvaNode: node,
16990
17062
  node: node.getAttrs()
16991
17063
  }));
@@ -17001,22 +17073,50 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
17001
17073
  if (child.props.children) this.recursivelyUpdateKeys(child.props.children);
17002
17074
  }
17003
17075
  }
17004
- handlePaste() {
17076
+ handlePaste(position, relativePosition) {
17077
+ const stage = this.instance.getStage();
17005
17078
  if (this.toPaste) {
17006
- const { mousePoint, container } = this.instance.getMousePointer();
17079
+ const nodesToSelect = [];
17007
17080
  for (const element of Object.keys(this.toPaste.weave)) {
17008
- const node = this.toPaste.weave[element];
17081
+ const node = this.toPaste.weave[element].element;
17082
+ const posRelativeToSelection = this.toPaste.weave[element].posRelativeToSelection;
17083
+ let containerId = this.toPaste.weave[element].containerId;
17009
17084
  if (node.props.children) this.recursivelyUpdateKeys(node.props.children);
17010
17085
  const newNodeId = v4_default();
17011
17086
  delete node.props.containerId;
17012
17087
  node.key = newNodeId;
17013
17088
  node.props.id = newNodeId;
17014
- node.props.x = mousePoint.x + (node.props.x - this.toPaste.weaveMinPoint.x);
17015
- node.props.y = mousePoint.y + (node.props.y - this.toPaste.weaveMinPoint.y);
17016
- this.instance.addNode(node, container?.getAttrs().id);
17089
+ if (position) {
17090
+ const container = containerOverCursor(this.instance, [], relativePosition);
17091
+ let localPos = position;
17092
+ if (!container) {
17093
+ containerId = this.instance.getMainLayer()?.getAttrs().id ?? "";
17094
+ const scale = stage.scaleX();
17095
+ const stagePos = stage.position();
17096
+ localPos = {
17097
+ x: (localPos.x - stagePos.x) / scale,
17098
+ y: (localPos.y - stagePos.y) / scale
17099
+ };
17100
+ }
17101
+ if (container && container.getAttrs().nodeType === "frame") {
17102
+ containerId = container.getAttrs().id ?? "";
17103
+ localPos = container.getAbsoluteTransform().copy().invert().point(position);
17104
+ }
17105
+ const nodeHandler = this.instance.getNodeHandler(node.props.nodeType ?? "");
17106
+ if (nodeHandler) {
17107
+ const realOffset = nodeHandler.realOffset(node);
17108
+ node.props.x = localPos.x + realOffset.x + posRelativeToSelection.x;
17109
+ node.props.y = localPos.y + realOffset.y + posRelativeToSelection.y;
17110
+ }
17111
+ }
17112
+ this.instance.addNode(node, containerId);
17113
+ const realNode = this.instance.getStage().findOne(`#${newNodeId}`);
17114
+ if (realNode) nodesToSelect.push(realNode);
17017
17115
  this.instance.emitEvent("onPaste");
17018
- this.instance.emitEvent("onPaste", void 0);
17019
17116
  }
17117
+ this.instance.emitEvent("onPaste", void 0);
17118
+ const nodesSelectionPlugin = this.getNodesSelectionPlugin();
17119
+ nodesSelectionPlugin?.setSelectedNodes(nodesToSelect);
17020
17120
  this.toPaste = void 0;
17021
17121
  }
17022
17122
  this.cancel();
@@ -17028,8 +17128,9 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
17028
17128
  stage.container().focus();
17029
17129
  this.setState(COPY_PASTE_NODES_PLUGIN_STATE.IDLE);
17030
17130
  const nodesSelectionPlugin = this.getNodesSelectionPlugin();
17031
- const selectedNodes = nodesSelectionPlugin.getSelectedNodes();
17032
- if (selectedNodes.length === 0) return;
17131
+ const selectedNodes = nodesSelectionPlugin?.getSelectedNodes();
17132
+ if (!selectedNodes || selectedNodes.length === 0) return;
17133
+ const box = getBoundingBox(stage, selectedNodes);
17033
17134
  const copyClipboard = {
17034
17135
  weaveInstanceId: this.instance.getId(),
17035
17136
  weave: {},
@@ -17038,33 +17139,67 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
17038
17139
  y: 0
17039
17140
  }
17040
17141
  };
17041
- const result = this.instance.nodesToGroupSerialized(selectedNodes);
17042
- if (result && result.serializedNodes && result.serializedNodes.length > 0) {
17043
- copyClipboard.weaveMinPoint = result.minPoint;
17044
- for (const serializedNode of result.serializedNodes) copyClipboard.weave[serializedNode.key ?? ""] = serializedNode;
17045
- try {
17046
- await this.writeClipboardData(JSON.stringify(copyClipboard));
17047
- this.instance.emitEvent("onCopy");
17048
- } catch (ex) {
17049
- this.instance.emitEvent("onCopy", ex);
17050
- }
17142
+ for (const node of selectedNodes) {
17143
+ const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
17144
+ if (!nodeHandler) continue;
17145
+ const parentNode = node.getParent();
17146
+ let parentId = parentNode?.getAttrs().id;
17147
+ if (parentNode?.getAttrs().nodeId) {
17148
+ const realParent = this.instance.getStage().findOne(`#${parentNode.getAttrs().nodeId}`);
17149
+ if (realParent) parentId = realParent.getAttrs().id;
17150
+ }
17151
+ if (!parentId) continue;
17152
+ const serializedNode = nodeHandler.serialize(node);
17153
+ const nodeBox = node.getClientRect({ relativeTo: stage });
17154
+ copyClipboard.weave[serializedNode.key ?? ""] = {
17155
+ element: serializedNode,
17156
+ posRelativeToSelection: {
17157
+ x: nodeBox.x - (box?.x ?? 0),
17158
+ y: nodeBox.y - (box?.y ?? 0)
17159
+ },
17160
+ containerId: parentId
17161
+ };
17162
+ }
17163
+ try {
17164
+ await this.writeClipboardData(JSON.stringify(copyClipboard));
17165
+ this.instance.emitEvent("onCopy");
17166
+ } catch (ex) {
17167
+ this.instance.emitEvent("onCopy", ex);
17051
17168
  }
17052
17169
  }
17053
17170
  async copy() {
17054
17171
  await this.performCopy();
17055
17172
  }
17056
- async paste() {
17173
+ async paste(position, relativePosition) {
17174
+ const stage = this.instance.getStage();
17057
17175
  try {
17058
- const continueToPaste = await this.readClipboardData();
17059
- if (continueToPaste) this.handlePaste();
17176
+ const readText = await navigator.clipboard.readText();
17177
+ const continueToPaste = this.isWeaveData(readText);
17178
+ if (continueToPaste) {
17179
+ this.handlePaste(position, relativePosition);
17180
+ return;
17181
+ }
17060
17182
  } catch (ex) {
17061
17183
  this.instance.emitEvent("onPaste", ex);
17062
17184
  }
17063
17185
  try {
17064
17186
  const items = await navigator.clipboard.read();
17065
- const position = this.instance.getStage().getRelativePointerPosition();
17066
- if (position) this.instance.emitEvent("onPasteExternal", {
17067
- position,
17187
+ let pastePosition = position;
17188
+ if (typeof pastePosition === "undefined") {
17189
+ const container = stage.container();
17190
+ const scale = stage.scale();
17191
+ const position$1 = stage.position();
17192
+ const centerClientX = container.clientWidth / 2;
17193
+ const centerClientY = container.clientHeight / 2;
17194
+ const centerX = (centerClientX - position$1.x) / scale.x;
17195
+ const centerY = (centerClientY - position$1.y) / scale.y;
17196
+ pastePosition = {
17197
+ x: centerX,
17198
+ y: centerY
17199
+ };
17200
+ }
17201
+ this.instance.emitEvent("onPasteExternal", {
17202
+ position: pastePosition,
17068
17203
  items
17069
17204
  });
17070
17205
  } catch (ex) {
@@ -17086,7 +17221,6 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
17086
17221
  }
17087
17222
  getNodesSelectionPlugin() {
17088
17223
  const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
17089
- if (!nodesSelectionPlugin) throw new Error("WeaveNodesSelectionPlugin plugin not found");
17090
17224
  return nodesSelectionPlugin;
17091
17225
  }
17092
17226
  isClipboardApiEnabled() {
@@ -17095,7 +17229,8 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
17095
17229
  async getAvailablePasteMode(canHandleExternal) {
17096
17230
  if (!this.isClipboardApiEnabled()) return WEAVE_COPY_PASTE_PASTE_MODES.CLIPBOARD_API_NOT_SUPPORTED;
17097
17231
  try {
17098
- const allowPaste = await this.readClipboardData();
17232
+ const readText = await navigator.clipboard.readText();
17233
+ const allowPaste = this.isWeaveData(readText);
17099
17234
  if (allowPaste) return WEAVE_COPY_PASTE_PASTE_MODES.INTERNAL;
17100
17235
  const items = await navigator.clipboard.read();
17101
17236
  if (await canHandleExternal(items)) return WEAVE_COPY_PASTE_PASTE_MODES.EXTERNAL;
@@ -17314,7 +17449,7 @@ var WeaveNode = class {
17314
17449
  if (this.isSelecting() && this.isNodeSelected(node) && this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
17315
17450
  clearContainerTargets(this.instance);
17316
17451
  const layerToMove = containerOverCursor(this.instance, [node]);
17317
- if (layerToMove && !hasFrames(node)) layerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetEnter, { bubbles: true });
17452
+ if (layerToMove && !hasFrames(node) && node.isDragging()) layerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetEnter, { bubbles: true });
17318
17453
  }
17319
17454
  };
17320
17455
  node.on("dragmove", (0, import_lodash.throttle)(handleDragMove, 100));
@@ -17334,12 +17469,10 @@ var WeaveNode = class {
17334
17469
  if (nodesDistanceSnappingPlugin) nodesDistanceSnappingPlugin.cleanupGuidelines();
17335
17470
  const layerToMove = containerOverCursor(this.instance, [node]);
17336
17471
  let containerToMove = this.instance.getMainLayer();
17337
- if (layerToMove) {
17338
- containerToMove = layerToMove;
17339
- containerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, { bubbles: true });
17340
- }
17472
+ if (layerToMove) containerToMove = layerToMove;
17341
17473
  let moved = false;
17342
17474
  if (containerToMove && !hasFrames(node)) moved = moveNodeToContainer(this.instance, e.target, containerToMove);
17475
+ if (containerToMove) containerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, { bubbles: true });
17343
17476
  if (!moved) this.instance.updateNode(this.serialize(node));
17344
17477
  }
17345
17478
  });
@@ -17479,6 +17612,12 @@ var WeaveNode = class {
17479
17612
  const snappingPlugin = this.instance.getPlugin(WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY);
17480
17613
  return snappingPlugin;
17481
17614
  }
17615
+ realOffset(instance) {
17616
+ return {
17617
+ x: 0,
17618
+ y: 0
17619
+ };
17620
+ }
17482
17621
  };
17483
17622
 
17484
17623
  //#endregion
@@ -18192,30 +18331,10 @@ var WeaveTargetingManager = class {
18192
18331
  }
18193
18332
  isNodesBoundingBoxIntersecting(nodes, nodeB) {
18194
18333
  const stage = this.instance.getStage();
18195
- const a = this.getBoundingBoxOfNodes(nodes);
18334
+ const a = getBoundingBox(stage, nodes);
18196
18335
  const b = nodeB.getClientRect({ relativeTo: stage });
18197
18336
  return !(a.x + a.width < b.x || a.x > b.x + b.width || a.y + a.height < b.y || a.y > b.y + b.height);
18198
18337
  }
18199
- getBoundingBoxOfNodes(nodes) {
18200
- const stage = this.instance.getStage();
18201
- if (!nodes || nodes.length === 0) return {
18202
- x: 0,
18203
- y: 0,
18204
- width: 0,
18205
- height: 0
18206
- };
18207
- const rects = nodes.map((node) => node.getClientRect({ relativeTo: stage }));
18208
- const minX = Math.min(...rects.map((r) => r.x));
18209
- const minY = Math.min(...rects.map((r) => r.y));
18210
- const maxX = Math.max(...rects.map((r) => r.x + r.width));
18211
- const maxY = Math.max(...rects.map((r) => r.y + r.height));
18212
- return {
18213
- x: minX,
18214
- y: minY,
18215
- width: maxX - minX,
18216
- height: maxY - minY
18217
- };
18218
- }
18219
18338
  nodeIntersectsContainerElement(node, actualLayer) {
18220
18339
  const stage = this.instance.getStage();
18221
18340
  const containers = stage.find(".containerCapable");
@@ -18235,7 +18354,7 @@ var WeaveTargetingManager = class {
18235
18354
  }
18236
18355
  } else {
18237
18356
  let nodeActualContainer = node.getParent();
18238
- if (nodeActualContainer.getAttrs().nodeId) {
18357
+ if (nodeActualContainer?.getAttrs().nodeId) {
18239
18358
  const realParent = stage.findOne(`#${nodeActualContainer.getAttrs().nodeId}`);
18240
18359
  if (realParent) nodeActualContainer = realParent;
18241
18360
  }
@@ -18264,7 +18383,7 @@ var WeaveTargetingManager = class {
18264
18383
  this.logger.debug({ point }, "getMousePointer");
18265
18384
  const stage = this.instance.getStage();
18266
18385
  const mainLayer = this.instance.getMainLayer();
18267
- let relativeMousePointer = point ? point : mainLayer?.getRelativePointerPosition() ?? {
18386
+ let relativeMousePointer = typeof point !== "undefined" ? point : mainLayer?.getRelativePointerPosition() ?? {
18268
18387
  x: 0,
18269
18388
  y: 0
18270
18389
  };
@@ -18287,8 +18406,8 @@ var WeaveTargetingManager = class {
18287
18406
  measureContainer = containerOfNode;
18288
18407
  }
18289
18408
  }
18290
- if (container?.getAttrs().nodeType !== "layer") relativeMousePointer = measureContainer?.getRelativePointerPosition() ?? relativeMousePointer;
18291
- if (container?.getAttrs().nodeType === "layer") relativeMousePointer = measureContainer?.getRelativePointerPosition() ?? {
18409
+ if (typeof point === "undefined" && container?.getAttrs().nodeType !== "layer") relativeMousePointer = measureContainer?.getRelativePointerPosition() ?? relativeMousePointer;
18410
+ if (typeof point === "undefined" && container?.getAttrs().nodeType === "layer") relativeMousePointer = measureContainer?.getRelativePointerPosition() ?? {
18292
18411
  x: 0,
18293
18412
  y: 0
18294
18413
  };
@@ -19046,7 +19165,7 @@ var WeaveRegisterManager = class {
19046
19165
 
19047
19166
  //#endregion
19048
19167
  //#region package.json
19049
- var version = "0.51.0";
19168
+ var version = "0.52.1";
19050
19169
 
19051
19170
  //#endregion
19052
19171
  //#region src/managers/setup.ts
@@ -20052,7 +20171,7 @@ var WeaveEllipseNode = class extends WeaveNode {
20052
20171
  ellipse.allowedAnchors = () => {
20053
20172
  const stage = this.instance.getStage();
20054
20173
  const actualEllipse = stage.findOne(`#${ellipse.id()}`);
20055
- if (actualEllipse.getAttrs().keepAspectRatio) return [
20174
+ if (actualEllipse?.getAttrs().keepAspectRatio) return [
20056
20175
  "top-left",
20057
20176
  "top-right",
20058
20177
  "bottom-left",
@@ -20089,6 +20208,12 @@ var WeaveEllipseNode = class extends WeaveNode {
20089
20208
  y: 1
20090
20209
  });
20091
20210
  }
20211
+ realOffset(element) {
20212
+ return {
20213
+ x: element.props.radiusX,
20214
+ y: element.props.radiusY
20215
+ };
20216
+ }
20092
20217
  };
20093
20218
 
20094
20219
  //#endregion
@@ -20631,6 +20756,7 @@ var WeaveImageToolAction = class extends WeaveAction {
20631
20756
  initialized = false;
20632
20757
  initialCursor = null;
20633
20758
  cursorPadding = 5;
20759
+ forceMainContainer = false;
20634
20760
  onPropsChange = void 0;
20635
20761
  update = void 0;
20636
20762
  constructor() {
@@ -20723,10 +20849,8 @@ var WeaveImageToolAction = class extends WeaveAction {
20723
20849
  crossOrigin: "anonymous",
20724
20850
  ...options
20725
20851
  };
20726
- if (!position) {
20727
- stage.container().style.cursor = "crosshair";
20728
- stage.container().focus();
20729
- }
20852
+ stage.container().style.cursor = "crosshair";
20853
+ stage.container().focus();
20730
20854
  this.imageId = v4_default();
20731
20855
  this.imageURL = imageURL;
20732
20856
  this.preloadImgs[this.imageId] = new Image();
@@ -20753,10 +20877,8 @@ var WeaveImageToolAction = class extends WeaveAction {
20753
20877
  }
20754
20878
  addImageNode(position) {
20755
20879
  const stage = this.instance.getStage();
20756
- if (!position) {
20757
- stage.container().style.cursor = "crosshair";
20758
- stage.container().focus();
20759
- }
20880
+ stage.container().style.cursor = "crosshair";
20881
+ stage.container().focus();
20760
20882
  if (position) {
20761
20883
  this.setState(IMAGE_TOOL_STATE.SELECTED_POSITION);
20762
20884
  this.handleAdding(position);
@@ -20816,8 +20938,11 @@ var WeaveImageToolAction = class extends WeaveAction {
20816
20938
  height: this.preloadImgs[this.imageId].height
20817
20939
  }
20818
20940
  });
20819
- this.instance.addNode(node, this.container?.getAttrs().id);
20820
- this.instance.emitEvent("onAddedImage", { imageURL: this.props.imageURL });
20941
+ this.instance.addNode(node, this.forceMainContainer ? this.instance.getMainLayer()?.getAttrs().id : this.container?.getAttrs().id);
20942
+ this.instance.emitEvent("onAddedImage", {
20943
+ imageURL: this.props.imageURL,
20944
+ nodeId: this.imageId
20945
+ });
20821
20946
  }
20822
20947
  this.setState(IMAGE_TOOL_STATE.FINISHED);
20823
20948
  }
@@ -20829,6 +20954,7 @@ var WeaveImageToolAction = class extends WeaveAction {
20829
20954
  this.cancelAction = cancelAction;
20830
20955
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
20831
20956
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
20957
+ this.forceMainContainer = params?.forceMainContainer ?? false;
20832
20958
  if (params?.imageURL) {
20833
20959
  this.loadImage(params.imageURL, params?.options ?? void 0, params?.position ?? void 0);
20834
20960
  return;
@@ -20850,6 +20976,7 @@ var WeaveImageToolAction = class extends WeaveAction {
20850
20976
  stage.container().style.cursor = "default";
20851
20977
  this.initialCursor = null;
20852
20978
  this.imageId = null;
20979
+ this.forceMainContainer = false;
20853
20980
  this.container = void 0;
20854
20981
  this.imageURL = null;
20855
20982
  this.clickPoint = null;
@@ -21686,6 +21813,12 @@ var WeaveStarNode = class extends WeaveNode {
21686
21813
  y: 1
21687
21814
  });
21688
21815
  }
21816
+ realOffset(element) {
21817
+ return {
21818
+ x: element.props.outerRadius,
21819
+ y: element.props.outerRadius
21820
+ };
21821
+ }
21689
21822
  };
21690
21823
 
21691
21824
  //#endregion
@@ -21803,6 +21936,12 @@ var WeaveRegularPolygonNode = class extends WeaveNode {
21803
21936
  y: 1
21804
21937
  });
21805
21938
  }
21939
+ realOffset(element) {
21940
+ return {
21941
+ x: element.props.radius,
21942
+ y: element.props.radius
21943
+ };
21944
+ }
21806
21945
  };
21807
21946
 
21808
21947
  //#endregion
@@ -22471,20 +22610,39 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
22471
22610
  });
22472
22611
  this.setZoom(scale, false);
22473
22612
  }
22474
- fitToSelection() {
22613
+ fitToSelection(smartZoom = false) {
22475
22614
  if (!this.enabled) return;
22476
22615
  const stage = this.instance.getStage();
22477
22616
  const selectionPlugin = this.getNodesSelectionPlugin();
22478
22617
  if (!selectionPlugin) return;
22479
22618
  const nodes = selectionPlugin.getTransformer().getNodes();
22480
22619
  if (nodes.length === 0) return;
22620
+ const box = getBoundingBox(stage, selectionPlugin.getTransformer().getNodes());
22621
+ if (box.width === 0 || box.height === 0) return;
22622
+ const container = stage.container();
22623
+ const scale = stage.scale();
22624
+ const viewportWidth = container.clientWidth;
22625
+ const viewportHeight = container.clientHeight;
22626
+ const visibleStageWidth = viewportWidth / scale.x;
22627
+ const visibleStageHeight = viewportHeight / scale.y;
22628
+ const fitsInView = box.width + this.config.fitToSelection.padding * 2 <= visibleStageWidth && box.height + this.config.fitToSelection.padding * 2 <= visibleStageHeight;
22629
+ const selectionCenter = {
22630
+ x: box.x + box.width / 2,
22631
+ y: box.y + box.height / 2
22632
+ };
22633
+ if (smartZoom && fitsInView) {
22634
+ const newPosition = {
22635
+ x: viewportWidth / 2 - selectionCenter.x * scale.x,
22636
+ y: viewportHeight / 2 - selectionCenter.y * scale.y
22637
+ };
22638
+ stage.position(newPosition);
22639
+ return;
22640
+ }
22481
22641
  this.setZoom(1, false);
22482
22642
  stage.setAttrs({
22483
22643
  x: 0,
22484
22644
  y: 0
22485
22645
  });
22486
- const box = getBoundingBox(stage, selectionPlugin.getTransformer().getNodes());
22487
- if (box.width === 0 || box.height === 0) return;
22488
22646
  const stageBox = {
22489
22647
  width: stage.width(),
22490
22648
  height: stage.height()
@@ -22493,22 +22651,22 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
22493
22651
  const availableScreenHeight = stageBox.height - 2 * this.config.fitToSelection.padding;
22494
22652
  const scaleX = availableScreenWidth / box.width;
22495
22653
  const scaleY = availableScreenHeight / box.height;
22496
- const scale = Math.min(scaleX, scaleY);
22654
+ const finalScale = Math.min(scaleX, scaleY);
22497
22655
  stage.scale({
22498
- x: scale,
22499
- y: scale
22656
+ x: finalScale,
22657
+ y: finalScale
22500
22658
  });
22501
22659
  const selectionCenterX = box.x + box.width / 2;
22502
22660
  const selectionCenterY = box.y + box.height / 2;
22503
- const canvasCenterX = stage.width() / (2 * scale);
22504
- const canvasCenterY = stage.height() / (2 * scale);
22505
- const stageX = (canvasCenterX - selectionCenterX) * scale;
22506
- const stageY = (canvasCenterY - selectionCenterY) * scale;
22661
+ const canvasCenterX = stage.width() / (2 * finalScale);
22662
+ const canvasCenterY = stage.height() / (2 * finalScale);
22663
+ const stageX = (canvasCenterX - selectionCenterX) * finalScale;
22664
+ const stageY = (canvasCenterY - selectionCenterY) * finalScale;
22507
22665
  stage.position({
22508
22666
  x: stageX,
22509
22667
  y: stageY
22510
22668
  });
22511
- this.setZoom(scale, false);
22669
+ this.setZoom(finalScale, false);
22512
22670
  }
22513
22671
  enable() {
22514
22672
  this.enabled = true;
@@ -22603,20 +22761,21 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
22603
22761
  lastCenter = null;
22604
22762
  }, { passive: false });
22605
22763
  const handleWheel = (e) => {
22606
- e.evt.preventDefault();
22607
- const stage$1 = this.instance.getStage();
22608
- const performZoom = this.isCtrlOrMetaPressed || !this.isCtrlOrMetaPressed && e.evt.ctrlKey && e.evt.deltaMode === 0;
22609
- if (!this.enabled || !stage$1.isFocused() || !performZoom) return;
22610
- const delta = e.evt.deltaY > 0 ? 1 : -1;
22764
+ const performZoom = this.isCtrlOrMetaPressed || !this.isCtrlOrMetaPressed && e.ctrlKey && e.deltaMode === 0;
22765
+ const mouseX = e.clientX;
22766
+ const mouseY = e.clientY;
22767
+ const elementUnderMouse = document.elementFromPoint(mouseX, mouseY);
22768
+ if (!this.enabled || !performZoom || getClosestParentWithId(elementUnderMouse) !== stage.container()) return;
22769
+ const delta = e.deltaY > 0 ? 1 : -1;
22611
22770
  this.zoomVelocity += delta;
22612
- this.isTrackpad = Math.abs(e.evt.deltaY) < 15 && e.evt.deltaMode === 0;
22771
+ this.isTrackpad = Math.abs(e.deltaY) < 15 && e.deltaMode === 0;
22613
22772
  if (!this.zooming) {
22614
22773
  this.zooming = true;
22615
22774
  this.zoomInertiaType = WEAVE_STAGE_ZOOM_TYPE.MOUSE_WHEEL;
22616
22775
  requestAnimationFrame(this.zoomTick.bind(this));
22617
22776
  }
22618
22777
  };
22619
- stage.on("wheel", handleWheel);
22778
+ window.addEventListener("wheel", handleWheel, { passive: false });
22620
22779
  }
22621
22780
  getInertiaScale() {
22622
22781
  const stage = this.instance.getStage();
@@ -22789,7 +22948,7 @@ var WeaveFitToSelectionToolAction = class extends WeaveAction {
22789
22948
  }
22790
22949
  trigger(cancelAction, params) {
22791
22950
  const stageZoomPlugin = this.getStageZoomPlugin();
22792
- stageZoomPlugin.fitToSelection();
22951
+ stageZoomPlugin.fitToSelection(params?.smartZoom ?? false);
22793
22952
  this.previousAction = params.previousAction;
22794
22953
  this.cancelAction = cancelAction;
22795
22954
  this.cancelAction();
@@ -25111,7 +25270,7 @@ const WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO = 4;
25111
25270
  const WEAVE_GRID_DEFAULT_RADIUS = 1;
25112
25271
  const WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO = 2;
25113
25272
  const WEAVE_GRID_DEFAULT_MAJOR_EVERY = 10;
25114
- const WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS = 300;
25273
+ const WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS = 250;
25115
25274
  const WEAVE_GRID_LAYER_ID = "gridLayer";
25116
25275
 
25117
25276
  //#endregion
@@ -25486,16 +25645,17 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
25486
25645
  this.panning = false;
25487
25646
  });
25488
25647
  const handleWheel = (e) => {
25489
- e.evt.preventDefault();
25490
- const stage$1 = this.instance.getStage();
25491
- const performPanning = !this.isCtrlOrMetaPressed && !e.evt.ctrlKey;
25492
- if (!this.enabled || !stage$1.isFocused() || this.isCtrlOrMetaPressed || e.evt.buttons === 4 || !performPanning) return;
25648
+ const performPanning = !this.isCtrlOrMetaPressed && !e.ctrlKey;
25649
+ const mouseX = e.clientX;
25650
+ const mouseY = e.clientY;
25651
+ const elementUnderMouse = document.elementFromPoint(mouseX, mouseY);
25652
+ if (!this.enabled || this.isCtrlOrMetaPressed || e.buttons === 4 || !performPanning || getClosestParentWithId(elementUnderMouse) !== stage.container()) return;
25493
25653
  this.getContextMenuPlugin()?.cancelLongPressTimer();
25494
- stage$1.x(stage$1.x() - e.evt.deltaX);
25495
- stage$1.y(stage$1.y() - e.evt.deltaY);
25654
+ stage.x(stage.x() - e.deltaX);
25655
+ stage.y(stage.y() - e.deltaY);
25496
25656
  this.instance.emitEvent("onStageMove");
25497
25657
  };
25498
- stage.on("wheel", handleWheel);
25658
+ window.addEventListener("wheel", handleWheel, { passive: false });
25499
25659
  stage.container().style.touchAction = "none";
25500
25660
  stage.container().style.userSelect = "none";
25501
25661
  stage.container().style.setProperty("-webkit-user-drag", "none");
@@ -26894,6 +27054,7 @@ exports.TEXT_TOOL_ACTION_NAME = TEXT_TOOL_ACTION_NAME
26894
27054
  exports.TEXT_TOOL_STATE = TEXT_TOOL_STATE
26895
27055
  exports.WEAVE_ARROW_NODE_TYPE = WEAVE_ARROW_NODE_TYPE
26896
27056
  exports.WEAVE_COPY_PASTE_NODES_KEY = WEAVE_COPY_PASTE_NODES_KEY
27057
+ exports.WEAVE_COPY_PASTE_PASTE_CATCHER_ID = WEAVE_COPY_PASTE_PASTE_CATCHER_ID
26897
27058
  exports.WEAVE_COPY_PASTE_PASTE_MODES = WEAVE_COPY_PASTE_PASTE_MODES
26898
27059
  exports.WEAVE_DEFAULT_USER_INFO_FUNCTION = WEAVE_DEFAULT_USER_INFO_FUNCTION
26899
27060
  exports.WEAVE_ELLIPSE_NODE_TYPE = WEAVE_ELLIPSE_NODE_TYPE
@@ -26989,6 +27150,7 @@ exports.clearContainerTargets = clearContainerTargets
26989
27150
  exports.containerOverCursor = containerOverCursor
26990
27151
  exports.containsNodeDeep = containsNodeDeep
26991
27152
  exports.getBoundingBox = getBoundingBox
27153
+ exports.getClosestParentWithId = getClosestParentWithId
26992
27154
  exports.getContrastTextColor = getContrastTextColor
26993
27155
  exports.getExportBoundingBox = getExportBoundingBox
26994
27156
  exports.getSelectedNodesMetadata = getSelectedNodesMetadata