Track HiveGrid Cloud planning reference
This commit is contained in:
1 parent
b3d5ea6764
commit
e341c5938a
5784 files changed
+1104929
-3
No files matched your search
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Form-Widget bootstrap loader (Phase 05 Task #58).
|
||||
*
|
||||
* Tenants embed this on their site with:
|
||||
*
|
||||
* <script src="https://<host>/embed/widget.js" data-form-key="abc123"
|
||||
* data-host="https://forms.example.com"
|
||||
* async></script>
|
||||
*
|
||||
* The loader:
|
||||
* 1. Reads `data-form-key` and optional `data-host` from its own <script> tag.
|
||||
* 2. Inserts a sandboxed <iframe> pointing at `<host>/embed/forms/<formKey>`.
|
||||
* 3. Listens for postMessage events from the iframe:
|
||||
* - `tcform:resize` -> updates iframe height for dynamic content
|
||||
* - `tcform:submitted` / `tcform:error` -> re-emits as
|
||||
* CustomEvents on document for parent-site code to listen on.
|
||||
*
|
||||
* Build-target: hand-crafted minified ES5-compatible JS in
|
||||
* `apps/web/public/embed/widget.js`. This file is the readable source
|
||||
* kept for documentation + tests. Keep both in sync.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
if (typeof window === "undefined" || typeof document === "undefined") return;
|
||||
const script = (document.currentScript as HTMLScriptElement | null) ?? findSelf();
|
||||
if (!script) return;
|
||||
|
||||
const formKey = script.getAttribute("data-form-key");
|
||||
if (!formKey) return;
|
||||
|
||||
const explicitHost = script.getAttribute("data-host");
|
||||
const defaultHost = new URL(script.src).origin;
|
||||
const host = explicitHost ?? defaultHost;
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = host + "/embed/forms/" + encodeURIComponent(formKey) + "?origin=" + encodeURIComponent(location.origin);
|
||||
iframe.setAttribute("title", "Form");
|
||||
iframe.setAttribute("loading", "lazy");
|
||||
iframe.setAttribute("sandbox", "allow-scripts allow-forms allow-same-origin");
|
||||
iframe.style.cssText = "border:0;width:100%;min-height:200px;max-width:100%;display:block";
|
||||
|
||||
const parent = script.parentNode;
|
||||
if (!parent) return;
|
||||
parent.insertBefore(iframe, script.nextSibling);
|
||||
|
||||
window.addEventListener("message", (event) => {
|
||||
if (event.source !== iframe.contentWindow) return;
|
||||
const data = event.data;
|
||||
if (!data || typeof data !== "object" || typeof data.type !== "string") return;
|
||||
if (data.type === "tcform:resize" && typeof data.height === "number") {
|
||||
iframe.style.height = Math.max(100, Math.min(8000, data.height)) + "px";
|
||||
return;
|
||||
}
|
||||
if (data.type === "tcform:submitted" || data.type === "tcform:error") {
|
||||
document.dispatchEvent(new CustomEvent(data.type, { detail: data }));
|
||||
}
|
||||
});
|
||||
|
||||
function findSelf(): HTMLScriptElement | null {
|
||||
const scripts = document.getElementsByTagName("script");
|
||||
for (let i = scripts.length - 1; i >= 0; i--) {
|
||||
const s = scripts[i];
|
||||
if (s.src && s.src.indexOf("/embed/widget.js") !== -1) return s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
Reference in new issue
Block a user