- Go backend (server/)
- Frontend (web/, server/static/)
- Database and deployment files
- Scripts and docs
Co-Authored-By: 狸花猫/Claude-Qwen3.6-Plus 🐾
192 lines
6.4 KiB
JavaScript
192 lines
6.4 KiB
JavaScript
var __extends = this && this.__extends || function () {
|
||
var _extendStatics = function extendStatics(d, b) {
|
||
_extendStatics = Object.setPrototypeOf || {
|
||
__proto__: []
|
||
} instanceof Array && function (d, b) {
|
||
d.__proto__ = b;
|
||
} || function (d, b) {
|
||
for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
|
||
};
|
||
return _extendStatics(d, b);
|
||
};
|
||
return function (d, b) {
|
||
if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||
_extendStatics(d, b);
|
||
function __() {
|
||
this.constructor = d;
|
||
}
|
||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
};
|
||
}();
|
||
import { modifyCSS, createDom } from '@antv/dom-util';
|
||
import { isString } from '@antv/util';
|
||
import insertCss from 'insert-css';
|
||
import Base from '../base';
|
||
typeof document !== 'undefined' && insertCss("\n .g6-component-contextmenu {\n border: 1px solid #e2e2e2;\n border-radius: 4px;\n font-size: 12px;\n color: #545454;\n background-color: rgba(255, 255, 255, 0.9);\n padding: 10px 8px;\n box-shadow: rgb(174, 174, 174) 0px 0px 10px;\n }\n .g6-contextmenu-ul {\n padding: 0;\n margin: 0;\n list-style: none;\n }\n\n");
|
||
var Menu = /** @class */function (_super) {
|
||
__extends(Menu, _super);
|
||
function Menu(config) {
|
||
return _super.call(this, config) || this;
|
||
}
|
||
Menu.prototype.getDefaultCfgs = function () {
|
||
return {
|
||
offsetX: 6,
|
||
offsetY: 6,
|
||
handleMenuClick: undefined,
|
||
// 指定菜单内容,function(e) {...}
|
||
getContent: function getContent(e) {
|
||
return "\n <ul class='g6-contextmenu-ul'>\n <li>\u83DC\u5355\u98791</li>\n <li>\u83DC\u5355\u98792</li>\n </ul>\n ";
|
||
},
|
||
shouldBegin: function shouldBegin(e) {
|
||
return true;
|
||
},
|
||
// 菜单隐藏事件
|
||
onHide: function onHide() {
|
||
return true;
|
||
},
|
||
itemTypes: ['node', 'edge', 'combo'],
|
||
trigger: 'contextmenu'
|
||
};
|
||
};
|
||
// class-methods-use-this
|
||
Menu.prototype.getEvents = function () {
|
||
if (this.get('trigger') === 'click') {
|
||
return {
|
||
click: 'onMenuShow',
|
||
touchend: 'onMenuShow'
|
||
};
|
||
}
|
||
return {
|
||
contextmenu: 'onMenuShow'
|
||
};
|
||
};
|
||
Menu.prototype.init = function () {
|
||
var className = this.get('className');
|
||
var menu = createDom("<div class=".concat(className || 'g6-component-contextmenu', "></div>"));
|
||
modifyCSS(menu, {
|
||
top: '0px',
|
||
position: 'absolute',
|
||
visibility: 'hidden'
|
||
});
|
||
var container = this.get('container');
|
||
if (!container) {
|
||
container = this.get('graph').get('container');
|
||
}
|
||
if (isString(container)) {
|
||
container = document.getElementById(container);
|
||
}
|
||
container.appendChild(menu);
|
||
this.set('menu', menu);
|
||
};
|
||
Menu.prototype.onMenuShow = function (e) {
|
||
var self = this;
|
||
e.preventDefault();
|
||
var itemTypes = this.get('itemTypes');
|
||
if (!e.item) {
|
||
if (itemTypes.indexOf('canvas') === -1) {
|
||
self.onMenuHide();
|
||
return;
|
||
}
|
||
} else {
|
||
if (e.item && e.item.getType && itemTypes.indexOf(e.item.getType()) === -1) {
|
||
self.onMenuHide();
|
||
return;
|
||
}
|
||
}
|
||
var shouldBegin = this.get('shouldBegin');
|
||
if (!shouldBegin(e)) return;
|
||
var menuDom = this.get('menu');
|
||
var getContent = this.get('getContent');
|
||
var graph = this.get('graph');
|
||
var menu = getContent(e, graph);
|
||
if (isString(menu)) {
|
||
menuDom.innerHTML = menu;
|
||
} else {
|
||
menuDom.innerHTML = menu.outerHTML;
|
||
}
|
||
// 清除之前监听的事件
|
||
this.removeMenuEventListener();
|
||
var handleMenuClick = this.get('handleMenuClick');
|
||
if (handleMenuClick) {
|
||
var handleMenuClickWrapper = function handleMenuClickWrapper(evt) {
|
||
handleMenuClick(evt.target, e.item, graph);
|
||
};
|
||
this.set('handleMenuClickWrapper', handleMenuClickWrapper);
|
||
menuDom.addEventListener('click', handleMenuClickWrapper);
|
||
}
|
||
var width = graph.get('width');
|
||
var height = graph.get('height');
|
||
var bbox = menuDom.getBoundingClientRect();
|
||
var offsetX = this.get('offsetX') || 0;
|
||
var offsetY = this.get('offsetY') || 0;
|
||
var graphTop = graph.getContainer().offsetTop;
|
||
var graphLeft = graph.getContainer().offsetLeft;
|
||
var x = e.canvasX + graphLeft + offsetX;
|
||
var y = e.canvasY + graphTop + offsetY;
|
||
// when the menu is (part of) out of the canvas
|
||
if (x + bbox.width > width) {
|
||
x = e.canvasX - bbox.width - offsetX + graphLeft;
|
||
}
|
||
if (y + bbox.height > height) {
|
||
y = e.canvasY - bbox.height - offsetY + graphTop;
|
||
}
|
||
if (y < 0) {
|
||
y = 0;
|
||
}
|
||
modifyCSS(menuDom, {
|
||
top: "".concat(y, "px"),
|
||
left: "".concat(x, "px"),
|
||
visibility: 'visible'
|
||
});
|
||
// 左键单击会触发 body 上监听的 click 事件,导致菜单展示出来后又立即被隐藏了,需要过滤掉
|
||
var triggeredByFirstClick = this.get('trigger') === 'click';
|
||
var handler = function handler(evt) {
|
||
if (triggeredByFirstClick) {
|
||
triggeredByFirstClick = false;
|
||
return;
|
||
}
|
||
self.onMenuHide();
|
||
};
|
||
// 如果在页面中其他任意地方进行click, 隐去菜单
|
||
document.body.addEventListener('click', handler);
|
||
this.set('handler', handler);
|
||
};
|
||
Menu.prototype.removeMenuEventListener = function () {
|
||
var handleMenuClickWrapper = this.get('handleMenuClickWrapper');
|
||
var handler = this.get('handler');
|
||
if (handleMenuClickWrapper) {
|
||
var menuDom = this.get('menu');
|
||
menuDom.removeEventListener('click', handleMenuClickWrapper);
|
||
this.set('handleMenuClickWrapper', null);
|
||
}
|
||
if (handler) {
|
||
document.body.removeEventListener('click', handler);
|
||
}
|
||
};
|
||
Menu.prototype.onMenuHide = function () {
|
||
var menuDom = this.get('menu');
|
||
if (menuDom) {
|
||
modifyCSS(menuDom, {
|
||
visibility: 'hidden'
|
||
});
|
||
}
|
||
// 隐藏菜单后需要移除事件监听
|
||
this.removeMenuEventListener();
|
||
};
|
||
Menu.prototype.destroy = function () {
|
||
var menu = this.get('menu');
|
||
this.removeMenuEventListener();
|
||
if (menu) {
|
||
var container = this.get('container');
|
||
if (!container) {
|
||
container = this.get('graph').get('container');
|
||
}
|
||
if (isString(container)) {
|
||
container = document.getElementById(container);
|
||
}
|
||
container.removeChild(menu);
|
||
}
|
||
};
|
||
return Menu;
|
||
}(Base);
|
||
export default Menu; |