@logicflow/extension 2.0.21 → 2.1.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/.turbo/turbo-build.log +18 -17
- package/CHANGELOG.md +29 -0
- package/dist/index.css +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/components/menu/index.d.ts +52 -8
- package/es/components/menu/index.js +471 -188
- package/es/components/mini-map/index.js +3 -0
- package/es/index.css +1 -1
- package/es/style/index.css +1 -1
- package/es/style/raw.d.ts +1 -1
- package/es/style/raw.js +1 -1
- package/es/tools/label/index.js +10 -3
- package/es/tools/proximity-connect/index.js +1 -1
- package/es/tools/snapshot/index.d.ts +5 -0
- package/es/tools/snapshot/index.js +65 -8
- package/lib/components/menu/index.d.ts +52 -8
- package/lib/components/menu/index.js +471 -188
- package/lib/components/mini-map/index.js +3 -0
- package/lib/index.css +1 -1
- package/lib/style/index.css +1 -1
- package/lib/style/raw.d.ts +1 -1
- package/lib/style/raw.js +1 -1
- package/lib/tools/label/index.js +10 -3
- package/lib/tools/proximity-connect/index.js +1 -1
- package/lib/tools/snapshot/index.d.ts +5 -0
- package/lib/tools/snapshot/index.js +65 -8
- package/package.json +5 -3
- package/src/components/menu/index.ts +512 -204
- package/src/components/mini-map/index.ts +5 -0
- package/src/style/index.less +16 -4
- package/src/style/raw.ts +14 -4
- package/src/tools/label/index.ts +13 -5
- package/src/tools/proximity-connect/index.ts +1 -2
- package/src/tools/snapshot/index.ts +80 -9
- package/stats.html +1 -1
|
@@ -41,35 +41,55 @@ var DefaultNodeMenuKey = 'lf:defaultNodeMenu';
|
|
|
41
41
|
var DefaultEdgeMenuKey = 'lf:defaultEdgeMenu';
|
|
42
42
|
var DefaultGraphMenuKey = 'lf:defaultGraphMenu';
|
|
43
43
|
var DefaultSelectionMenuKey = 'lf:defaultSelectionMenu';
|
|
44
|
+
var menuKeyMap = {
|
|
45
|
+
nodeMenu: DefaultNodeMenuKey,
|
|
46
|
+
edgeMenu: DefaultEdgeMenuKey,
|
|
47
|
+
graphMenu: DefaultGraphMenuKey,
|
|
48
|
+
selectionMenu: DefaultSelectionMenuKey,
|
|
49
|
+
};
|
|
50
|
+
var defaultMenuConfig = {
|
|
51
|
+
nodeMenu: [],
|
|
52
|
+
edgeMenu: [],
|
|
53
|
+
graphMenu: [],
|
|
54
|
+
selectionMenu: [],
|
|
55
|
+
};
|
|
44
56
|
var Menu = /** @class */ (function () {
|
|
45
57
|
function Menu(_a) {
|
|
46
58
|
var lf = _a.lf;
|
|
47
59
|
var _this = this;
|
|
48
60
|
this.__currentData = null;
|
|
61
|
+
this.__isSilentMode = false;
|
|
49
62
|
this.lf = lf;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
this.__menuDOM = document.createElement('ul');
|
|
64
|
+
this.__isSilentMode = lf.graphModel.editConfigModel.isSilentMode;
|
|
65
|
+
this.menuTypeMap = new Map();
|
|
66
|
+
this.init();
|
|
67
|
+
this.lf.setMenuConfig = function (config) {
|
|
68
|
+
_this.setMenuConfig(config);
|
|
69
|
+
};
|
|
70
|
+
this.lf.addMenuConfig = function (config) {
|
|
71
|
+
_this.addMenuConfig(config);
|
|
72
|
+
};
|
|
73
|
+
this.lf.setMenuByType = function (config) {
|
|
74
|
+
_this.setMenuByType(config);
|
|
75
|
+
};
|
|
76
|
+
this.lf.changeMenuItemDisableStatus = function (menuKey, text, disabled) {
|
|
77
|
+
_this.changeMenuItemDisableStatus(menuKey, text, disabled);
|
|
78
|
+
};
|
|
79
|
+
this.lf.getMenuConfig = function (menuKey) {
|
|
80
|
+
return _this.getMenuConfig(menuKey);
|
|
81
|
+
};
|
|
82
|
+
this.lf.resetMenuConfigByType = function (menuType) {
|
|
83
|
+
_this.resetMenuConfigByType(menuType);
|
|
84
|
+
};
|
|
65
85
|
}
|
|
66
86
|
/**
|
|
67
87
|
* 初始化设置默认内置菜单栏
|
|
68
88
|
*/
|
|
69
89
|
Menu.prototype.init = function () {
|
|
70
90
|
var _this = this;
|
|
71
|
-
var _a, _b, _c
|
|
72
|
-
|
|
91
|
+
var _a, _b, _c;
|
|
92
|
+
defaultMenuConfig.nodeMenu = [
|
|
73
93
|
{
|
|
74
94
|
text: '删除',
|
|
75
95
|
callback: function (node) {
|
|
@@ -89,8 +109,8 @@ var Menu = /** @class */ (function () {
|
|
|
89
109
|
},
|
|
90
110
|
},
|
|
91
111
|
];
|
|
92
|
-
(_a = this.menuTypeMap) === null || _a === void 0 ? void 0 : _a.set(DefaultNodeMenuKey,
|
|
93
|
-
|
|
112
|
+
(_a = this.menuTypeMap) === null || _a === void 0 ? void 0 : _a.set(DefaultNodeMenuKey, defaultMenuConfig.nodeMenu);
|
|
113
|
+
defaultMenuConfig.edgeMenu = [
|
|
94
114
|
{
|
|
95
115
|
text: '删除',
|
|
96
116
|
callback: function (edge) {
|
|
@@ -104,9 +124,9 @@ var Menu = /** @class */ (function () {
|
|
|
104
124
|
},
|
|
105
125
|
},
|
|
106
126
|
];
|
|
107
|
-
(_b = this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.set(DefaultEdgeMenuKey,
|
|
108
|
-
|
|
109
|
-
|
|
127
|
+
(_b = this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.set(DefaultEdgeMenuKey, defaultMenuConfig.edgeMenu);
|
|
128
|
+
defaultMenuConfig.graphMenu = [];
|
|
129
|
+
defaultMenuConfig.selectionMenu = [
|
|
110
130
|
{
|
|
111
131
|
text: '删除',
|
|
112
132
|
callback: function (elements) {
|
|
@@ -116,138 +136,12 @@ var Menu = /** @class */ (function () {
|
|
|
116
136
|
},
|
|
117
137
|
},
|
|
118
138
|
];
|
|
119
|
-
(
|
|
120
|
-
};
|
|
121
|
-
Menu.prototype.render = function (lf, container) {
|
|
122
|
-
var _this = this;
|
|
123
|
-
if (lf.options.isSilentMode)
|
|
124
|
-
return;
|
|
125
|
-
this.__container = container;
|
|
126
|
-
this.__currentData = null; // 当前展示的菜单所属元素的model数据
|
|
127
|
-
if (this.__menuDOM) {
|
|
128
|
-
this.__menuDOM.className = 'lf-menu';
|
|
129
|
-
container.appendChild(this.__menuDOM);
|
|
130
|
-
// 将选项的click事件委托至menu容器
|
|
131
|
-
// 在捕获阶段拦截并执行
|
|
132
|
-
this.__menuDOM.addEventListener('click', function (event) {
|
|
133
|
-
event.stopPropagation();
|
|
134
|
-
var target = event.target;
|
|
135
|
-
// 菜单有多层dom,需要精确获取菜单项所对应的dom
|
|
136
|
-
// 除菜单项dom外,应考虑两种情况
|
|
137
|
-
// 1. 菜单项的子元素 2. 菜单外层容器
|
|
138
|
-
while (Array.from(target.classList).indexOf('lf-menu-item') === -1 &&
|
|
139
|
-
Array.from(target.classList).indexOf('lf-menu') === -1) {
|
|
140
|
-
target = target === null || target === void 0 ? void 0 : target.parentElement;
|
|
141
|
-
}
|
|
142
|
-
if (Array.from(target.classList).indexOf('lf-menu-item') > -1) {
|
|
143
|
-
// 如果点击区域在菜单项内
|
|
144
|
-
;
|
|
145
|
-
target.onclickCallback(_this.__currentData);
|
|
146
|
-
// 点击后隐藏menu
|
|
147
|
-
if (_this.__menuDOM) {
|
|
148
|
-
_this.__menuDOM.style.display = 'none';
|
|
149
|
-
}
|
|
150
|
-
_this.__currentData = null;
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
// 如果点击区域不在菜单项内
|
|
154
|
-
console.warn('点击区域不在菜单项内,请检查代码!');
|
|
155
|
-
}
|
|
156
|
-
}, true);
|
|
157
|
-
}
|
|
158
|
-
// 通过事件控制菜单的显示和隐藏
|
|
159
|
-
this.lf.on('node:contextmenu', function (_a) {
|
|
160
|
-
var _b, _c;
|
|
161
|
-
var data = _a.data, position = _a.position, e = _a.e;
|
|
162
|
-
var _d = position.domOverlayPosition, x = _d.x, y = _d.y;
|
|
163
|
-
var id = data.id;
|
|
164
|
-
var model = _this.lf.graphModel.getNodeModelById(id);
|
|
165
|
-
if (!model)
|
|
166
|
-
return;
|
|
167
|
-
var menuList = [];
|
|
168
|
-
var typeMenus = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(model.type);
|
|
169
|
-
// 1.如果单个节点自定义了菜单,以单个节点自定义为准
|
|
170
|
-
if (model && model.menu && Array.isArray(model.menu)) {
|
|
171
|
-
menuList = model.menu;
|
|
172
|
-
}
|
|
173
|
-
else if (typeMenus) {
|
|
174
|
-
// 2.如果当前节点类型定义了菜单,再取该配置
|
|
175
|
-
menuList = typeMenus;
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
// 3.最后取全局默认
|
|
179
|
-
menuList = (_c = _this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.get(DefaultNodeMenuKey);
|
|
180
|
-
}
|
|
181
|
-
_this.__currentData = data;
|
|
182
|
-
_this.showMenu(x, y, menuList, {
|
|
183
|
-
width: model.width,
|
|
184
|
-
height: model.height,
|
|
185
|
-
clientX: e.clientX,
|
|
186
|
-
clientY: e.clientY,
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
this.lf.on('edge:contextmenu', function (_a) {
|
|
190
|
-
var _b, _c, _d;
|
|
191
|
-
var data = _a.data, position = _a.position, e = _a.e;
|
|
192
|
-
var _e = position.domOverlayPosition, x = _e.x, y = _e.y;
|
|
193
|
-
var id = data.id;
|
|
194
|
-
var model = _this.lf.graphModel.getEdgeModelById(id);
|
|
195
|
-
if (!model)
|
|
196
|
-
return;
|
|
197
|
-
var menuList = [];
|
|
198
|
-
var typeMenus = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(model.type);
|
|
199
|
-
// 菜单优先级: model.menu > typeMenus > defaultEdgeMenu,注释同上节点
|
|
200
|
-
if (model && model.menu && Array.isArray(model.menu)) {
|
|
201
|
-
menuList = model.menu;
|
|
202
|
-
}
|
|
203
|
-
else if (typeMenus) {
|
|
204
|
-
menuList = typeMenus;
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
menuList = (_d = (_c = _this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.get(DefaultEdgeMenuKey)) !== null && _d !== void 0 ? _d : [];
|
|
208
|
-
}
|
|
209
|
-
_this.__currentData = data;
|
|
210
|
-
_this.showMenu(x, y, menuList, {
|
|
211
|
-
width: model.width,
|
|
212
|
-
height: model.height,
|
|
213
|
-
clientX: e.clientX,
|
|
214
|
-
clientY: e.clientY,
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
this.lf.on('blank:contextmenu', function (_a) {
|
|
218
|
-
var _b, _c;
|
|
219
|
-
var position = _a.position;
|
|
220
|
-
var menuList = (_c = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(DefaultGraphMenuKey)) !== null && _c !== void 0 ? _c : [];
|
|
221
|
-
var _d = position.domOverlayPosition, x = _d.x, y = _d.y;
|
|
222
|
-
_this.__currentData = __assign({}, position.canvasOverlayPosition);
|
|
223
|
-
_this.showMenu(x, y, menuList);
|
|
224
|
-
});
|
|
225
|
-
this.lf.on('selection:contextmenu', function (_a) {
|
|
226
|
-
var _b;
|
|
227
|
-
var data = _a.data, position = _a.position;
|
|
228
|
-
var menuList = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(DefaultSelectionMenuKey);
|
|
229
|
-
var _c = position.domOverlayPosition, x = _c.x, y = _c.y;
|
|
230
|
-
_this.__currentData = data;
|
|
231
|
-
_this.showMenu(x, y, menuList);
|
|
232
|
-
});
|
|
233
|
-
this.lf.on('node:mousedown', function () {
|
|
234
|
-
_this.__menuDOM.style.display = 'none';
|
|
235
|
-
});
|
|
236
|
-
this.lf.on('edge:click', function () {
|
|
237
|
-
_this.__menuDOM.style.display = 'none';
|
|
238
|
-
});
|
|
239
|
-
this.lf.on('blank:click', function () {
|
|
240
|
-
_this.__menuDOM.style.display = 'none';
|
|
241
|
-
});
|
|
242
|
-
};
|
|
243
|
-
Menu.prototype.destroy = function () {
|
|
244
|
-
var _a;
|
|
245
|
-
if (this.__menuDOM) {
|
|
246
|
-
(_a = this === null || this === void 0 ? void 0 : this.__container) === null || _a === void 0 ? void 0 : _a.removeChild(this.__menuDOM);
|
|
247
|
-
this.__menuDOM = undefined;
|
|
248
|
-
}
|
|
139
|
+
(_c = this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.set(DefaultSelectionMenuKey, defaultMenuConfig.selectionMenu);
|
|
249
140
|
};
|
|
250
141
|
Menu.prototype.showMenu = function (x, y, menuList, options) {
|
|
142
|
+
// 在静默模式下不显示菜单
|
|
143
|
+
if (this.__isSilentMode)
|
|
144
|
+
return;
|
|
251
145
|
if (!menuList || !menuList.length)
|
|
252
146
|
return;
|
|
253
147
|
var menu = this.__menuDOM;
|
|
@@ -327,15 +221,98 @@ var Menu = /** @class */ (function () {
|
|
|
327
221
|
}
|
|
328
222
|
};
|
|
329
223
|
/**
|
|
330
|
-
*
|
|
224
|
+
* 通用的菜单配置处理方法
|
|
331
225
|
*/
|
|
332
|
-
Menu.prototype.
|
|
333
|
-
var
|
|
334
|
-
|
|
335
|
-
|
|
226
|
+
Menu.prototype.processMenuConfig = function (config, operation) {
|
|
227
|
+
var _this = this;
|
|
228
|
+
if (!config)
|
|
229
|
+
return;
|
|
230
|
+
var menuTypes = [
|
|
231
|
+
'nodeMenu',
|
|
232
|
+
'edgeMenu',
|
|
233
|
+
'graphMenu',
|
|
234
|
+
'selectionMenu',
|
|
235
|
+
];
|
|
236
|
+
menuTypes.forEach(function (menuType) {
|
|
237
|
+
var _a, _b, _c, _d;
|
|
238
|
+
var menuConfig = config[menuType];
|
|
239
|
+
var menuKey = menuKeyMap[menuType];
|
|
240
|
+
if (menuConfig === undefined)
|
|
241
|
+
return;
|
|
242
|
+
if (operation === 'set') {
|
|
243
|
+
// 设置菜单配置
|
|
244
|
+
(_a = _this.menuTypeMap) === null || _a === void 0 ? void 0 : _a.set(menuKey, menuConfig ? menuConfig : []);
|
|
245
|
+
}
|
|
246
|
+
else if (operation === 'add' && Array.isArray(menuConfig)) {
|
|
247
|
+
// 追加菜单配置(只支持数组类型)
|
|
248
|
+
var existingMenuList = (_c = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(menuKey)) !== null && _c !== void 0 ? _c : [];
|
|
249
|
+
(_d = _this.menuTypeMap) === null || _d === void 0 ? void 0 : _d.set(menuKey, existingMenuList.concat(menuConfig));
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
};
|
|
253
|
+
/**
|
|
254
|
+
* 创建图片元素
|
|
255
|
+
*/
|
|
256
|
+
Menu.prototype.createImageElement = function (src, alt) {
|
|
257
|
+
var img = document.createElement('img');
|
|
258
|
+
img.src = src;
|
|
259
|
+
img.alt = alt;
|
|
260
|
+
img.style.width = '16px';
|
|
261
|
+
img.style.height = '16px';
|
|
262
|
+
img.style.objectFit = 'contain';
|
|
263
|
+
return img;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* 检查是否为图片文件路径
|
|
267
|
+
*/
|
|
268
|
+
Menu.prototype.isImageFile = function (iconString) {
|
|
269
|
+
var imageExtensions = [
|
|
270
|
+
'.png',
|
|
271
|
+
'.jpg',
|
|
272
|
+
'.jpeg',
|
|
273
|
+
'.gif',
|
|
274
|
+
'.svg',
|
|
275
|
+
'.webp',
|
|
276
|
+
'.ico',
|
|
277
|
+
'.bmp',
|
|
278
|
+
];
|
|
279
|
+
return imageExtensions.some(function (ext) { return iconString.toLowerCase().includes(ext); });
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* 处理图标逻辑
|
|
283
|
+
*/
|
|
284
|
+
Menu.prototype.processIcon = function (iconContainer, icon, text) {
|
|
285
|
+
var _a;
|
|
286
|
+
if (typeof icon !== 'string') {
|
|
287
|
+
// 如果icon是true,保持原有逻辑(创建空的图标容器)
|
|
336
288
|
return;
|
|
337
289
|
}
|
|
338
|
-
|
|
290
|
+
var iconString = icon;
|
|
291
|
+
// 1. base64格式的图片数据
|
|
292
|
+
if (iconString.startsWith('data:image/')) {
|
|
293
|
+
var img = this.createImageElement(iconString, text || 'icon');
|
|
294
|
+
iconContainer.appendChild(img);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
// 2. 图片文件路径
|
|
298
|
+
if (this.isImageFile(iconString)) {
|
|
299
|
+
var img = this.createImageElement(iconString, text || 'icon');
|
|
300
|
+
iconContainer.appendChild(img);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
// 3. HTML内容(包含< >标签)
|
|
304
|
+
if (iconString.includes('<') && iconString.includes('>')) {
|
|
305
|
+
iconContainer.innerHTML = iconString;
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
// 4. CSS类名(以空格分隔的多个类名或以.开头)
|
|
309
|
+
if (iconString.includes(' ') || iconString.startsWith('.')) {
|
|
310
|
+
var iconClasses = iconString.replace(/^\./, '').split(' ');
|
|
311
|
+
(_a = iconContainer.classList).add.apply(_a, __spreadArray([], __read(iconClasses), false));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
// 5. 单个CSS类名
|
|
315
|
+
iconContainer.classList.add(iconString);
|
|
339
316
|
};
|
|
340
317
|
/**
|
|
341
318
|
* 获取 Menu DOM
|
|
@@ -343,20 +320,22 @@ var Menu = /** @class */ (function () {
|
|
|
343
320
|
* @return 菜单项 DOM
|
|
344
321
|
*/
|
|
345
322
|
Menu.prototype.__getMenuDom = function (list) {
|
|
323
|
+
var _this = this;
|
|
346
324
|
var menuList = [];
|
|
347
325
|
list &&
|
|
348
326
|
list.length > 0 &&
|
|
349
327
|
list.forEach(function (item) {
|
|
350
328
|
var element = document.createElement('li');
|
|
351
329
|
if (item.className) {
|
|
352
|
-
element.className = "lf-menu-item ".concat(item.className);
|
|
330
|
+
element.className = "lf-menu-item ".concat(item.disabled ? 'lf-menu-item__disabled' : '', " ").concat(item.className);
|
|
353
331
|
}
|
|
354
332
|
else {
|
|
355
|
-
element.className =
|
|
333
|
+
element.className = "lf-menu-item ".concat(item.disabled ? 'lf-menu-item__disabled' : '');
|
|
356
334
|
}
|
|
357
|
-
if (item.icon
|
|
335
|
+
if (item.icon) {
|
|
358
336
|
var icon = document.createElement('span');
|
|
359
337
|
icon.className = 'lf-menu-item-icon';
|
|
338
|
+
_this.processIcon(icon, item.icon, item.text);
|
|
360
339
|
element.appendChild(icon);
|
|
361
340
|
}
|
|
362
341
|
var text = document.createElement('span');
|
|
@@ -365,46 +344,188 @@ var Menu = /** @class */ (function () {
|
|
|
365
344
|
text.innerText = item.text;
|
|
366
345
|
}
|
|
367
346
|
element.appendChild(text);
|
|
347
|
+
if (item.disabled) {
|
|
348
|
+
element.setAttribute('disabled', 'true');
|
|
349
|
+
}
|
|
350
|
+
;
|
|
368
351
|
element.onclickCallback = item.callback;
|
|
369
352
|
menuList.push(element);
|
|
370
353
|
});
|
|
371
354
|
return menuList;
|
|
372
355
|
};
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
356
|
+
/**
|
|
357
|
+
* 更新菜单项DOM元素的禁用状态
|
|
358
|
+
* @param text 菜单项文本
|
|
359
|
+
* @param disabled 是否禁用
|
|
360
|
+
*/
|
|
361
|
+
Menu.prototype.updateMenuItemDOMStatus = function (text, disabled) {
|
|
362
|
+
if (!this.__menuDOM || this.__menuDOM.style.display === 'none') {
|
|
377
363
|
return;
|
|
378
364
|
}
|
|
379
|
-
//
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
(
|
|
365
|
+
// 查找对应的菜单项DOM元素
|
|
366
|
+
var menuItems = Array.from(this.__menuDOM.querySelectorAll('.lf-menu-item'));
|
|
367
|
+
var targetMenuItem = menuItems.find(function (menuItemElement) {
|
|
368
|
+
var textElement = menuItemElement.querySelector('.lf-menu-item-text');
|
|
369
|
+
return (textElement === null || textElement === void 0 ? void 0 : textElement.textContent) === text;
|
|
370
|
+
});
|
|
371
|
+
if (targetMenuItem) {
|
|
372
|
+
var element = targetMenuItem;
|
|
373
|
+
if (disabled) {
|
|
374
|
+
element.classList.add('lf-menu-item__disabled');
|
|
375
|
+
element.setAttribute('disabled', 'true');
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
element.classList.remove('lf-menu-item__disabled');
|
|
379
|
+
element.removeAttribute('disabled');
|
|
380
|
+
}
|
|
381
|
+
}
|
|
388
382
|
};
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
383
|
+
/**
|
|
384
|
+
* 设置静默模式监听器
|
|
385
|
+
* 当 isSilentMode 变化时,动态更新菜单的显隐状态
|
|
386
|
+
*/
|
|
387
|
+
Menu.prototype.setupSilentModeListener = function () {
|
|
388
|
+
var _this = this;
|
|
389
|
+
// 创建并保存事件处理器引用
|
|
390
|
+
this.__editConfigChangeHandler = function (_a) {
|
|
391
|
+
var data = _a.data;
|
|
392
|
+
var newIsSilentMode = data.isSilentMode;
|
|
393
|
+
if (newIsSilentMode !== _this.__isSilentMode) {
|
|
394
|
+
_this.__isSilentMode = newIsSilentMode;
|
|
395
|
+
_this.updateMenuVisibility(!newIsSilentMode);
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
// 监听编辑配置变化
|
|
399
|
+
this.lf.on('editConfig:changed', this.__editConfigChangeHandler);
|
|
400
|
+
};
|
|
401
|
+
/**
|
|
402
|
+
* 更新菜单显隐状态
|
|
403
|
+
*/
|
|
404
|
+
Menu.prototype.updateMenuVisibility = function (visible) {
|
|
405
|
+
if (!this.__menuDOM)
|
|
393
406
|
return;
|
|
407
|
+
if (visible) {
|
|
408
|
+
if (this.__currentData) {
|
|
409
|
+
this.__menuDOM.style.display = 'block';
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
this.__menuDOM.style.display = 'none';
|
|
414
|
+
this.__currentData = null; // 清除当前数据
|
|
394
415
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
416
|
+
};
|
|
417
|
+
/**
|
|
418
|
+
* 检查菜单是否正在显示并重新渲染
|
|
419
|
+
*/
|
|
420
|
+
Menu.prototype.refreshCurrentMenu = function () {
|
|
421
|
+
var _a;
|
|
422
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
423
|
+
if (!this.__menuDOM ||
|
|
424
|
+
this.__menuDOM.style.display === 'none' ||
|
|
425
|
+
!this.__currentData) {
|
|
426
|
+
return;
|
|
399
427
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
428
|
+
// 保存当前菜单的位置
|
|
429
|
+
var _m = this.__menuDOM.style, left = _m.left, top = _m.top;
|
|
430
|
+
// 根据当前数据类型获取对应的菜单配置
|
|
431
|
+
var menuList = [];
|
|
432
|
+
// 判断当前数据类型并获取相应菜单
|
|
433
|
+
if (this.__currentData && typeof this.__currentData === 'object') {
|
|
434
|
+
if ('sourceNodeId' in this.__currentData &&
|
|
435
|
+
'targetNodeId' in this.__currentData) {
|
|
436
|
+
// 边菜单
|
|
437
|
+
var model = this.lf.graphModel.getEdgeModelById(this.__currentData.id);
|
|
438
|
+
if (model) {
|
|
439
|
+
var typeMenus = (_b = this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(model.type);
|
|
440
|
+
if (model.menu && Array.isArray(model.menu)) {
|
|
441
|
+
menuList = model.menu;
|
|
442
|
+
}
|
|
443
|
+
else if (typeMenus) {
|
|
444
|
+
menuList = typeMenus;
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
menuList = (_d = (_c = this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.get(DefaultEdgeMenuKey)) !== null && _d !== void 0 ? _d : [];
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
else if ('id' in this.__currentData && 'type' in this.__currentData) {
|
|
452
|
+
// 节点菜单
|
|
453
|
+
var model = this.lf.graphModel.getNodeModelById(this.__currentData.id);
|
|
454
|
+
if (model) {
|
|
455
|
+
var typeMenus = (_e = this.menuTypeMap) === null || _e === void 0 ? void 0 : _e.get(model.type);
|
|
456
|
+
if (model.menu && Array.isArray(model.menu)) {
|
|
457
|
+
menuList = model.menu;
|
|
458
|
+
}
|
|
459
|
+
else if (typeMenus) {
|
|
460
|
+
menuList = typeMenus;
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
menuList = (_g = (_f = this.menuTypeMap) === null || _f === void 0 ? void 0 : _f.get(DefaultNodeMenuKey)) !== null && _g !== void 0 ? _g : [];
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
else if ('nodes' in this.__currentData &&
|
|
468
|
+
'edges' in this.__currentData) {
|
|
469
|
+
// 选区菜单
|
|
470
|
+
menuList = (_j = (_h = this.menuTypeMap) === null || _h === void 0 ? void 0 : _h.get(DefaultSelectionMenuKey)) !== null && _j !== void 0 ? _j : [];
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
// 画布菜单
|
|
474
|
+
menuList = (_l = (_k = this.menuTypeMap) === null || _k === void 0 ? void 0 : _k.get(DefaultGraphMenuKey)) !== null && _l !== void 0 ? _l : [];
|
|
475
|
+
}
|
|
403
476
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
477
|
+
// 重新渲染菜单
|
|
478
|
+
if (menuList && menuList.length > 0) {
|
|
479
|
+
this.__menuDOM.innerHTML = '';
|
|
480
|
+
(_a = this.__menuDOM).append.apply(_a, __spreadArray([], __read(this.__getMenuDom(menuList)), false));
|
|
481
|
+
// 恢复菜单位置(如果有的话)
|
|
482
|
+
if (left)
|
|
483
|
+
this.__menuDOM.style.left = left;
|
|
484
|
+
if (top)
|
|
485
|
+
this.__menuDOM.style.top = top;
|
|
407
486
|
}
|
|
487
|
+
else {
|
|
488
|
+
// 如果没有菜单项,隐藏菜单
|
|
489
|
+
this.__menuDOM.style.display = 'none';
|
|
490
|
+
this.__currentData = null;
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
/**
|
|
494
|
+
* 设置指定类型元素的菜单
|
|
495
|
+
*/
|
|
496
|
+
Menu.prototype.setMenuByType = function (_a) {
|
|
497
|
+
var _b;
|
|
498
|
+
var type = _a.type, menu = _a.menu;
|
|
499
|
+
if (!type || !menu) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
(_b = this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.set(type, menu);
|
|
503
|
+
this.refreshCurrentMenu(); // 实时更新DOM
|
|
504
|
+
};
|
|
505
|
+
Menu.prototype.getMenuConfig = function (menuKey) {
|
|
506
|
+
var _a, _b;
|
|
507
|
+
return (_b = (_a = this.menuTypeMap) === null || _a === void 0 ? void 0 : _a.get(menuKeyMap[menuKey])) !== null && _b !== void 0 ? _b : [];
|
|
508
|
+
};
|
|
509
|
+
Menu.prototype.resetMenuConfigByType = function (menuKey) {
|
|
510
|
+
var _a;
|
|
511
|
+
this.setMenuConfig((_a = {},
|
|
512
|
+
_a[menuKey] = defaultMenuConfig[menuKey],
|
|
513
|
+
_a));
|
|
514
|
+
// setMenuConfig 已经包含了 refreshCurrentMenu 调用
|
|
515
|
+
};
|
|
516
|
+
Menu.prototype.resetAllMenuConfig = function () {
|
|
517
|
+
this.setMenuConfig(defaultMenuConfig);
|
|
518
|
+
// setMenuConfig 已经包含了 refreshCurrentMenu 调用
|
|
519
|
+
};
|
|
520
|
+
// 复写菜单
|
|
521
|
+
Menu.prototype.setMenuConfig = function (config) {
|
|
522
|
+
this.processMenuConfig(config, 'set');
|
|
523
|
+
this.refreshCurrentMenu(); // 实时更新DOM
|
|
524
|
+
};
|
|
525
|
+
// 在默认菜单后面追加菜单项
|
|
526
|
+
Menu.prototype.addMenuConfig = function (config) {
|
|
527
|
+
this.processMenuConfig(config, 'add');
|
|
528
|
+
this.refreshCurrentMenu(); // 实时更新DOM
|
|
408
529
|
};
|
|
409
530
|
/**
|
|
410
531
|
* @deprecated
|
|
@@ -420,6 +541,168 @@ var Menu = /** @class */ (function () {
|
|
|
420
541
|
else {
|
|
421
542
|
throw new Error("The first parameter of changeMenuConfig should be 'add' or 'reset'");
|
|
422
543
|
}
|
|
544
|
+
// addMenuConfig 和 setMenuConfig 已经包含了 refreshCurrentMenu 调用
|
|
545
|
+
};
|
|
546
|
+
Menu.prototype.changeMenuItemDisableStatus = function (menuKey, text, disabled) {
|
|
547
|
+
var _a, _b;
|
|
548
|
+
if (!menuKey || !text) {
|
|
549
|
+
console.warn('params is vaild');
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
var menuList = (_b = (_a = this.menuTypeMap) === null || _a === void 0 ? void 0 : _a.get(menuKeyMap[menuKey])) !== null && _b !== void 0 ? _b : [];
|
|
553
|
+
if (!menuList.length) {
|
|
554
|
+
console.warn("menuMap: ".concat(menuKey, " is not exist"));
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
var menuItem = menuList.find(function (item) { return item.text === text; });
|
|
558
|
+
if (!menuItem) {
|
|
559
|
+
console.warn("menuItem: ".concat(text, " is not exist"));
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
menuItem.disabled = disabled;
|
|
563
|
+
// 如果菜单当前正在显示,则同时更新DOM元素的样式
|
|
564
|
+
this.updateMenuItemDOMStatus(text, disabled);
|
|
565
|
+
};
|
|
566
|
+
Menu.prototype.render = function (lf, container) {
|
|
567
|
+
var _this = this;
|
|
568
|
+
if (lf.graphModel.editConfigModel.isSilentMode)
|
|
569
|
+
return;
|
|
570
|
+
this.__container = container;
|
|
571
|
+
this.__currentData = null; // 当前展示的菜单所属元素的model数据
|
|
572
|
+
// 监听 isSilentMode 变化
|
|
573
|
+
this.setupSilentModeListener();
|
|
574
|
+
if (this.__menuDOM) {
|
|
575
|
+
this.__menuDOM.className = 'lf-menu';
|
|
576
|
+
container.appendChild(this.__menuDOM);
|
|
577
|
+
// 将选项的click事件委托至menu容器
|
|
578
|
+
// 在捕获阶段拦截并执行
|
|
579
|
+
this.__menuDOM.addEventListener('click', function (event) {
|
|
580
|
+
event.stopPropagation();
|
|
581
|
+
var target = event.target;
|
|
582
|
+
// 菜单有多层dom,需要精确获取菜单项所对应的dom
|
|
583
|
+
// 除菜单项dom外,应考虑两种情况
|
|
584
|
+
// 1. 菜单项的子元素 2. 菜单外层容器
|
|
585
|
+
while (Array.from(target.classList).indexOf('lf-menu-item') === -1 &&
|
|
586
|
+
Array.from(target.classList).indexOf('lf-menu') === -1) {
|
|
587
|
+
target = target === null || target === void 0 ? void 0 : target.parentElement;
|
|
588
|
+
}
|
|
589
|
+
if (Array.from(target.classList).indexOf('lf-menu-item__disabled') > -1)
|
|
590
|
+
return;
|
|
591
|
+
if (Array.from(target.classList).indexOf('lf-menu-item') > -1) {
|
|
592
|
+
// 如果菜单项被禁用,则不执行回调
|
|
593
|
+
;
|
|
594
|
+
target.onclickCallback(_this.__currentData, target);
|
|
595
|
+
// 点击后隐藏menu
|
|
596
|
+
if (_this.__menuDOM) {
|
|
597
|
+
_this.__menuDOM.style.display = 'none';
|
|
598
|
+
}
|
|
599
|
+
_this.__currentData = null;
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
// 如果点击区域不在菜单项内
|
|
603
|
+
console.warn('点击区域不在菜单项内,请检查代码!');
|
|
604
|
+
}
|
|
605
|
+
}, true);
|
|
606
|
+
}
|
|
607
|
+
// 通过事件控制菜单的显示和隐藏
|
|
608
|
+
this.lf.on('node:contextmenu', function (_a) {
|
|
609
|
+
var _b, _c;
|
|
610
|
+
var data = _a.data, position = _a.position, e = _a.e;
|
|
611
|
+
var _d = position.domOverlayPosition, x = _d.x, y = _d.y;
|
|
612
|
+
var id = data.id;
|
|
613
|
+
var model = _this.lf.graphModel.getNodeModelById(id);
|
|
614
|
+
if (!model || _this.__isSilentMode)
|
|
615
|
+
return;
|
|
616
|
+
var menuList = [];
|
|
617
|
+
var typeMenus = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(model.type);
|
|
618
|
+
// 1.如果单个节点自定义了菜单,以单个节点自定义为准
|
|
619
|
+
if (model && model.menu && Array.isArray(model.menu)) {
|
|
620
|
+
menuList = model.menu;
|
|
621
|
+
}
|
|
622
|
+
else if (typeMenus) {
|
|
623
|
+
// 2.如果当前节点类型定义了菜单,再取该配置
|
|
624
|
+
menuList = typeMenus;
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
// 3.最后取全局默认
|
|
628
|
+
menuList = (_c = _this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.get(DefaultNodeMenuKey);
|
|
629
|
+
}
|
|
630
|
+
_this.__currentData = data;
|
|
631
|
+
_this.showMenu(x, y, menuList, {
|
|
632
|
+
width: model.width,
|
|
633
|
+
height: model.height,
|
|
634
|
+
clientX: e.clientX,
|
|
635
|
+
clientY: e.clientY,
|
|
636
|
+
});
|
|
637
|
+
});
|
|
638
|
+
this.lf.on('edge:contextmenu', function (_a) {
|
|
639
|
+
var _b, _c, _d;
|
|
640
|
+
var data = _a.data, position = _a.position, e = _a.e;
|
|
641
|
+
var _e = position.domOverlayPosition, x = _e.x, y = _e.y;
|
|
642
|
+
var id = data.id;
|
|
643
|
+
var model = _this.lf.graphModel.getEdgeModelById(id);
|
|
644
|
+
if (!model || _this.__isSilentMode)
|
|
645
|
+
return;
|
|
646
|
+
var menuList = [];
|
|
647
|
+
var typeMenus = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(model.type);
|
|
648
|
+
// 菜单优先级: model.menu > typeMenus > defaultEdgeMenu,注释同上节点
|
|
649
|
+
if (model && model.menu && Array.isArray(model.menu)) {
|
|
650
|
+
menuList = model.menu;
|
|
651
|
+
}
|
|
652
|
+
else if (typeMenus) {
|
|
653
|
+
menuList = typeMenus;
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
menuList = (_d = (_c = _this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.get(DefaultEdgeMenuKey)) !== null && _d !== void 0 ? _d : [];
|
|
657
|
+
}
|
|
658
|
+
_this.__currentData = data;
|
|
659
|
+
_this.showMenu(x, y, menuList, {
|
|
660
|
+
width: model.width,
|
|
661
|
+
height: model.height,
|
|
662
|
+
clientX: e.clientX,
|
|
663
|
+
clientY: e.clientY,
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
this.lf.on('blank:contextmenu', function (_a) {
|
|
667
|
+
var _b, _c;
|
|
668
|
+
var position = _a.position;
|
|
669
|
+
if (_this.__isSilentMode)
|
|
670
|
+
return;
|
|
671
|
+
var menuList = (_c = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(DefaultGraphMenuKey)) !== null && _c !== void 0 ? _c : [];
|
|
672
|
+
var _d = position.domOverlayPosition, x = _d.x, y = _d.y;
|
|
673
|
+
_this.__currentData = __assign({}, position.canvasOverlayPosition);
|
|
674
|
+
_this.showMenu(x, y, menuList);
|
|
675
|
+
});
|
|
676
|
+
this.lf.on('selection:contextmenu', function (_a) {
|
|
677
|
+
var _b;
|
|
678
|
+
var data = _a.data, position = _a.position;
|
|
679
|
+
if (_this.__isSilentMode)
|
|
680
|
+
return;
|
|
681
|
+
var menuList = (_b = _this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.get(DefaultSelectionMenuKey);
|
|
682
|
+
var _c = position.domOverlayPosition, x = _c.x, y = _c.y;
|
|
683
|
+
_this.__currentData = data;
|
|
684
|
+
_this.showMenu(x, y, menuList);
|
|
685
|
+
});
|
|
686
|
+
this.lf.on('node:mousedown', function () {
|
|
687
|
+
_this.__menuDOM.style.display = 'none';
|
|
688
|
+
});
|
|
689
|
+
this.lf.on('edge:click', function () {
|
|
690
|
+
_this.__menuDOM.style.display = 'none';
|
|
691
|
+
});
|
|
692
|
+
this.lf.on('blank:click', function () {
|
|
693
|
+
_this.__menuDOM.style.display = 'none';
|
|
694
|
+
});
|
|
695
|
+
};
|
|
696
|
+
Menu.prototype.destroy = function () {
|
|
697
|
+
var _a;
|
|
698
|
+
// 清理事件监听器
|
|
699
|
+
if (this.__editConfigChangeHandler) {
|
|
700
|
+
this.lf.off('editConfig:changed', this.__editConfigChangeHandler);
|
|
701
|
+
}
|
|
702
|
+
if (this.__menuDOM) {
|
|
703
|
+
(_a = this === null || this === void 0 ? void 0 : this.__container) === null || _a === void 0 ? void 0 : _a.removeChild(this.__menuDOM);
|
|
704
|
+
this.__menuDOM = undefined;
|
|
705
|
+
}
|
|
423
706
|
};
|
|
424
707
|
Menu.pluginName = 'menu';
|
|
425
708
|
return Menu;
|