commit d06776dadf8e263919b4460e3d8f0f1603587907
parent 64c8901abce610c8f458d41d3da4313dfa27231b
Author: finwo <finwo@pm.me>
Date: Thu, 29 Oct 2020 09:29:16 +0100
Added rendering a state
Diffstat:
2 files changed, 58 insertions(+), 15 deletions(-)
diff --git a/index.js b/index.js
@@ -16,6 +16,15 @@
base: '/partial',
};
+ const util = fwebc.util = {
+ isObject(obj) {
+ if (null === obj) return false;
+ if ('object' !== typeof obj) return false;
+ if (Array.isArray(obj)) return false;
+ return true;
+ }
+ };
+
// Override configs
fwebc.cfg = cfg => {
Object.assign(config, cfg);
@@ -37,18 +46,34 @@
// Register a component
fwebc.register = (name, source) => {
if (window.customElements.get(name)) return;
+
+ // Remove nested template tags
+ let template = document.createElement('template');
+ template.innerHTML = source;
+ if (template.content.firstChild instanceof HTMLTemplateElement) {
+ template = template.content.firstChild;
+ }
+
+ // Extract scripts
+ let code = '';
+ for(const child of [...template.content.children]) {
+ if (!(child instanceof HTMLScriptElement)) continue;
+ code += child.innerHTML;
+ template.content.removeChild(child);
+ }
+
+ // Template should be a string
+ template = template.innerHTML;
+
+ // Register the actual element
window.customElements.define(name, class extends HTMLElement {
constructor() {
super();
- // Build shadowroot
- let template = document.createElement('template');
- template.innerHTML = source;
- if (template.content.firstChild instanceof HTMLTemplateElement) {
- template = template.content.firstChild;
- }
+ this.state = {};
+
+ // Initialize shadow root
this.root = this.attachShadow({ mode: 'open' });
- this.root.appendChild(template.content);
// Run plugins
for (const plugin of plugins) {
@@ -56,25 +81,31 @@
}
// Run component code
- (new Function([...this.root.children]
- .filter(el => el instanceof HTMLScriptElement)
- .map(el => el.innerHTML)
- .join('')
- )).call(this);
+ (new Function(code)).call(this);
+ this.root.innerHTML = this.render();
// Load dependencies
if (this.dependencies) {
dependencies.forEach(fwebc.load);
}
+
+
+ }
+
+ render() {
+ const fn = new Function(...Object.keys(this.state), "return `"+ template.replace(/`/g,'\\`') + "`;");
+ return fn(...Object.values(this.state));
}
update(data) {
Object.entries(data)
.forEach(([key, value]) => {
- this.state[key] = this.isObject(this.state[key]) &&
- this.isObject(value) ? {...this.state[key], ...value} : value;
+ this.state[key] = util.isObject(this.state[key]) &&
+ util.isObject(value) ? {...this.state[key], ...value} : value;
});
+ this.root.innerHTML = this.render();
}
+
});
};
diff --git a/test/partial/my-app.tag b/test/partial/my-app.tag
@@ -1,8 +1,20 @@
<template>
- <h2>Bird is the word!</h2>
+ <h2>Bird is the ${subject}!</h2>
+ <p> Currently running for ${n} seconds</p>
<style>
h2 {
color: #555;
}
</style>
+ <script>
+ this.state = {
+ n: 0,
+ subject: 'WORD',
+ };
+ setInterval(() => {
+ this.update({
+ n: this.state.n + 1,
+ });
+ }, 1000);
+ </script>
</template>