Skip to content

Commit fb6dcb4

Browse files
committed
docs: patch html-includes if needed
See justinfagnani/html-include-element#21
1 parent d8418f1 commit fb6dcb4

File tree

2 files changed

+87
-3
lines changed

2 files changed

+87
-3
lines changed

docs/demo/demo.ts

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,88 @@
1-
import 'html-include-element';
1+
import { HTMLIncludeElement } from 'html-include-element';
2+
3+
/* eslint-disable no-console */
4+
/**
5+
* quick hack to avoid page load errors if subresources are missing from demo files
6+
* @see https://github.com/justinfagnani/html-include-element/pull/21
7+
*/
8+
if (!HTMLIncludeElement.prototype.attributeChangedCallback.toString().includes('await Promise.all([...this.shadowRoot.querySelectorAll')) {
9+
console.info('No need to patch <html-include>');
10+
} else {
11+
console.info('Patching <html-include>');
12+
const isLinkAlreadyLoaded = (link: HTMLLinkElement) => {
13+
try {
14+
return !!(link.sheet && link.sheet.cssRules);
15+
} catch (error) {
16+
if (error.name === 'InvalidAccessError' || error.name === 'SecurityError') {
17+
return false;
18+
} else {
19+
throw error;
20+
}
21+
}
22+
};
23+
24+
const linkLoaded = async function linkLoaded(link: HTMLLinkElement) {
25+
return new Promise((resolve, reject) => {
26+
if (!('onload' in HTMLLinkElement.prototype)) {
27+
resolve(null);
28+
} else if (isLinkAlreadyLoaded(link)) {
29+
resolve(link.sheet);
30+
} else {
31+
link.addEventListener('load', () => resolve(link.sheet), { once: true });
32+
link.addEventListener('error', () => reject({ link }), { once: true });
33+
}
34+
});
35+
};
36+
37+
HTMLIncludeElement.prototype.attributeChangedCallback = async function attributeChangedCallback(name: string, _: string, newValue: string) {
38+
if (name === 'src') {
39+
let text = '';
40+
try {
41+
const mode = this.mode || 'cors';
42+
const response = await fetch(newValue, { mode });
43+
if (!response.ok) {
44+
throw new Error(`html-include fetch failed: ${response.statusText}`);
45+
}
46+
text = await response.text();
47+
if (this.src !== newValue) {
48+
// the src attribute was changed before we got the response, so bail
49+
return;
50+
}
51+
} catch (e) {
52+
console.error(e);
53+
}
54+
// Don't destroy the light DOM if we're using shadow DOM, so that slotted content is respected
55+
if (this.noShadow) {
56+
this.innerHTML = text;
57+
}
58+
this.shadowRoot.innerHTML = `
59+
<style>
60+
:host {
61+
display: block;
62+
}
63+
</style>
64+
${this.noShadow ? '<slot></slot>' : text}
65+
`;
66+
67+
// If we're not using shadow DOM, then the consuming root
68+
// is responsible to load its own resources
69+
if (!this.noShadow) {
70+
const results = await Promise.allSettled([...this.shadowRoot.querySelectorAll('link')].map(linkLoaded));
71+
for (const result of results) {
72+
if (result.status === 'rejected') {
73+
const { link } = result.reason;
74+
const message = `Could not load ${link.href}`;
75+
console.error(message);
76+
}
77+
}
78+
}
79+
80+
this.dispatchEvent(new Event('load'));
81+
}
82+
};
83+
}
84+
/* eslint-enable no-console */
85+
286
import 'api-viewer-element';
387
import '@vaadin/split-layout';
488

elements/pfe-jump-links/demo/pfe-jump-links.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { installRouter } from 'pwa-helpers/router.js';
1010
* @this {HTMLElement}
1111
*/
1212
async function route(location = window.location, event) {
13-
event.preventDefault();
14-
event.stopPropagating();
13+
event?.preventDefault();
14+
event?.stopPropagating();
1515
if (location.hash) {
1616
root?.querySelector(location.hash)?.scrollIntoView({ behavior: 'smooth' });
1717
}

0 commit comments

Comments
 (0)