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