@flowgram.ai/free-layout-core 0.1.0-alpha.14 → 0.1.0-alpha.16

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/index.js CHANGED
@@ -26,8 +26,8 @@ var __decorateClass = (decorators, target, key, kind) => {
26
26
  };
27
27
 
28
28
  // src/index.ts
29
- var src_exports = {};
30
- __export(src_exports, {
29
+ var index_exports = {};
30
+ __export(index_exports, {
31
31
  EditorCursorState: () => EditorCursorState,
32
32
  InteractiveType: () => InteractiveType,
33
33
  LINE_HOVER_DISTANCE: () => LINE_HOVER_DISTANCE,
@@ -79,13 +79,12 @@ __export(src_exports, {
79
79
  usePlayground: () => import_core25.usePlayground,
80
80
  usePlaygroundContainer: () => import_core25.usePlaygroundContainer,
81
81
  usePlaygroundContext: () => import_core25.usePlaygroundContext,
82
- usePlaygroundLatest: () => import_core25.usePlaygroundLatest,
83
82
  usePlaygroundReadonlyState: () => usePlaygroundReadonlyState,
84
83
  useRefresh: () => import_core25.useRefresh,
85
84
  useService: () => import_core25.useService,
86
85
  useWorkflowDocument: () => useWorkflowDocument
87
86
  });
88
- module.exports = __toCommonJS(src_exports);
87
+ module.exports = __toCommonJS(index_exports);
89
88
 
90
89
  // src/workflow-commands.ts
91
90
  var WorkflowCommands = /* @__PURE__ */ ((WorkflowCommands2) => {
@@ -497,6 +496,7 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
497
496
  ...Array.from(elements).map((element) => ({
498
497
  portID: element.getAttribute("data-port-id"),
499
498
  type: element.getAttribute("data-port-type"),
499
+ location: element.getAttribute("data-port-location"),
500
500
  targetElement: element
501
501
  }))
502
502
  );
@@ -818,11 +818,11 @@ var WorkflowLineRenderData = class extends import_core7.EntityData {
818
818
  * WARNING: 这个方法,必须在 requestAnimationFrame / useLayoutEffect 中调用,否则会引起浏览器强制重排
819
819
  */
820
820
  updatePosition() {
821
- this.data.position.from = this.entity.from.getData(WorkflowNodePortsData).getOutputPoint(this.entity.info.fromPort);
821
+ this.data.position.from = this.entity.from.ports.getOutputPoint(this.entity.info.fromPort);
822
822
  if (this.entity.info.drawingTo) {
823
823
  this.data.position.to = this.entity.info.drawingTo;
824
824
  } else {
825
- this.data.position.to = this.entity.to?.getData(WorkflowNodePortsData)?.getInputPoint(this.entity.info.toPort) ?? {
825
+ this.data.position.to = this.entity.to?.ports?.getInputPoint(this.entity.info.toPort) ?? {
826
826
  x: this.data.position.from.x,
827
827
  y: this.data.position.from.y,
828
828
  location: this.data.position.from.location === "right" ? "left" : "top"
@@ -1084,13 +1084,13 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core8.Entity
1084
1084
  return this.getData(WorkflowLineRenderData).calcDistance(pos);
1085
1085
  }
1086
1086
  get fromPort() {
1087
- return this.from.getData(WorkflowNodePortsData).getPortEntityByKey("output", this.info.fromPort);
1087
+ return this.from.ports.getPortEntityByKey("output", this.info.fromPort);
1088
1088
  }
1089
1089
  get toPort() {
1090
1090
  if (!this.to) {
1091
1091
  return void 0;
1092
1092
  }
1093
- return this.to.getData(WorkflowNodePortsData).getPortEntityByKey("input", this.info.toPort);
1093
+ return this.to.ports.getPortEntityByKey("input", this.info.toPort);
1094
1094
  }
1095
1095
  /**
1096
1096
  * 获取线条真实的输入输出节点坐标
@@ -1120,7 +1120,9 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core8.Entity
1120
1120
  get disabled() {
1121
1121
  return this.linesManager.isDisabledLine(this, this.uiState.disabled);
1122
1122
  }
1123
- /** 是否竖向 */
1123
+ /**
1124
+ * @deprecated
1125
+ */
1124
1126
  get vertical() {
1125
1127
  const fromLocation = this.fromPort.location;
1126
1128
  const toLocation = this.toPort?.location;
@@ -1789,7 +1791,7 @@ var WorkflowLinesManager = class {
1789
1791
  */
1790
1792
  getPortFromMousePos(pos) {
1791
1793
  const allNodes = this.getSortedNodes().reverse();
1792
- const allPorts = allNodes.map((node) => node.getData(WorkflowNodePortsData).allPorts).flat();
1794
+ const allPorts = allNodes.map((node) => node.ports.allPorts).flat();
1793
1795
  const targetPort = allPorts.find((port) => port.isHovered(pos.x, pos.y));
1794
1796
  if (targetPort) {
1795
1797
  const containNodes = this.getContainNodesFromMousePos(pos);
@@ -2228,8 +2230,11 @@ var WorkflowDocument = class extends import_document8.FlowDocument {
2228
2230
  originParent,
2229
2231
  meta
2230
2232
  });
2233
+ this.options.preNodeCreate?.(node);
2231
2234
  const datas = dataRegistries ? this.nodeDataRegistries.concat(...dataRegistries) : this.nodeDataRegistries;
2232
2235
  node.addInitializeData(datas);
2236
+ node.ports = node.getData(WorkflowNodePortsData);
2237
+ node.lines = node.getData(WorkflowNodeLinesData);
2233
2238
  node.onDispose(() => this.onNodeDisposeEmitter.fire({ node }));
2234
2239
  this.options.fromNodeJSON?.(node, data, true);
2235
2240
  isNew = true;
@@ -2637,6 +2642,18 @@ function checkDragSuccess(time, e, originLine) {
2637
2642
  }
2638
2643
  return false;
2639
2644
  }
2645
+ function reverseLocation(sourceLocation) {
2646
+ switch (sourceLocation) {
2647
+ case "bottom":
2648
+ return "top";
2649
+ case "left":
2650
+ return "right";
2651
+ case "top":
2652
+ return "bottom";
2653
+ case "right":
2654
+ return "left";
2655
+ }
2656
+ }
2640
2657
  var WorkflowDragService = class {
2641
2658
  constructor() {
2642
2659
  this._onDragLineEventEmitter = new import_utils16.Emitter();
@@ -2668,10 +2685,6 @@ var WorkflowDragService = class {
2668
2685
  return Promise.resolve(false);
2669
2686
  }
2670
2687
  this.isDragging = true;
2671
- const sameParent = this.childrenOfContainer(selectedNodes);
2672
- if (sameParent && sameParent.flowNodeType !== import_document10.FlowNodeBaseType.ROOT) {
2673
- selectedNodes = [sameParent];
2674
- }
2675
2688
  let startPosition = this.getNodesPosition(selectedNodes);
2676
2689
  let startPositions = selectedNodes.map((node) => {
2677
2690
  const transform = node.getData(import_core15.TransformData);
@@ -2733,6 +2746,7 @@ var WorkflowDragService = class {
2733
2746
  triggerEvent,
2734
2747
  dragger
2735
2748
  });
2749
+ this.resetContainerInternalPosition(selectedNodes);
2736
2750
  }
2737
2751
  });
2738
2752
  const { clientX, clientY } = import_core15.MouseTouchEvent.getEventCoord(triggerEvent);
@@ -2773,7 +2787,7 @@ var WorkflowDragService = class {
2773
2787
  const targetNode = event.currentTarget;
2774
2788
  domNode = cloneNode ? cloneNode(e) : targetNode.cloneNode(true);
2775
2789
  const bounds = targetNode.getBoundingClientRect();
2776
- startPos = { x: bounds.left, y: bounds.top };
2790
+ startPos = { x: bounds.left + window.scrollX, y: bounds.top + window.scrollY };
2777
2791
  import_utils16.domUtils.setStyle(domNode, {
2778
2792
  zIndex: 1e3,
2779
2793
  position: "absolute",
@@ -3003,12 +3017,48 @@ var WorkflowDragService = class {
3003
3017
  };
3004
3018
  }
3005
3019
  }
3020
+ /**
3021
+ * 容器内子节点总体位置重置为0
3022
+ */
3023
+ resetContainerInternalPosition(nodes) {
3024
+ const container = this.childrenOfContainer(nodes);
3025
+ if (!container) {
3026
+ return;
3027
+ }
3028
+ const bounds = import_utils16.Rectangle.enlarge(
3029
+ container.blocks.map((node) => {
3030
+ const x = node.transform.position.x - node.transform.bounds.width / 2;
3031
+ const y = node.transform.position.y;
3032
+ const width = node.transform.bounds.width;
3033
+ const height = node.transform.bounds.height;
3034
+ return new import_utils16.Rectangle(x, y, width, height);
3035
+ })
3036
+ );
3037
+ const containerTransform = container.getData(import_core15.TransformData);
3038
+ containerTransform.update({
3039
+ position: {
3040
+ x: containerTransform.position.x + bounds.x,
3041
+ y: containerTransform.position.y + bounds.y
3042
+ }
3043
+ });
3044
+ this.document.layout.updateAffectedTransform(container);
3045
+ container.blocks.forEach((node) => {
3046
+ const transform = node.getData(import_core15.TransformData);
3047
+ transform.update({
3048
+ position: {
3049
+ x: transform.position.x - bounds.x,
3050
+ y: transform.position.y - bounds.y
3051
+ }
3052
+ });
3053
+ this.document.layout.updateAffectedTransform(node);
3054
+ });
3055
+ }
3006
3056
  childrenOfContainer(nodes) {
3007
3057
  if (nodes.length === 0) {
3008
3058
  return;
3009
3059
  }
3010
3060
  const sourceContainer = nodes[0]?.parent;
3011
- if (!sourceContainer || sourceContainer.collapsedChildren.length !== nodes.length) {
3061
+ if (!sourceContainer) {
3012
3062
  return;
3013
3063
  }
3014
3064
  const valid = nodes.every((node) => node?.parent === sourceContainer);
@@ -3094,7 +3144,7 @@ var WorkflowDragService = class {
3094
3144
  line.drawingTo = {
3095
3145
  x: dragPos.x,
3096
3146
  y: dragPos.y,
3097
- location: line.fromPort.location === "right" ? "left" : "top"
3147
+ location: reverseLocation(line.fromPort.location)
3098
3148
  };
3099
3149
  }
3100
3150
  originLine?.validate();
@@ -3209,7 +3259,7 @@ var WorkflowDragService = class {
3209
3259
  }
3210
3260
  /** 获取最近的 port */
3211
3261
  getNearestPort(node, mousePos) {
3212
- const portsData = node.getData(WorkflowNodePortsData);
3262
+ const portsData = node.ports;
3213
3263
  const distanceSortedPorts = portsData.inputPorts.sort((a, b) => {
3214
3264
  const aDistance = Math.abs(mousePos.y - a.point.y);
3215
3265
  const bDistance = Math.abs(mousePos.y - b.point.y);
@@ -3414,7 +3464,7 @@ var isFirefox = navigator?.userAgent?.includes?.("Firefox");
3414
3464
  function useNodeRender(nodeFromProps) {
3415
3465
  const node = nodeFromProps || (0, import_react2.useContext)(import_core21.PlaygroundEntityContext);
3416
3466
  const renderData = node.getData(import_document13.FlowNodeRenderData);
3417
- const portsData = node.getData(WorkflowNodePortsData);
3467
+ const portsData = node.ports;
3418
3468
  const readonly = usePlaygroundReadonlyState();
3419
3469
  const dragService = (0, import_core21.useService)(WorkflowDragService);
3420
3470
  const selectionService = (0, import_core21.useService)(WorkflowSelectService);
@@ -3639,11 +3689,35 @@ WorkflowDocumentContribution = __decorateClass([
3639
3689
 
3640
3690
  // src/utils/get-url-params.ts
3641
3691
  function getUrlParams() {
3642
- return location.search.replace(/^\?/, "").split("&").reduce((res, key) => {
3692
+ const paramsMap = /* @__PURE__ */ new Map();
3693
+ location.search.replace(/^\?/, "").split("&").forEach((key) => {
3694
+ if (!key) return;
3643
3695
  const [k, v] = key.split("=");
3644
- res[k] = v;
3645
- return res;
3646
- }, {});
3696
+ if (k) {
3697
+ const decodedKey = decodeURIComponent(k.trim());
3698
+ const decodedValue = v ? decodeURIComponent(v.trim()) : "";
3699
+ const dangerousProps = [
3700
+ "__proto__",
3701
+ "constructor",
3702
+ "prototype",
3703
+ "__defineGetter__",
3704
+ "__defineSetter__",
3705
+ "__lookupGetter__",
3706
+ "__lookupSetter__",
3707
+ "hasOwnProperty",
3708
+ "isPrototypeOf",
3709
+ "propertyIsEnumerable",
3710
+ "toString",
3711
+ "valueOf",
3712
+ "toLocaleString"
3713
+ ];
3714
+ if (dangerousProps.includes(decodedKey.toLowerCase())) {
3715
+ return;
3716
+ }
3717
+ paramsMap.set(decodedKey, decodedValue);
3718
+ }
3719
+ });
3720
+ return Object.fromEntries(paramsMap);
3647
3721
  }
3648
3722
 
3649
3723
  // src/workflow-document-container-module.ts
@@ -3719,7 +3793,6 @@ var WorkflowDocumentContainerModule = new import_inversify10.ContainerModule(
3719
3793
  usePlayground,
3720
3794
  usePlaygroundContainer,
3721
3795
  usePlaygroundContext,
3722
- usePlaygroundLatest,
3723
3796
  usePlaygroundReadonlyState,
3724
3797
  useRefresh,
3725
3798
  useService,