@flowgram.ai/document
Version:
automation flow engine
1,627 lines (1,610 loc) • 101 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp(target, key, result);
return result;
};
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ConstantKeys: () => ConstantKeys,
DEFAULT_FLOW_NODE_META: () => DEFAULT_FLOW_NODE_META,
DEFAULT_SIZE: () => DEFAULT_SIZE,
DEFAULT_SPACING: () => DEFAULT_SPACING,
DRAGGING_TYPE: () => DRAGGING_TYPE,
DefaultSpacingKey: () => DefaultSpacingKey,
FLOW_DEFAULT_HIDDEN_TYPES: () => FLOW_DEFAULT_HIDDEN_TYPES,
FlowDocument: () => FlowDocument,
FlowDocumentConfig: () => FlowDocumentConfig,
FlowDocumentConfigDefaultData: () => FlowDocumentConfigDefaultData,
FlowDocumentConfigEnum: () => FlowDocumentConfigEnum,
FlowDocumentContainerModule: () => FlowDocumentContainerModule,
FlowDocumentContribution: () => FlowDocumentContribution,
FlowDocumentOptions: () => FlowDocumentOptions,
FlowDocumentOptionsDefault: () => FlowDocumentOptionsDefault,
FlowDocumentProvider: () => FlowDocumentProvider,
FlowDocumentTransformerEntity: () => FlowDocumentTransformerEntity,
FlowDragService: () => FlowDragService,
FlowGroupController: () => FlowGroupController,
FlowGroupService: () => FlowGroupService,
FlowLayout: () => FlowLayout,
FlowLayoutContribution: () => FlowLayoutContribution,
FlowLayoutDefault: () => FlowLayoutDefault,
FlowNodeBaseType: () => FlowNodeBaseType,
FlowNodeEntity: () => FlowNodeEntity,
FlowNodeRegistry: () => FlowNodeRegistry,
FlowNodeRenderData: () => FlowNodeRenderData,
FlowNodeSplitType: () => FlowNodeSplitType,
FlowNodeTransformData: () => FlowNodeTransformData,
FlowNodeTransitionData: () => FlowNodeTransitionData,
FlowOperationBaseService: () => FlowOperationBaseService,
FlowOperationBaseServiceImpl: () => FlowOperationBaseServiceImpl,
FlowRendererStateEntity: () => FlowRendererStateEntity,
FlowTransitionLabelEnum: () => FlowTransitionLabelEnum,
FlowTransitionLineEnum: () => FlowTransitionLineEnum,
FlowVirtualTree: () => FlowVirtualTree,
LABEL_SIDE_TYPE: () => LABEL_SIDE_TYPE,
OperationType: () => OperationType,
drawLineToBottom: () => drawLineToBottom,
drawLineToNext: () => drawLineToNext,
getDefaultSpacing: () => getDefaultSpacing
});
module.exports = __toCommonJS(src_exports);
// src/typings/flow.ts
var FlowNodeBaseType = /* @__PURE__ */ ((FlowNodeBaseType2) => {
FlowNodeBaseType2["START"] = "start";
FlowNodeBaseType2["DEFAULT"] = "default";
FlowNodeBaseType2["ROOT"] = "root";
FlowNodeBaseType2["EMPTY"] = "empty";
FlowNodeBaseType2["INLINE_BLOCKS"] = "inlineBlocks";
FlowNodeBaseType2["BLOCK_ICON"] = "blockIcon";
FlowNodeBaseType2["BLOCK"] = "block";
FlowNodeBaseType2["BLOCK_ORDER_ICON"] = "blockOrderIcon";
FlowNodeBaseType2["GROUP"] = "group";
FlowNodeBaseType2["END"] = "end";
FlowNodeBaseType2["BREAK"] = "break";
FlowNodeBaseType2["CONDITION"] = "condition";
FlowNodeBaseType2["SUB_CANVAS"] = "subCanvas";
FlowNodeBaseType2["MULTI_INPUTS"] = "multiInputs";
FlowNodeBaseType2["MULTI_OUTPUTS"] = "multiOutputs";
FlowNodeBaseType2["INPUT"] = "input";
FlowNodeBaseType2["OUTPUT"] = "output";
FlowNodeBaseType2["SLOT"] = "slot";
FlowNodeBaseType2["SLOT_BLOCK"] = "slotBlock";
return FlowNodeBaseType2;
})(FlowNodeBaseType || {});
var FlowNodeSplitType = /* @__PURE__ */ ((FlowNodeSplitType2) => {
FlowNodeSplitType2["SIMPLE_SPLIT"] = "simpleSplit";
FlowNodeSplitType2["DYNAMIC_SPLIT"] = "dynamicSplit";
FlowNodeSplitType2["STATIC_SPLIT"] = "staticSplit";
return FlowNodeSplitType2;
})(FlowNodeSplitType || {});
var FlowDocumentConfigEnum = /* @__PURE__ */ ((FlowDocumentConfigEnum2) => {
FlowDocumentConfigEnum2["END_NODES_REFINE_BRANCH"] = "END_NODES_REFINE_BRANCH";
return FlowDocumentConfigEnum2;
})(FlowDocumentConfigEnum || {});
var FLOW_DEFAULT_HIDDEN_TYPES = [
"root" /* ROOT */,
"inlineBlocks" /* INLINE_BLOCKS */,
"block" /* BLOCK */
];
// src/typings/flow-layout.ts
var FlowLayout = Symbol("FlowLayout");
var FlowLayoutContribution = Symbol("FlowLayoutContribution");
var FlowLayoutDefault = /* @__PURE__ */ ((FlowLayoutDefault2) => {
FlowLayoutDefault2["VERTICAL_FIXED_LAYOUT"] = "vertical-fixed-layout";
FlowLayoutDefault2["HORIZONTAL_FIXED_LAYOUT"] = "horizontal-fixed-layout";
return FlowLayoutDefault2;
})(FlowLayoutDefault || {});
((FlowLayoutDefault2) => {
function isVertical(layout) {
return layout.name === "vertical-fixed-layout" /* VERTICAL_FIXED_LAYOUT */;
}
FlowLayoutDefault2.isVertical = isVertical;
})(FlowLayoutDefault || (FlowLayoutDefault = {}));
// src/typings/flow-transition.ts
var FlowTransitionLineEnum = /* @__PURE__ */ ((FlowTransitionLineEnum2) => {
FlowTransitionLineEnum2[FlowTransitionLineEnum2["STRAIGHT_LINE"] = 0] = "STRAIGHT_LINE";
FlowTransitionLineEnum2[FlowTransitionLineEnum2["DIVERGE_LINE"] = 1] = "DIVERGE_LINE";
FlowTransitionLineEnum2[FlowTransitionLineEnum2["MERGE_LINE"] = 2] = "MERGE_LINE";
FlowTransitionLineEnum2[FlowTransitionLineEnum2["ROUNDED_LINE"] = 3] = "ROUNDED_LINE";
FlowTransitionLineEnum2[FlowTransitionLineEnum2["CUSTOM_LINE"] = 4] = "CUSTOM_LINE";
FlowTransitionLineEnum2[FlowTransitionLineEnum2["DRAGGING_LINE"] = 5] = "DRAGGING_LINE";
return FlowTransitionLineEnum2;
})(FlowTransitionLineEnum || {});
var FlowTransitionLabelEnum = /* @__PURE__ */ ((FlowTransitionLabelEnum2) => {
FlowTransitionLabelEnum2[FlowTransitionLabelEnum2["ADDER_LABEL"] = 0] = "ADDER_LABEL";
FlowTransitionLabelEnum2[FlowTransitionLabelEnum2["TEXT_LABEL"] = 1] = "TEXT_LABEL";
FlowTransitionLabelEnum2[FlowTransitionLabelEnum2["COLLAPSE_LABEL"] = 2] = "COLLAPSE_LABEL";
FlowTransitionLabelEnum2[FlowTransitionLabelEnum2["COLLAPSE_ADDER_LABEL"] = 3] = "COLLAPSE_ADDER_LABEL";
FlowTransitionLabelEnum2[FlowTransitionLabelEnum2["CUSTOM_LABEL"] = 4] = "CUSTOM_LABEL";
FlowTransitionLabelEnum2[FlowTransitionLabelEnum2["BRANCH_DRAGGING_LABEL"] = 5] = "BRANCH_DRAGGING_LABEL";
return FlowTransitionLabelEnum2;
})(FlowTransitionLabelEnum || {});
// src/typings/flow-node-register.ts
var DefaultSpacingKey = {
/**
* 普通节点间距。垂直 / 水平
*/
NODE_SPACING: "SPACING",
/**
* 分支节点间距
*/
BRANCH_SPACING: "BRANCH_SPACING",
/**
* 圆弧线条 x radius
*/
ROUNDED_LINE_X_RADIUS: "ROUNDED_LINE_X_RADIUS",
/**
* 圆弧线条 y radius
*/
ROUNDED_LINE_Y_RADIUS: "ROUNDED_LINE_Y_RADIUS",
/**
* dynamicSplit block list 下部留白间距,因为有两个拐弯,所以翻一倍
*/
INLINE_BLOCKS_PADDING_BOTTOM: "INLINE_BLOCKS_PADDING_BOTTOM",
/**
* 复合节点距离上个节点的距离
* 条件分支菱形下边和分支的距离
*/
COLLAPSED_SPACING: "COLLAPSED_SPACING",
/**
* width of hover area
*/
HOVER_AREA_WIDTH: "HOVER_AREA_WIDTH"
};
var DEFAULT_SPACING = {
NULL: 0,
[DefaultSpacingKey.NODE_SPACING]: 32,
// 普通节点间距。垂直 / 水平
[DefaultSpacingKey.BRANCH_SPACING]: 20,
// 分支节点间距
/**
* @deprecated use 'BRANCH_SPACING' instead
*/
MARGIN_RIGHT: 20,
// 分支节点右边间距
INLINE_BLOCK_PADDING_BOTTOM: 16,
// block 底部留白
INLINE_BLOCKS_PADDING_TOP: 30,
// block list 上部留白间距
// JS 浮点数有误差,1046.6 -1006.6 = 39.9999999,会导致 间距/20 < 2 导致布局计算问题,因此需要额外增加 0.1 像素
[DefaultSpacingKey.INLINE_BLOCKS_PADDING_BOTTOM]: 40.1,
// block lit 下部留白间距,因为有两个拐弯,所以翻一倍
MIN_INLINE_BLOCK_SPACING: 200,
// 分支间最小边距 (垂直布局)
MIN_INLINE_BLOCK_SPACING_HORIZONTAL: 80,
// 分支间最小边距 (水平布局)
[DefaultSpacingKey.COLLAPSED_SPACING]: 12,
// 复合节点距离上个节点的距离
[DefaultSpacingKey.ROUNDED_LINE_X_RADIUS]: 16,
// 圆弧线条 x radius
[DefaultSpacingKey.ROUNDED_LINE_Y_RADIUS]: 20,
// 圆弧线条 y radius
[DefaultSpacingKey.HOVER_AREA_WIDTH]: 20
// width of hover area
};
var DRAGGING_TYPE = /* @__PURE__ */ ((DRAGGING_TYPE2) => {
DRAGGING_TYPE2["NODE"] = "node";
DRAGGING_TYPE2["BRANCH"] = "branch";
return DRAGGING_TYPE2;
})(DRAGGING_TYPE || {});
var LABEL_SIDE_TYPE = /* @__PURE__ */ ((LABEL_SIDE_TYPE2) => {
LABEL_SIDE_TYPE2["PRE_BRANCH"] = "pre_branch";
LABEL_SIDE_TYPE2["NORMAL_BRANCH"] = "normal_branch";
return LABEL_SIDE_TYPE2;
})(LABEL_SIDE_TYPE || {});
var DEFAULT_SIZE = {
width: 280,
height: 60
};
var DEFAULT_FLOW_NODE_META = (nodeType, document) => {
const hidden = FLOW_DEFAULT_HIDDEN_TYPES.includes(nodeType);
return {
isStart: nodeType === "start",
hidden,
defaultExpanded: document.options.allNodesDefaultExpanded,
size: DEFAULT_SIZE,
origin: document.layout.getDefaultNodeOrigin(),
isInlineBlocks: nodeType === "inlineBlocks" /* INLINE_BLOCKS */,
// miniSize: { width: 200, height: 40 },
spacing: DEFAULT_SPACING.SPACING,
inlineSpacingPre: 0,
inlineSpacingAfter: 0,
expandable: true,
draggable: true,
selectable: true,
renderKey: "",
minInlineBlockSpacing: () => {
const isVertical = FlowLayoutDefault.isVertical(document.layout);
return isVertical ? DEFAULT_SPACING.MIN_INLINE_BLOCK_SPACING : DEFAULT_SPACING.MIN_INLINE_BLOCK_SPACING_HORIZONTAL;
}
};
};
var FlowNodeRegistry;
((FlowNodeRegistry4) => {
function mergeChildRegistries(r1 = [], r2 = []) {
if (r1.length === 0 || r2.length === 0) {
return [...r1, ...r2];
}
const r1Filter = r1.map((r1Current) => {
const r2Current = r2.find((n) => n.type === r1Current.type);
if (r2Current) {
return merge(r1Current, r2Current, r1Current.type);
}
return r1Current;
});
const r2Filter = r2.filter((n) => !r1.some((r) => r.type === n.type));
return [...r1Filter, ...r2Filter];
}
FlowNodeRegistry4.mergeChildRegistries = mergeChildRegistries;
function merge(registry1, registry2, finalType) {
const extendKeys = registry1.__extends__ ? registry1.__extends__.slice() : [];
if (registry1.type !== registry2.type) {
extendKeys.unshift(registry1.type);
}
return {
...registry1,
...registry2,
extendChildRegistries: mergeChildRegistries(
registry1.extendChildRegistries,
registry2.extendChildRegistries
),
meta: { ...registry1.meta, ...registry2.meta },
extend: void 0,
type: finalType,
__extends__: extendKeys
};
}
FlowNodeRegistry4.merge = merge;
function extend(registry, extendRegistries) {
if (!extendRegistries.length) return registry;
return extendRegistries.reduce((res, ext) => merge(res, ext, registry.type), registry);
}
FlowNodeRegistry4.extend = extend;
})(FlowNodeRegistry || (FlowNodeRegistry = {}));
// src/typings/flow-operation.ts
var OperationType = /* @__PURE__ */ ((OperationType2) => {
OperationType2["addFromNode"] = "addFromNode";
OperationType2["deleteFromNode"] = "deleteFromNode";
OperationType2["addBlock"] = "addBlock";
OperationType2["deleteBlock"] = "deleteBlock";
OperationType2["createGroup"] = "createGroup";
OperationType2["ungroup"] = "ungroup";
OperationType2["moveNodes"] = "moveNodes";
OperationType2["moveBlock"] = "moveBlock";
OperationType2["moveChildNodes"] = "moveChildNodes";
OperationType2["addNodes"] = "addNodes";
OperationType2["deleteNodes"] = "deleteNodes";
OperationType2["changeNode"] = "changeNode";
OperationType2["addChildNode"] = "addChildNode";
OperationType2["deleteChildNode"] = "deleteChildNode";
OperationType2["addNode"] = "addNode";
OperationType2["deleteNode"] = "deleteNode";
return OperationType2;
})(OperationType || {});
var FlowOperationBaseService = Symbol("FlowOperationBaseService");
// src/entities/flow-node-entity.ts
var import_core4 = require("@flowgram.ai/core");
// src/datas/flow-node-transform-data.ts
var import_utils2 = require("@flowgram.ai/utils");
var import_core2 = require("@flowgram.ai/core");
// src/datas/flow-node-render-data.ts
var import_utils = require("@flowgram.ai/utils");
var import_core = require("@flowgram.ai/core");
var _FlowNodeRenderData = class _FlowNodeRenderData extends import_core.EntityData {
constructor(entity) {
super(entity);
this.onExtInfoChangeEmitter = new import_utils.Emitter();
this.onExtInfoChange = this.onExtInfoChangeEmitter.event;
this.toDispose.push(
import_utils.Disposable.create(() => {
if (this._node) this._node.remove();
})
);
}
get key() {
return this.entity.id;
}
getDefaultData() {
const { addable, expandable, defaultExpanded } = this.entity.getNodeMeta();
return {
addable,
expandable,
expanded: defaultExpanded || false,
activated: false,
hovered: false,
dragging: false,
stackIndex: 0
};
}
updateExtInfo(info) {
if (import_utils.Compare.isChanged(this.data.extInfo, info)) {
const oldInfo = this.data.extInfo;
this.update({
extInfo: info
});
this.onExtInfoChangeEmitter.fire({ oldInfo, newInfo: info });
}
}
getExtInfo() {
return this.data.extInfo;
}
get addable() {
return this.data.addable;
}
get expandable() {
return this.data.expandable;
}
get draggable() {
const { draggable } = this.entity.getNodeMeta();
if (typeof draggable === "function") {
return draggable(this.entity);
}
return draggable;
}
get expanded() {
return this.data.expanded;
}
set expanded(expanded) {
if (this.expandable && this.data.expanded !== expanded) {
this.data.expanded = expanded;
this.fireChange();
}
}
toggleExpand() {
this.expanded = !this.expanded;
}
toggleMouseEnter(silent = false) {
this.entity.document.renderState.setNodeHovered(this.entity);
if (silent) return;
const transform = this.entity.getData(FlowNodeTransformData);
if (transform.renderState.hidden) {
return;
}
if (this.mouseLeaveTimeout) {
clearTimeout(this.mouseLeaveTimeout);
this.mouseLeaveTimeout = void 0;
}
transform.renderState.hovered = true;
if (this.entity.isFirst && this.entity.parent?.id !== "root") {
transform.parent.renderState.activated = true;
} else {
transform.renderState.activated = true;
}
}
toggleMouseLeave(silent = false) {
this.entity.document.renderState.setNodeHovered(void 0);
if (silent) return;
const transform = this.entity.getData(FlowNodeTransformData);
this.mouseLeaveTimeout = setTimeout(() => {
transform.renderState.hovered = false;
if (this.entity.isFirst && this.entity.parent?.id !== "root") {
transform.parent.renderState.activated = false;
}
transform.renderState.activated = false;
}, 200);
}
get hidden() {
return this.entity.hidden;
}
set hovered(hovered) {
this.data.hovered = hovered;
this.fireChange();
}
get hovered() {
return this.data.hovered;
}
get dragging() {
return this.data.dragging;
}
set dragging(dragging) {
if (this.data.dragging !== dragging) {
this.data.dragging = dragging;
this.fireChange();
}
}
set activated(activated) {
if (this.entity.flowNodeType === "blockIcon" /* BLOCK_ICON */ && this.entity.parent) {
this.entity.parent.getData(_FlowNodeRenderData).activated = activated;
return;
}
if (this.data.activated !== activated) {
this.data.activated = activated;
this.fireChange();
}
}
get activated() {
const { entity } = this;
if (entity.parent && entity.parent.getData(_FlowNodeRenderData).activated) {
return true;
}
return this.data.activated;
}
get stackIndex() {
return this.data.stackIndex;
}
set stackIndex(index) {
this.data.stackIndex = index;
}
get lineActivated() {
const { activated } = this;
if (!activated) return false;
return Boolean(
this.entity.parent?.getData(_FlowNodeRenderData)?.activated || this.entity.isInlineBlock || this.entity.next?.getData(_FlowNodeRenderData).activated
);
}
get node() {
if (this._node) return this._node;
this._node = import_utils.domUtils.createDivWithClass("gedit-flow-activity-node");
this._node.dataset.testid = "sdk.workflow.canvas.node";
this._node.dataset.nodeId = this.entity.id;
return this._node;
}
dispose() {
super.dispose();
this.onExtInfoChangeEmitter.dispose();
}
};
_FlowNodeRenderData.type = "FlowNodeRenderData";
var FlowNodeRenderData = _FlowNodeRenderData;
// src/datas/flow-node-transform-data.ts
var _FlowNodeTransformData = class _FlowNodeTransformData extends import_core2.EntityData {
constructor(entity) {
super(entity);
this.localDirty = true;
const { origin } = this.entity.getNodeMeta();
this.transform = this.entity.addData(import_core2.TransformData);
this.transform.changeLocked = true;
this.transform.update({ origin: { ...origin } });
this.transform.changeLocked = false;
this.renderState = this.entity.addData(FlowNodeRenderData);
this.bindChange(this.transform);
this.toDispose.push(
import_utils2.Disposable.create(() => {
const { next, parent } = this;
if (next) next.localDirty = true;
if (parent) parent.localDirty = true;
})
);
}
get origin() {
return this.transform.origin;
}
get key() {
return this.entity.id;
}
getDefaultData() {
const { size, hidden } = this.entity.getNodeMeta();
return {
size: !hidden ? { ...size } : { width: 0, height: 0 }
};
}
/**
* 获取节点是否展开
*/
get collapsed() {
return this.entity.collapsed;
}
set collapsed(collapsed) {
this.entity.collapsed = collapsed;
this.localDirty = true;
if (this.firstChild) this.firstChild.localDirty = true;
this.fireChange();
}
/**
* 获取节点的大小
*/
get size() {
return this.entity.memoGlobal("size", () => {
if (this.isContainer) return this.transform.localSize;
return this.data.size;
});
}
get position() {
const { position } = this.transform;
return {
x: position.x,
y: position.y
};
}
set position(position) {
this.transform.update({
position
});
}
set size(size) {
const { width, height } = this.data.size;
if (this.isContainer) return;
if (size.width !== width || size.height !== height) {
this._data.size = { ...size };
this.localDirty = true;
this.fireChange();
}
}
get inputPoint() {
return this.entity.memoGlobal("inputPoint", () => {
const { getInputPoint } = this.entity.getNodeRegistry();
return getInputPoint ? getInputPoint(this, this.entity.document.layout) : this.defaultInputPoint;
});
}
get defaultInputPoint() {
return this.entity.memoGlobal(
"defaultInputPoint",
() => this.entity.document.layout.getDefaultInputPoint(this.entity)
);
}
get defaultOutputPoint() {
return this.entity.memoGlobal(
"defaultOutputPoint",
() => this.entity.document.layout.getDefaultOutputPoint(this.entity)
);
}
get outputPoint() {
return this.entity.memoGlobal("outputPoint", () => {
const { getOutputPoint } = this.entity.getNodeRegistry();
return getOutputPoint ? getOutputPoint(this, this.entity.document.layout) : this.defaultOutputPoint;
});
}
/**
* 原点的最左偏移
*/
get originDeltaX() {
return this.entity.memoLocal("originDeltaX", () => {
const { children } = this;
const { getOriginDeltaX } = this.entity.getNodeRegistry();
if (getOriginDeltaX) return getOriginDeltaX(this, this.entity.document.layout);
if (children.length === 0) {
return -this.size.width * this.origin.x;
}
if (children.length === 1) return children[0].originDeltaX;
if (this.entity.isInlineBlocks && children.length > 1) {
return children[0].originDeltaX + this.transform.position.x;
}
return children.reduce((res, child) => {
const deltaX = child.originDeltaX;
return res === void 0 || deltaX < res ? deltaX : res;
}, void 0);
});
}
/**
* 原点 y 轴偏移
*/
get originDeltaY() {
return this.entity.memoLocal("originDeltaY", () => {
const { children } = this;
const { getOriginDeltaY } = this.entity.getNodeRegistry();
if (getOriginDeltaY) return getOriginDeltaY(this, this.entity.document.layout);
if (children.length === 0) {
return -this.size.height * this.origin.y;
}
if (children.length === 1) return children[0].originDeltaY;
if (this.entity.isInlineBlocks && children.length > 1) {
return children[0].originDeltaY + this.transform.position.y;
}
return children.reduce((res, child) => {
const deltaY = child.originDeltaY;
return res === void 0 || deltaY < res ? deltaY : res;
}, void 0);
});
}
/**
* 绝对坐标 bbox, 不包含自身的 spacing(marginBottom), 但是包含 inlineSpacing 和 子节点的 spacing
*/
get bounds() {
return this.entity.memoGlobal("bounds", () => {
const { transform } = this;
if (this.isContainer) {
const childrenRects = transform.children.map(
(c) => c.entity.getData(_FlowNodeTransformData).boundsWithPadding
);
return import_utils2.Rectangle.enlarge(childrenRects).withPadding(this.padding);
}
return transform.bounds;
});
}
get boundsWithPadding() {
return this.entity.memoGlobal("boundsWithPadding", () => {
const { transform } = this;
if (this.isContainer) {
const childrenRects = transform.children.map(
(c) => c.entity.getData(_FlowNodeTransformData).boundsWithPadding
);
return import_utils2.Rectangle.enlarge(childrenRects).withPadding(this.padding);
}
return transform.bounds.clone().withPadding(this.padding);
});
}
get isContainer() {
return this.transform.isContainer;
}
/**
* 相对坐标 bbox, 这里的 localBounds 会加入 padding 一起算
*/
get localBounds() {
return this.entity.memoLocal("localBounds", () => {
const { transform } = this;
if (this.isContainer) {
const childrenRects = transform.children.map(
(c) => c.entity.getData(_FlowNodeTransformData).localBounds
);
const childrenBounds = import_utils2.Rectangle.enlarge(childrenRects).withPadding(this.padding);
return import_core2.Bounds.applyMatrix(childrenBounds, transform.localTransform);
}
return transform.localBounds.clone().withPadding(this.padding);
});
}
get padding() {
return this.entity.document.layout.getPadding(this.entity);
}
setParentTransform(transform) {
if (this.transform.parent !== transform?.transform) {
this.localDirty = true;
}
this.transform.setParent(transform?.transform);
}
get spacing() {
const { spacing } = this.entity.getNodeMeta();
return typeof spacing === "function" ? spacing(this) : spacing;
}
get inlineSpacingPre() {
const { inlineSpacingPre } = this.entity.getNodeMeta();
return typeof inlineSpacingPre === "function" ? inlineSpacingPre(this) : inlineSpacingPre;
}
get inlineSpacingAfter() {
const { inlineSpacingAfter } = this.entity.getNodeMeta();
return typeof inlineSpacingAfter === "function" ? inlineSpacingAfter(this) : inlineSpacingAfter;
}
get minInlineBlockSpacing() {
const { minInlineBlockSpacing } = this.entity.getNodeMeta();
return typeof minInlineBlockSpacing === "function" ? minInlineBlockSpacing(this) : minInlineBlockSpacing;
}
get children() {
return this.entity.children.map(
(child) => child.getData(_FlowNodeTransformData)
);
}
/**
* 上一个节点的 transform 数据
*/
get pre() {
return this.entity.pre?.getData(_FlowNodeTransformData);
}
get originParent() {
return this.entity.originParent?.getData(_FlowNodeTransformData);
}
get isFirst() {
return this.entity.isFirst;
}
get isLast() {
return this.entity.isLast;
}
get lastChild() {
return this.entity.lastChild?.getData(_FlowNodeTransformData);
}
get firstChild() {
return this.entity.firstChild?.getData(_FlowNodeTransformData);
}
/**
* 下一个节点的 transform 数据
*/
get next() {
return this.entity.next?.getData(_FlowNodeTransformData);
}
/**
* parent 节点的 transform 数据
*/
get parent() {
return this.entity.parent?.getData(_FlowNodeTransformData);
}
};
_FlowNodeTransformData.type = "FlowNodeTransformData";
var FlowNodeTransformData = _FlowNodeTransformData;
// src/datas/flow-node-transition-data.ts
var import_utils3 = require("@flowgram.ai/utils");
var import_core3 = require("@flowgram.ai/core");
var drawLineToNext = (transition) => {
const { transform } = transition;
const currentOutput = transform.outputPoint;
if (transform.next) {
return [
{
type: 0 /* STRAIGHT_LINE */,
from: currentOutput,
to: transform.next.inputPoint
}
];
}
return [];
};
var drawLineToBottom = (transition) => {
const { transform } = transition;
const currentOutput = transform.outputPoint;
const parentOutput = transform.parent?.outputPoint;
if (!transform.next && parentOutput && !new import_utils3.Point().copyFrom(currentOutput).equals(parentOutput) && !transition.isNodeEnd) {
return [
{
type: 0 /* STRAIGHT_LINE */,
from: currentOutput,
to: parentOutput
}
];
}
return [];
};
var FlowNodeTransitionData = class extends import_core3.EntityData {
getDefaultData() {
return {};
}
formatLines(lines) {
if (this.entity.document.options?.formatNodeLines) {
return this.entity.document.options?.formatNodeLines?.(this.entity, lines);
}
return lines;
}
formatLabels(labels) {
if (this.entity.document.options.formatNodeLabels) {
return this.entity.document.options?.formatNodeLabels?.(this.entity, labels);
}
return labels;
}
get lines() {
return this.entity.memoGlobal("lines", () => {
const { getChildLines } = this.entity.parent?.getNodeRegistry() || {};
if (getChildLines) {
return this.formatLines(getChildLines(this, this.entity.document.layout));
}
const { getLines } = this.entity.getNodeRegistry();
if (getLines) {
return this.formatLines(getLines(this, this.entity.document.layout));
}
if (this.transform.entity.isInlineBlock) {
return [];
}
return this.formatLines([...drawLineToNext(this), ...drawLineToBottom(this)]);
});
}
get labels() {
return this.entity.memoGlobal("labels", () => {
const { getChildLabels } = this.entity.parent?.getNodeRegistry() || {};
if (getChildLabels) {
return this.formatLabels(getChildLabels(this, this.entity.document.layout));
}
const { getLabels } = this.entity.getNodeRegistry();
if (getLabels) {
return this.formatLabels(getLabels(this, this.entity.document.layout));
}
if (this.transform.entity.isInlineBlock) {
return [];
}
const currentOutput = this.transform.outputPoint;
if (this.transform.next) {
return this.formatLabels([
{
offset: import_utils3.Point.getMiddlePoint(currentOutput, this.transform.next.inputPoint),
type: 0 /* ADDER_LABEL */
}
]);
}
const parentOutput = this.transform.parent?.outputPoint;
if (parentOutput && !new import_utils3.Point().copyFrom(currentOutput).equals(parentOutput) && !this.isNodeEnd) {
return this.formatLabels([
{
offset: parentOutput,
type: 0 /* ADDER_LABEL */
}
]);
}
return [];
});
}
constructor(entity) {
super(entity);
this.transform = this.entity.addData(FlowNodeTransformData);
this.renderData = this.entity.addData(FlowNodeRenderData);
this.bindChange(this.transform);
this.bindChange(this.renderData);
}
get collapsed() {
return this.entity.collapsed;
}
get isNodeEnd() {
return this.entity.isNodeEnd;
}
};
FlowNodeTransitionData.type = "FlowNodeTransitionData";
// src/entities/flow-node-entity.ts
var FlowNodeEntity = class extends import_core4.Entity {
constructor(conf) {
super(conf);
this._memoLocalCache = /* @__PURE__ */ new Map();
this._memoGlobalCache = /* @__PURE__ */ new Map();
this.flowNodeType = "unknown";
// 流程类型
/**
* 是否隐藏
*/
this._hidden = false;
this.index = -1;
this.document = conf.document;
this.flowNodeType = conf.flowNodeType;
this.originParent = conf.originParent;
this.metaFromJSON = conf.meta;
this.onDispose(() => {
this.document.originTree.getChildren(this).slice().forEach((child) => {
child.dispose();
});
this.document.originTree.remove(this, false);
this.originParent = void 0;
});
}
initData(initConf) {
if (initConf.originParent !== this.originParent) {
this.originParent = initConf.originParent;
this._registerCache = void 0;
}
if (initConf.parent) {
initConf.parent.addChild(this, initConf.index);
}
if (initConf.meta !== this.metaFromJSON) {
this._metaCache = void 0;
this.metaFromJSON = initConf.meta;
}
this._hidden = !!(this.getNodeMeta().hidden || initConf.hidden);
}
get isStart() {
return this.getNodeMeta().isStart;
}
get isFirst() {
return !this.pre;
}
get isLast() {
return !this.next;
}
/**
* 子节点采用水平布局
*/
get isInlineBlocks() {
const originIsInlineBlocks = this.getNodeMeta().isInlineBlocks;
return typeof originIsInlineBlocks === "function" ? originIsInlineBlocks(this) : originIsInlineBlocks;
}
/**
* 水平节点
*/
get isInlineBlock() {
const parent = this.document.renderTree.getParent(this);
return !!(parent && parent.isInlineBlocks);
}
/**
* 节点结束标记
* - 当前节点是结束节点
* - 当前节点最后一个节点包含结束标记
* - 当前节点为 inlineBlock,每一个 block 包含结束标记
*
* 由子元素确定,因此使用 memoLocal
*/
get isNodeEnd() {
return this.memoLocal("isNodeEnd", () => {
if (this.getNodeMeta().isNodeEnd) {
return true;
}
if (this.isInlineBlocks && this.collapsedChildren.length) {
return this.collapsedChildren.every((child) => child.isNodeEnd);
}
if (this.lastCollapsedChild) {
return this.lastCollapsedChild.isNodeEnd;
}
return false;
});
}
/**
* 添加 子节点
*
* @param child 插入节点
*/
addChild(child, index) {
if (child.parent === this) return;
this.document.originTree.addChild(this, child, index);
}
get hasChild() {
return this.children.length > 0;
}
get pre() {
return this.document.renderTree.getPre(this);
}
get next() {
return this.document.renderTree.getNext(this);
}
get parent() {
return this.document.renderTree.getParent(this);
}
getNodeRegistry() {
if (this._registerCache) return this._registerCache;
this._registerCache = this.document.getNodeRegistry(this.flowNodeType, this.originParent);
return this._registerCache;
}
/**
* @deprecated
* use getNodeRegistry instead
*/
getNodeRegister() {
return this.getNodeRegistry();
}
getNodeMeta() {
if (this._metaCache) return this._metaCache;
if (this.metaFromJSON) {
this._metaCache = {
...this.getNodeRegistry().meta,
...this.metaFromJSON
};
} else {
this._metaCache = this.getNodeRegistry().meta;
}
return this._metaCache;
}
/**
* 获取所有子节点,包含 child 及其所有兄弟节点
*/
get allChildren() {
const children = [];
for (const child of this.children) {
children.push(child);
children.push(...child.allChildren);
}
return children;
}
/**
* 获取所有收起的子节点,包含 child 及其所有兄弟节点
*/
get allCollapsedChildren() {
const children = [];
for (const child of this.collapsedChildren) {
children.push(child);
children.push(...child.allCollapsedChildren);
}
return children;
}
/**
*
* Get child blocks
*
* use `blocks` instead
* @deprecated
*/
get collapsedChildren() {
return this.document.renderTree.getCollapsedChildren(this);
}
/**
* Get child blocks
*/
get blocks() {
return this.collapsedChildren;
}
/**
* Get last block
*/
get lastBlock() {
return this.lastCollapsedChild;
}
/**
* use `lastBlock` instead
*/
get lastCollapsedChild() {
const { collapsedChildren } = this;
return collapsedChildren[collapsedChildren.length - 1];
}
/**
* 获取子节点,如果子节点收起来,则会返回 空数组
*/
get children() {
return this.document.renderTree.getChildren(this);
}
get lastChild() {
const { children } = this;
return children[children.length - 1];
}
get firstChild() {
return this.children[0];
}
memoLocal(key, fn) {
if (this._memoLocalCache.has(key)) {
return this._memoLocalCache.get(key);
}
const data = fn();
this._memoLocalCache.set(key, data);
return data;
}
memoGlobal(key, fn) {
if (this._memoGlobalCache.has(key)) {
return this._memoGlobalCache.get(key);
}
const data = fn();
this._memoGlobalCache.set(key, data);
return data;
}
clearMemoGlobal() {
this._memoGlobalCache.clear();
}
clearMemoLocal() {
this._memoLocalCache.clear();
}
get childrenLength() {
return this.children.length;
}
get collapsed() {
if (this.document.renderTree.isCollapsed(this)) return true;
return !!this.parent?.collapsed;
}
set collapsed(collapsed) {
this.document.renderTree.setCollapsed(this, collapsed);
this.clearMemoGlobal();
this.clearMemoLocal();
}
get hidden() {
return this._hidden;
}
// 展开该节点
openInsideCollapsed() {
this.document.renderTree.openNodeInsideCollapsed(this);
}
/**
* 可以重载
*/
getJSONData() {
return this.getExtInfo();
}
/**
* 生成 JSON
* @param newId
*/
toJSON() {
return this.document.toNodeJSON(this);
}
get isVertical() {
return this.document.layout.name === "vertical-fixed-layout" /* VERTICAL_FIXED_LAYOUT */;
}
/**
* 修改节点扩展信息
* @param info
*/
updateExtInfo(extInfo) {
this.getData(FlowNodeRenderData).updateExtInfo(extInfo);
}
/**
* 获取节点扩展信息
*/
getExtInfo() {
return this.getData(FlowNodeRenderData).getExtInfo();
}
get onExtInfoChange() {
return this.renderData.onExtInfoChange;
}
/**
* 获取渲染数据
*/
get renderData() {
return this.getData(FlowNodeRenderData);
}
/**
* 获取位置大小数据
*/
get transform() {
return this.getData(FlowNodeTransformData);
}
/**
* 获取节点的位置及大小矩形
*/
get bounds() {
return this.transform.bounds;
}
/**
* Check node extend type
*/
isExtend(parentType) {
return this.document.isExtend(this.flowNodeType, parentType);
}
/**
* Check node type
* @param parentType
*/
isTypeOrExtendType(parentType) {
return this.document.isTypeOrExtendType(this.flowNodeType, parentType);
}
};
FlowNodeEntity.type = "FlowNodeEntity";
((FlowNodeEntity2) => {
function is(obj) {
return obj instanceof FlowNodeEntity2;
}
FlowNodeEntity2.is = is;
})(FlowNodeEntity || (FlowNodeEntity = {}));
// src/entities/flow-document-transformer-entity.ts
var import_utils4 = require("@flowgram.ai/utils");
var import_core5 = require("@flowgram.ai/core");
var FlowDocumentTransformerEntity = class extends import_core5.ConfigEntity {
constructor(conf) {
super(conf);
this.onRefreshEmitter = new import_utils4.Emitter();
this.lastTransformVersion = -1;
this.lastTreeVersion = -1;
this.onRefresh = this.onRefreshEmitter.event;
this.document = conf.document;
this.toDispose.push(
this.document.originTree.onTreeChange(() => {
this.config.treeVersion += 1;
this.fireChange();
})
);
this.toDispose.push(this.onRefreshEmitter);
}
getDefaultConfig() {
return {
loading: true,
treeVersion: 0
};
}
get loading() {
return this.config.loading;
}
set loading(loading) {
if (this.config.loading !== loading) {
this.config.loading = loading;
this.fireChange();
}
}
/**
* 更新矩阵结构 (这个只有在树结构变化时候才会触发,如:添加节点、删除节点、改变位置节点)
*/
updateTransformsTree() {
this.document.renderTree.traverse((node, depth, index) => {
const transform = node.getData(FlowNodeTransformData);
if (transform.collapsed) {
transform.transform.clearChildren();
}
if (node.parent) {
transform.setParentTransform(node.parent.getData(FlowNodeTransformData));
}
node.index = index;
});
}
clear() {
this.lastTreeVersion = -1;
this.lastTransformVersion = -1;
}
isTreeDirty() {
const transformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);
const isTreeVersionChanged = this.lastTreeVersion !== this.config.treeVersion;
const isTransformVersionChanged = this.lastTransformVersion !== transformVersion;
return isTreeVersionChanged || isTransformVersionChanged;
}
/**
* 刷新节点的相对偏移
*/
refresh() {
const transformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);
const isTreeVersionChanged = this.lastTreeVersion !== this.config.treeVersion;
const isTransformVersionChanged = this.lastTransformVersion !== transformVersion;
this.entityManager.changeEntityLocked = true;
if (isTreeVersionChanged) {
this.document.renderTree.updateRenderStruct();
this.updateTransformsTree();
this.lastTreeVersion = this.config.treeVersion;
}
if (isTreeVersionChanged || isTransformVersionChanged) {
this.document.layout.update();
this.lastTransformVersion = this.entityManager.getEntityDataVersion(FlowNodeTransformData);
this.lastTreeVersion = this.config.treeVersion;
this.onRefreshEmitter.fire();
}
this.entityManager.changeEntityLocked = false;
}
};
FlowDocumentTransformerEntity.type = "FlowDocumentTransformerEntity";
// src/entities/flow-renderer-state-entity.ts
var import_lodash = require("lodash");
var import_core6 = require("@flowgram.ai/core");
var FlowRendererStateEntity = class extends import_core6.ConfigEntity {
getDefaultConfig() {
return {};
}
constructor(conf) {
super(conf);
}
getNodeHovered() {
return this.config.nodeHoveredId ? this.entityManager.getEntityById(this.config.nodeHoveredId) : void 0;
}
setNodeHovered(node) {
this.updateConfig({
nodeHoveredId: node?.id
});
}
getDragLabelSide() {
return this.config.dragLabelSide;
}
setDragLabelSide(dragLabelSide) {
this.updateConfig({
dragLabelSide
});
}
getNodeDroppingId() {
return this.config.nodeDroppingId;
}
setNodeDroppingId(nodeDroppingId) {
this.updateConfig({
nodeDroppingId
});
}
getDragStartEntity() {
const { nodeDragStartId } = this.config;
return this.entityManager.getEntityById(nodeDragStartId);
}
setDragStartEntity(node) {
this.updateConfig({
nodeDragStartId: node?.id
});
}
// 拖拽多个节点时
getDragEntities() {
const { nodeDragIds } = this.config;
return (nodeDragIds || []).map((_id) => this.entityManager.getEntityById(_id));
}
// 设置拖拽的节点
setDragEntities(nodes) {
this.updateConfig({
nodeDragIds: nodes.map((_node) => _node.id),
nodeDragIdsWithChildren: nodes.map((_node) => [_node.id, ..._node.allCollapsedChildren.map((_n) => _n.id)]).flat()
});
}
onNodeHoveredChange(fn, debounceTime = 100) {
return this.onConfigChanged((0, import_lodash.debounce)(() => fn(this.getNodeHovered()), debounceTime));
}
};
FlowRendererStateEntity.type = "FlowRendererStateEntity";
// src/flow-document.ts
var import_lodash2 = require("lodash");
var import_inversify2 = require("inversify");
var import_utils7 = require("@flowgram.ai/utils");
var import_core7 = require("@flowgram.ai/core");
// src/flow-virtual-tree.ts
var import_utils5 = require("@flowgram.ai/utils");
var FlowVirtualTree = class _FlowVirtualTree {
constructor(root) {
this.root = root;
this.onTreeChangeEmitter = new import_utils5.Emitter();
/**
* tree 结构变化时候触发
*/
this.onTreeChange = this.onTreeChangeEmitter.event;
this.map = /* @__PURE__ */ new Map();
}
dispose() {
this.map.clear();
this.onTreeChangeEmitter.dispose();
}
getInfo(node) {
let res = this.map.get(node);
if (!res) {
res = { children: [] };
this.map.set(node, res);
}
return res;
}
clear() {
this.map.clear();
}
cloneMap() {
const newMap = /* @__PURE__ */ new Map();
for (const [key, value] of this.map) {
newMap.set(key, {
...value,
children: value.children.slice()
});
}
return newMap;
}
clone() {
const newTree = new _FlowVirtualTree(this.root);
newTree.map = this.cloneMap();
return newTree;
}
remove(node, withChildren = true) {
this.removeParent(node);
if (withChildren) {
this._removeChildren(node);
}
this.map.delete(node);
this.fireTreeChange();
}
addChild(parent, child, index) {
const parentInfo = this.getInfo(parent);
const childInfo = this.getInfo(child);
if (childInfo.parent) {
if (childInfo.parent === parent) return child;
if (childInfo.parent !== parent) {
this.removeParent(child);
}
}
const len = parentInfo.children.length;
const idx = typeof index === "undefined" ? len - 1 : index - 1;
const lastChild = parentInfo.children[idx];
const nextChild = parentInfo.children[idx + 1];
if (lastChild) this.getInfo(lastChild).next = child;
if (nextChild) this.getInfo(nextChild).pre = child;
childInfo.pre = lastChild;
childInfo.next = nextChild;
parentInfo.children.splice(idx + 1, 0, child);
childInfo.parent = parent;
this.fireTreeChange();
return child;
}
moveChilds(parent, childs, index) {
const parentInfo = this.getInfo(parent);
const len = parentInfo.children.length;
let childIndex = index ?? len;
childs.forEach((child) => {
const childInfo = this.getInfo(child);
if (childInfo.parent) {
this.removeParent(child);
}
});
childs.forEach((child) => {
const childInfo = this.getInfo(child);
let lastChild = parentInfo.children[childIndex - 1];
let nextChild = parentInfo.children[childIndex];
if (lastChild) this.getInfo(lastChild).next = child;
if (nextChild) this.getInfo(nextChild).pre = child;
childInfo.pre = lastChild;
childInfo.next = nextChild;
parentInfo.children.splice(childIndex, 0, child);
childInfo.parent = parent;
childIndex++;
});
this.fireTreeChange();
return childs;
}
getById(id) {
for (const node of this.map.keys()) {
if (node.id === id) return node;
}
}
/**
* 插入节点到后边
* @param before
* @param after
*/
insertAfter(before, after) {
const beforeInfo = this.getInfo(before);
const afterInfo = this.getInfo(after);
this.removeParent(after);
if (beforeInfo.parent) {
const parentInfo = this.getInfo(beforeInfo.parent);
parentInfo.children.splice(parentInfo.children.indexOf(before) + 1, 0, after);
const { next } = beforeInfo;
if (next) {
this.getInfo(next).pre = after;
}
afterInfo.next = next;
beforeInfo.next = after;
afterInfo.pre = before;
afterInfo.parent = beforeInfo.parent;
}
this.fireTreeChange();
}
removeParent(node) {
const info = this.getInfo(node);
if (!info.parent) return;
const parentInfo = this.getInfo(info.parent);
const index = parentInfo.children.indexOf(node);
parentInfo.children.splice(index, 1);
const { pre, next } = info;
if (pre) this.getInfo(pre).next = next;
if (next) this.getInfo(next).pre = pre;
this.fireTreeChange();
}
_removeChildren(node) {
const children = this.getChildren(node);
if (children.length > 0) {
children.forEach((child) => {
this._removeChildren(child);
this.map.delete(child);
});
}
}
getParent(node) {
return this.getInfo(node).parent;
}
getPre(node) {
return this.getInfo(node).pre;
}
getNext(node) {
return this.getInfo(node).next;
}
getChildren(node) {
return this.getInfo(node).children;
}
traverse(fn, node = this.root, depth = 0, index = 0) {
const breaked = fn(node, depth, index);
if (breaked) return true;
const info = this.getInfo(node);
const shouldBreak = info.children.find((child, i) => this.traverse(fn, child, depth + 1, i));
if (shouldBreak) return true;
}
/**
* 通知文档树结构更新
*/
fireTreeChange() {
this.onTreeChangeEmitter.fire();
}
get size() {
return this.map.size;
}
toString(showType) {
const ret = [];
this.traverse((node, depth) => {
if (depth === 0) {
ret.push(node.id);
} else {
ret.push(
`|${new Array(depth).fill("--").join("")} ${showType ? `${node.flowNodeType}(${node.id})` : node.id}`
);
}
});
return `${ret.join("\n")}`;
}
};
// src/flow-render-tree.ts
var FlowRenderTree = class extends FlowVirtualTree {
constructor(root, originTree, document) {
super(root);
this.root = root;
/**
* 折叠的节点
* @protected
*/
this.nodesCollapsed = /* @__PURE__ */ new Set();
this.originTree = originTree;
this.onTreeChange = this.originTree.onTreeChange;
this.document = document;
}
isCollapsed(node) {
return this.nodesCollapsed.has(node);
}
get collapsedNodeList() {
return Array.from(this.nodesCollapsed);
}
/**
* 折叠元素
* @param node
* @param collapsed
*/
setCollapsed(node, collapsed) {
if (collapsed) {
this.nodesCollapsed.add(node);
} else {
this.nodesCollapsed.delete(node);
}
this.originTree.fireTreeChange();
}
/**
*
*/
openNodeInsideCollapsed(node) {
let curr = this.originTree.getInfo(node)?.parent;
while (curr) {
if (this.nodesCollapsed.has(curr)) {
this.nodesCollapsed.delete(curr);
}
const { parent } = this.originTree.getInfo(curr) || {};
curr = parent;
}
this.originTree.fireTreeChange();
}
/**
* 更新结束节点等位置信息,分支里如果全是结束节点则要做相应的偏移
*/
updateRenderStruct() {
this.map = this.originTree.cloneMap();
if (this.document.config.get("END_NODES_REFINE_BRANCH" /* END_NODES_REFINE_BRANCH */)) {
this.refineBranch(this.root);
}
this.hideCollapsed();
}
/**
* 隐藏收起节点
*/
hideCollapsed() {
this.nodesCollapsed.forEach((collapsedNode) => {
const collapsedNodeInfo = this.getInfo(collapsedNode);
if (!collapsedNodeInfo) {
this.nodesCollapsed.delete(collapsedNode);
return;
}
const iconChild = collapsedNodeInfo.children.find(
(_child) => _child.flowNodeType === "blockIcon" /* BLOCK_ICON */ || _child.flowNodeType === "blockOrderIcon" /* BLOCK_ORDER_ICON */
);
if (iconChild) {
const iconInfo = this.getInfo(iconChild);
iconInfo.next = void 0;
iconInfo.pre = void 0;
collapsedNodeInfo.children = [iconChild];
return;
}
collapsedNodeInfo.children = [];
});
}
// 节点是否为结束节点
isNodeEnd(node) {
if (node.getNodeMeta().isNodeEnd) {
return true;
}
const { children } = this.getInfo(node);
if (children.length > 0 && node.isInlineBlocks) {
return children.every((child) => this.isNodeEnd(child));
}
if (node.isInlineBlock) {
return this.isNodeEnd(children[children.length - 1]);
}
return false;
}
/**
* 优化精简分支线
* - 结束节点拉直分支线
*/
refineBranch(block) {
let curr = this.getInfo(block).children[0];
while (curr) {
if (curr.flowNodeType === "dynamicSplit" /* DYNAMIC_SPLIT */ || curr.flowNodeType === "staticSplit" /* STATIC_SPLIT */) {
const { next, children: branchChildren } = this.getInfo(curr);
const { children } = this.getInfo(branchChildren[1]);
const passBlocks = (children || []).filter((child) => !this.isNodeEnd(child));
const shouldDragAllNextNodes = passBlocks.length === 1;
if (shouldDragAllNextNodes && next) {
this.dragNextNodesToBlock(passBlocks[0], next);
}
children?.forEach((child) => {
this.refineBranch(child);
});
if (shouldDragAllNextNodes) {
break;
}
}
curr = curr.next;
}
}
// 结束节点拽分支,将后续节点拽到对应分支内
dragNextNodesToBlock(toBlock, next) {
const toBlockInfo = this.getInfo(toBlock);
const nextInfo = this.getInfo(next);
const toBlockLastChild = toBlockInfo.children[toBlock.children.length - 1];
if (nextInfo.parent) {
const nextParentInfo = this.getInfo(nextInfo.parent);
if (nextInfo.pre) {
this.getInfo(nextInfo.pre).next = void 0;
}
if (toBlockLastChild) {
const lastChildInfo = this.getInfo(toBlockLastChild);
lastChildInfo.next = next;
nextInfo.pre = toBlockLastChild;
}
const nextNodeIn