From e9acf7c4b576f4736896dd9cf65520918085b634 Mon Sep 17 00:00:00 2001 From: cwpeng Date: Sun, 12 Sep 2021 11:25:17 +0800 Subject: [PATCH 1/8] Change render() to init() --- wc/WComponent.js | 8 +------- wc/components/Button.js | 2 +- wc/components/Calendar.js | 8 +++++--- wc/components/Code.js | 2 +- wc/components/Dialog.js | 2 +- wc/components/Form.js | 2 +- wc/components/Heading.js | 2 +- wc/components/List.js | 2 +- wc/components/ListItem.js | 2 +- wc/components/Quote.js | 2 +- wc/components/checkable/Checkable.js | 2 +- wc/components/layout/Grid.js | 4 ++-- wc/components/layout/Nav.js | 2 +- wc/components/layout/NavPart.js | 2 +- wc/components/layout/Section.js | 2 +- wc/components/spa/SPALink.js | 2 +- wc/components/spa/SPAPage.js | 6 ++++-- 17 files changed, 25 insertions(+), 27 deletions(-) diff --git a/wc/WComponent.js b/wc/WComponent.js index 05c23c3..61f4876 100644 --- a/wc/WComponent.js +++ b/wc/WComponent.js @@ -19,14 +19,8 @@ class WComponent extends HTMLElement{ this.bindProps(); this.attachShadow({ mode: 'open' }); this.setStylesheet(this.stylesheet); - this.componentWillRender(); - this.render(); - this.componentDidRender(); + this.init(); } - - componentWillRender() {} - componentDidRender() {} - /** * Set all properties from all observed attributes. */ diff --git a/wc/components/Button.js b/wc/components/Button.js index f2fd092..2a73c71 100644 --- a/wc/components/Button.js +++ b/wc/components/Button.js @@ -132,7 +132,7 @@ class Button extends WComponent{ constructor(){ super(); } - render(){ + init(){ const classList=[]; classList.push(this.display, this.size, this.outlined?"outline-"+this.color:this.color); const attrs={}; diff --git a/wc/components/Calendar.js b/wc/components/Calendar.js index a719567..3586ba3 100644 --- a/wc/components/Calendar.js +++ b/wc/components/Calendar.js @@ -77,14 +77,16 @@ class Calendar extends WComponent{ constructor(){ super(); } + /* componentWillRender(){ this.calendar=null; this.calendarDate=new Date(); this.entries={}; } + */ changeMonth(offset){ this.calendarDate.setMonth(this.calendarDate.getMonth()+offset); - this.render(); + this.init(); } addEntry(entry){ if(this.entries[entry.date]){ @@ -92,9 +94,9 @@ class Calendar extends WComponent{ }else{ this.entries[entry.date]=[entry]; } - this.render(); + this.init(); } - render(){ + init(){ if(this.calendar!==null){ this.calendar.remove(); } diff --git a/wc/components/Code.js b/wc/components/Code.js index 85230cb..28bf602 100644 --- a/wc/components/Code.js +++ b/wc/components/Code.js @@ -143,7 +143,7 @@ class Code extends WComponent{ }; - render() { + init() { const props = { className: 'code' }; diff --git a/wc/components/Dialog.js b/wc/components/Dialog.js index 688030e..2915e63 100644 --- a/wc/components/Dialog.js +++ b/wc/components/Dialog.js @@ -19,7 +19,7 @@ class Dialog extends WComponent{ constructor(){ super(); } - render(){ + init(){ this.dialog=DOM.create("div", {props:{className:"dialog"}}); this.head=DOM.create("slot", {props:{name:"head"}}, this.dialog); this.main=DOM.create("slot", {props:{name:"main"}}, this.dialog); diff --git a/wc/components/Form.js b/wc/components/Form.js index c755415..d3e816e 100644 --- a/wc/components/Form.js +++ b/wc/components/Form.js @@ -107,7 +107,7 @@ class Form extends WComponent{ }); }); } - render() { + init() { const attrs = { name: this.name, action: this.action, diff --git a/wc/components/Heading.js b/wc/components/Heading.js index a857c4f..a333bba 100644 --- a/wc/components/Heading.js +++ b/wc/components/Heading.js @@ -60,7 +60,7 @@ class Heading extends WComponent{ super(); } - render() { + init() { const props = { className: `heading${this.underlined ? ' underlined' : ''}` }; diff --git a/wc/components/List.js b/wc/components/List.js index 0768e0e..d141229 100644 --- a/wc/components/List.js +++ b/wc/components/List.js @@ -53,7 +53,7 @@ class List extends WComponent{ constructor(){ super(); } - render(){ + init(){ const list=DOM.create("div", {props:{className:"list"}, attrs:{appearance: this.appearance}}, this.shadowRoot); DOM.create("slot", {}, list); /* diff --git a/wc/components/ListItem.js b/wc/components/ListItem.js index 83ae7c2..3d9f732 100644 --- a/wc/components/ListItem.js +++ b/wc/components/ListItem.js @@ -37,7 +37,7 @@ class ListItem extends WComponent{ constructor(){ super(); } - render(){ + init(){ // render const mark=this.parentElement.mark?this.parentElement.mark:""; const markedItem=DOM.create("div", {props:{className:"item"}, attrs:{mark, disabled: this.disabled}}, this.shadowRoot); diff --git a/wc/components/Quote.js b/wc/components/Quote.js index bb6ff8f..c44d78f 100644 --- a/wc/components/Quote.js +++ b/wc/components/Quote.js @@ -35,7 +35,7 @@ class Quote extends WComponent{ return this.getDefaultValueByName('align'); } - render() { + init() { DOM.create('style', { props: { textContent: stylesheet } }, this.shadowRoot); const container = DOM.create('div', { props: { className: this.parseAlign() } }, this.shadowRoot); diff --git a/wc/components/checkable/Checkable.js b/wc/components/checkable/Checkable.js index 7e22347..7041e02 100644 --- a/wc/components/checkable/Checkable.js +++ b/wc/components/checkable/Checkable.js @@ -102,7 +102,7 @@ class Checkable extends WComponent{ }; this.shadowRoot.addEventListener('click', this.clickHandler); } - render() { + init() { const ctn = DOM.create('div', null, this.shadowRoot); const inputAttrs = { type: this.type }; diff --git a/wc/components/layout/Grid.js b/wc/components/layout/Grid.js index 132051c..a542bed 100644 --- a/wc/components/layout/Grid.js +++ b/wc/components/layout/Grid.js @@ -38,7 +38,7 @@ class Grid extends WComponent{ } `, "grid"); } - render(){ + init(){ this.setGridStylesheet(this.columns, this.rows); if(!this.container){ this.container=DOM.create("div", {props:{className:"container"}}, this.shadowRoot); @@ -46,7 +46,7 @@ class Grid extends WComponent{ } } attributeChangedCallback(name, oldValue, newValue){ - this.render(); + this.init(); } } Grid.prototype.stylesheet=stylesheet; diff --git a/wc/components/layout/Nav.js b/wc/components/layout/Nav.js index 9887499..efd6bc1 100644 --- a/wc/components/layout/Nav.js +++ b/wc/components/layout/Nav.js @@ -11,7 +11,7 @@ class Nav extends WComponent{ constructor(){ super(); } - render(){ + init(){ const root=DOM.create("slot", {}, this.shadowRoot); } } diff --git a/wc/components/layout/NavPart.js b/wc/components/layout/NavPart.js index 21ff4c4..a52a27d 100644 --- a/wc/components/layout/NavPart.js +++ b/wc/components/layout/NavPart.js @@ -99,7 +99,7 @@ class NavPart extends WComponent{ } `); } - render(){ + init(){ let rwdSize = this["rwd-size"]; if(this["rwd-effect"]!=="none" && rwdSize!=="none"){ if(rwdSize==="mobile"){ diff --git a/wc/components/layout/Section.js b/wc/components/layout/Section.js index e3c8b24..432db39 100644 --- a/wc/components/layout/Section.js +++ b/wc/components/layout/Section.js @@ -20,7 +20,7 @@ class Section extends WComponent{ constructor(){ super(); } - render(){ + init(){ const grid=DOM.create(`${window.prefix}-grid`, {attrs:{ columns:3, rows:2 }, styles:{ diff --git a/wc/components/spa/SPALink.js b/wc/components/spa/SPALink.js index 8ca7169..a9ce1c0 100644 --- a/wc/components/spa/SPALink.js +++ b/wc/components/spa/SPALink.js @@ -15,7 +15,7 @@ class SPALink extends WComponent{ constructor(){ super(); } - render(){ + init(){ DOM.create("slot", {events:{ click:()=>{ this.changePage() diff --git a/wc/components/spa/SPAPage.js b/wc/components/spa/SPAPage.js index 6fff7f5..b21a884 100644 --- a/wc/components/spa/SPAPage.js +++ b/wc/components/spa/SPAPage.js @@ -32,6 +32,7 @@ class SPAPage extends WComponent{ this.setCurrent(this.match(window.location.pathname)); }); } + /* componentWillRender(){ this.current=this.match(window.location.pathname); this.events={ @@ -39,6 +40,7 @@ class SPAPage extends WComponent{ dispose:new Event("dispose") }; } + */ match(path){ return path.startsWith(this.path); } @@ -47,9 +49,9 @@ class SPAPage extends WComponent{ return; } this.current=current; - this.render(); + this.init(); } - render(){ + init(){ const props={ className:this.current?"show":"hide" }; From 693a34335f12e2646abdafc07f2601721d231585 Mon Sep 17 00:00:00 2001 From: cwpeng Date: Sun, 12 Sep 2021 11:34:33 +0800 Subject: [PATCH 2/8] Remove componentWillRender and componentDidRender --- wc/components/Calendar.js | 26 +++++++++++---------- wc/components/spa/SPAPage.js | 44 ++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/wc/components/Calendar.js b/wc/components/Calendar.js index 3586ba3..1c03f46 100644 --- a/wc/components/Calendar.js +++ b/wc/components/Calendar.js @@ -77,16 +77,9 @@ class Calendar extends WComponent{ constructor(){ super(); } - /* - componentWillRender(){ - this.calendar=null; - this.calendarDate=new Date(); - this.entries={}; - } - */ changeMonth(offset){ this.calendarDate.setMonth(this.calendarDate.getMonth()+offset); - this.init(); + this.update(); } addEntry(entry){ if(this.entries[entry.date]){ @@ -94,12 +87,21 @@ class Calendar extends WComponent{ }else{ this.entries[entry.date]=[entry]; } - this.init(); + this.update(); } init(){ - if(this.calendar!==null){ - this.calendar.remove(); - } + // init fields + this.calendar=null; + this.calendarDate=new Date(); + this.entries={}; + // first render + this.render(); + } + update(){ + this.calendar.remove(); + this.render(); + } + render(){ // create calendar const calendar=DOM.create("div", {props:{ className:"calendar" diff --git a/wc/components/spa/SPAPage.js b/wc/components/spa/SPAPage.js index b21a884..ce582e2 100644 --- a/wc/components/spa/SPAPage.js +++ b/wc/components/spa/SPAPage.js @@ -32,29 +32,14 @@ class SPAPage extends WComponent{ this.setCurrent(this.match(window.location.pathname)); }); } - /* - componentWillRender(){ - this.current=this.match(window.location.pathname); + init(){ + // init custom events this.events={ init:new Event("init"), dispose:new Event("dispose") }; - } - */ - match(path){ - return path.startsWith(this.path); - } - setCurrent(current){ - if(this.current===current){ - return; - } - this.current=current; - this.init(); - } - init(){ - const props={ - className:this.current?"show":"hide" - }; + // handle template + this.current=this.match(window.location.pathname); if(this.current){ // if shown, take content outside of template const template=this.querySelector("template"); if(template!==null){ @@ -62,17 +47,38 @@ class SPAPage extends WComponent{ template.remove(); } } + // first render + this.render(); + } + update(){ + this.render(); + } + render(){ + const props={ + className:this.current?"show":"hide" + }; if(this.root){ DOM.modify(this.root, {props: props}); }else{ this.root=DOM.create("slot", {props: props}, this.shadowRoot); } + // fire custom event if(this.current){ this.dispatchEvent(this.events.init); }else{ this.dispatchEvent(this.events.dispose); } } + match(path){ + return path.startsWith(this.path); + } + setCurrent(current){ + if(this.current===current){ + return; + } + this.current=current; + this.update(); + } } SPAPage.prototype.stylesheet=stylesheet; export default SPAPage; \ No newline at end of file From 0cb98d7fb269d4d75f862a9e3d16a81e7c34d51c Mon Sep 17 00:00:00 2001 From: cwpeng Date: Sun, 12 Sep 2021 12:25:15 +0800 Subject: [PATCH 3/8] Add attributeChangedCallback Lifecycle --- wc/WComponent.js | 9 +++++++++ wc/components/Form.js | 3 ++- wc/components/checkable/Checkable.js | 4 +++- wc/components/spa/SPAPage.js | 3 +-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/wc/WComponent.js b/wc/WComponent.js index 61f4876..49c4f80 100644 --- a/wc/WComponent.js +++ b/wc/WComponent.js @@ -32,6 +32,15 @@ class WComponent extends HTMLElement{ this[attr.name] = this.getAttribute(attr.name); }); } + /** + * Call update method in attribute changed callback if attribute name is acceptable + */ + attributeChangedCallback(name, oldValue, newValue){ + if(typeof this.constructor.attributes[name] === 'object'){ + this.update({name, oldValue, newValue}); + } + } + update(){} /** * Dynamically create getters & setters for property-attribute sync * by parsing class field attribute object. diff --git a/wc/components/Form.js b/wc/components/Form.js index d3e816e..cb97bfc 100644 --- a/wc/components/Form.js +++ b/wc/components/Form.js @@ -46,7 +46,8 @@ class Form extends WComponent{ this.bindEvents(); } - attributeChangedCallback(name, oldValue, newValue) { + update(args) { + const {name, oldValue, newValue} = args; const form = this.shadowRoot.querySelector('form'); const value = this.getAttributeParserByName(name)(newValue, this.constructor.attributes[name]); form[name] = value; diff --git a/wc/components/checkable/Checkable.js b/wc/components/checkable/Checkable.js index 7041e02..9c5030f 100644 --- a/wc/components/checkable/Checkable.js +++ b/wc/components/checkable/Checkable.js @@ -78,7 +78,9 @@ class Checkable extends WComponent{ this.bindEvents(); } - attributeChangedCallback(name, oldValue, newValue) { + update(args) { + const {name, oldValue, newValue} = args; + console.log(name, oldValue, newValue); // called when init because getter change attribute from null to something if(name === this.constructor.attributes.checked.name || name === this.constructor.attributes.disabled.name) { const input = this.shadowRoot.querySelector('input'); diff --git a/wc/components/spa/SPAPage.js b/wc/components/spa/SPAPage.js index ce582e2..a8450a7 100644 --- a/wc/components/spa/SPAPage.js +++ b/wc/components/spa/SPAPage.js @@ -50,7 +50,7 @@ class SPAPage extends WComponent{ // first render this.render(); } - update(){ + update(args){ this.render(); } render(){ @@ -77,7 +77,6 @@ class SPAPage extends WComponent{ return; } this.current=current; - this.update(); } } SPAPage.prototype.stylesheet=stylesheet; From 34f63691cd1c9fb2b82c7ccb4e90b3758296e2ce Mon Sep 17 00:00:00 2001 From: cwpeng Date: Sun, 12 Sep 2021 13:03:10 +0800 Subject: [PATCH 4/8] Change issue description in comment --- wc/components/checkable/Checkable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wc/components/checkable/Checkable.js b/wc/components/checkable/Checkable.js index 9c5030f..4831f22 100644 --- a/wc/components/checkable/Checkable.js +++ b/wc/components/checkable/Checkable.js @@ -80,7 +80,7 @@ class Checkable extends WComponent{ update(args) { const {name, oldValue, newValue} = args; - console.log(name, oldValue, newValue); // called when init because getter change attribute from null to something + console.log(name, oldValue, newValue); // called right after init because first-added attribute will trigger attributeChangedCallback if(name === this.constructor.attributes.checked.name || name === this.constructor.attributes.disabled.name) { const input = this.shadowRoot.querySelector('input'); From 012a152e9ab53c29bd1b4d08dc29fc34abc64d83 Mon Sep 17 00:00:00 2001 From: Niz Kuo Date: Sun, 12 Sep 2021 22:20:54 +0800 Subject: [PATCH 5/8] Update wc/components/Form.js --- wc/components/Form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wc/components/Form.js b/wc/components/Form.js index cb97bfc..3ab7f36 100644 --- a/wc/components/Form.js +++ b/wc/components/Form.js @@ -46,7 +46,7 @@ class Form extends WComponent{ this.bindEvents(); } - update(args) { + update({ name, oldValue, newValue } = {}) { const {name, oldValue, newValue} = args; const form = this.shadowRoot.querySelector('form'); const value = this.getAttributeParserByName(name)(newValue, this.constructor.attributes[name]); From e60904c5bef90e5238430408bbb827e333c05c6b Mon Sep 17 00:00:00 2001 From: Niz Kuo Date: Sun, 12 Sep 2021 22:21:00 +0800 Subject: [PATCH 6/8] Update wc/components/Form.js --- wc/components/Form.js | 1 - 1 file changed, 1 deletion(-) diff --git a/wc/components/Form.js b/wc/components/Form.js index 3ab7f36..3988e28 100644 --- a/wc/components/Form.js +++ b/wc/components/Form.js @@ -47,7 +47,6 @@ class Form extends WComponent{ } update({ name, oldValue, newValue } = {}) { - const {name, oldValue, newValue} = args; const form = this.shadowRoot.querySelector('form'); const value = this.getAttributeParserByName(name)(newValue, this.constructor.attributes[name]); form[name] = value; From 764e5615f1dd1699eb863bf1af5b75ebf564fd2b Mon Sep 17 00:00:00 2001 From: Niz Kuo Date: Sun, 12 Sep 2021 22:21:06 +0800 Subject: [PATCH 7/8] Update wc/components/checkable/Checkable.js --- wc/components/checkable/Checkable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wc/components/checkable/Checkable.js b/wc/components/checkable/Checkable.js index 4831f22..36de306 100644 --- a/wc/components/checkable/Checkable.js +++ b/wc/components/checkable/Checkable.js @@ -78,7 +78,7 @@ class Checkable extends WComponent{ this.bindEvents(); } - update(args) { + update({ name, oldValue, newValue } = {}) { const {name, oldValue, newValue} = args; console.log(name, oldValue, newValue); // called right after init because first-added attribute will trigger attributeChangedCallback if(name === this.constructor.attributes.checked.name From 88ffe34a0eb51a8e869c738d1f2947ad80af23dc Mon Sep 17 00:00:00 2001 From: Niz Kuo Date: Sun, 12 Sep 2021 22:21:11 +0800 Subject: [PATCH 8/8] Update wc/components/checkable/Checkable.js --- wc/components/checkable/Checkable.js | 1 - 1 file changed, 1 deletion(-) diff --git a/wc/components/checkable/Checkable.js b/wc/components/checkable/Checkable.js index 36de306..a8ffd21 100644 --- a/wc/components/checkable/Checkable.js +++ b/wc/components/checkable/Checkable.js @@ -79,7 +79,6 @@ class Checkable extends WComponent{ } update({ name, oldValue, newValue } = {}) { - const {name, oldValue, newValue} = args; console.log(name, oldValue, newValue); // called right after init because first-added attribute will trigger attributeChangedCallback if(name === this.constructor.attributes.checked.name || name === this.constructor.attributes.disabled.name) {