@web-atoms/core-docs
Version:
227 lines • 8.39 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "./types"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AtomBinder = exports.symbolBindable = exports.symbolHandlers = void 0;
const types_1 = require("./types");
exports.symbolHandlers = Symbol.for("handlers");
exports.symbolBindable = Symbol.for("bindable");
class AtomBinder {
static refreshValue(target, key) {
const handlers = AtomBinder.get_WatchHandler(target, key);
if (handlers === undefined || handlers == null) {
return;
}
for (const item of handlers) {
item(target, key);
}
if (target.onPropertyChanged) {
target.onPropertyChanged(key);
}
}
static add_WatchHandler(target, key, handler) {
if (target == null) {
return;
}
const handlers = AtomBinder.get_WatchHandler(target, key);
handlers.push(handler);
if (Array.isArray(target)) {
return;
}
// get existing property definition if it ha any
const pv = AtomBinder.getPropertyDescriptor(target, key);
// return if it has a getter
// in case of getter/setter, it is responsibility of setter to refresh
// object
if (pv && pv.get) {
return;
}
const tw = target;
let bindables = tw[exports.symbolBindable];
if (bindables === undefined) {
bindables = {};
Object.defineProperty(tw, exports.symbolBindable, {
value: bindables,
enumerable: false,
writable: true,
configurable: true
});
}
// if (!tw._$_bindable) {
// tw._$_bindable = {};
// }
if (!bindables[key]) {
bindables[key] = 1;
const o = target[key];
const nk = Symbol.for(key);
target[nk] = o;
const set = function (v) {
const ov = this[nk];
// tslint:disable-next-line:triple-equals
if (ov === undefined ? ov === v : ov == v) {
return;
}
this[nk] = v;
AtomBinder.refreshValue(this, key);
};
const get = function () {
return this[nk];
};
if (pv) {
delete target[key];
Object.defineProperty(target, key, {
get,
set,
configurable: true,
enumerable: true
});
}
else {
Object.defineProperty(target, key, {
get, set, enumerable: true, configurable: true
});
}
}
}
static getPropertyDescriptor(target, key) {
const pv = Object.getOwnPropertyDescriptor(target, key);
if (!pv) {
const pt = Object.getPrototypeOf(target);
if (pt) {
return AtomBinder.getPropertyDescriptor(pt, key);
}
}
return pv;
}
static get_WatchHandler(target, key) {
if (target == null) {
return null;
}
let handlers = target[exports.symbolHandlers];
if (handlers === undefined) {
handlers = {};
Object.defineProperty(target, exports.symbolHandlers, {
value: handlers,
enumerable: false,
writable: true,
configurable: true
});
}
// if (!handlers) {
// handlers = {};
// target._$_handlers = handlers;
// }
let handlersForKey = handlers[key];
if (handlersForKey === undefined || handlersForKey == null) {
handlersForKey = [];
handlers[key] = handlersForKey;
}
return handlersForKey;
}
static remove_WatchHandler(target, key, handler) {
if (target == null) {
return;
}
const handlers = target[exports.symbolHandlers];
if (typeof handlers === "undefined") {
return;
}
const handlersForKey = target[exports.symbolHandlers][key];
if (handlersForKey === undefined || handlersForKey == null) {
return;
}
// handlersForKey = handlersForKey.filter( (f) => f !== handler);
types_1.ArrayHelper.remove(handlersForKey, (f) => f === handler);
if (!handlersForKey.length) {
handlers[key] = null;
delete handlers[key];
}
}
static invokeItemsEvent(target, mode, index, item) {
const key = "_items";
const handlers = AtomBinder.get_WatchHandler(target, key);
if (!handlers) {
return;
}
for (const obj of handlers) {
obj(target, mode, index, item);
}
AtomBinder.refreshValue(target, "length");
}
static refreshItems(ary) {
AtomBinder.invokeItemsEvent(ary, "refresh", -1, null);
}
static add_CollectionChanged(target, handler) {
if (target == null) {
throw new Error("Target Array to watch cannot be null");
}
if (handler == null) {
throw new Error("Target handle to watch an Array cannot be null");
}
const handlers = AtomBinder.get_WatchHandler(target, "_items");
handlers.push(handler);
return { dispose: () => {
AtomBinder.remove_CollectionChanged(target, handler);
}
};
}
static remove_CollectionChanged(t, handler) {
if (t == null) {
return;
}
const target = t;
const handlers = target[exports.symbolHandlers];
if (typeof handlers === "undefined") {
return;
}
const key = "_items";
const handlersForKey = handlers[key];
if (handlersForKey === undefined || handlersForKey == null) {
return;
}
types_1.ArrayHelper.remove(handlersForKey, (f) => f === handler);
if (!handlersForKey.length) {
handlers[key] = null;
delete handlers[key];
}
}
static watch(item, property, f) {
AtomBinder.add_WatchHandler(item, property, f);
return {
dispose: () => {
AtomBinder.remove_WatchHandler(item, property, f);
}
};
}
static clear(a) {
a.length = 0;
this.invokeItemsEvent(a, "refresh", -1, null);
AtomBinder.refreshValue(a, "length");
}
static addItem(a, item) {
const index = a.length;
a.push(item);
this.invokeItemsEvent(a, "add", index, item);
AtomBinder.refreshValue(a, "length");
}
static removeItem(a, item) {
const i = a.findIndex((x) => x === item);
if (i === -1) {
return false;
}
a.splice(i, 1);
AtomBinder.invokeItemsEvent(a, "remove", i, item);
AtomBinder.refreshValue(a, "length");
return true;
}
}
exports.AtomBinder = AtomBinder;
});
//# sourceMappingURL=AtomBinder.js.map