Skip to content

Commit

Permalink
feat: script support
Browse files Browse the repository at this point in the history
  • Loading branch information
infodusha committed Aug 24, 2023
1 parent 0b1129d commit 9b47052
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ So later you can use include your template with:
# TODO

* Watch for attribute changes (from js)
* Extended script support
* Full style encapsulation (when not a shadow root mode)
* Full slot support

Expand Down
4 changes: 4 additions & 0 deletions example/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@
padding: 1rem;
}
</style>

<script>
console.log(this);
</script>
56 changes: 53 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ document.addEventListener('DOMContentLoaded', () => {

async function fetchFromLinks(element) {
const links = Array.from(element.querySelectorAll(`link[rel='preload'][as='fetch'][href$='.html']:not([${ignoreDataAttribute}])`));
await Promise.all(links.map(defineHtml));
await Promise.all(links.map((link) => link.getAttribute('href')).map(defineHtml));
}

async function defineHtml(link) {
const href = link.getAttribute('href');
async function defineHtml(href) {
const response = await fetch(href);
const text = await response.text();
const definedElement = parser.parseFromString(text, 'text/html');
Expand All @@ -23,6 +22,7 @@ function createCustomElement(definedElement) {
const useShadow = template.hasAttribute('data-shadow');
const selector = template.getAttribute('data-selector');
const styles = definedElement.querySelectorAll('style');
const scripts = definedElement.querySelectorAll('script');

function setEmulatedStyles() {
for (const style of styles) {
Expand Down Expand Up @@ -61,6 +61,7 @@ function createCustomElement(definedElement) {
if (useShadow) {
this.#setShadowStyles();
}
this.#execScripts();
}

#getContent() {
Expand Down Expand Up @@ -115,7 +116,56 @@ function createCustomElement(definedElement) {
this.shadowRoot.appendChild(element);
}
}

#execScripts() {
for (const script of scripts) {
if (script.getAttribute('type') === 'module') {
const url = URL.createObjectURL(new Blob([script.innerText], {type: 'text/javascript'}));
import(url).then(() => URL.revokeObjectURL(url)).catch(console.error);
} else {
const code = Function(script.innerText);
try {
code.call(this);
} catch (e) {
const stack = ErrorStackModifier.fromError(e);
const currentPlaceStackLength = ErrorStackModifier.current().items.length;
const cutSize = currentPlaceStackLength - 2;
const newStack = new ErrorStackModifier(stack.items.slice(0, -cutSize));
newStack.applyToRow((r) => r.replace('DefineHTMLElement.eval', selector));
console.error(newStack.toString());
}
}
}
}
}

customElements.define(selector, DefineHTMLElement);
}

class ErrorStackModifier {
static current() {
return ErrorStackModifier.fromError(new Error());
}

static fromError(e) {
return new ErrorStackModifier(e.stack.split('\n'));
}

#items;

get items() {
return this.#items.slice();
}

constructor(items) {
this.#items = items.slice();
}

applyToRow(fn) {
this.#items = this.#items.map(fn);
}

toString() {
return this.#items.join('\n');
}
}

0 comments on commit 9b47052

Please sign in to comment.