Make SkyElement more classy.

The syntax for implementing a SkyElement is now:

<sky-element name="element-name">
<template>
  <!-- template here -->
</template>
<script>
module.exports = class extends SkyElement {
  attached() {
     // ...
  }
  // .. methods here ..
}.register();
</script>
</sky-element>

The register() static method on SkyElement subclasses calls
document.registerElement() and returns the generated constructor.
It uses the parent <sky-element>'s name attribute to set the name
of the element.

R=rafaelw@chromium.org

Review URL: https://codereview.chromium.org/788943003
This commit is contained in:
Elliott Sprehn 2014-12-16 16:28:28 -08:00
parent 8cd1801dc7
commit 5f6c32c247
14 changed files with 112 additions and 83 deletions

View File

@ -7,6 +7,12 @@
<import src="city-data-service.sky" as="CityDataService" /> <import src="city-data-service.sky" as="CityDataService" />
<import src="city-sequence.sky" as="CitySequence" /> <import src="city-sequence.sky" as="CitySequence" />
<script>
// TODO(esprehn): exports should start as the empty object.
module.exports = {};
</script>
<sky-element name="state-header">
<template> <template>
<style> <style>
div { div {
@ -20,15 +26,15 @@
<div>{{ state }}</div> <div>{{ state }}</div>
</template> </template>
<script> <script>
SkyElement({ module.exports.StateHeaderElement = class extends SkyElement {
name: 'state-header',
set datum(datum) { set datum(datum) {
this.state = datum.state; this.state = datum.state;
} }
}); }.register();
</script> </script>
</sky-element>
<sky-element name="letter-header">
<template> <template>
<style> <style>
div { div {
@ -42,15 +48,15 @@ SkyElement({
<div>{{ letter }}</div> <div>{{ letter }}</div>
</template> </template>
<script> <script>
SkyElement({ module.exports.LetterHeaderElement = class extends SkyElement {
name: 'letter-header',
set datum(datum) { set datum(datum) {
this.letter = datum.letter; this.letter = datum.letter;
} }
}); }.register();
</script> </script>
</sky-element>
<sky-element name="city-item">
<template> <template>
<style> <style>
:host { :host {
@ -85,16 +91,16 @@ SkyElement({
</div> </div>
</template> </template>
<script> <script>
SkyElement({ module.exports.CityItemElement = class extends SkyElement {
name: 'city-item',
set datum(datum) { set datum(datum) {
this.name = datum.name; this.name = datum.name;
this.population = datum.population; this.population = datum.population;
} }
}); }.register();
</script> </script>
</sky-element>
<sky-element name="city-list">
<template> <template>
<style> <style>
@ -146,14 +152,12 @@ SkyElement({
} }
</style> </style>
<div id="scroller" fit> <div id="scroller" fit>
<div id="scrollarea"> <div id="scrollarea">
<div id="contentarea"> <div id="contentarea">
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
@ -540,16 +544,18 @@ SkyElement({
this.drawBottom = 0; this.drawBottom = 0;
} }
SkyElement({ module.exports.CityListElement = class extends SkyElement {
name: 'city-list',
loader: null,
scroller: null,
tiler: null,
date: null,
month: null,
views: null,
attached: function() { created() {
this.loader = null;
this.scroller = null;
this.tiler = null;
this.date = null;
this.month = null;
this.views = null;
}
attached() {
this.views = {}; this.views = {};
this.loader = new Loader(this); this.loader = new Loader(this);
this.scroller = new Scroller(); this.scroller = new Scroller();
@ -570,44 +576,43 @@ SkyElement({
self.domReady(); self.domReady();
self.loader.maybeLoadMoreData(self.dataLoaded); self.loader.maybeLoadMoreData(self.dataLoaded);
}); });
}, }
domReady: function() { domReady() {
this.scroller.setup(this.shadowRoot.getElementById('scroller'), this.scroller.setup(this.shadowRoot.getElementById('scroller'),
this.shadowRoot.getElementById('scrollarea'), this.shadowRoot.getElementById('scrollarea'),
this.shadowRoot.getElementById('contentarea')); this.shadowRoot.getElementById('contentarea'));
var scrollFrame = this.scroller.getCurrentFrame(); var scrollFrame = this.scroller.getCurrentFrame();
this.tiler.setupViews(scrollFrame); this.tiler.setupViews(scrollFrame);
}, }
updateView: function(data, scrollChanged) { updateView(data, scrollChanged) {
var scrollFrame = this.scroller.getCurrentFrame(); var scrollFrame = this.scroller.getCurrentFrame();
this.tiler.drawTiles(scrollFrame, data); this.tiler.drawTiles(scrollFrame, data);
var datum = scrollChanged ? var datum = scrollChanged ?
this.tiler.getFirstVisibleDatum(scrollFrame) : null; this.tiler.getFirstVisibleDatum(scrollFrame) : null;
this.loader.maybeLoadMoreData(this.dataLoaded, datum); this.loader.maybeLoadMoreData(this.dataLoaded, datum);
}, }
dataLoaded: function(data, indexOffset) { dataLoaded(data, indexOffset) {
var scrollFrame = this.scroller.getCurrentFrame(); var scrollFrame = this.scroller.getCurrentFrame();
this.tiler.updateFirstItem(indexOffset); this.tiler.updateFirstItem(indexOffset);
this.updateView(data.items, false); this.updateView(data.items, false);
}, }
handleScroll: function(event) { handleScroll(event) {
if (!this.scroller.captureNewFrame(event)) if (!this.scroller.captureNewFrame(event))
return; return;
this.updateView(this.loader.getItems(), true); this.updateView(this.loader.getItems(), true);
}, }
scrollBy: function(amount) { scrollBy(amount) {
this.scrollerElement.scrollTop += amount; this.scrollerElement.scrollTop += amount;
this.handleScroll({ target: this.scrollerElement }); this.handleScroll({ target: this.scrollerElement });
} }
}); }.register();
})(this); })(this);
</script> </script>
</sky-element>

View File

@ -6,6 +6,7 @@
<import src="../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../framework/sky-element/sky-element.sky" as="SkyElement" />
<import src="../framework/xmlhttprequest.sky" as="XMLHttpRequest" /> <import src="../framework/xmlhttprequest.sky" as="XMLHttpRequest" />
<sky-element name="file-browser">
<template> <template>
<style> <style>
heading { heading {
@ -21,12 +22,13 @@
</template> </template>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: 'file-browser', created() {
url: '', this.url = '';
files: [], this.files = [];
directories: [], this.directories = [];
attached: function() { }
attached() {
this.url = this.ownerDocument.URL; this.url = this.ownerDocument.URL;
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open('GET', this.url + '?format=json'); xhr.open('GET', this.url + '?format=json');
@ -37,5 +39,6 @@ SkyElement({
}).bind(this); }).bind(this);
xhr.send(); xhr.send();
} }
}); }.register();
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-header">
<template> <template>
<style> <style>
:host { :host {
@ -12,7 +14,7 @@
<content></content> <content></content>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-header" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-menu-button">
<template> <template>
<style> <style>
:host { :host {
@ -13,7 +15,7 @@
<content></content> <content></content>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-menu-button" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-panel-content">
<template> <template>
<style> <style>
:host { :host {
@ -8,7 +10,7 @@
<content></content> <content></content>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-panel-content" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-panel-header">
<template> <template>
<style> <style>
:host { :host {
@ -11,7 +13,7 @@
<content></content> <content></content>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-panel-header" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-panel">
<template> <template>
<style> <style>
:host { :host {
@ -10,7 +12,7 @@
<content></content> <content></content>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-panel" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-scrollable">
<template> <template>
<style> <style>
:host { :host {
@ -10,7 +12,7 @@
<content></content> <content></content>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-scrollable" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-search-input">
<template> <template>
<style> <style>
:host { :host {
@ -19,7 +21,7 @@
<span class="input-text"><t>flights today to dc by price</t></span> <span class="input-text"><t>flights today to dc by price</t></span>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-search-input" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-title">
<template> <template>
<style> <style>
:host { :host {
@ -12,7 +14,7 @@
<content></content> <content></content>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-title" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-toast">
<template> <template>
<style> <style>
:host { :host {
@ -30,7 +32,7 @@
</div> </div>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-toast" }.register();
});
</script> </script>
</sky-element>

View File

@ -1,4 +1,6 @@
<import src="../../framework/sky-element/sky-element.sky" as="SkyElement" /> <import src="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<sky-element name="app-toolbar">
<template> <template>
<style> <style>
:host { :host {
@ -9,7 +11,7 @@
<content></content> <content></content>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "app-toolbar" }.register();
});
</script> </script>
</sky-element>

View File

@ -10,6 +10,7 @@
<import src="app-scrollable.sky" /> <import src="app-scrollable.sky" />
<import src="app-toast.sky" /> <import src="app-toast.sky" />
<sky-element name="flights-app">
<template> <template>
<style> <style>
* { box-sizing: border-box; } * { box-sizing: border-box; }
@ -200,7 +201,7 @@
</app-toast> </app-toast>
</template> </template>
<script> <script>
SkyElement({ module.exports = class extends SkyElement {
name: "flights-app", }.register();
});
</script> </script>
</sky-element>

View File

@ -1,5 +1,5 @@
<sky> <sky>
<import src="flights-app.sky" /> <import src="flights-app.sky" as="FlightsAppElement"/>
<style> <style>
sky { sky {
height: 100%; height: 100%;
@ -8,8 +8,8 @@
<script> <script>
// TODO(esprehn): Work around a bug where having <flights-app /> in the // TODO(esprehn): Work around a bug where having <flights-app /> in the
// page doesn't render anything until the first input event. // page doesn't render anything until the first input event.
addEventListener("load", function() { window.addEventListener("load", function() {
document.querySelector("sky").appendChild(document.createElement("flights-app")); document.querySelector("sky").appendChild(new FlightsAppElement());
}); });
</script> </script>
</sky> </sky>