Skip to content

Instantly share code, notes, and snippets.

@simonw
Created October 21, 2019 18:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simonw/dec4bec9ec6041c053bc0466f1203da1 to your computer and use it in GitHub Desktop.
Save simonw/dec4bec9ec6041c053bc0466f1203da1 to your computer and use it in GitHub Desktop.
An autoescaping JavaScript template tagged literal
class Safe extends String {}
function safe(s) {
if (!(s instanceof Safe)) {
return new Safe(s);
} else {
return s;
}
}
function htmlEscape(html) {
return html.replace(
/&/g, '&'
).replace(
/>/g, '>'
).replace(
/</g, '&lt;'
).replace(
/"/g, '&quot;'
).replace(
/'/g, '&#039;'
);
}
var autoescape = (fragments, ...inserts) => safe(fragments.map(
(fragment, i) => {
var bit = fragment;
var insert = (inserts[i] || '');
if (!(insert instanceof Safe)) {
insert = htmlEscape(insert.toString());
}
return fragment + insert;
}
).join(''));
function renderResults(docs) {
var html = docs.map(doc => autoescape`
<div class="result">
<h2><a href="${doc.url}">${doc.title}</a></h2>
<div class="result-body">
<p>${doc.summary}...</p>
<p>Updated ${formatTimestamp(doc.updated)} by ${doc.updated_by} (${doc.format}) ${doc.source_url ? safe(`<a href="${doc.source_url}">source</a>`): ''}</p>
</div>
</div>`).join("");
document.getElementById("content").innerHTML = html;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment