Files
owl/src/blockdom/text.ts
T

88 lines
2.0 KiB
TypeScript
Raw Normal View History

2020-11-26 16:45:25 +01:00
import type { VNode } from "./index";
const getDescriptor = (o: any, p: any) => Object.getOwnPropertyDescriptor(o, p)!;
const nodeProto = Node.prototype;
const characterDataProto = CharacterData.prototype;
const nodeInsertBefore = nodeProto.insertBefore;
const characterDataSetData = getDescriptor(characterDataProto, "data").set!;
const nodeRemoveChild = nodeProto.removeChild;
2021-11-29 13:22:04 +01:00
abstract class VSimpleNode {
2022-02-08 12:49:10 +01:00
text: string | String;
2020-11-26 16:45:25 +01:00
parentEl?: HTMLElement | undefined;
2021-11-29 13:22:04 +01:00
el?: any;
2020-11-26 16:45:25 +01:00
2022-02-08 12:49:10 +01:00
constructor(text: string | String) {
2020-11-26 16:45:25 +01:00
this.text = text;
}
2021-11-29 13:22:04 +01:00
mountNode(node: Node, parent: HTMLElement, afterNode: Node | null) {
2020-11-26 16:45:25 +01:00
this.parentEl = parent;
nodeInsertBefore.call(parent, node, afterNode);
this.el = node;
}
moveBefore(other: VText | null, afterNode: Node | null) {
const target = other ? other.el! : afterNode;
nodeInsertBefore.call(this.parentEl, this.el!, target);
}
beforeRemove() {}
remove() {
nodeRemoveChild.call(this.parentEl, this.el!);
}
firstNode(): Node {
return this.el!;
}
toString() {
return this.text;
}
}
2021-11-29 13:22:04 +01:00
class VText extends VSimpleNode {
mount(parent: HTMLElement, afterNode: Node | null) {
this.mountNode(document.createTextNode(toText(this.text)), parent, afterNode);
}
patch(other: VText) {
const text2 = other.text;
if (this.text !== text2) {
characterDataSetData.call(this.el!, toText(text2));
this.text = text2;
}
}
}
class VComment extends VSimpleNode {
mount(parent: HTMLElement, afterNode: Node | null) {
this.mountNode(document.createComment(toText(this.text)), parent, afterNode);
}
patch() {}
}
2022-02-08 12:49:10 +01:00
export function text(str: string | String): VNode<VText> {
2020-11-26 16:45:25 +01:00
return new VText(str);
}
2021-11-29 13:22:04 +01:00
export function comment(str: string): VNode<VComment> {
return new VComment(str);
}
2020-11-26 16:45:25 +01:00
export function toText(value: any): string {
switch (typeof value) {
case "string":
return value;
case "number":
return String(value);
case "boolean":
return value ? "true" : "false";
default:
return value || "";
}
}