Apply remaining audit fixes; document radii and code palette in DESIGN.md
- Token sweep: exact-value gold literals now use --wg-border / --wg-border-soft / --wg-focus - Topbar: drop invalid role="menuitem" (no parent role="menu") - topics_list: topic-select icons get role="checkbox", tabindex, aria-label; client.js makes them keyboard-operable and syncs aria-checked - category.tpl: copy-handle link gets an accessible name, "View Original" moved to i18n, external-link icon aria-hidden, stretched link inside aria-hidden alert removed from tab order - Footer: all copy moved to [[westgate:footer.*]] keys; year injected via filter:middleware.renderFooter instead of hard-coded 2026 - client.js: batch table measurements before writes (no interleaved reflow), .catch on the category class map so search results never hang, category selector match uses fw-bold class instead of inline style - Forced-colors focus fallback: transparent outline alongside the box-shadow focus ring - DESIGN.md: real radius scale (3/4/6/8px), code-block palette, motion & modes section, placeholder alpha Verified against the sow-nodebb dev container: themed code blocks render in posts, footer i18n + year, checkbox roles in served HTML. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+31
-3
@@ -115,13 +115,15 @@
|
||||
return element && element.offsetWidth ? element.offsetWidth : 0;
|
||||
}
|
||||
|
||||
function setMobileTableMinWidth(table, wrapper) {
|
||||
function measureMobileTableMinWidth(table) {
|
||||
const columnCount = getTableColumnCount(table);
|
||||
const measuredWidth = getRenderedWidth(table);
|
||||
const columnWidthFloor = getTableColumnWidthFloor(table, columnCount);
|
||||
const desktopWidthFloor = tableUsesFluidWidth(table) && columnCount >= 8 ? WIKI_TABLE_DESKTOP_MIN_WIDTH : 0;
|
||||
const minWidth = Math.ceil(Math.max(measuredWidth, columnWidthFloor, desktopWidthFloor));
|
||||
return Math.ceil(Math.max(measuredWidth, columnWidthFloor, desktopWidthFloor));
|
||||
}
|
||||
|
||||
function applyMobileTableMinWidth(wrapper, minWidth) {
|
||||
if (minWidth > 0 && wrapper && wrapper.style && typeof wrapper.style.setProperty === 'function') {
|
||||
wrapper.style.setProperty('--wg-mobile-table-min-width', `${minWidth}px`);
|
||||
}
|
||||
@@ -133,6 +135,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const wrapped = [];
|
||||
toArray(scope.querySelectorAll(WIKI_TABLE_SELECTOR)).forEach((table) => {
|
||||
if (!table || !table.parentNode || table.closest(SKIP_TABLE_SELECTOR)) {
|
||||
return;
|
||||
@@ -144,8 +147,16 @@
|
||||
wrapper.setAttribute('aria-label', 'Scrollable table');
|
||||
table.parentNode.insertBefore(wrapper, table);
|
||||
wrapper.appendChild(table);
|
||||
setMobileTableMinWidth(table, wrapper);
|
||||
wrapped.push({ table, wrapper });
|
||||
});
|
||||
|
||||
// batch: measure every table first, then write, so reads and writes
|
||||
// don't interleave and force repeated reflows
|
||||
wrapped
|
||||
.map(({ table, wrapper }) => ({ wrapper, minWidth: measureMobileTableMinWidth(table) }))
|
||||
.forEach(({ wrapper, minWidth }) => {
|
||||
applyMobileTableMinWidth(wrapper, minWidth);
|
||||
});
|
||||
}
|
||||
|
||||
function getWestgateTopbar() {
|
||||
@@ -223,6 +234,20 @@
|
||||
$(document).ready(function () {
|
||||
wrapWestgateWikiTables(document);
|
||||
initWestgateTopbar();
|
||||
|
||||
// topic-select checkboxes are <i> elements; make them keyboard-operable
|
||||
$(document).on('keydown', 'i[component="topic/select"]', function (ev) {
|
||||
if (ev.key === 'Enter' || ev.key === ' ') {
|
||||
ev.preventDefault();
|
||||
$(this).trigger('click');
|
||||
}
|
||||
});
|
||||
$(document).on('click', 'i[component="topic/select"]', function () {
|
||||
// core toggles the icon class in its own click handler; sync after it runs
|
||||
setTimeout(() => {
|
||||
this.setAttribute('aria-checked', this.classList.contains('fa-check-square') ? 'true' : 'false');
|
||||
}, 0);
|
||||
});
|
||||
$(window).on('action:ajaxify.end', function () {
|
||||
wrapWestgateWikiTables(document);
|
||||
initWestgateTopbar();
|
||||
@@ -272,6 +297,9 @@
|
||||
class: category.class || classMap[String(category.cid)] || '',
|
||||
}));
|
||||
callback(null, payload);
|
||||
}).catch(() => {
|
||||
// class map is cosmetic; never block search results on it
|
||||
callback(null, payload);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user