@@ -322,62 +322,57 @@ function embed_script(cfg::AnythingLLMConfig, embed_uuid::String; embed_options=
322322 [" $(k) =\" $(escape_attr (v)) \" " for (k, v) in attrs],
323323 " \n " ,
324324 )
325- return string (
326- """
325+ return string ("""
327326<script>
328- // Render the AnythingLLM embed inside a sandboxed iframe to avoid clashing with Documenter and require.js.
327+ // Render the AnythingLLM embed inside an isolated shadow DOM to avoid clashes with Documenter/ require.js.
329328(function() {
330- const injectEmbed = () => {
331- if (document.getElementById("anythingllm-embed-frame")) return;
332-
333- const iframe = document.createElement("iframe");
334- iframe.id = "anythingllm-embed-frame";
335- iframe.title = "AnythingLLM chat";
336- iframe.style.position = "fixed";
337- iframe.style.bottom = "0";
338- iframe.style.right = "0";
339- iframe.style.width = "80px";
340- iframe.style.height = "80px";
341- iframe.style.maxWidth = "min(90vw, 80px)";
342- iframe.style.maxHeight = "min(90vh, 80px)";
343- iframe.style.border = "none";
344- iframe.style.zIndex = "2147483000";
345- iframe.style.background = "transparent";
346- iframe.sandbox = "allow-same-origin allow-scripts allow-popups allow-forms allow-modals";
347- iframe.loading = "lazy";
348-
349- const html = `
350- <!doctype html>
351- <html>
352- <head>
353- <style>
354- html, body { margin: 0; padding: 0; overflow: hidden; background: transparent; }
355- </style>
356- </head>
357- <body>
358- <script
359- """ ,
360- attr_lines,
329+ const hostId = "anythingllm-embed-shadow-host";
330+ if (document.getElementById(hostId)) return;
331+
332+ const host = document.createElement("div");
333+ host.id = hostId;
334+ host.style.position = "fixed";
335+ host.style.bottom = "0";
336+ host.style.right = "0";
337+ host.style.zIndex = "2147483000";
338+ host.style.pointerEvents = "none"; // allow clicks only through the shadow content
339+ document.body.appendChild(host);
340+
341+ const shadow = host.attachShadow({ mode: "open" });
342+
343+ const style = document.createElement("style");
344+ style.textContent = `
345+ :host { all: initial; }
346+ .anythingllm-shell {
347+ position: relative;
348+ width: min(90vw, 440px);
349+ height: min(90vh, 720px);
350+ pointer-events: none;
351+ }
352+ .anythingllm-shell > * {
353+ pointer-events: auto;
354+ }
355+ `;
356+ shadow.appendChild(style);
357+
358+ const shell = document.createElement("div");
359+ shell.className = "anythingllm-shell";
360+ shadow.appendChild(shell);
361+
362+ const script = document.createElement("script");
363+ """ )
364+ *
365+ join ([" script.setAttribute(\" $(escape_attr (k)) \" , \" $(escape_attr (v)) \" );" for (k, v) in attrs], " \n " )
366+ *
361367 """
362- src=""" ,
363- script_src,
364- """ >
365- <\\ /script>
366- </body>
367- </html>`;
368- iframe.srcdoc = html;
369- document.body.appendChild(iframe);
370- };
371-
372- if (document.readyState === "complete" || document.readyState === "interactive") {
373- injectEmbed();
374- } else {
375- window.addEventListener("DOMContentLoaded", injectEmbed);
376- }
368+ script.src = \" """ *
369+ script_src *
370+ """ \" ;
371+ script.async = true;
372+ shell.appendChild(script);
377373})();
378374</script>
379- """ ,
380- )
375+ """
381376end
382377
383378function integrate_anythingllm (
0 commit comments