This commit is contained in:
Shan Carter
2017-03-10 11:10:04 -08:00
parent 8807bb1778
commit feea10ed4e
26 changed files with 6340 additions and 252 deletions
+86
View File
@@ -0,0 +1,86 @@
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;
};
};
+38
View File
@@ -0,0 +1,38 @@
// import '@webcomponents/shadycss/scoping-shim';
export const Template = (name, templateString, useShadow = true) => {
const template = document.createElement('template');
template.innerHTML = templateString;
// ShadyCSS.prepareTemplate(template, name);
return (superclass) => {
return class extends superclass {
constructor() {
super();
this.clone = document.importNode(template.content, true);
if (useShadow) {
// ShadyCSS.applyStyle(this);
this.shadow_ = this.attachShadow({mode: 'open'});
this.shadow_.appendChild(clone);
}
}
connectedCallback() {
if (!useShadow) {
this.insertBefore(this.clone, this.firstChild);
}
}
get root() {
if (useShadow) {
return this.shadow_;
}
return this;
}
$(query) {
return this.root.querySelector(query);
}
$$(query) {
return this.root.querySelectorAll(query);
}
}
}
};