mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[REF] initial prototype of owl 2
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import type { VNode } from "./index";
|
||||
|
||||
const nodeProto = Node.prototype;
|
||||
|
||||
const nodeInsertBefore = nodeProto.insertBefore;
|
||||
const nodeRemoveChild = nodeProto.removeChild;
|
||||
|
||||
class VHtml {
|
||||
html: string;
|
||||
parentEl?: HTMLElement | undefined;
|
||||
content: ChildNode[] = [];
|
||||
|
||||
constructor(html: string) {
|
||||
this.html = html;
|
||||
}
|
||||
|
||||
mount(parent: HTMLElement, afterNode: Node | null) {
|
||||
this.parentEl = parent;
|
||||
const template = document.createElement("template");
|
||||
template.innerHTML = this.html;
|
||||
this.content = [...(template.content.childNodes as any)];
|
||||
for (let elem of this.content) {
|
||||
nodeInsertBefore.call(parent, elem, afterNode);
|
||||
}
|
||||
if (!this.content.length) {
|
||||
const textNode = document.createTextNode("");
|
||||
this.content.push(textNode);
|
||||
nodeInsertBefore.call(parent, textNode, afterNode);
|
||||
}
|
||||
}
|
||||
|
||||
moveBefore(other: VHtml | null, afterNode: Node | null) {
|
||||
const target = other ? other.content[0] : afterNode;
|
||||
const parent = this.parentEl;
|
||||
for (let elem of this.content) {
|
||||
nodeInsertBefore.call(parent, elem, target);
|
||||
}
|
||||
}
|
||||
|
||||
patch(other: VHtml) {
|
||||
if (this === other) {
|
||||
return;
|
||||
}
|
||||
const html2 = other.html;
|
||||
if (this.html !== html2) {
|
||||
const parent = this.parentEl;
|
||||
// insert new html in front of current
|
||||
const afterNode = this.content[0];
|
||||
const template = document.createElement("template");
|
||||
template.innerHTML = html2;
|
||||
const content = [...(template.content.childNodes as any)];
|
||||
for (let elem of content) {
|
||||
nodeInsertBefore.call(parent, elem, afterNode);
|
||||
}
|
||||
if (!content.length) {
|
||||
const textNode = document.createTextNode("");
|
||||
content.push(textNode);
|
||||
nodeInsertBefore.call(parent, textNode, afterNode);
|
||||
}
|
||||
|
||||
// remove current content
|
||||
this.remove();
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
|
||||
beforeRemove() {}
|
||||
|
||||
remove() {
|
||||
const parent = this.parentEl;
|
||||
for (let elem of this.content) {
|
||||
nodeRemoveChild.call(parent, elem);
|
||||
}
|
||||
}
|
||||
|
||||
firstNode(): Node {
|
||||
return this.content[0]!;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.html;
|
||||
}
|
||||
}
|
||||
|
||||
export function html(str: string): VNode<VHtml> {
|
||||
return new VHtml(str);
|
||||
}
|
||||
Reference in New Issue
Block a user