Skip to content

Instantly share code, notes, and snippets.

@eddieantonio
Last active June 8, 2020 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eddieantonio/07f7c1d11bbeffc2c85d372e925a9fc5 to your computer and use it in GitHub Desktop.
Save eddieantonio/07f7c1d11bbeffc2c85d372e925a9fc5 to your computer and use it in GitHub Desktop.
/*!
* Copyright (c) 2020 Eddie Antonio Santos
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/.
*/
/**
* Simplifies interaction with <template> tags:
*
* Access the innerText of all <slot>s as properties of the template tag.
*
* <template id="template:hello">
* <h1> <slot name="salutation">Hello</slot>, <slot name="recipient">World</slot>!</h1>
* </template>
*
* <body>
* </body>
*
* <script>
* let greeting = SmartTemplate.fromId('template:hello')
* greeting.salutation = 'Goodbye'
* greeting.recipient = 'cruel world'
* greeting.appendTo(document.body)
* </script>
*/
export default class SmartTemplate {
constructor(element) {
this._el = element.content.firstElementChild.cloneNode(true)
// Create getters and setters for each slot
for (let slot of this._el.querySelectorAll('slot[name]')) {
createGettersAndSetters(this, slot)
}
}
set recipient(newText) {
return this._el.querySelector('slot[name=recipient]').innerText = newText
}
static fromId(id) {
let element = document.getElementById(id)
if (element == null)
throw new Error(`Could not find element with id="${id}"`)
return new SmartTemplate(element)
}
appendTo(element) {
element.appendChild(this._el)
return this;
}
}
function createGettersAndSetters(obj, slot) {
return Object.defineProperty(obj, slot.name, {
get: () => slot.innerText,
set: (newValue) => slot.innerText = newValue
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment