bizydraft 0.2.49__py3-none-any.whl → 0.2.87__py3-none-any.whl

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.

Potentially problematic release.


This version of bizydraft might be problematic. Click here for more details.

@@ -17,128 +17,131 @@ let originalRequestAnimationFrame = null; // 保存原始的requestAnimationFram
17
17
 
18
18
  // 冻结工作流,添加遮罩层
19
19
  function freezeWorkflow(isworkflow = false) {
20
- // 设置冻结状态
21
- isFrozen = true;
22
- // 禁用全局快捷键和鼠标事件
23
- blockGlobalEvents(true);
20
+ // 设置冻结状态
21
+ isFrozen = true;
22
+ // 禁用全局快捷键和鼠标事件
23
+ blockGlobalEvents(true);
24
24
 
25
- // 创建遮罩层
26
- createOverlay();
25
+ // 创建遮罩层
26
+ createOverlay();
27
27
 
28
- // 更新高亮节点列表
29
- updateHighlightedNodes();
28
+ // 更新高亮节点列表
29
+ updateHighlightedNodes();
30
30
 
31
- // 启用鼠标追踪
32
- enableMouseTracking();
31
+ // 启用鼠标追踪
32
+ enableMouseTracking();
33
33
 
34
- // 禁用节点搜索容器
35
- disableNodeSearch(true);
34
+ // 禁用节点搜索容器
35
+ disableNodeSearch(true);
36
36
 
37
- // 显示底部提示
38
- showBottomTip(isworkflow);
37
+ // 显示底部提示
38
+ showBottomTip(isworkflow);
39
39
 
40
- // 阻止拖拽上传文件
41
- blockDragDropEvents(true);
40
+ // 阻止拖拽上传文件
41
+ blockDragDropEvents(true);
42
42
 
43
- // 关闭并禁用最小地图按钮
44
- setMiniMapButtonDisabled(true, true);
43
+ // 关闭并禁用最小地图按钮
44
+ setMiniMapButtonDisabled(true, true);
45
45
  }
46
46
 
47
47
  // 解冻工作流,移除遮罩层
48
48
  function unfreezeWorkflow() {
49
- isFrozen = false;
50
- // 恢复原始的requestAnimationFrame
51
- if (originalRequestAnimationFrame && window.requestAnimationFrame !== originalRequestAnimationFrame) {
52
- window.requestAnimationFrame = originalRequestAnimationFrame;
53
- originalRequestAnimationFrame = null;
54
- }
49
+ isFrozen = false;
50
+ // 恢复原始的requestAnimationFrame
51
+ if (
52
+ originalRequestAnimationFrame &&
53
+ window.requestAnimationFrame !== originalRequestAnimationFrame
54
+ ) {
55
+ window.requestAnimationFrame = originalRequestAnimationFrame;
56
+ originalRequestAnimationFrame = null;
57
+ }
55
58
 
56
- // 恢复全局快捷键和鼠标事件
57
- blockGlobalEvents(false);
59
+ // 恢复全局快捷键和鼠标事件
60
+ blockGlobalEvents(false);
58
61
 
59
- // 移除遮罩层
60
- removeOverlay();
62
+ // 移除遮罩层
63
+ removeOverlay();
61
64
 
62
- // 清空高亮节点列表
63
- highlightedNodes.clear();
65
+ // 清空高亮节点列表
66
+ highlightedNodes.clear();
64
67
 
65
- // 禁用鼠标追踪
66
- disableMouseTracking();
68
+ // 禁用鼠标追踪
69
+ disableMouseTracking();
67
70
 
68
- // 恢复节点搜索容器
69
- disableNodeSearch(false);
71
+ // 恢复节点搜索容器
72
+ disableNodeSearch(false);
70
73
 
71
- // 隐藏底部提示
72
- hideBottomTip();
74
+ // 隐藏底部提示
75
+ hideBottomTip();
73
76
 
74
- // 恢复拖拽上传文件
75
- blockDragDropEvents(false);
77
+ // 恢复拖拽上传文件
78
+ blockDragDropEvents(false);
76
79
 
77
- // 恢复最小地图按钮可用
78
- setMiniMapButtonDisabled(false);
80
+ // 恢复最小地图按钮可用
81
+ setMiniMapButtonDisabled(false);
79
82
  }
80
83
 
81
84
  // 显示提示信息
82
85
  function showBottomTip(isworkflow = false) {
83
- // 如果已经存在提示元素,先移除
84
- if (bottomTipElement) {
85
- bottomTipElement.remove();
86
- bottomTipElement = null;
87
- }
88
-
89
- // 创建提示元素
90
- bottomTipElement = document.createElement('div');
91
- bottomTipElement.id = 'aiapp-bottom-tip';
92
-
93
- // 设置样式
94
- bottomTipElement.style.position = 'fixed';
95
- bottomTipElement.style.left = '64%';
96
- bottomTipElement.style.top = '89%';
97
- bottomTipElement.style.transform = 'translate(-50%, -50%)';
98
- bottomTipElement.style.backgroundColor = 'white'; // 白色背景
99
- bottomTipElement.style.color = 'black'; // 黑色文字
100
- bottomTipElement.style.padding = '10px 20px';
101
- bottomTipElement.style.textAlign = 'center';
102
- bottomTipElement.style.fontSize = '14px';
103
- bottomTipElement.style.zIndex = '10000';
104
- bottomTipElement.style.borderRadius = '4px';
105
- bottomTipElement.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.15)';
106
- bottomTipElement.style.border = '1px solid #e0e0e0';
107
-
108
- // 根据模式设置不同的提示文本
109
- if (isworkflow) {
110
- bottomTipElement.textContent = '发布工作流时不可编辑原工作流';
111
- } else {
112
- bottomTipElement.textContent = '编辑AI应用参数时不可编辑原工作流';
113
- }
114
-
115
- // 添加到DOM
116
- document.body.appendChild(bottomTipElement);
86
+ // 如果已经存在提示元素,先移除
87
+ if (bottomTipElement) {
88
+ bottomTipElement.remove();
89
+ bottomTipElement = null;
90
+ }
91
+
92
+ // 创建提示元素
93
+ bottomTipElement = document.createElement("div");
94
+ bottomTipElement.id = "aiapp-bottom-tip";
95
+
96
+ // 设置样式
97
+ bottomTipElement.style.position = "fixed";
98
+ bottomTipElement.style.left = "64%";
99
+ bottomTipElement.style.top = "89%";
100
+ bottomTipElement.style.transform = "translate(-50%, -50%)";
101
+ bottomTipElement.style.backgroundColor = "white"; // 白色背景
102
+ bottomTipElement.style.color = "black"; // 黑色文字
103
+ bottomTipElement.style.padding = "10px 20px";
104
+ bottomTipElement.style.textAlign = "center";
105
+ bottomTipElement.style.fontSize = "14px";
106
+ bottomTipElement.style.zIndex = "10000";
107
+ bottomTipElement.style.borderRadius = "4px";
108
+ bottomTipElement.style.boxShadow = "0 2px 8px rgba(0, 0, 0, 0.15)";
109
+ bottomTipElement.style.border = "1px solid #e0e0e0";
110
+
111
+ // 根据模式设置不同的提示文本
112
+ if (isworkflow) {
113
+ bottomTipElement.textContent = "发布工作流时不可编辑原工作流";
114
+ } else {
115
+ bottomTipElement.textContent = "编辑AI应用参数时不可编辑原工作流";
116
+ }
117
+
118
+ // 添加到DOM
119
+ document.body.appendChild(bottomTipElement);
117
120
  }
118
121
 
119
122
  // 隐藏底部提示信息
120
123
  function hideBottomTip() {
121
- if (bottomTipElement) {
122
- bottomTipElement.remove();
123
- bottomTipElement = null;
124
- }
124
+ if (bottomTipElement) {
125
+ bottomTipElement.remove();
126
+ bottomTipElement = null;
127
+ }
125
128
  }
126
129
 
127
130
  // 禁用或启用节点搜索功能
