Fix broken payment page: escape html/body heredocs in page_open
Dev — Build & local smoke test / build-smoke (pull_request) Failing after 1m27s

elc's heredoc parser treats <html> as an opener and scans forward for
</html>, which exists inside page_close's return statement. This caused
the entire El source of page_close to be injected verbatim into the
page_open output string, terminating the document before Stripe scripts
could load.

Fix: put <!DOCTYPE html><html lang="en"> in a quoted string literal
and use <head>...</head> as the sole heredoc in page_open — closes
within the same function, no cross-boundary scanning. Stub page_close
in styles.el as extern fn so dist/page_close.c supplies the definition.

Also fix elc-broken hyphenated attributes in dist/page_close.c:
aria-label, stroke-width, stroke-linecap, &times;, and several
text nodes that had whitespace stripped by the heredoc parser.
This commit is contained in:
2026-05-09 12:56:50 -05:00
parent 66e3ac6321
commit 7f27f4be9f
2 changed files with 4 additions and 67 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+3 -66
View File
@@ -16,9 +16,7 @@
// in the noscript fallback style).
fn page_open() -> String {
return <!DOCTYPE html>
<html lang="en">
<head>
let h: String = <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Neuron - The AI That Remembers You</title>
@@ -1962,68 +1960,7 @@ fn page_open() -> String {
}
</script>
</head>
<body>
return "<!DOCTYPE html><html lang=\"en\">" + h + "<body>"
}
fn page_close() -> String {
let widgets: String = <div id="page-widgets">
<script src="/js/chat-widget.js" defer></script>
<!-- Neuron Demo Chat Widget -->
<div id="neuron-demo-btn">
<button onclick="neuronDemoToggle()" aria-label="Chat with Neuron">
<img src="/assets/brand/neuron-brain.png" alt="">
Try Neuron
</button>
</div>
<div id="neuron-demo-panel" style="display:none">
<div id="neuron-demo-header">
<div id="neuron-demo-header-left">
<img src="/assets/brand/neuron-brain.png" alt="Neuron">
<div>
<span>Neuron</span>
<div id="neuron-demo-header-sub">Live Demo</div>
</div>
</div>
<div style="display:flex;align-items:center;gap:0.75rem">
<span id="neuron-demo-countdown" style="font-family:var(--body);font-size:0.65rem;font-weight:700;letter-spacing:0.06em;text-transform:uppercase;color:rgba(255,255,255,0.90)"></span>
<button id="neuron-demo-close" onclick="neuronDemoToggle()" aria-label="Close">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,.85)" stroke-width="1.75" stroke-linecap="round">
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
</div>
</div>
<div id="neuron-demo-messages"></div>
<div id="neuron-demo-turnstile" style="padding:0.75rem 1rem 0;transition:opacity 0.6s,max-height 0.6s;overflow:hidden;max-height:80px"></div>
<div id="neuron-demo-input-row" style="display:none">
<input type="text" id="neuron-demo-text" placeholder="Ask me anything..." autocomplete="off" maxlength="8000">
<button id="neuron-demo-send" onclick="neuronDemoSend()">Send</button>
</div>
</div>
<!-- Share preview modal: shown after the user clicks Share on an AI bubble.
Renders the share-card layout in an iframe (via srcdoc) so the visitor
sees exactly what the public card will look like before publishing. -->
<div id="neuron-share-preview-modal" style="display:none;position:fixed;inset:0;z-index:200000;background:rgba(13,13,20,.55);align-items:center;justify-content:center;padding:1.5rem;font-family:'IBM Plex Sans',system-ui,sans-serif">
<div style="background:#fff;width:100%;max-width:640px;max-height:90vh;display:flex;flex-direction:column;border-radius:12px;box-shadow:0 24px 80px rgba(0,0,0,.35);overflow:hidden">
<div style="display:flex;align-items:center;justify-content:space-between;padding:1rem 1.25rem;border-bottom:1px solid rgba(0,0,0,.08)">
<div>
<div style="font-size:.65rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:#6B6B7E">Preview</div>
<div style="font-size:1rem;font-weight:500;color:#0D0D14;margin-top:.15rem">This is what you are about to publish</div>
</div>
<button type="button" id="neuron-share-preview-close" aria-label="Close" style="background:none;border:none;cursor:pointer;color:#6B6B7E;padding:.25rem;line-height:1;font-size:1.5rem">&times;</button>
</div>
<iframe id="neuron-share-preview-frame" style="flex:1;width:100%;min-height:420px;border:0;background:#FAFAF8" sandbox="allow-same-origin"></iframe>
<div style="display:flex;align-items:center;justify-content:flex-end;gap:.6rem;padding:.85rem 1.25rem;border-top:1px solid rgba(0,0,0,.08);background:#FAFAF8">
<button type="button" id="neuron-share-preview-cancel" style="background:#fff;border:1px solid rgba(0,0,0,.18);color:#3A3A4A;cursor:pointer;padding:.55rem 1rem;font:inherit;font-size:.8rem;font-weight:500;border-radius:6px">Cancel</button>
<button type="button" id="neuron-share-preview-publish" style="background:#0052A0;border:1px solid #0052A0;color:#fff;cursor:pointer;padding:.55rem 1.1rem;font:inherit;font-size:.8rem;font-weight:600;letter-spacing:.04em;border-radius:6px">Publish to gallery</button>
</div>
</div>
</div>
<script src="/js/styles.js" defer></script>
</div>
return widgets + "</body></html>"
}
extern fn page_close() -> String