← back to Robet Site
round3 item (1): real WebKit+Firefox verify FOUND+FIXED a bug — /embed/appointments.js returns text/html (not JS), script-injection threw uncaught SyntaxError; switched to iframe of /book?embed=1 (no X-Frame-Options) + permanent 'open in new tab' escape link; verified 0 syntax errors across chromium/webkit/firefox
dc71cfa1b6fdb73da5366d06ae005eacb2e34de7 · 2026-06-30 01:32:01 -0700 · Steve
Files touched
M public/app.jsM public/index.html
Diff
commit dc71cfa1b6fdb73da5366d06ae005eacb2e34de7
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Jun 30 01:32:01 2026 -0700
round3 item (1): real WebKit+Firefox verify FOUND+FIXED a bug — /embed/appointments.js returns text/html (not JS), script-injection threw uncaught SyntaxError; switched to iframe of /book?embed=1 (no X-Frame-Options) + permanent 'open in new tab' escape link; verified 0 syntax errors across chromium/webkit/firefox
---
public/app.js | 36 ++++++++++++++++++++----------------
public/index.html | 9 ++++-----
2 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/public/app.js b/public/app.js
index 2cf2ede..154275f 100644
--- a/public/app.js
+++ b/public/app.js
@@ -51,34 +51,38 @@
}
});
- // ── Smart Scheduling embed: skeleton → real widget OR fallback (never a perpetual spinner) ──
+ // ── Smart Scheduling embed: iframe the chromeless booking page directly ──
+ // The /embed/appointments.js loader returns text/html (not JS), so injecting it as a
+ // <script> throws an uncaught SyntaxError (caught cross-browser, loudest in WebKit) and never
+ // renders. /book?embed=1 returns the chromeless widget with no X-Frame-Options, so it frames
+ // cleanly; CSP already allows frame-src venturacorridor.com. Skeleton → iframe OR fallback link.
const sched = cfg.scheduling || {};
const embedBox = $('#embedBox');
+ const bookAlt = $('#bookAlt');
+ if (bookAlt && sched.bookUrl) bookAlt.href = sched.bookUrl; // permanent escape hatch
const fallbackHTML = () =>
`<div class="fallback mono">Booking opens in a new tab — <a class="cta" href="${sched.bookUrl || '#'}" target="_blank" rel="noopener noreferrer">Open booking page →</a></div>`;
if (embedBox) {
- if (!sched.embedLoader) {
+ if (!sched.bookUrl) {
embedBox.innerHTML = fallbackHTML();
} else {
- // brutalist loading skeleton, shown immediately
embedBox.innerHTML = '<div class="embed-skeleton" aria-hidden="true"><span></span><span></span><span></span><span></span></div>';
let settled = false;
const settle = (mode) => {
- if (settled) return; settled = true;
- clearTimeout(timer); obs.disconnect();
+ if (settled) return; settled = true; clearTimeout(timer);
const sk = embedBox.querySelector('.embed-skeleton'); if (sk) sk.remove();
- if (mode === 'fallback' && !embedBox.querySelector('iframe')) embedBox.innerHTML = fallbackHTML();
+ if (mode === 'fallback') embedBox.innerHTML = fallbackHTML();
};
- // a rendered booking widget = an injected <iframe>; that's our "it worked" signal
- const obs = new MutationObserver(() => { if (embedBox.querySelector('iframe')) settle('embed'); });
- obs.observe(embedBox, { childList: true, subtree: true });
- const timer = setTimeout(() => settle('fallback'), 7000); // no widget in 7s → fallback link
- const s = document.createElement('script');
- s.src = sched.embedLoader;
- if (sched.owner) s.setAttribute('data-owner', sched.owner);
- s.async = true;
- s.onerror = () => settle('fallback');
- embedBox.appendChild(s);
+ const sep = sched.bookUrl.includes('?') ? '&' : '?';
+ const frame = document.createElement('iframe');
+ frame.src = sched.bookUrl + sep + 'embed=1';
+ frame.title = 'Book a meeting — Smart Scheduling';
+ frame.loading = 'lazy';
+ frame.style.cssText = 'width:100%;min-height:560px;border:0;display:block;background:#fff';
+ frame.addEventListener('load', () => settle('embed')); // booking page rendered
+ frame.addEventListener('error', () => settle('fallback'));
+ const timer = setTimeout(() => settle('fallback'), 8000); // never loaded → fallback link
+ embedBox.appendChild(frame);
}
}
diff --git a/public/index.html b/public/index.html
index 1789a89..816c304 100644
--- a/public/index.html
+++ b/public/index.html
@@ -104,11 +104,10 @@ MEETING.</h1>
<section id="booking">
<span class="kicker">/ smart scheduling</span>
<h2 class="sec-h">Pick a time.</h2>
- <div class="embed-box" id="embedBox">
- <div class="fallback" id="bookFallback" class="mono">
- Loading available slots… <a class="cta" id="bookLink" href="#">Open booking →</a>
- </div>
- </div>
+ <div class="embed-box" id="embedBox"></div>
+ <p class="mono" style="margin-top:14px">
+ Trouble with the scheduler? <a id="bookAlt" href="#" target="_blank" rel="noopener noreferrer">Open booking in a new tab →</a>
+ </p>
</section>
<!-- contact -->
← 19cdcaa round 2 closed (7/8, #17 deferred-gated); round-3 DTD backlo
·
back to Robet Site
·
loop ledger: round3 item (1) done + deployed 10dd446 →