128
131
  function disableNodeSearch(disable) {
129
- // 如果已经有样式元素,先移除它
130
- if (nodeSearchStyleElement) {
131
- nodeSearchStyleElement.remove();
132
- nodeSearchStyleElement = null;
133
- }
134
-
135
- if (disable) {
136
- // 创建样式元素
137
- nodeSearchStyleElement = document.createElement('style');
138
- nodeSearchStyleElement.id = 'aiapp-disable-node-search-style';
139
-
140
- // 添加CSS规则来禁用节点搜索容器和相关元素
141
- nodeSearchStyleElement.textContent = `
132
+ // 如果已经有样式元素,先移除它
133
+ if (nodeSearchStyleElement) {
134
+ nodeSearchStyleElement.remove();
135
+ nodeSearchStyleElement = null;
136
+ }
137
+
138
+ if (disable) {
139
+ // 创建样式元素
140
+ nodeSearchStyleElement = document.createElement("style");
141
+ nodeSearchStyleElement.id = "aiapp-disable-node-search-style";
142
+
143
+ // 添加CSS规则来禁用节点搜索容器和相关元素
144
+ nodeSearchStyleElement.textContent = `
142
145
  /* 禁用节点搜索容器 */
143
146
  .comfy-vue-node-search-container,
144
147
  .litegraph-dialog,
@@ -154,394 +157,412 @@ function disableNodeSearch(disable) {
154
157
  }
155
158
  `;
156
159
 
157
- // 添加到文档头部
158
- document.head.appendChild(nodeSearchStyleElement);
159
- }
160
+ // 添加到文档头部
161
+ document.head.appendChild(nodeSearchStyleElement);
162
+ }
160
163
  }
161
164
 
162
165
  // 阻止全局快捷键和鼠标事件
163
166
  function blockGlobalEvents(block) {
164
- if (block && !globalEventBlocked) {
165
- // 启用拦截
166
- globalEventBlocked = true;
167
-
168
- // 阻止键盘快捷键
169
- keyboardListener = function(e) {
170
- // 检查是否是需要阻止的按键
171
- // 阻止: 退格键(8), Delete(46), Ctrl+C(67), Ctrl+V(86), Ctrl+Z(90), Ctrl+Y(89)
172
- const key = e.keyCode || e.which;
173
- const isCtrl = e.ctrlKey || e.metaKey;
174
-
175
- // 检查节点附近的鼠标位置 - 如果在节点附近则不阻止
176
- // const isNearHighlightedNode = isMouseNearHighlightedNode(e);
177
-
178
- // if ( (
179
- // key === 8 || // Backspace
180
- // key === 46 || // Delete
181
- // (isCtrl && (
182
- // key === 67 || // C
183
- // key === 86 || // V
184
- // key === 90 || // Z
185
- // key === 89 // Y
186
- // ))
187
- // )) {
188
- // console.log('阻止键盘快捷键:', e.key, key);
189
- e.preventDefault();
190
- e.stopPropagation();
191
- e.stopImmediatePropagation();
192
-
193
- // 只在冻结模式下覆盖requestAnimationFrame
194
- if (isFrozen && !originalRequestAnimationFrame) {
195
- // 保存原始的 requestAnimationFrame
196
- originalRequestAnimationFrame = window.requestAnimationFrame;
197
-
198
- // 覆盖 requestAnimationFrame,过滤掉包含撤销逻辑的回调
199
- window.requestAnimationFrame = function(callback) {
200
- // 检查回调函数是否包含撤销相关的逻辑
201
- const callbackStr = callback.toString();
202
- if (callbackStr.includes('undoRedo') ||
203
- callbackStr.includes('changeTracker') ||
204
- callbackStr.includes('checkState')) {
205
- console.log('拦截了包含撤销逻辑的 requestAnimationFrame');
206
- // 返回一个空函数,不执行撤销逻辑
207
- return originalRequestAnimationFrame(() => {});
208
- }
209
- // 其他回调正常执行
210
- return originalRequestAnimationFrame(callback);
211
- };
212
- }
213
-
214
- return false;
215
- // }
216
- };
217
-
218
- // 阻止右键菜单
219
- contextMenuListener = function(e) {
220
- // 检查鼠标是否在高亮节点附近
221
- const isNearHighlightedNode = isMouseNearHighlightedNode(e);
222
-
223
- // 如果不在高亮节点附近,阻止右键菜单
224
- if (!isNearHighlightedNode) {
225
- e.preventDefault();
226
- e.stopPropagation();
227
- return false;
228
- }
167
+ if (block && !globalEventBlocked) {
168
+ // 启用拦截
169
+ globalEventBlocked = true;
170
+
171
+ // 阻止键盘快捷键
172
+ keyboardListener = function (e) {
173
+ // 检查是否是需要阻止的按键
174
+ // 阻止: 退格键(8), Delete(46), Ctrl+C(67), Ctrl+V(86), Ctrl+Z(90), Ctrl+Y(89)
175
+ const key = e.keyCode || e.which;
176
+ const isCtrl = e.ctrlKey || e.metaKey;
177
+
178
+ // 检查节点附近的鼠标位置 - 如果在节点附近则不阻止
179
+ // const isNearHighlightedNode = isMouseNearHighlightedNode(e);
180
+
181
+ // if ( (
182
+ // key === 8 || // Backspace
183
+ // key === 46 || // Delete
184
+ // (isCtrl && (
185
+ // key === 67 || // C
186
+ // key === 86 || // V
187
+ // key === 90 || // Z
188
+ // key === 89 // Y
189
+ // ))
190
+ // )) {
191
+ // console.log('阻止键盘快捷键:', e.key, key);
192
+ e.preventDefault();
193
+ e.stopPropagation();
194
+ e.stopImmediatePropagation();
195
+
196
+ // 只在冻结模式下覆盖requestAnimationFrame
197
+ if (isFrozen && !originalRequestAnimationFrame) {
198
+ // 保存原始的 requestAnimationFrame
199
+ originalRequestAnimationFrame = window.requestAnimationFrame;
200
+
201
+ // 覆盖 requestAnimationFrame,过滤掉包含撤销逻辑的回调
202
+ window.requestAnimationFrame = function (callback) {
203
+ // 检查回调函数是否包含撤销相关的逻辑
204
+ const callbackStr = callback.toString();
205
+ if (
206
+ callbackStr.includes("undoRedo") ||
207
+ callbackStr.includes("changeTracker") ||
208
+ callbackStr.includes("checkState")
209
+ ) {
210
+ console.log("拦截了包含撤销逻辑的 requestAnimationFrame");
211
+ // 返回一个空函数,不执行撤销逻辑
212
+ return originalRequestAnimationFrame(() => {});
213
+ }
214
+ // 其他回调正常执行
215
+ return originalRequestAnimationFrame(callback);
229
216
  };
217
+ }
230
218
 
231
- // 添加事件监听器
232
- document.addEventListener('keydown', keyboardListener, true);
233
- document.addEventListener('contextmenu', contextMenuListener, true);
234
-
235
- // 保存并替换LiteGraph的双击相关方法
236
- if (window.LGraphCanvas) {
237
- // 保存原始方法
238
- originalMethods = {
239
- showNodePanel: LGraphCanvas.prototype.showNodePanel,
240
- processNodeDblClicked: LGraphCanvas.prototype.processNodeDblClicked,
241
- processContextMenu: LGraphCanvas.prototype.processContextMenu
242
- };
243
-
244
- // 禁用节点面板(双击弹出的)
245
- LGraphCanvas.prototype.showNodePanel = function() {
246
- return false;
247
- };
248
-
249
- // 禁用节点双击
250
- LGraphCanvas.prototype.processNodeDblClicked = function() {
251
- return false;
252
- };
253
-
254
- // 禁用右键菜单
255
- LGraphCanvas.prototype.processContextMenu = function(node, event) {
256
- // 检查是否在高亮节点附近
257
- if (node && highlightedNodes.has(node.id)) {
258
- // 在高亮节点上,允许菜单
259
- if (originalMethods.processContextMenu) {
260
- return originalMethods.processContextMenu.call(this, node, event);
261
- }
262
- } else {
263
- // 检查鼠标是否在节点附近(即使不是该节点本身)
264
- if (event && isMouseNearHighlightedNode(event)) {
265
- return false; // 在节点附近但不允许菜单
266
- }
267
- return false;
268
- }
269
- };
270
- }
271
-
272
- } else if (!block && globalEventBlocked) {
273
- // 禁用拦截
274
- globalEventBlocked = false;
219
+ return false;
220
+ // }
221
+ };
275
222
 
276
- // 移除事件监听器
277
- document.removeEventListener('keydown', keyboardListener, true);
278
- document.removeEventListener('contextmenu', contextMenuListener, true);
223
+ // 阻止右键菜单
224
+ contextMenuListener = function (e) {
225
+ // 检查鼠标是否在高亮节点附近
226
+ const isNearHighlightedNode = isMouseNearHighlightedNode(e);
279
227
 
280
- // 恢复LiteGraph的方法
281
- if (window.LGraphCanvas && originalMethods) {
282
- if (originalMethods.showNodePanel) {
283
- LGraphCanvas.prototype.showNodePanel = originalMethods.showNodePanel;
284
- }
285
-
286
- if (originalMethods.processNodeDblClicked) {
287
- LGraphCanvas.prototype.processNodeDblClicked = originalMethods.processNodeDblClicked;
288
- }
228
+ // 如果不在高亮节点附近,阻止右键菜单
229
+ if (!isNearHighlightedNode) {
230
+ e.preventDefault();
231
+ e.stopPropagation();
232
+ return false;
233
+ }
234
+ };
235
+
236
+ // 添加事件监听器
237
+ document.addEventListener("keydown", keyboardListener, true);
238
+ document.addEventListener("contextmenu", contextMenuListener, true);
239
+
240
+ // 保存并替换LiteGraph的双击相关方法
241
+ if (window.LGraphCanvas) {
242
+ // 保存原始方法
243
+ originalMethods = {
244
+ showNodePanel: LGraphCanvas.prototype.showNodePanel,
245
+ processNodeDblClicked: LGraphCanvas.prototype.processNodeDblClicked,
246
+ processContextMenu: LGraphCanvas.prototype.processContextMenu,
247
+ };
248
+
249
+ // 禁用节点面板(双击弹出的)
250
+ LGraphCanvas.prototype.showNodePanel = function () {
251
+ return false;
252
+ };
289
253
 
290
- if (originalMethods.processContextMenu) {
291
- LGraphCanvas.prototype.processContextMenu = originalMethods.processContextMenu;
292
- }
254
+ // 禁用节点双击
255
+ LGraphCanvas.prototype.processNodeDblClicked = function () {
256
+ return false;
257
+ };
258
+
259
+ // 禁用右键菜单
260
+ LGraphCanvas.prototype.processContextMenu = function (node, event) {
261
+ // 检查是否在高亮节点附近
262
+ if (node && highlightedNodes.has(node.id)) {
263
+ // 在高亮节点上,允许菜单
264
+ if (originalMethods.processContextMenu) {
265
+ return originalMethods.processContextMenu.call(this, node, event);
266
+ }
267
+ } else {
268
+ // 检查鼠标是否在节点附近(即使不是该节点本身)
269
+ if (event && isMouseNearHighlightedNode(event)) {
270
+ return false; // 在节点附近但不允许菜单
271
+ }
272
+ return false;
293
273
  }
294
-
295
- originalMethods = null;
296
- keyboardListener = null;
297
- contextMenuListener = null;
274
+ };
298
275
  }
276
+ } else if (!block && globalEventBlocked) {
277
+ // 禁用拦截
278
+ globalEventBlocked = false;
279
+
280
+ // 移除事件监听器
281
+ document.removeEventListener("keydown", keyboardListener, true);
282
+ document.removeEventListener("contextmenu", contextMenuListener, true);
283
+
284
+ // 恢复LiteGraph的方法
285
+ if (window.LGraphCanvas && originalMethods) {
286
+ if (originalMethods.showNodePanel) {
287
+ LGraphCanvas.prototype.showNodePanel = originalMethods.showNodePanel;
288
+ }
289
+
290
+ if (originalMethods.processNodeDblClicked) {
291
+ LGraphCanvas.prototype.processNodeDblClicked =
292
+ originalMethods.processNodeDblClicked;
293
+ }
294
+
295
+ if (originalMethods.processContextMenu) {
296
+ LGraphCanvas.prototype.processContextMenu =
297
+ originalMethods.processContextMenu;
298
+ }
299
+ }
300
+
301
+ originalMethods = null;
302
+ keyboardListener = null;
303
+ contextMenuListener = null;
304
+ }
299
305
  }
300
306
 
301
307
  // 检查鼠标是否在高亮节点附近(包括扩展范围)
302
308
  function isMouseNearHighlightedNode(e) {
303
- if (!app || !app.graph) return false;
304
-
305
- // 转换为图形坐标
306
- const pos = app.canvas.convertEventToCanvasOffset(e);
307
-
308
- // 检查所有高亮节点
309
- for (const node of app.graph._nodes) {
310
- if (node && node._aiAppHighlighted) {
311
- // 使用正确的属性名:_pos 和 _posSize
312
- const nodeX = node._pos[0];
313
- const nodeY = node._pos[1];
314
- const nodeWidth = node._posSize[2];
315
- const nodeHeight = node._posSize[3];
316
-
317
- const nodeBounds = {
318
- left: nodeX - 10,
319
- top: nodeY - 50,
320
- right: nodeX + nodeWidth + 2,
321
- bottom: nodeY + nodeHeight + 2
322
- };
323
-
324
- // 检查鼠标是否在扩展边界内
325
- if (pos[0] >= nodeBounds.left && pos[0] <= nodeBounds.right &&
326
- pos[1] >= nodeBounds.top && pos[1] <= nodeBounds.bottom) {
327
- return true;
328
- }
329
- }
309
+ if (!app || !app.graph) return false;
310
+
311
+ // 转换为图形坐标
312
+ const pos = app.canvas.convertEventToCanvasOffset(e);
313
+
314
+ // 检查所有高亮节点
315
+ for (const node of app.graph._nodes) {
316
+ if (node && node._aiAppHighlighted) {
317
+ // 使用正确的属性名:_pos 和 _posSize
318
+ const nodeX = node._pos[0];
319
+ const nodeY = node._pos[1];
320
+ const nodeWidth = node._posSize[2];
321
+ const nodeHeight = node._posSize[3];
322
+
323
+ const nodeBounds = {
324
+ left: nodeX - 10,
325
+ top: nodeY - 50,
326
+ right: nodeX + nodeWidth + 2,
327
+ bottom: nodeY + nodeHeight + 2,
328
+ };
329
+
330
+ // 检查鼠标是否在扩展边界内
331
+ if (
332
+ pos[0] >= nodeBounds.left &&
333
+ pos[0] <= nodeBounds.right &&
334
+ pos[1] >= nodeBounds.top &&
335
+ pos[1] <= nodeBounds.bottom
336
+ ) {
337
+ return true;
338
+ }
330
339
  }
340
+ }
331
341
 
332
- return false;
342
+ return false;
333
343
  }
334
344
 
335
345
  // 创建遮罩层
336
346
  function createOverlay() {
337
- // 如果已存在,先移除
338
- removeOverlay();
339
-
340
- // 创建新的遮罩层
341
- freezeOverlay = document.createElement('div');
342
- freezeOverlay.id = 'aiapp-freeze-overlay';
343
-
344
- // 设置样式
345
- freezeOverlay.style.position = 'absolute';
346
- freezeOverlay.style.top = '0';
347
- freezeOverlay.style.left = '0';
348
- freezeOverlay.style.width = '100%';
349
- freezeOverlay.style.height = '100%';
350
- freezeOverlay.style.backgroundColor = 'transparent';
351
- freezeOverlay.style.zIndex = '9999';
352
- freezeOverlay.style.pointerEvents = 'none'; // 默认不拦截事件,让画布可移动
353
- freezeOverlay.style.cursor = 'move'; // 默认指示可拖动
354
-
355
- // 添加事件监听
356
- freezeOverlay.addEventListener('mousedown', handleOverlayMouseDown);
357
-
358
- // 添加到DOM
359
- const container = document.querySelector('#graph-canvas')?.parentElement || document.body;
360
- container.appendChild(freezeOverlay);
347
+ // 如果已存在,先移除
348
+ removeOverlay();
349
+
350
+ // 创建新的遮罩层
351
+ freezeOverlay = document.createElement("div");
352
+ freezeOverlay.id = "aiapp-freeze-overlay";
353
+
354
+ // 设置样式
355
+ freezeOverlay.style.position = "absolute";
356
+ freezeOverlay.style.top = "0";
357
+ freezeOverlay.style.left = "0";
358
+ freezeOverlay.style.width = "100%";
359
+ freezeOverlay.style.height = "100%";
360
+ freezeOverlay.style.backgroundColor = "transparent";
361
+ freezeOverlay.style.zIndex = "9999";
362
+ freezeOverlay.style.pointerEvents = "none"; // 默认不拦截事件,让画布可移动
363
+ freezeOverlay.style.cursor = "move"; // 默认指示可拖动
364
+
365
+ // 添加事件监听
366
+ freezeOverlay.addEventListener("mousedown", handleOverlayMouseDown);
367
+
368
+ // 添加到DOM
369
+ const container =
370
+ document.querySelector("#graph-canvas")?.parentElement || document.body;
371
+ container.appendChild(freezeOverlay);
361
372
  }
362
373
 
363
374
  // 移除遮罩层
364
375
  function removeOverlay() {
365
- if (freezeOverlay) {
366
- freezeOverlay.removeEventListener('mousedown', handleOverlayMouseDown);
367
- freezeOverlay.remove();
368
- freezeOverlay = null;
369
- }
376
+ if (freezeOverlay) {
377
+ freezeOverlay.removeEventListener("mousedown", handleOverlayMouseDown);
378
+ freezeOverlay.remove();
379
+ freezeOverlay = null;
380
+ }
370
381
  }
371
382
 
372
383
  // 启用鼠标追踪
373
384
  function enableMouseTracking() {
374
- if (!mouseTrackingEnabled) {
375
- mouseMoveListener = handleMouseMove.bind(this);
376
- document.addEventListener('mousemove', mouseMoveListener);
377
- mouseTrackingEnabled = true;
378
- }
385
+ if (!mouseTrackingEnabled) {
386
+ mouseMoveListener = handleMouseMove.bind(this);
387
+ document.addEventListener("mousemove", mouseMoveListener);
388
+ mouseTrackingEnabled = true;
389
+ }
379
390
  }
380
391
 
381
392
  // 禁用鼠标追踪
382
393
  function disableMouseTracking() {
383
- if (mouseTrackingEnabled) {
384
- document.removeEventListener('mousemove', mouseMoveListener);
385
- mouseMoveListener = null;
386
- mouseTrackingEnabled = false;
387
- }
394
+ if (mouseTrackingEnabled) {
395
+ document.removeEventListener("mousemove", mouseMoveListener);
396
+ mouseMoveListener = null;
397
+ mouseTrackingEnabled = false;
398
+ }
388
399
  }
389
400
 
390
401
  // 处理鼠标移动事件
391
402
  function handleMouseMove(e) {
392
- if (!freezeOverlay || !app || !app.graph) return;
393
-
394
- // 转换为图形坐标
395
- const pos = app.canvas.convertEventToCanvasOffset(e);
396
-
397
- // 检查鼠标是否在高亮节点附近
398
- let isNearHighlightedNode = false;
399
- for (const node of app.graph._nodes) {
400
- if (node && node._aiAppHighlighted) {
401
- // 使用正确的属性名:_pos 和 _posSize
402
- const nodeX = node._pos[0];
403
- const nodeY = node._pos[1];
404
- const nodeWidth = node._posSize[2];
405
- const nodeHeight = node._posSize[3];
406
-
407
- const nodeBounds = {
408
- left: nodeX - 10,
409
- top: nodeY - 50,
410
- right: nodeX + nodeWidth + 2,
411
- bottom: nodeY + nodeHeight + 2
412
- };
413
-
414
- if (pos[0] >= nodeBounds.left && pos[0] <= nodeBounds.right &&
415
- pos[1] >= nodeBounds.top && pos[1] <= nodeBounds.bottom) {
416
- isNearHighlightedNode = true;
417
- break;
418
- }
419
- }
420
- }
421
-
422
- // 根据鼠标位置控制遮罩层
423
- if (isNearHighlightedNode) {
424
- // 鼠标在高亮节点附近,打开遮罩层
425
- showOverlay();
426
- } else {
427
- // 鼠标在空白区域,隐藏遮罩层
428
- hideOverlay();
403
+ if (!freezeOverlay || !app || !app.graph) return;
404
+
405
+ // 转换为图形坐标
406
+ const pos = app.canvas.convertEventToCanvasOffset(e);
407
+
408
+ // 检查鼠标是否在高亮节点附近
409
+ let isNearHighlightedNode = false;
410
+ for (const node of app.graph._nodes) {
411
+ if (node && node._aiAppHighlighted) {
412
+ // 使用正确的属性名:_pos 和 _posSize
413
+ const nodeX = node._pos[0];
414
+ const nodeY = node._pos[1];
415
+ const nodeWidth = node._posSize[2];
416
+ const nodeHeight = node._posSize[3];
417
+
418
+ const nodeBounds = {
419
+ left: nodeX - 10,
420
+ top: nodeY - 50,
421
+ right: nodeX + nodeWidth + 2,
422
+ bottom: nodeY + nodeHeight + 2,
423
+ };
424
+
425
+ if (
426
+ pos[0] >= nodeBounds.left &&
427
+ pos[0] <= nodeBounds.right &&
428
+ pos[1] >= nodeBounds.top &&
429
+ pos[1] <= nodeBounds.bottom
430
+ ) {
431
+ isNearHighlightedNode = true;
432
+ break;
433
+ }
429
434
  }
435
+ }
436
+
437
+ // 根据鼠标位置控制遮罩层
438
+ if (isNearHighlightedNode) {
439
+ // 鼠标在高亮节点附近,打开遮罩层
440
+ showOverlay();
441
+ } else {
442
+ // 鼠标在空白区域,隐藏遮罩层
443
+ hideOverlay();
444
+ }
430
445
  }
431
446
 
432
447
  // 显示遮罩层
433
448
  function showOverlay() {
434
- if (freezeOverlay) {
435
- freezeOverlay.style.pointerEvents = 'all';
436
- freezeOverlay.style.cursor = 'pointer';
437
- }
449
+ if (freezeOverlay) {
450
+ freezeOverlay.style.pointerEvents = "all";
451
+ freezeOverlay.style.cursor = "pointer";
452
+ }
438
453
  }
439
454
 
440
455
  // 隐藏遮罩层
441
456
  function hideOverlay() {
442
- if (freezeOverlay) {
443
- freezeOverlay.style.pointerEvents = 'none';
444
- }
457
+ if (freezeOverlay) {
458
+ freezeOverlay.style.pointerEvents = "none";
459
+ }
445
460
  }
446
461
 
447
462
  // 更新高亮节点列表
448
463
  function updateHighlightedNodes() {
449
- highlightedNodes.clear();
464
+ highlightedNodes.clear();
450
465
 
451
- if (!app || !app.graph || !app.graph._nodes) return;
466
+ if (!app || !app.graph || !app.graph._nodes) return;
452
467
 
453
- for (const node of app.graph._nodes) {
454
- if (node && node._aiAppHighlighted) {
455
- highlightedNodes.add(node.id);
456
- }
468
+ for (const node of app.graph._nodes) {
469
+ if (node && node._aiAppHighlighted) {
470
+ highlightedNodes.add(node.id);
457
471
  }
472
+ }
458
473
  }
459
474
  //关闭并禁用小地图按钮
460
475
  function setMiniMapButtonDisabled(disabled, clickIfActive = false) {
461
- const miniMapBtn = document.querySelector('button[data-testid="toggle-minimap-button"]');
462
- if (!miniMapBtn) return;
463
-
464
- if (disabled) {
465
- const isActive = miniMapBtn.classList.contains('minimap-active') ||
466
- miniMapBtn.hasAttribute('minimap-active') ||
467
- miniMapBtn.getAttribute('aria-pressed') === 'true';
468
- if (clickIfActive && isActive) {
469
- miniMapBtn.click();
470
- }
471
- miniMapBtn.disabled = true;
472
- } else {
473
- miniMapBtn.disabled = false;
476
+ const miniMapBtn = document.querySelector(
477
+ 'button[data-testid="toggle-minimap-button"]'
478
+ );
479
+ if (!miniMapBtn) return;
480
+
481
+ if (disabled) {
482
+ const isActive =
483
+ miniMapBtn.classList.contains("minimap-active") ||
484
+ miniMapBtn.hasAttribute("minimap-active") ||
485
+ miniMapBtn.getAttribute("aria-pressed") === "true";
486
+ if (clickIfActive && isActive) {
487
+ miniMapBtn.click();
474
488
  }
489
+ miniMapBtn.disabled = true;
490
+ } else {
491
+ miniMapBtn.disabled = false;
492
+ }
475
493
  }
476
494
 
477
495
  // 处理遮罩层上的鼠标按下事件
478
496
  function handleOverlayMouseDown(e) {
479
- // 检查是否点击了高亮节点附近
480
- const isNearHighlightedNode = isMouseNearHighlightedNode(e);
481
-
482
- if (isNearHighlightedNode) {
483
- // 获取实际点击的节点(用于发送消息)
484
- const nodeUnderMouse = getNodeUnderMouse(e);
485
-
486
- if (nodeUnderMouse) {
487
- // 发送消息到前端,通知节点被点击
488
- window.parent.postMessage({
489
- type: 'CANVAS_NODE_CLICKED',
490
- nodeId: nodeUnderMouse.id,
491
- nodeTitle: nodeUnderMouse.title,
492
- nodeType: nodeUnderMouse.type
493
- }, '*');
494
- }
495
-
496
- // 阻止事件冒泡,避免触发其他处理
497
- e.preventDefault();
498
- e.stopPropagation();
499
- return false;
497
+ // 检查是否点击了高亮节点附近
498
+ const isNearHighlightedNode = isMouseNearHighlightedNode(e);
499
+
500
+ if (isNearHighlightedNode) {
501
+ // 获取实际点击的节点(用于发送消息)
502
+ const nodeUnderMouse = getNodeUnderMouse(e);
503
+
504
+ if (nodeUnderMouse) {
505
+ // 发送消息到前端,通知节点被点击
506
+ window.parent.postMessage(
507
+ {
508
+ type: "CANVAS_NODE_CLICKED",
509
+ nodeId: nodeUnderMouse.id,
510
+ nodeTitle: nodeUnderMouse.title,
511
+ nodeType: nodeUnderMouse.type,
512
+ },
513
+ "*"
514
+ );
500
515
  }
501
516
 
502
- // 让事件传递给画布 - 允许画布正常处理点击事件
503
- return true;
517
+ // 阻止事件冒泡,避免触发其他处理
518
+ e.preventDefault();
519
+ e.stopPropagation();
520
+ return false;
521
+ }
522
+
523
+ // 让事件传递给画布 - 允许画布正常处理点击事件
524
+ return true;
504
525
  }
505
526
 
506
527
  // 获取鼠标下方的节点
507
528
  function getNodeUnderMouse(e) {
508
- if (!app || !app.graph) return null;
529
+ if (!app || !app.graph) return null;
509
530
 
510
- // 获取画布位置
511
- const canvas = document.querySelector('canvas');
512
- if (!canvas) return null;
531
+ // 获取画布位置
532
+ const canvas = document.querySelector("canvas");
533
+ if (!canvas) return null;
513
534
 
514
- // 转换为图形坐标
515
- const pos = app.canvas.convertEventToCanvasOffset(e);
535
+ // 转换为图形坐标
536
+ const pos = app.canvas.convertEventToCanvasOffset(e);
516
537
 
517
- // 检查点击位置是否在某个节点上
518
- const node = app.graph.getNodeOnPos(pos[0], pos[1]);
519
- return node;
538
+ // 检查点击位置是否在某个节点上
539
+ const node = app.graph.getNodeOnPos(pos[0], pos[1]);
540
+ return node;
520
541
  }
521
542
 
522
543
  // 阻止拖拽上传文件
523
544
  function blockDragDropEvents(enable) {
524
- if (enable) {
525
- if (dragDropBlocker) return; // 已经阻止过了
526
- dragDropBlocker = function(e) {
527
- e.preventDefault();
528
- e.stopPropagation();
529
- return false;
530
- };
531
- document.addEventListener('dragover', dragDropBlocker, true);
532
- document.addEventListener('drop', dragDropBlocker, true);
533
- } else {
534
- if (!dragDropBlocker) return;
535
- document.removeEventListener('dragover', dragDropBlocker, true);
536
- document.removeEventListener('drop', dragDropBlocker, true);
537
- dragDropBlocker = null;
538
- }
545
+ if (enable) {
546
+ if (dragDropBlocker) return; // 已经阻止过了
547
+ dragDropBlocker = function (e) {
548
+ e.preventDefault();
549
+ e.stopPropagation();
550
+ return false;
551
+ };
552
+ document.addEventListener("dragover", dragDropBlocker, true);
553
+ document.addEventListener("drop", dragDropBlocker, true);
554
+ } else {
555
+ if (!dragDropBlocker) return;
556
+ document.removeEventListener("dragover", dragDropBlocker, true);
557
+ document.removeEventListener("drop", dragDropBlocker, true);
558
+ dragDropBlocker = null;
559
+ }
539
560
  }
540
561
 
541
562
  export {
542
- freezeWorkflow,
543
- unfreezeWorkflow,
544
- isMouseNearHighlightedNode,
545
- getNodeUnderMouse,
546
- updateHighlightedNodes
563
+ freezeWorkflow,
564
+ unfreezeWorkflow,
565
+ isMouseNearHighlightedNode,
566
+ getNodeUnderMouse,
567
+ updateHighlightedNodes,
547
568
  };