JSFiddle - React, Tailwind, and code Playground
by kentaromiura
HTML
<custom-element name="kenta-b" noscript extends="b">
<template>this should be bold</template>
</custom-element>
<custom-element name="kenta-simple" noscript>
<template>
<b> Simple element </b>
</template>
</custom-element>
<custom-element name="kenta-foo" constructor="foo">
<template>foo
<span><div data-id="test1">this is for testing deep clonenode</div></span>
<span data-id="test2"></span>
</template>
<script>
document.register.tag('kenta-foo', {
options: true,
ready: function(){
console.log('ready', this, foo)
//testing the $ shortcuts
console.log(this.$.test1.innerHTML)
this.$.test2.innerHTML = "test"
},
created: function(){
console.log('created', this)
},
test: function(){
console.log('test!')
}
})
</script>
<style>
kenta-foo {
display: block;
color:red;
}
</style>
</custom-element>
<kenta-foo id=test></kenta-foo>
<kenta-simple></kenta-simple>
<kenta-b></kenta-b>
<script>
onload = function(){
document.getElementById('test').test()
console.log(typeof(foo) !== 'undefined')
}
</script>
JavaScript
(function(global){
if (!document.register) document.register = document.registerElement
var customElements = {},
create = Object.create || function(proto){
var f = function(){}
f.prototype = proto
return new f()
},
has = (has = Object.prototype.hasOwnProperty, has.call.bind(has)),
nop = function(){},
collect = function(from, collected){
if (document.querySelectorAll) return document.querySelectorAll('[data-id]', from)
collected = collected || []
if ('getAttribute' in from && from.getAttribute('data-id')){
collected.push(from)
}
for (var i = 0, max = from.children.length; i<max; i++){
collect(from.children[i], collected)
}
return collected
}
document.register.tag = function(name, options){
options = options || {}
if (!customElements[name]){
customElements[name] = {
options: options
}
return;
}
var xtends = customElements[name].xtends,
ctor = customElements[name].ctor,
proto = xtends? create(document.createElement(xtends).constructor.prototype) : create(HTMLElement.prototype),
created = options.created || nop,
ready = options.ready || nop,
onAttributeChange = options.attributeChangedCallback || nop,
attributes = customElements[name].attributes.split(' '),
template = customElements[name].content,
descriptor = function(attribute){
return {
enumerable: true,
get: function(){
return this.getAttribute(attribute)
},
set: function(value){
this.setAttribute(attribute, value)
}
}
}
delete options.created
delete options.ready
delete options.attributeChangedCallback
for (var any in options){
if (has(options, any)){
proto[any] = options[any]
}
}
...