Skip to content

Instantly share code, notes, and snippets.

@dogoku
Last active August 6, 2022 23:20
Show Gist options
  • Save dogoku/c2881a6585eed158ad2bc6e934a907df to your computer and use it in GitHub Desktop.
Save dogoku/c2881a6585eed158ad2bc6e934a907df to your computer and use it in GitHub Desktop.
Helper functions that simplify compiling and running stencil source code in the browser
function loadStencilCompiler(doc = document) {
const s = doc.createElement('script');
// loading from jsdelivr because skypack is not converting this file correctly
s.src = 'https://cdn.jsdelivr.net/npm/@stencil/core@latest/compiler/stencil.min.js';
return new Promise((resolve, reject) => {
s.onload = () => resolve(window.stencil.transpile);
s.onerror = reject;
doc.body.appendChild(s);
});
}
// auto inject the h import, to reduce boilerplace required in source
const h = "import { h } from 'https://cdn.skypack.dev/@stencil/core';\n"
export async function compileStencil(source, doc = document) {
if (!source) { throw new Error('no source code provided to compile') }
// async load the stencil compiler and get the transpile function
const transpile = await loadStencilCompiler(doc);
// transpile source and grab code from result
const { code } = await transpile(h + source, { sourceMap: false });
// replace import url with one the browser can resolve
return code.replace('@stencil/core/internal/client', 'https://cdn.skypack.dev/@stencil/core/internal/client');
}
export async function runStencil(source, doc = document) {
if (!source) { throw new Error('no source code provided to compile') }
// async load the stencil compiler and get the transpile function
const code = await compileStencil(source, doc);
// make a script tag of type module and set script tag's content to the transpiled code
const s = doc.createElement('script');
s.type = 'module';
s.innerHTML = code
// append script tag to execute transpiled code
doc.body.appendChild(s);
}
export async function parseFromHTML(selector, doc = document) {
let list = [];
if (typeof selector === 'string') {
list = doc.querySelectorAll(selector)
} else if (selector.innerHTML) {
list = [selector]
} else if (list.forEach) {
list= selector;
}
list.forEach(el => runStencil(el.textContent, doc));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment