mirror of
https://github.com/wassname/template.git
synced 2026-07-13 11:30:02 +08:00
86 lines
2.2 KiB
JavaScript
86 lines
2.2 KiB
JavaScript
export function propName(attr) {
|
|
return attr.replace(/(\-[a-z])/g, (s) => s.toUpperCase().replace('-', ''));
|
|
}
|
|
|
|
export function attrName(prop) {
|
|
return prop.replace(/([A-Z])/g, (s) => '-' + s.toLowerCase());
|
|
}
|
|
|
|
export function deserializeAttribute(value, type) {
|
|
switch (type) {
|
|
case String:
|
|
break;
|
|
case Array:
|
|
case Object:
|
|
try {
|
|
value = JSON.parse(value);
|
|
} catch (e) {
|
|
}
|
|
break;
|
|
case Boolean:
|
|
value = value != 'false' && value != '0' && value;
|
|
break;
|
|
default:
|
|
}
|
|
return value;
|
|
}
|
|
|
|
const immediately = window.setImmediate || function(fn, args) {
|
|
window.setTimeout(function() {
|
|
fn.apply(this, args);
|
|
}, 0);
|
|
};
|
|
|
|
export const Properties = (properties) => {
|
|
const keys = Object.keys(properties);
|
|
const attrs = keys.map((k) => attrName(k));
|
|
return (superclass) => {
|
|
const cls = class extends superclass {
|
|
static get observedAttributes() {
|
|
return attrs;
|
|
}
|
|
attributeChangedCallback(attr, oldValue, newValue) {
|
|
const prop = propName(attr);
|
|
const value = deserializeAttribute(newValue, properties[prop].type);
|
|
this[prop] = value;
|
|
}
|
|
_propertiesChanged() {
|
|
if (!this.propertiesChangedCallback) {
|
|
return;
|
|
}
|
|
clearTimeout(this._propertiesChangedTimeout);
|
|
this._propertiesChangedTimeout = immediately(() => {
|
|
this.propertiesChangedCallback(this);
|
|
});
|
|
}
|
|
}
|
|
keys.forEach(function(k) {
|
|
const secret = `_${k}`;
|
|
const callback = `${k}Changed`;
|
|
const defaultValue = properties[k].value;
|
|
Object.defineProperty(cls.prototype, k, {
|
|
get: function() {
|
|
let value = this[secret];
|
|
if (value) {
|
|
return value;
|
|
}
|
|
if (defaultValue && typeof defaultValue == 'function') {
|
|
this[secret] = defaultValue();
|
|
} else {
|
|
this[secret] = defaultValue;
|
|
}
|
|
return this[secret];
|
|
},
|
|
set: function(value) {
|
|
const oldValue = this[secret];
|
|
this[secret] = value;
|
|
if (this[callback]) {
|
|
this[callback](value, oldValue);
|
|
}
|
|
this._propertiesChanged();
|
|
}
|
|
});
|
|
});
|
|
return cls;
|
|
};
|
|
}; |