mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-24 12:49:03 -05:00
fix: short stacked labels, declared lookup hash
This commit is contained in:
1 parent
8667956a0b
commit
b967cb8d04
2 files changed
+73
-6
No files matched your search
@@ -16,6 +16,10 @@
|
||||
// so the row is wider than a phone at any length (NetherSX2's File,
|
||||
// Required, Hash summary measured 604 px in a 358 px column).
|
||||
//
|
||||
// A stacked cell is labelled with its column name, or with the header's
|
||||
// `title` when the table's writer gives one: "Name as declared" wrapped to two
|
||||
// lines in the label column, its title "Declared as" does not.
|
||||
//
|
||||
// A table of RECORD_ROWS rows or more gets its filter box here, above it.
|
||||
// Written by site.ts once the page had painted, the box pushed the table
|
||||
// down (CLS 0.066 on gaps-files-to-source). site.ts only wires it.
|
||||
@@ -101,6 +105,9 @@ const headingBefore = (ctx, table, title) => {
|
||||
return title || 'this table';
|
||||
};
|
||||
|
||||
// The label a stacked cell shows: the header's title, else its text.
|
||||
export const stackedLabel = (title, text) => String(title ?? '').trim() || text;
|
||||
|
||||
const filterBox = ({ id, heading, labels, rows }) => ({
|
||||
type: 'element',
|
||||
tagName: 'div',
|
||||
@@ -136,7 +143,9 @@ export default function stackTables() {
|
||||
const head = elements(table, 'thead')[0];
|
||||
const body = elements(table, 'tbody')[0];
|
||||
if (!head || !body) return;
|
||||
const labels = elements(head, 'th').map((cell) => ctx.textContent(cell).trim());
|
||||
const headers = elements(head, 'th');
|
||||
const labels = headers.map((cell) => ctx.textContent(cell).trim());
|
||||
const stacked = headers.map((cell, column) => stackedLabel(cell.properties?.title, labels[column]));
|
||||
const rows = elements(body, 'tr');
|
||||
const frontmatter = ctx.data.astro?.frontmatter ?? {};
|
||||
if (rows.length >= RECORD_ROWS) {
|
||||
@@ -153,7 +162,7 @@ export default function stackTables() {
|
||||
if (kind === 'kv' || rows.length >= RECORD_ROWS) return;
|
||||
for (const row of rows) {
|
||||
elements(row, 'td').forEach((cell, column) => {
|
||||
if (labels[column] && cell.properties?.dataLabel === undefined) ctx.setProperty(cell, 'dataLabel', labels[column]);
|
||||
if (stacked[column] && cell.properties?.dataLabel === undefined) ctx.setProperty(cell, 'dataLabel', stacked[column]);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
|
||||
const HASH_LENGTHS: Record<number, string> = { 8: 'CRC32', 32: 'MD5', 40: 'SHA1', 64: 'SHA256' };
|
||||
// One line of api/v1/lookup/. `system_name` is read when a record carries it.
|
||||
// `algorithm` is the hash the value was found under, `declared` the hash
|
||||
// type the setup or profile wrote for that entry.
|
||||
type Item = {
|
||||
algorithm: string;
|
||||
declared?: string;
|
||||
layer: string;
|
||||
name?: string;
|
||||
value: string;
|
||||
@@ -111,10 +114,12 @@ const filterTable = (table: HTMLTableElement) => {
|
||||
// A stacked table of many rows leaves its column names out of the HTML
|
||||
// (rehype-stack-tables.mjs): each cell gets its own here, as the table nears
|
||||
// the screen. The name sits in the left room every stacked cell keeps, so
|
||||
// writing it moves nothing.
|
||||
// writing it moves nothing. A header's `title` is its short stacked name.
|
||||
const stackedLabel = (cell: Element) => cell.getAttribute('title')?.trim() || (cell.textContent?.trim() ?? '');
|
||||
|
||||
const labelCells = (table: HTMLTableElement) => {
|
||||
if (table.dataset.rbStack !== 'true') return;
|
||||
const labels = [...table.querySelectorAll('thead th')].map((cell) => cell.textContent?.trim() ?? '');
|
||||
const labels = [...table.querySelectorAll('thead th')].map(stackedLabel);
|
||||
for (const row of table.tBodies[0]?.rows ?? []) {
|
||||
[...row.cells].forEach((cell, column) => {
|
||||
if (labels[column] && !cell.dataset.label) cell.dataset.label = labels[column];
|
||||
@@ -173,6 +178,49 @@ const enhanceTables = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// Paths
|
||||
|
||||
// A long path breaks at its separators, never inside a word. The build
|
||||
// writes the `wbr` of a page's first BREAK_BUDGET separators
|
||||
// (rehype-short-code.mjs), since each is an element of the page. The others
|
||||
// are written here, as their code nears the screen. Same rule: inline code
|
||||
// over 30 characters, a break after each `/` and `\` but the last character.
|
||||
const LONG_CODE = 30;
|
||||
const SEPARATORS = /([/\\])(?!$)/g;
|
||||
const SEPARATOR = /[/\\](?!$)/;
|
||||
const unbrokenPath = (code: Element) =>
|
||||
!code.closest('pre') &&
|
||||
!code.querySelector('wbr') &&
|
||||
[...code.childNodes].every((child) => child.nodeType === Node.TEXT_NODE) &&
|
||||
(code.textContent ?? '').length > LONG_CODE &&
|
||||
SEPARATOR.test(code.textContent ?? '');
|
||||
const breakPath = (code: Element) => {
|
||||
if (!unbrokenPath(code)) return;
|
||||
const parts = (code.textContent ?? '').split(SEPARATORS).flatMap((piece, index) => [
|
||||
...(piece ? [document.createTextNode(piece)] : []),
|
||||
...(index % 2 ? [document.createElement('wbr')] : []),
|
||||
]);
|
||||
code.replaceChildren(...parts);
|
||||
};
|
||||
const breakPaths = () => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
for (const entry of entries) {
|
||||
if (!entry.isIntersecting) continue;
|
||||
breakPath(entry.target);
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
},
|
||||
{ rootMargin: '400px 0px' },
|
||||
);
|
||||
const idle = window.requestIdleCallback ?? ((callback: () => void) => setTimeout(callback, 1));
|
||||
idle(() => {
|
||||
for (const code of document.querySelectorAll('.sl-markdown-content code')) {
|
||||
if (unbrokenPath(code)) observer.observe(code);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Hashing a file on this device: SHA1 and SHA256 by Web Crypto, MD5 and
|
||||
// CRC32 here, since Web Crypto has neither. The bytes never leave the page.
|
||||
|
||||
@@ -381,6 +429,14 @@ const agreed = (values: (string | undefined)[]): string | undefined => {
|
||||
// "system:md5", and any file that has it passes.
|
||||
const anyName = (name: string) => !name || name.includes(':');
|
||||
|
||||
// The column name a stacked row shows where the full one wraps on a phone,
|
||||
// as rehype-stack-tables.mjs reads a header's `title`.
|
||||
const STACKED_LABELS: Record<string, string> = { 'Name as declared': 'Declared as' };
|
||||
|
||||
// "Hash matched" is the hash the setup's list writes, whatever was pasted:
|
||||
// Batocera declares an MD5, so its row says MD5 when a CRC32 found it.
|
||||
const declaredHash = (item: Item) => (item.declared || item.algorithm).toUpperCase();
|
||||
|
||||
const setupTable = (rows: { item: Item; entry?: Declared; setup: string }[]) => {
|
||||
const table = document.createElement('table');
|
||||
const head = table.createTHead().insertRow();
|
||||
@@ -388,6 +444,7 @@ const setupTable = (rows: { item: Item; entry?: Declared; setup: string }[]) =>
|
||||
const cell = document.createElement('th');
|
||||
cell.scope = 'col';
|
||||
cell.textContent = label;
|
||||
if (STACKED_LABELS[label]) cell.title = STACKED_LABELS[label];
|
||||
head.append(cell);
|
||||
}
|
||||
const body = table.createTBody();
|
||||
@@ -399,12 +456,12 @@ const setupTable = (rows: { item: Item; entry?: Declared; setup: string }[]) =>
|
||||
link(item.url, setup),
|
||||
anyName(name) ? 'Any name' : code(name),
|
||||
destination ? code(destination) : '-',
|
||||
item.algorithm.toUpperCase(),
|
||||
declaredHash(item),
|
||||
entry?.required === undefined ? '-' : entry.required ? 'Yes' : 'No',
|
||||
];
|
||||
cells.forEach((content, column) => {
|
||||
const cell = row.insertCell();
|
||||
cell.dataset.label = head.cells[column].textContent!;
|
||||
cell.dataset.label = stackedLabel(head.cells[column]);
|
||||
cell.append(content);
|
||||
});
|
||||
}
|
||||
@@ -892,6 +949,7 @@ const notFound = () => {
|
||||
resolveFileAddress();
|
||||
followMovedCard();
|
||||
enhanceTables();
|
||||
breakPaths();
|
||||
hashSearch();
|
||||
glossaryTerms();
|
||||
osTabs();
|
||||
|
||||
Reference in new issue
Block a user