Created
January 5, 2015 02:11
-
-
Save christospappas/183781edbcf141ce8f20 to your computer and use it in GitHub Desktop.
Nucleus: Lightweight Web Components
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Nucleus = {}; | |
Nucleus.components = {}; | |
Nucleus.Component = (function() { | |
var _elementPrototype; | |
var _reservedPropertiesRegex = /created|attached|detached|attributeChanged|extends|template/; | |
function element(tagName, definition) { | |
_elementPrototype = Object.create(getExtendsPrototype(definition.extends)); | |
attachCallbacks(definition); | |
attachProperties(definition); | |
Nucleus.components[tagName] = _elementPrototype; | |
var registerElementOptions = { prototype: _elementPrototype }; | |
if (definition.extends) { | |
registerElementOptions.extends = definition.extends; | |
} | |
document.registerElement(tagName, registerElementOptions); | |
}; | |
function getTagPrototype(tag) { | |
return tag ? HTMLElement.prototype : Object.getPrototypeOf(document.createElement(tag)); | |
}; | |
function getExtendsPrototype(name) { | |
if (Nucleus.components[name]) { | |
return Nucleus.components[name]; | |
} | |
return getTagPrototype(name); | |
}; | |
function loadTemplate(name) { | |
var root = this.createShadowRoot(); | |
var link = document.querySelector('link[rel="import"]'); | |
var content = link.import; | |
var template = content.querySelector('#' + name + 'Template'); | |
var clone = document.importNode(template.content, true); | |
root.appendChild(clone); | |
}; | |
function attachCallbacks(definition) { | |
if (definition.created) { | |
_elementPrototype.createdCallback = function() { | |
if (definition.template) { | |
loadTemplate.call(this, definition.template); | |
} | |
Object.observe(this, propertyChanged.bind(this)); | |
definition.created.call(this); | |
}; | |
} | |
if (definition.attached) { | |
_elementPrototype.attachedCallback = definition.attached; | |
} | |
if (definition.detached) { | |
_elementPrototype.detachedCallback = definition.detached; | |
} | |
if (definition.attributeChanged) { | |
_elementPrototype.attributeChangedCallback = definition.attributeChanged; | |
} | |
}; | |
function attachProperties(definition) { | |
for (var key in definition) { | |
if (key.match(_reservedPropertiesRegex)) { | |
continue; | |
} | |
if (definition.hasOwnProperty(key)) { | |
_elementPrototype[key] = definition[key]; | |
} | |
} | |
}; | |
function propertyChanged(changes) { | |
changes.forEach((change) => { | |
var handler = this[change.name + 'Changed']; | |
if (handler) { | |
handler.call(this, change); | |
} | |
}); | |
}; | |
return element; | |
})(); | |
export default Nucleus; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment