@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.
@@ -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
- var isSilentMode = lf.options.isSilentMode;
51
- if (!isSilentMode) {
52
- this.__menuDOM = document.createElement('ul');
53
- this.menuTypeMap = new Map();
54
- this.init();
55
- this.lf.setMenuConfig = function (config) {
56
- _this.setMenuConfig(config);
57
- };
58
- this.lf.addMenuConfig = function (config) {
59
- _this.addMenuConfig(config);
60
- };
61
- this.lf.setMenuByType = function (config) {
62
- _this.setMenuByType(config);
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, _d;
72
- var defaultNodeMenu = [
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, defaultNodeMenu);
93
- var defaultEdgeMenu = [
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, defaultEdgeMenu);
108
- (_c = this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.set(DefaultGraphMenuKey, []);
109
- var DefaultSelectionMenu = [
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
- (_d = this.menuTypeMap) === null || _d === void 0 ? void 0 : _d.set(DefaultSelectionMenuKey, DefaultSelectionMenu);
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.setMenuByType = function (_a) {
333
- var _b;
334
- var type = _a.type, menu = _a.menu;
335
- if (!type || !menu) {
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
- (_b = this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.set(type, menu);
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 = 'lf-menu-item';
333
+ element.className = "lf-menu-item ".concat(item.disabled ? 'lf-menu-item__disabled' : '');
356
334
  }
357
- if (item.icon === true) {
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
- Menu.prototype.setMenuConfig = function (config) {
375
- var _a, _b, _c;
376
- if (!config) {
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
- // node
380
- config.nodeMenu !== undefined &&
381
- ((_a = this.menuTypeMap) === null || _a === void 0 ? void 0 : _a.set(DefaultNodeMenuKey, config.nodeMenu ? config.nodeMenu : []));
382
- // edge
383
- config.edgeMenu !== undefined &&
384
- ((_b = this.menuTypeMap) === null || _b === void 0 ? void 0 : _b.set(DefaultEdgeMenuKey, config.edgeMenu ? config.edgeMenu : []));
385
- // graph
386
- config.graphMenu !== undefined &&
387
- ((_c = this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.set(DefaultGraphMenuKey, config.graphMenu ? config.graphMenu : []));
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
- Menu.prototype.addMenuConfig = function (config) {
391
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
392
- if (!config) {
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
- // 追加项时,只支持数组类型,对false不做操作
396
- if (Array.isArray(config.nodeMenu)) {
397
- var menuList = (_b = (_a = this.menuTypeMap) === null || _a === void 0 ? void 0 : _a.get(DefaultNodeMenuKey)) !== null && _b !== void 0 ? _b : [];
398
- (_c = this.menuTypeMap) === null || _c === void 0 ? void 0 : _c.set(DefaultNodeMenuKey, menuList.concat(config.nodeMenu));
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
- if (Array.isArray(config.edgeMenu)) {
401
- var menuList = (_e = (_d = this.menuTypeMap) === null || _d === void 0 ? void 0 : _d.get(DefaultEdgeMenuKey)) !== null && _e !== void 0 ? _e : [];
402
- (_f = this.menuTypeMap) === null || _f === void 0 ? void 0 : _f.set(DefaultEdgeMenuKey, menuList.concat(config.edgeMenu));
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
- if (Array.isArray(config.graphMenu)) {
405
- var menuList = (_h = (_g = this.menuTypeMap) === null || _g === void 0 ? void 0 : _g.get(DefaultGraphMenuKey)) !== null && _h !== void 0 ? _h : [];
406
- (_j = this.menuTypeMap) === null || _j === void 0 ? void 0 : _j.set(DefaultGraphMenuKey, menuList.concat(config.graphMenu));
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;