Skip to content

Instantly share code, notes, and snippets.

@cletusw
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cletusw/64a0e8fda34eba1b8cd1 to your computer and use it in GitHub Desktop.
Save cletusw/64a0e8fda34eba1b8cd1 to your computer and use it in GitHub Desktop.
Attribute Web Components (Decorators?)
View live: http://bl.ocks.org/cletusw/64a0e8fda34eba1b8cd1
TODO: Make dynamic (adding or removing the attribute adds or removes the functionality)
<link rel="import" href="registerCustomAttribute.html">
<style>
html /deep/ [cw-circle] {
background-color: #ccc;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
</style>
<script>
registerCustomAttribute('cw-circle', function() {
this.radius = Number(this.getAttribute('radius')) || 100;
this.area = function() {
return Math.PI * this.radius * this.radius;
};
this.grow = function() {
this.radius++;
};
this.logRadius = function() {
console.log(this.radius);
};
this.shrink = function() {
this.radius--;
};
this.style.width = this.radius + "px";
this.style.height = this.radius + "px";
this.addEventListener('click', this.logRadius);
return this;
});
</script>
<!DOCTYPE html>
<html>
<head>
<link rel="import" href="cw-circle.html">
<link rel="import" href="shadow-element.html">
<style>
span {
text-align: center;
}
</style>
</head>
<body>
<shadow-element cw-circle radius="200">
<span>Not Shadow DOM</span>
</shadow-element>
<div cw-circle>
<span>Not Shadow DOM</span>
</div>
</body>
</html>
<script>
var registerCustomAttribute = (function() {
var queuedAttributes = [];
if (document.readyState !== 'complete') {
window.addEventListener('load', ready);
}
function ready() {
window.removeEventListener('load', ready);
queuedAttributes.forEach(function(attr) {
upgradeElements(attr.attrName, attr.constructor);
});
}
function upgradeElements(attrName, constructor) {
var els = document.querySelectorAll('html /deep/ [' + attrName + ']');
Array.prototype.forEach.call(els, function(el) {
constructor.call(el);
});
}
return function(attrName, constructor) {
if (document.readyState === 'complete') {
upgradeElements(attrName, constructor);
}
else {
queuedAttributes.push({
attrName: attrName,
constructor: constructor
});
}
};
})();
</script>
<link rel="import" href="cw-circle.html">
<template id="shadow-element-template">
<style>
:host {
display: block;
}
div {
background-color: yellow !important;
color: blue;
}
</style>
<div cw-circle>
<content></content>
</div>
</template>
<script>
var ShadowElement = (function() {
var template = document.currentScript.ownerDocument.querySelector('#shadow-element-template');
var ShadowElementProto = Object.create(HTMLElement.prototype);
ShadowElementProto.createdCallback = function() {
var clone = document.importNode(template.content, true);
this.createShadowRoot().appendChild(clone);
};
return document.registerElement('shadow-element', {
prototype: ShadowElementProto
});
})();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment