@whop/embedded-components-vanilla-js
Version:
Whop Elements loading utility
98 lines (97 loc) • 3.22 kB
JavaScript
import { ORIGIN, SCRIPT_URL } from "./url.mjs";
const isWhopElementsScriptURL = (url)=>{
const result = url.startsWith(ORIGIN) && url.endsWith("/elements.js");
return result;
};
const findScript = ()=>{
const scripts = document.querySelectorAll(`script[src^="${ORIGIN}"]`);
for (const script of scripts){
if (!script || !isWhopElementsScriptURL(script.src)) {
continue;
}
return script;
}
return null;
};
const injectScript = ()=>{
const script = document.createElement("script");
script.src = SCRIPT_URL;
const headOrBody = document.head || document.body;
if (!headOrBody) {
throw new Error("Expected document.body not to be null. WhopElements requires a <body> element.");
}
headOrBody.appendChild(script);
return script;
};
let whopElementsPromise = null;
let onErrorListener = null;
let onLoadListener = null;
const onError = (reject)=>(cause)=>{
reject(new Error("Failed to load WhopElements", {
cause
}));
};
const onLoad = (resolve, reject)=>()=>{
if (window.WhopElements) {
resolve(window.WhopElements);
} else {
reject(new Error("WhopElements not available"));
}
};
const loadScript = ()=>{
if (whopElementsPromise !== null) {
return whopElementsPromise;
}
whopElementsPromise = new Promise((resolve, reject)=>{
if (typeof window === "undefined" || typeof document === "undefined") {
resolve(null);
return;
}
if (window.WhopElements) {
resolve(window.WhopElements);
return;
}
try {
let script = findScript();
if (!script) {
script = injectScript();
} else if (script && onLoadListener !== null && onErrorListener !== null) {
script.removeEventListener("load", onLoadListener);
script.removeEventListener("error", onErrorListener);
script.parentNode?.removeChild(script);
script = injectScript();
}
onLoadListener = onLoad(resolve, reject);
onErrorListener = onError(reject);
script.addEventListener("load", onLoadListener);
script.addEventListener("error", onErrorListener);
} catch (error) {
if (error instanceof Error) {
reject(error);
} else {
reject(new Error("Failed to load WhopElements", {
cause: error
}));
}
return;
}
});
return whopElementsPromise.catch((error)=>{
whopElementsPromise = null;
if (error instanceof Error) {
return Promise.reject(error);
} else {
return Promise.reject(new Error("Failed to load WhopElements", {
cause: error
}));
}
});
};
const initWhopElements = (maybeWhopElements, args)=>{
if (maybeWhopElements === null) {
return null;
}
const WhopElements = maybeWhopElements;
return new WhopElements(...args);
};
export { findScript, initWhopElements, loadScript };