/**
* "Made with HuggingChat" badge injected into artifacts deployed to a static
* Space. Previews never get it — only the shipped `index.html`.
*
* The artifact page is arbitrary author HTML/CSS, so the badge is isolated on
* both sides:
* - its markup lives in a **closed shadow root**, so page selectors (and page
* scripts) can't reach in, and the badge's own CSS can't leak out;
* - the host element's layout/paint properties are set as **inline
* `!important`** declarations, which outrank every author stylesheet rule
* (including `!important` ones), so a stray `div { display: none }` or
* `* { position: static }` can't hide or dislodge it. `all: initial` is set
* first to drop inherited values (font, color, visibility, transform…).
*
* A MutationObserver re-attaches the host if the page replaces `document.body`
* content wholesale (common in artifacts that render a whole app into the body).
*/
const END_SCRIPT_TAG = "";
/** Attribute marking the badge host, also used as the idempotency check. */
export const BADGE_HOST_ATTRIBUTE = "data-huggingchat-badge";
const BADGE_URL = "https://huggingface.co/chat";
const BADGE_LABEL = "Made with HuggingChat";
// Same mark as static/huggingchat/logo.svg, inlined so the badge stays
// self-contained (a deployed Space must not depend on chat-ui being reachable).
const BADGE_LOGO = ``;
const BADGE_SHADOW_HTML = `${BADGE_LOGO}${BADGE_LABEL}`;
// Inline host styles, each applied with `important` so no author rule can win.
// Order matters: `all` resets everything, so it must come first.
const HOST_STYLES: Array<[string, string]> = [
["all", "initial"],
["position", "fixed"],
["right", "12px"],
["bottom", "12px"],
["z-index", "2147483647"],
["display", "block"],
["visibility", "visible"],
["opacity", "1"],
["pointer-events", "auto"],
["width", "auto"],
["height", "auto"],
["margin", "0"],
["padding", "0"],
["max-width", "none"],
["max-height", "none"],
["transform", "none"],
["filter", "none"],
["clip-path", "none"],
["color-scheme", "light"],
];
function buildBadgeScript(): string {
const shadowHtml = JSON.stringify(BADGE_SHADOW_HTML).replace(/<\//g, "<\\/");
const hostStyles = JSON.stringify(HOST_STYLES);
return `` would
* terminate the artifact's script and corrupt the page — and scanning for the
* *last* match is quadratic on content that repeats the tag. Appending has
* neither problem and produces the same result in the browser.
*/
export function appendHuggingChatBadge(html: string): string {
return html + "\n" + buildBadgeScript() + "\n";
}