UNPKG

vasille-jsx

Version:

The first Developer eXperience Orientated front-end framework (JSX components)

167 lines (166 loc) 4.52 kB
import { ArrayModel, Destroyable, MapModel, Reactive, SetModel } from "vasille"; import { ProxyReference, proxyObject } from "./objects.js"; const symbol = Symbol("proxy"); class Context extends Destroyable { constructor() { super(...arguments); this.ctx = new Reactive({}); } checkEnable(value) { if (value && typeof value === "object" && value.constructor === Object) { return this.enableObject(value); } return value; } checkDisable(value) { if (value && typeof value === "object" && value.constructor === Object) { this.disableObject(value); } } enableObject(o) { const ref = new ProxyReference(undefined); o[symbol] = ref; this.ctx.register(ref); return proxyObject(o, ref); } disableObject(o) { this.ctx.release(o[symbol]); } destroy() { this.ctx.destroy(); } } export class ContextArray extends ArrayModel { constructor(data) { const ctx = new Context(); if (data instanceof Array) { for (let i = 0; i < data.length; i++) { data[i] = ctx.checkEnable(data[i]); } } super(data); this.ctx = ctx; } fill(value, start, end) { value = this.ctx.checkEnable(value); return super.fill(value, start, end); } pop() { const value = super.pop(); this.ctx.checkDisable(value); return value; } push(...items) { for (let i = 0; i < items.length; i++) { items[i] = this.ctx.checkEnable(items[i]); } return super.push(...items); } shift() { const value = super.shift(); this.ctx.checkDisable(value); return value; } splice(start, deleteCount, ...items) { for (let i = 0; i < items.length; i++) { items[i] = this.ctx.checkEnable(items[i]); } const removed = super.splice(start, deleteCount, ...items); for (const item of removed) { this.ctx.checkDisable(removed); } return removed; } unshift(...items) { for (let i = 0; i < items.length; i++) { items[i] = this.ctx.checkEnable(items[i]); } return super.unshift(...items); } replace(at, with_) { this.ctx.checkDisable(this[at]); with_ = this.ctx.checkEnable(with_); return super.replace(at, with_); } destroy() { super.destroy(); this.ctx.destroy(); } } export class ContextMap extends MapModel { constructor(map) { const ctx = new Context(); /* istanbul ignore else */ if (map) { for (const item of map) { item[1] = ctx.checkEnable(item[1]); } } super(map); this.ctx = ctx; } clear() { for (const value of this.values()) { this.ctx.checkDisable(value); } super.clear(); } delete(key) { this.ctx.checkDisable(this.get(key)); return super.delete(key); } set(key, value) { this.ctx.checkDisable(this.get(key)); value = this.ctx.checkEnable(value); return super.set(key, value); } destroy() { super.destroy(); this.ctx.destroy(); } } export class ContextSet extends SetModel { constructor(set) { const ctx = new Context(); const real = new Map(); /* istanbul ignore else */ if (set) { for (let i = 0; i < set.length; i++) { real.set(set[i], (set[i] = ctx.checkEnable(set[i]))); } } super(set); this.ctx = ctx; this.real = real; } add(value) { if (!this.real.has(value)) { this.real.set(value, (value = this.ctx.checkEnable(value))); return super.add(value); } return this; } has(value) { return this.real.has(value); } clear() { for (const item of this) { this.ctx.checkDisable(item); } super.clear(); this.real.clear(); } delete(value) { const real = this.real.get(value); if (real !== undefined) { this.ctx.checkDisable(value); this.real.delete(value); return super.delete(real); } return false; } destroy() { super.destroy(); this.ctx.destroy(); } }