Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions scripts/check.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ assert(html.includes("Search the library"));
assert(html.includes("Search by title, task, or contributor"));
assert(html.includes('class="search-field"'));
assert(html.includes("styles.css?v=20260623-row-background-v2"));
assert(html.includes("script.js?v=20260623-proxy-auth"));
assert(html.includes("script.js?v=20260625-form-protection"));
assert(css.includes(".search-control-label"));
assert(css.includes(".search-control:hover .search-field"));
assert(css.includes(".search-control:focus-within .search-field"));
Expand All @@ -135,7 +135,7 @@ assert.match(css, /\.loop-table td\s*\{[^}]*background:\s*transparent;[^}]*\}/);
assert.equal((html.match(/data-here-now-credit/g) || []).length, 2);
for (const page of [learnHtml, agentHtml]) {
assert(page.includes("styles.css?v=20260623-row-background-v2"));
assert(page.includes("script.js?v=20260623-proxy-auth"));
assert(page.includes("script.js?v=20260625-form-protection"));
}
for (const page of [html, learnHtml, agentHtml]) {
const brandPosition = page.indexOf('class="brand-lockup"');
Expand Down Expand Up @@ -181,6 +181,20 @@ for (const collectionConfig of [suggestions, weeklySignups]) {
}
assert(workerSource.includes("TURNSTILE_RATE_LIMITER.limit"));
assert(workerSource.includes("https://challenges.cloudflare.com/turnstile/v0/siteverify"));
assert(browserScript.includes("function setTurnstileUnavailable"));
assert(browserScript.includes("setTurnstileReady(widget, token)"));
assert(
browserScript.includes(
"weeklyButton.disabled = !turnstileWidgets.weeklySignups.token",
),
);
assert(
browserScript.includes(
"submitButton.disabled = !turnstileWidgets.suggestions.token",
),
);
assert(!browserScript.includes("Complete the verification check before signing up."));
assert(!browserScript.includes("Complete the verification check before submitting."));
assert(workerSource.includes("handleLoopRoute"));
assert(workerSource.includes("handleAuthVoteRoute"));
assert(browserScript.includes('document.querySelectorAll("[data-vote-controls]")'));
Expand Down
2 changes: 1 addition & 1 deletion site/agents/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
/>
<link rel="icon" type="image/png" href="../assets/favicon.png" />
<link rel="stylesheet" href="../styles.css?v=20260623-row-background-v2" />
<script src="../script.js?v=20260623-proxy-auth" defer></script>
<script src="../script.js?v=20260625-form-protection" defer></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
Expand Down
2 changes: 1 addition & 1 deletion site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@
]
}
</script>
<script src="./script.js?v=20260623-proxy-auth" defer></script>
<script src="./script.js?v=20260625-form-protection" defer></script>
<title>Loop Library: Repeatable AI Agent Workflows | Forward Future</title>
</head>
<body>
Expand Down
2 changes: 1 addition & 1 deletion site/learn/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
/>
<link rel="icon" type="image/png" href="../assets/favicon.png" />
<link rel="stylesheet" href="../styles.css?v=20260623-row-background-v2" />
<script src="../script.js?v=20260623-proxy-auth" defer></script>
<script src="../script.js?v=20260625-form-protection" defer></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
Expand Down
81 changes: 70 additions & 11 deletions site/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -983,14 +983,28 @@ let turnstileLoadPromise;
const turnstileWidgets = {
suggestions: {
action: "",
button: submitButton,
container: document.querySelector("#loop-turnstile"),
failureMessage:
"Spam protection is temporarily unavailable. Refresh and try again.",
id: null,
pendingMessage:
"Spam protection is still loading. Wait a moment and try again.",
setStatus: setFormStatus,
statusElement: formStatus,
token: "",
},
weeklySignups: {
action: "",
button: weeklyButton,
container: document.querySelector("#weekly-turnstile"),
failureMessage:
"Signups are temporarily unavailable. Refresh and try again.",
id: null,
pendingMessage:
"Spam protection is still loading. Wait a moment and try again.",
setStatus: setWeeklyStatus,
statusElement: weeklyStatus,
token: "",
},
};
Expand Down Expand Up @@ -1061,6 +1075,36 @@ function setProtectedButtonsDisabled(disabled) {
}
}

function setTurnstilePending(widget) {
widget.token = "";

if (widget.button) {
widget.button.disabled = true;
}
}

function setTurnstileReady(widget, token) {
widget.token = token;

if (
widget.statusElement &&
[widget.failureMessage, widget.pendingMessage].includes(
widget.statusElement.textContent,
)
) {
widget.setStatus("");
}

if (widget.button) {
widget.button.disabled = false;
}
}

function setTurnstileUnavailable(widget) {
setTurnstilePending(widget);
widget.setStatus(widget.failureMessage, "error");
}

function loadTurnstile() {
if (window.turnstile) {
return Promise.resolve(window.turnstile);
Expand Down Expand Up @@ -1113,19 +1157,19 @@ function renderTurnstile(turnstile, widget, siteKey) {
theme:
document.documentElement.dataset.theme === "dark" ? "dark" : "light",
callback(token) {
widget.token = token;
setTurnstileReady(widget, token);
},
"expired-callback"() {
widget.token = "";
setTurnstilePending(widget);
},
"error-callback"() {
widget.token = "";
setTurnstileUnavailable(widget);
},
});
}

function resetTurnstile(widget) {
widget.token = "";
setTurnstilePending(widget);

if (window.turnstile && widget.id !== null) {
window.turnstile.reset(widget.id);
Expand Down Expand Up @@ -1178,7 +1222,6 @@ async function initializeFormProtection() {
config.turnstileSiteKey,
);
formProtectionReady = true;
setProtectedButtonsDisabled(false);
} catch {
setFormStatus(
"Submissions are temporarily unavailable. Refresh and try again.",
Expand Down Expand Up @@ -1257,9 +1300,17 @@ if (form && submitButton && submitButtonLabel) {
return;
}

if (!formProtectionReady || !turnstileWidgets.suggestions.token) {
if (!formProtectionReady) {
setFormStatus(
"Submissions are temporarily unavailable. Refresh and try again.",
"error",
);
return;
}

if (!turnstileWidgets.suggestions.token) {
setFormStatus(
"Complete the verification check before submitting.",
turnstileWidgets.suggestions.pendingMessage,
"error",
);
return;
Expand Down Expand Up @@ -1317,7 +1368,7 @@ if (form && submitButton && submitButtonLabel) {
"error",
);
} finally {
submitButton.disabled = false;
submitButton.disabled = !turnstileWidgets.suggestions.token;
submitButtonLabel.textContent = "Submit loop";
}
});
Expand All @@ -1341,9 +1392,17 @@ if (weeklyForm && weeklyButton && weeklyButtonLabel) {
return;
}

if (!formProtectionReady || !turnstileWidgets.weeklySignups.token) {
if (!formProtectionReady) {
setWeeklyStatus(
"Signups are temporarily unavailable. Refresh and try again.",
"error",
);
return;
}

if (!turnstileWidgets.weeklySignups.token) {
setWeeklyStatus(
"Complete the verification check before signing up.",
turnstileWidgets.weeklySignups.pendingMessage,
"error",
);
return;
Expand Down Expand Up @@ -1380,7 +1439,7 @@ if (weeklyForm && weeklyButton && weeklyButtonLabel) {
"error",
);
} finally {
weeklyButton.disabled = false;
weeklyButton.disabled = !turnstileWidgets.weeklySignups.token;
weeklyButtonLabel.textContent = "Notify me weekly";
}
});
Expand Down
Loading