Move prototype accessor lookup into shared_utils as a generic helper
This commit is contained in:
@@ -21,23 +21,11 @@ import {
|
||||
importIndividualNodesInnerOnDragDrop,
|
||||
importIndividualNodesInnerOnDragOver,
|
||||
} from "./feature_import_individual_nodes.js";
|
||||
import {defineProperty, moveArrayItem} from "rgthree/common/shared_utils.js";
|
||||
|
||||
/**
|
||||
* Finds the `mode` accessor on the prototype chain. Newer ComfyUI frontends track `mode` as shell
|
||||
* state through an accessor on LGraphNode (backed by `_state.mode`), so our instance-level override
|
||||
* must delegate to it. Otherwise `_state.mode` (used when serializing) never sees the change.
|
||||
* Returns null on legacy frontends, where `mode` is a plain data property.
|
||||
*/
|
||||
function findPrototypeModeDescriptor(node: object): PropertyDescriptor | null {
|
||||
let proto = Object.getPrototypeOf(node);
|
||||
while (proto) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(proto, "mode");
|
||||
if (descriptor && (descriptor.get || descriptor.set)) return descriptor;
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
import {
|
||||
defineProperty,
|
||||
findPrototypePropertyDescriptor,
|
||||
moveArrayItem,
|
||||
} from "rgthree/common/shared_utils.js";
|
||||
|
||||
/**
|
||||
* A base node with standard methods, directly extending the LGraphNode.
|
||||
@@ -109,7 +97,10 @@ export abstract class RgthreeBaseNode extends LGraphNode {
|
||||
this.checkAndRunOnConstructed();
|
||||
});
|
||||
|
||||
const protoMode = findPrototypeModeDescriptor(this);
|
||||
// Newer ComfyUI frontends track `mode` through an accessor on LGraphNode (backed by
|
||||
// `_state.mode`, which is what gets serialized), so our override must delegate to it.
|
||||
// On legacy frontends `mode` is a plain data property and this is null.
|
||||
const protoMode = findPrototypePropertyDescriptor(this, "mode");
|
||||
const readMode = (): LGraphEventMode | undefined =>
|
||||
protoMode?.get ? protoMode.get.call(this) : this.rgthree_mode;
|
||||
|
||||
|
||||
@@ -235,6 +235,25 @@ export function defineProperty(instance: any, property: string, desc: PropertyDe
|
||||
return Object.defineProperty(instance, property, desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the accessor (getter and/or setter) for `property` on the prototype chain of `instance`,
|
||||
* skipping `instance`'s own properties. Useful when an instance-level property override needs to
|
||||
* delegate to an accessor defined by a parent class. Returns null if no accessor is found, e.g.
|
||||
* when the property is a plain data property.
|
||||
*/
|
||||
export function findPrototypePropertyDescriptor(
|
||||
instance: any,
|
||||
property: string,
|
||||
): PropertyDescriptor | null {
|
||||
let proto = Object.getPrototypeOf(instance);
|
||||
while (proto) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(proto, property);
|
||||
if (descriptor && (descriptor.get || descriptor.set)) return descriptor;
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if two DataViews are equal.
|
||||
*/
|
||||
|
||||
@@ -5,23 +5,7 @@ import { LogLevel, rgthree } from "./rgthree.js";
|
||||
import { addHelpMenuItem } from "./utils.js";
|
||||
import { RgthreeHelpDialog } from "../../rgthree/common/dialog.js";
|
||||
import { importIndividualNodesInnerOnDragDrop, importIndividualNodesInnerOnDragOver, } from "./feature_import_individual_nodes.js";
|
||||
import { defineProperty, moveArrayItem } from "../../rgthree/common/shared_utils.js";
|
||||
/**
|
||||
* Finds the `mode` accessor on the prototype chain. Newer ComfyUI frontends track `mode` as shell
|
||||
* state through an accessor on LGraphNode (backed by `_state.mode`), so our instance-level override
|
||||
* must delegate to it. Otherwise `_state.mode` (used when serializing) never sees the change.
|
||||
* Returns null on legacy frontends, where `mode` is a plain data property.
|
||||
*/
|
||||
function findPrototypeModeDescriptor(node) {
|
||||
let proto = Object.getPrototypeOf(node);
|
||||
while (proto) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(proto, "mode");
|
||||
if (descriptor && (descriptor.get || descriptor.set))
|
||||
return descriptor;
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
import { defineProperty, findPrototypePropertyDescriptor, moveArrayItem, } from "../../rgthree/common/shared_utils.js";
|
||||
export class RgthreeBaseNode extends LGraphNode {
|
||||
constructor(title = RgthreeBaseNode.title, skipOnConstructedCall = true) {
|
||||
super(title);
|
||||
@@ -48,18 +32,16 @@ export class RgthreeBaseNode extends LGraphNode {
|
||||
}
|
||||
this.checkAndRunOnConstructed();
|
||||
});
|
||||
const protoMode = findPrototypeModeDescriptor(this);
|
||||
const protoMode = findPrototypePropertyDescriptor(this, "mode");
|
||||
const readMode = () => (protoMode === null || protoMode === void 0 ? void 0 : protoMode.get) ? protoMode.get.call(this) : this.rgthree_mode;
|
||||
defineProperty(this, "mode", {
|
||||
get: () => readMode(),
|
||||
set: (mode) => {
|
||||
const oldMode = readMode();
|
||||
if (protoMode === null || protoMode === void 0 ? void 0 : protoMode.set) {
|
||||
// Newer frontends: write through so `_state.mode` (used by serialization) stays in sync.
|
||||
protoMode.set.call(this, mode);
|
||||
}
|
||||
else {
|
||||
// Legacy frontends: keep the original behavior.
|
||||
this.rgthree_mode = mode;
|
||||
}
|
||||
if (oldMode != mode) {
|
||||
|
||||
@@ -156,6 +156,16 @@ export function defineProperty(instance, property, desc) {
|
||||
}
|
||||
return Object.defineProperty(instance, property, desc);
|
||||
}
|
||||
export function findPrototypePropertyDescriptor(instance, property) {
|
||||
let proto = Object.getPrototypeOf(instance);
|
||||
while (proto) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(proto, property);
|
||||
if (descriptor && (descriptor.get || descriptor.set))
|
||||
return descriptor;
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export function areDataViewsEqual(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user