Skip to content

Commit

Permalink
html tag function for generating templates
Browse files Browse the repository at this point in the history
Fixes #4937
  • Loading branch information
dfreedm committed Dec 4, 2017
1 parent 1fbb504 commit 1bba3ab
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 0 deletions.
61 changes: 61 additions & 0 deletions lib/utils/html-fn.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="boot.html">
<script>
(function() {
'use strict';

/**
* @param {*} value Object to stringify into HTML
* @return {string} HTML stringified form of `obj`
*/
function htmlValue(value) {
if (value instanceof HTMLElement) {
return /** @type {!HTMLElement} */(value).innerHTML;
} else if (value instanceof Node) {
return /** @type {!Node} */(value).textContent;
} else {
return value.toString();
}
}

/**
* Small tagged template string function to facilitate building a `<template>` element.
* Polymer.html will automatically compose HTML elements in `${}` blocks, allowing for easy
* composition of superclass templates, or partial templates.
*
* Example:
*
* static get template() {
* return Polymer.html`
* <style>:host{ content:"..." }</style>
* <div class="shadowed">${this.partialTemplate}</div>
* ${super.template}
* `;
* }
* static get partialTemplate() { return Polymer.html`<span>Partial!</span>`; }
*
* @memberof Polymer
* @param {!Array<string>} strings Constant parts of tagged template literal
* @param {!Array<*>} values Variable parts of tagged template literal
* @return {!HTMLTemplateElement} Constructed HTMLTemplateElement
*/
Polymer.html = function html(strings, ...values) {
/** @type {!Array<string>} */
const parts = [strings[0]];
const template = /** @type {!HTMLTemplateElement} */(document.createElement('template'));
for (let i = 0; i < values.length; i++) {
parts.push(htmlValue(values[i]), strings[i + 1]);
}
template.innerHTML = parts.join('');
return template;
};
})();
</script>
54 changes: 54 additions & 0 deletions test/smoke/html-fn.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<!DOCTYPE html>
<html>
<head>
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../../polymer-element.html">
<link rel="import" href="../../lib/utils/html-fn.html">
</head>
<body>
<script>
const html = Polymer.html;
class SuperClass extends Polymer.Element {
static get is() {return 'super-class';}
static get template() {
return html`
<style>#name {color: red}</style>
<h3 id="name">${this.is}</h3>
<div>${this.headerTemplate}</div>
[[myProp.stuffThatGoesHere]]
<div>${this.footerTemplate}</div>
`;
}
static get headerTemplate() { return html`<h1>Header</h1>`; }
static get footerTemplate() { return html`<h1>Footer</h1>`; }
}
customElements.define(SuperClass.is, SuperClass);
class SubClass extends SuperClass {
static get is() {return 'sub-class';}
static get template() {
return html`
<style>.frame {font-style: italic}</style>
<div class="frame">${super.template}</div>
`;
}
constructor() {
super();
this.myProp = {stuffThatGoesHere: '!stuff that goes here!'};
}
static get headerTemplate() { return html`<h2>Sub-header</h2>`; }
static get footerTemplate() { return html`<h2>Sub-footer</h2>`; }
}
customElements.define(SubClass.is, SubClass);
</script>
<super-class></super-class>
<sub-class></sub-class>
</body>

0 comments on commit 1bba3ab

Please sign in to comment.