Last active
August 29, 2023 13:25
-
-
Save edjw/a552c59b2aa6b58914203074d184287b to your computer and use it in GitHub Desktop.
load-github-gists
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
/** | |
* A script to fetch and apply JS and CSS from GitHub gists and GitLab snippets. | |
* Use with the Gistpad extension in VS Code for easy updating: | |
* https://marketplace.visualstudio.com/items?itemName=vsls-contrib.gistfs | |
* | |
* Note: For GitLab, it's likely the content fetch will fail due to CORS restrictions. | |
* With GitHub, rate limiting can be strict unless the gist is public. | |
* | |
* For html gists, specify the target using the html selector of an element on your page. | |
* Then optionally use on of these placement options. If you don't specify one, beforeend will be used | |
* "beforebegin": Before the element itself. | |
* "afterbegin": Just inside the element, before its first child. | |
* "beforeend": Just inside the element, after its last child (default). | |
* "afterend": After the element itself. | |
* | |
* const resources = [ | |
{ url: "https://gist.github.com/edjw/3b87206bd180598c1c715aff0bf79058", type: 'js' }, | |
{ url: "https://gist.github.com/edjw/0899714f1b44129932c59d968899b0e6", type: 'css' }, | |
{ url: "https://gist.github.com/edjw/07bd385fdd8d01d2e9c38bc5bf602526", type: 'html', target: 'a css selector for a html element' placement: "afterbegin"}, | |
{ url: "https://gist.github.com/edjw/07bd385fdd8d01d2e9c38bc5bf602526", type: 'html', target: 'a css selector for a html element'} | |
]; | |
*/ | |
(async function () { | |
const resources = [ | |
// { url: "https://gist.github.com/edjw/0899714f1b44129932c59d968899b0e6", type: "css" }, | |
// { url: "https://gist.github.com/edjw/3b87206bd180598c1c715aff0bf79058", type: 'js' }, | |
// // { url: "https://gist.github.com/edjw/07bd385fdd8d01d2e9c38bc5bf602526", type: 'html', target: "", placement: "afterbegin" } | |
]; | |
const defaultISTMainBodySelector = `article.node > div.content > div.field > div.field-items > div.field-item`; | |
async function applyGitHubGist(gistId, type, target, placement) { | |
try { | |
if (!['js', 'css', 'html'].includes(type)) { | |
console.error(`Unknown resource type: ${type}`); | |
return; | |
} | |
if (type === 'html') { | |
const targetElement = document.querySelector(target || defaultISTMainBodySelector); | |
if (!targetElement) { | |
console.error(`Target element not found in the DOM for selector: ${target || defaultISTMainBodySelector}`); | |
return; | |
} | |
const placements = ["beforebegin", "afterbegin", "beforeend", "afterend"]; | |
if (!placements.includes(placement)) { | |
console.error(`Invalid placement value: ${placement}`); | |
return; | |
} | |
} | |
const response = await fetch(`https://api.github.com/gists/${gistId}`); | |
if (!response.ok) { | |
console.error(`Error fetching GitHub gist ${gistId}: ${response.statusText}`); | |
return; | |
} | |
const data = await response.json(); | |
if (!data.files || Object.keys(data.files).length === 0) { | |
console.error('No files found in gist response.'); | |
return; | |
} | |
const fileContent = data.files[Object.keys(data.files)[0]].content; | |
if (type === 'js') { | |
eval(fileContent); | |
return; | |
} | |
if (type === 'css') { | |
const styleElem = document.createElement('style'); | |
styleElem.textContent = fileContent; | |
document.head.appendChild(styleElem); | |
return; | |
} | |
if (type === 'html') { | |
const targetElement = document.querySelector(target || defaultISTMainBodySelector); | |
targetElement.insertAdjacentHTML(placement || 'beforeend', fileContent); | |
} | |
} catch (error) { | |
console.error(`Error processing GitHub gist ${gistId}:`, error); | |
} | |
} | |
async function processResources(resources) { | |
const validTypes = ['js', 'css', 'html']; | |
for (const resource of resources) { | |
try { | |
const { type, target, placement, url } = resource; | |
console.log(`Processing ${type} URL: `, url); | |
const parsedURL = new URL(url); | |
if (parsedURL.hostname !== "gist.github.com") { | |
console.error(`URL not from GitHub: ${url}`); | |
continue; | |
} | |
const gistId = parsedURL.pathname.split('/').pop(); | |
if (!gistId) { | |
console.error(`Failed to extract gistId from URL: ${url}`); | |
continue; | |
} | |
if (!type) { | |
console.error(`Resource type is missing for URL: ${url}. Skipping resource.`); | |
continue; | |
} | |
if (!validTypes.includes(type)) { | |
console.error(`Invalid resource type: ${type}. Skipping resource.`); | |
continue; | |
} | |
if (type === 'html') { | |
const effectiveTarget = target || defaultISTMainBodySelector; | |
if (typeof effectiveTarget !== 'string' || !document.querySelector(effectiveTarget)) { | |
console.error(`Invalid or missing target for HTML resource URL: ${url}. Skipping resource.`); | |
continue; | |
} | |
if (placement && !["beforebegin", "afterbegin", "beforeend", "afterend"].includes(placement)) { | |
console.error(`Invalid placement value for HTML resource URL: ${url}. Skipping resource.`); | |
continue; | |
} | |
} | |
await applyGitHubGist(gistId, type, target, placement); | |
} catch (error) { | |
console.error(`Invalid URL: ${resource.url}`); | |
continue; | |
} | |
} | |
} | |
if (document.readyState === 'loading') { | |
document.addEventListener('DOMContentLoaded', () => processResources(resources)); | |
} else { | |
await processResources(resources); | |
} | |
})(); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment