Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Last active December 16, 2019 08:15
Show Gist options
  • Select an option

  • Save WebReflection/c4b802bc61578e85436f6e58e61d2789 to your computer and use it in GitHub Desktop.

Select an option

Save WebReflection/c4b802bc61578e85436f6e58e61d2789 to your computer and use it in GitHub Desktop.
A basic hyperHTML + Firebase example. 100% client side.
<!doctype html>
<html lang="en">
<head>
<title>hyperHTML &amp; Firebase</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style>
html { font-family: sans-serif; }
html, body, ul, p { padding: 0; margin: 0; }
ul, li { list-style: none; }
body > p, li { padding: 8px; }
li:nth-child(2n + 1) { background-color: #eee; }
li > * { display: block; }
li > span:last-child { font-size: .9em; text-align: right; color: #666; }
li > a, li > span:first-child { font-size: 1.1em; font-weight: bold;
text-decoration: none; line-height: 32px; }
</style>
<!-- JS dependencies: hyperHTML and Firebase -->
<script src="https://unpkg.com/hyperhtml@latest/min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.2.0/firebase.js"></script>
</head>
<body></body>
<script>
(() => {
const {bind, wire} = hyperHTML;
// in this example, we are not going
// to relate any specific object to wires,
// so we can just use html`content`
const html = (...args) => wire()(...args);
// the Firebase DB
const db = firebase
.initializeApp({databaseURL: 'https://hacker-news.firebaseio.com'})
.database()
.ref( 'v0' );
// let's use the body as hyperHTML context to populate
bind(document.body)
`${{
// show an indication that something is happening
placeholder: {html: '<p>Loading ...</p>'},
// while downloading latest top stories
// and creating the list of all items
any: new Promise(resolve => {
db.child('topstories')
.on('value', snap => {
resolve(
// instead of "Loading ..."
// we want now to put a UL element
// and show all the received items
html`<ul>${mapItems(snap.val())}</ul>`
);
});
})
}}`;
function mapItems(items) {
// per each id we create an LI element
return items.map(
id => html`<li data-id=${id}>${loadItem(id)}</li>`
);
}
function loadItem(id) {
// per each LI we load asynchronously basic story info
return {
placeholder: `fetching ${id} ...`,
any: new Promise(resolve => {
db.child(`/item/${id}`)
.once('value', snap => {
const item = snap.val();
const hostname = item.hostname || item.url;
resolve(html`
${{any: hostname ?
// if there is an hostname/url to show
// put a link and a shortened hostname info
html`<a href=${item.url} target=_blank>${item.title}</a>
<small>
${new URL(hostname).hostname.replace(/^www\./, '')}
</small>`:
// otherwise just show the title
html`<span>${item.title}</span>`
}}
<!-- show some extra info -->
<span>${item.score} points by <b>${item.by}</b></span>`);
});
})
};
}
})();
</script>
</html>
@WebReflection
Copy link
Copy Markdown
Author

@albertosantini
Copy link
Copy Markdown

albertosantini commented Sep 10, 2017

If you are wondering, like me, about placeholder and any properties and how it works, you may see the async setup.

https://viperhtml.js.org/hyperhtml/documentation/#essentials-10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment