Skip to content

Instantly share code, notes, and snippets.

@shgysk8zer0
Last active December 2, 2021 00: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 shgysk8zer0/ea40deafd59d7e9f451457f0d0319580 to your computer and use it in GitHub Desktop.
Save shgysk8zer0/ea40deafd59d7e9f451457f0d0319580 to your computer and use it in GitHub Desktop.
A demo of <github-gist> usage (See https://codepen.io/shgysk8zer0/full/jOGEJRj)
const protectedData = new WeakMap();
function render(target) {
const { user, gist, file, height, width } = target;
const { shadow } = protectedData.get(target);
const iframe = document.createElement('iframe');
const script = document.createElement('script');
const link = document.createElement('link');
const src = new URL(`/${user}/${gist}.js`, 'https://gist.github.com');
const controller = new AbortController();
link.rel = 'preconnect';
link.href = 'https://github.githubassets.com';
iframe.addEventListener('load', () => {
target.dispatchEvent(new Event('load'));
controller.abort();
}, {
signal: controller.signal,
once: true,
});
iframe.addEventListener('error', () => {
target.dispatchEvent(new Event('error'));
controller.abort();
}, {
signal: controller.signal,
once: true,
});
if (typeof file === 'string' && file.length !== 0) {
src.searchParams.set('file', file);
}
script.src = src.href;
iframe.referrerPolicy = 'no-referrer';
iframe.sandbox.add('allow-scripts');
iframe.frameBorder = 0;
if (! Number.isNaN(width)) {
iframe.width = width;
}
if (! Number.isNaN(height)) {
iframe.height = height;
}
if ('part' in iframe) {
iframe.part.add('embed');
}
iframe.srcdoc = `<!DOCTYPE html><head>${link.outerHTML}</head><html><body>${script.outerHTML}</body></html>`;
shadow.append(iframe);
}
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(({ target, isIntersecting }) => {
if (isIntersecting && protectedData.has(target)) {
observer.unobserve(target);
render(target);
protectedData.delete(target);
}
});
}, {
rootMargin: `${Math.round(0.5 * screen.height)}px`,
root: document.body,
});
customElements.define('github-gist', class HTMLGitHubGistElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
protectedData.set(this, { shadow });
}
connectedCallback() {
switch(this.loading) {
case 'lazy':
observer.observe(this);
break;
default:
render(this);
}
}
get file() {
return this.getAttribute('file');
}
set file(val) {
if (typeof val === 'string' && val.length !== 0) {
this.setAttribute('file', val);
} else {
this.removeAtttribute('file');
}
}
get gist() {
return this.getAttribute('gist');
}
set gist(val) {
if (typeof val === 'string' && val.length !== 0) {
this.setAttribute('gist', val);
} else {
this.removeAtttribute('gist');
}
}
get height() {
return parseInt(this.getAttribute('height'));
}
set height(val) {
if (Number.isSafeInteger(val) && val > 0) {
this.setAttribute('height', val);
} else {
this.removeAttribute('height');
}
}
get loading() {
return this.getAttribute('loading') || 'eager';
}
set loading(val) {
if (typeof val === 'string' && val.length !== 0) {
this.setAttribute('loading', val);
} else {
this.removeAttribute('val');
}
}
get user() {
return this.getAttribute('user');
}
set user(val) {
if (typeof val === 'string' && val.length !== 0) {
this.setAttribute('user', val);
} else {
this.removeAtttribute('user');
}
}
get width() {
return parseInt(this.getAttribute('width'));
}
set width(val) {
if (Number.isSafeInteger(val) && val > 0) {
this.setAttribute('width', val);
} else {
this.removeAttribute('width');
}
}
});
<script src="https://cdn.kernvalley.us/components/github/gist.js" crossorigin="anonymous" referrerpolicy="no-referrer" defer=""></script>
<script type="module" src="https://cdn.kernvalley.us/components/github/user.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<style>
github-gist::part(embed) {
max-width: 900px;
margin-left: max(10px, calc(50% - 450px));
margin-top: 20px;
width: calc(100% - 20px);
height: 400px;
}
</style>
<header>
<h1><code>&lt;github-gist&gt;</code> demo</h1>
</header>
<main>
<noscript>This demo requires JavaScript</noscript>
<blockquote>A demo of <code>&lt;github-gist&gt;</code> usage</blockquote>
<p>Here is a <a href="https://gist.github.com/shgysk8zer0/ea40deafd59d7e9f451457f0d0319580" rel="noopener noreferrer external">Gist</a> of all the code used to create this <a href="https://codepen.io/shgysk8zer0/full/jOGEJRj" rel="noopener noreferrer external">Pen.</a></p>
<h2>The HTML</h2>
<github-gist class="embed-html" user="shgysk8zer0" gist="ea40deafd59d7e9f451457f0d0319580" file="index.html" loading="lazy" width="900" height="400">
<p>Your browser does not support <code>customElements.define()</code>, which is required for this demo.</p>
</github-gist>
<h2>The JavaScript</h2>
<github-gist class="embed-js" user="shgysk8zer0" gist="ea40deafd59d7e9f451457f0d0319580" file="gist.js" loading="lazy" width="900" height="400">
</main>
<footer>
<hr />
<b>By:</b><br />
<github-user user="shgysk8zer0" loading="lazy"></github-user>
<github-user user="kernvalley" loading="lazy"></github-user>
</footer>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment