From da99259fc89f833007d184f25083a35081843448 Mon Sep 17 00:00:00 2001 From: CanadaHonk Date: Wed, 25 Oct 2023 23:51:14 +0100 Subject: [PATCH] layout: basic layout caching and invalidation --- engine/dom.js | 11 +++++++++++ engine/layout.js | 25 +++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/engine/dom.js b/engine/dom.js index dafab8b..46c0bae 100644 --- a/engine/dom.js +++ b/engine/dom.js @@ -26,6 +26,17 @@ export class Node { } } + allChildren() { + let o = []; + + for (const x of this.children) { + o.push(x); + o = o.concat(x.allChildren()); + } + + return o; + } + get id() { return this.attrs.id; } diff --git a/engine/layout.js b/engine/layout.js index 159308d..734aa6b 100644 --- a/engine/layout.js +++ b/engine/layout.js @@ -50,6 +50,8 @@ const defaultFontSize = 16; // px const byPtr = {}; export class LayoutNode extends Node { renderer = null; + + cache = {}; constructor(node, renderer) { super(); Object.assign(this, { ...node, renderer }); @@ -59,15 +61,14 @@ export class LayoutNode extends Node { const cache = k => { const f = this[k].bind(this); - let cached; + this[k] = function() { - if (cached) return cached; - return cached = f.apply(this, arguments); + if (this.cache[k]) return this.cache[k]; + return this.cache[k] = f.apply(this, arguments); }.bind(this); }; - // cache('x'); cache('y'); cache('width'); cache('height'); - + cache('x'); cache('y'); cache('width'); cache('height'); if (this.tagName === 'img') this.image(); } @@ -559,6 +560,8 @@ export class LayoutNode extends Node { this._image.style.display = 'none'; document.body.appendChild(this._image); + this._image.onload = () => this.invalidateCaches(); + return this._image; } @@ -626,10 +629,20 @@ export class LayoutNode extends Node { this.appendChild(text); } - invalidateCaches() { + invalidateCaches(sub = false) { super.invalidateCaches(); + // just invalidate the entire document + // todo: not do this + if (!sub) { + this.document.invalidateCaches(true); + for (const x of this.document.allChildren()) x.invalidateCaches(true); + } + + // if (this.parent) this.parent.invalidateCaches(); + this._cssCache = null; + this.cache = {}; } }