avocado-old/packages/mixins/property.js

79 lines
1.7 KiB
JavaScript
Raw Normal View History

2019-03-17 23:45:48 -05:00
export function PropertyMixin(key, meta = {}) {
if (!meta || 'object' !== typeof meta) {
throw new TypeError(
`Expected meta for Property(${
key
}) to be object. ${
JSON.stringify(meta)
} given.`
);
}
return (Superclass) => {
if (Superclass.prototype[key]) {
throw new TypeError(`can't redefine Avocado property "${key}"`);
}
if ('identity' === meta.transformProperty) {
meta.transformProperty = (key) => key;
}
else if (!meta.transformProperty) {
meta.transformProperty = (key) => `${key}_PRIVATE_PROPERTY`;
}
2019-03-18 19:57:31 -05:00
meta.emit = meta.emit || function(...args) {
if (this.emit) {
this.emit(...args);
}
}
2019-03-17 23:45:48 -05:00
meta.eq = meta.eq || function (l, r) {
return l === r;
}
meta.get = meta.get || function(value) {
return this[meta.transformProperty(key)];
}
meta.set = meta.set || function(value) {
this[meta.transformProperty(key)] = value;
}
let metaDefault;
if (null === meta.default) {
metaDefault = null;
}
else if (undefined === meta.default) {
metaDefault = undefined;
}
else {
metaDefault = JSON.parse(JSON.stringify(meta.default));
}
2019-03-22 11:24:50 -05:00
return class Property extends Superclass {
2019-03-17 23:45:48 -05:00
constructor(...args) {
super(...args);
2019-03-17 23:45:48 -05:00
if (undefined !== metaDefault) {
meta.set.call(this, metaDefault);
}
}
2019-03-22 11:24:50 -05:00
get [key]() {
2019-03-17 23:45:48 -05:00
return meta.get.call(this);
2019-03-22 11:24:50 -05:00
}
set [key](value) {
2019-03-17 23:45:48 -05:00
const old = meta.get.call(this);
meta.set.call(this, value);
2019-03-18 19:57:31 -05:00
if (meta.track && meta.emit && !meta.eq.call(this, old, value)) {
meta.emit.call(this, `${key}Changed`, old, value);
2019-03-17 23:45:48 -05:00
}
2019-03-22 11:24:50 -05:00
}
2019-03-17 23:45:48 -05:00
2019-03-22 11:24:50 -05:00
}
2019-03-17 23:45:48 -05:00
}
}