|
import { app } from "../../../scripts/app.js"; |
|
app.registerExtension({ |
|
name: "pysssss.ContextMenuHook", |
|
init() { |
|
const getOrSet = (target, name, create) => { |
|
if (name in target) return target[name]; |
|
return (target[name] = create()); |
|
}; |
|
const symbol = getOrSet(window, "__pysssss__", () => Symbol("__pysssss__")); |
|
const store = getOrSet(window, symbol, () => ({})); |
|
const contextMenuHook = getOrSet(store, "contextMenuHook", () => ({})); |
|
for (const e of ["ctor", "preAddItem", "addItem"]) { |
|
if (!contextMenuHook[e]) { |
|
contextMenuHook[e] = []; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
const ctorProxy = new Proxy(LiteGraph.ContextMenu, { |
|
construct(target, args) { |
|
return new LiteGraph.ContextMenu(...args); |
|
}, |
|
}); |
|
|
|
function triggerCallbacks(name, getArgs, handler) { |
|
const callbacks = contextMenuHook[name]; |
|
if (callbacks && callbacks instanceof Array) { |
|
for (const cb of callbacks) { |
|
const r = cb(...getArgs()); |
|
handler?.call(this, r); |
|
} |
|
} else { |
|
console.warn("[pysssss ๐]", `invalid ${name} callbacks`, callbacks, name in contextMenuHook); |
|
} |
|
} |
|
|
|
const addItem = LiteGraph.ContextMenu.prototype.addItem; |
|
LiteGraph.ContextMenu.prototype.addItem = function () { |
|
const proxy = new Proxy(this, { |
|
get(target, prop) { |
|
if (prop === "constructor") { |
|
return ctorProxy; |
|
} |
|
return target[prop]; |
|
}, |
|
}); |
|
proxy.__target__ = this; |
|
|
|
let el; |
|
let args = arguments; |
|
triggerCallbacks( |
|
"preAddItem", |
|
() => [el, this, args], |
|
(r) => { |
|
if (r !== undefined) el = r; |
|
} |
|
); |
|
|
|
if (el === undefined) { |
|
el = addItem.apply(proxy, arguments); |
|
} |
|
|
|
triggerCallbacks( |
|
"addItem", |
|
() => [el, this, args], |
|
(r) => { |
|
if (r !== undefined) el = r; |
|
} |
|
); |
|
return el; |
|
}; |
|
|
|
|
|
const ctxMenu = LiteGraph.ContextMenu; |
|
LiteGraph.ContextMenu = function (values, options) { |
|
if (options?.parentMenu) { |
|
if (options.parentMenu.__target__) { |
|
options.parentMenu = options.parentMenu.__target__; |
|
} |
|
} |
|
|
|
triggerCallbacks("ctor", () => [values, options]); |
|
return ctxMenu.call(this, values, options); |
|
}; |
|
LiteGraph.ContextMenu.prototype = ctxMenu.prototype; |
|
}, |
|
}); |
|
|