More flexible Widget node specification

This commit is contained in:
Tony Garnock-Jones 2024-04-17 13:24:37 +02:00
parent 80250fdac9
commit bf9d10813e
1 changed files with 27 additions and 20 deletions

View File

@ -20,23 +20,28 @@ type Wrapped = {
export type NodeGenerator = (t: HtmlTemplater) => ReturnType<HtmlTemplater>;
export class Widget implements EventTarget {
readonly nodeGenerator: NodeGenerator;
readonly facet: Facet;
private _node: ChildNode | null = null;
parentField: Dataflow.Field<ParentNode | null>;
callbacks = new Map<string, Map<EventListenerOrEventListenerObject, Wrapped>>();
get node(): ChildNode {
return this._node!;
}
constructor (node: ChildNode);
constructor (nodeGenerator: NodeGenerator);
constructor (template: string | HTMLTemplateElement, data: object);
constructor (arg0: NodeGenerator | string | HTMLTemplateElement, data?: object) {
constructor (arg0: ChildNode | NodeGenerator | string | HTMLTemplateElement, data?: object) {
let nodeGenerator: NodeGenerator;
if (data === void 0) {
this.nodeGenerator = arg0 as NodeGenerator;
if (typeof arg0 === 'function') {
nodeGenerator = arg0 as NodeGenerator;
} else {
nodeGenerator = () => [arg0 as ChildNode];
}
} else {
this.nodeGenerator = templateGenerator(arg0 as (string | HTMLTemplateElement), data);
nodeGenerator = templateGenerator(arg0 as (string | HTMLTemplateElement), data);
}
this.facet = Turn.activeFacet;
@ -49,7 +54,7 @@ export class Widget implements EventTarget {
const thisTemplate = template();
dataflow {
const nodes = this.nodeGenerator(thisTemplate);
const nodes = nodeGenerator(thisTemplate);
if (nodes.length !== 1) {
throw new Error(`@syndicate-lang/html2: Expected exactly one node from template`);
}
@ -59,24 +64,18 @@ export class Widget implements EventTarget {
throw new Error(`@syndicate-lang/html2: Node generator is not stable`);
}
}
}
field parentField: ParentNode | null = this._node?.parentNode ?? null;
this.parentField = parentField;
dataflow {
const p = this.parentField.value;
if (this.node.parentNode !== p) {
if (p === null) {
this.node.remove();
} else {
p.appendChild(this.node);
}
}
get _nodeAsParent(): ParentNode | null {
if (this._node && 'querySelector' in this._node) {
return this._node as unknown as ParentNode;
} else {
return null;
}
}
get parent(): ParentNode | null {
return this.parentField.value;
return this.node.parentNode;
}
set parent(p: string | ParentNode | null) {
@ -87,7 +86,15 @@ export class Widget implements EventTarget {
if (typeof p === 'string') {
p = wrt.querySelector(p);
}
this.parentField.value = p;
if (this.node.parentNode !== p) {
if (p === null) {
this.node.remove();
} else {
p.appendChild(this.node);
}
}
return this;
}