Skip to content

Instantly share code, notes, and snippets.

@akhilman
Last active May 4, 2020 16:35
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 akhilman/dba0dab68e8c8112ab2d446c7279261b to your computer and use it in GitHub Desktop.
Save akhilman/dba0dab68e8c8112ab2d446c7279261b to your computer and use it in GitHub Desktop.
code-block web component
import { LitElement, html, css, property, customElement } from "lit-element";
import { unsafeHTML } from "lit-html/directives/unsafe-html";
import * as hljs from "highlight.js";
@customElement("code-block")
export class CodeBlock extends LitElement {
@property() lang = "";
private contentUpdateObserver?: MutationObserver = undefined;
static get styles() {
return css`
@import "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.2/styles/github.min.css";
pre {
background-color: #f6f8fa;
border-radius: 3px;
padding: 16px;
marging: 0;
overflow: auto;
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;
font-size: 85%;
line-height: 1.45;
}
pre code {
font-family: inherit;
}
`;
}
render() {
const code = decodeHtml(this.innerHTML);
const highlightedCode = highlightCode(code, this.lang);
return html`
<pre><code>${unsafeHTML(highlightedCode)}</code></pre>
`;
}
connectedCallback() {
super.connectedCallback();
// Attach an observer to detect code change
const target = this;
const observer = new MutationObserver(() => target.requestUpdate());
observer.observe(this, {
characterData: true,
childList: true,
subtree: true
});
this.contentUpdateObserver = observer;
}
disconnectedCallback() {
super.disconnectedCallback();
if (this.contentUpdateObserver) {
this.contentUpdateObserver.disconnect();
}
}
}
function decodeHtml(html: string): string {
return new DOMParser().parseFromString(html, "text/html").documentElement
.textContent!;
}
function highlightCode(code: string, lang: string): string {
// https://highlightjs.readthedocs.io/en/latest/api.html#highlightauto-value-languagesubset
return hljs.highlightAuto(code, lang ? [lang] : undefined).value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment