Skip to content

Commit de6e329

Browse files
committed
attempt to switch to shadow dom
1 parent 6aed75e commit de6e329

File tree

2 files changed

+47
-52
lines changed

2 files changed

+47
-52
lines changed

src/AnythingLLMDocs.jl

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
"""
381376
end
382377

383378
function integrate_anythingllm(

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ end
3131
)
3232
@test length(assets) == 1
3333
@test assets[1] isa RawHTMLHeadContent
34-
@test occursin("anythingllm-embed-frame", String(assets[1].content))
34+
@test occursin("anythingllm-embed-shadow-host", String(assets[1].content))
3535
end
3636

3737
@testset "Aqua" begin

0 commit comments

Comments
 (0)