Fix comments UX regressions and HTMX/Turnstile behavior
- standardize comment and reply UI layout - target replies with stable OOB container IDs - remove stale empty-state on approved HTMX comments - initialize Turnstile widgets after HTMX swaps - add regression tests for empty-state, OOB targets, and reply form rerender Refs #48
This commit is contained in:
83
static/js/comments.js
Normal file
83
static/js/comments.js
Normal file
@@ -0,0 +1,83 @@
|
||||
(function () {
|
||||
function renderTurnstileWidgets(root) {
|
||||
if (!root || !window.turnstile || typeof window.turnstile.render !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
const widgets = [];
|
||||
if (root.matches && root.matches(".cf-turnstile")) {
|
||||
widgets.push(root);
|
||||
}
|
||||
if (root.querySelectorAll) {
|
||||
widgets.push(...root.querySelectorAll(".cf-turnstile"));
|
||||
}
|
||||
|
||||
widgets.forEach(function (widget) {
|
||||
if (widget.dataset.turnstileRendered === "true") {
|
||||
return;
|
||||
}
|
||||
if (widget.querySelector("iframe")) {
|
||||
widget.dataset.turnstileRendered = "true";
|
||||
return;
|
||||
}
|
||||
|
||||
const sitekey = widget.dataset.sitekey;
|
||||
if (!sitekey) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
sitekey: sitekey,
|
||||
theme: widget.dataset.theme || "auto",
|
||||
};
|
||||
if (widget.dataset.size) {
|
||||
options.size = widget.dataset.size;
|
||||
}
|
||||
if (widget.dataset.action) {
|
||||
options.action = widget.dataset.action;
|
||||
}
|
||||
if (widget.dataset.appearance) {
|
||||
options.appearance = widget.dataset.appearance;
|
||||
}
|
||||
|
||||
window.turnstile.render(widget, options);
|
||||
widget.dataset.turnstileRendered = "true";
|
||||
});
|
||||
}
|
||||
|
||||
function syncCommentsEmptyState() {
|
||||
const emptyState = document.getElementById("comments-empty-state");
|
||||
const commentsList = document.getElementById("comments-list");
|
||||
if (!emptyState || !commentsList) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hasComments = commentsList.querySelector("[data-comment-item='true']") !== null;
|
||||
emptyState.classList.toggle("hidden", hasComments);
|
||||
}
|
||||
|
||||
function onTurnstileReady(root) {
|
||||
if (!window.turnstile || typeof window.turnstile.ready !== "function") {
|
||||
return;
|
||||
}
|
||||
window.turnstile.ready(function () {
|
||||
renderTurnstileWidgets(root || document);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
syncCommentsEmptyState();
|
||||
onTurnstileReady(document);
|
||||
});
|
||||
|
||||
document.addEventListener("htmx:afterSwap", function (event) {
|
||||
const target = event.detail && event.detail.target ? event.detail.target : document;
|
||||
syncCommentsEmptyState();
|
||||
onTurnstileReady(target);
|
||||
});
|
||||
|
||||
window.addEventListener("load", function () {
|
||||
syncCommentsEmptyState();
|
||||
onTurnstileReady(document);
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user