← back to Stringwallpaper

public/drill.js

37 lines

// ── href-to-deeper-data primitives — SINGLE SOURCE OF TRUTH (HARD rule, 2026-07-31) ──
// Every displayed data point must be an href to its deeper (filtered) data. These are the
// reusable atoms; a viewer's index.html loads this file, then defines FIELDS, FIL, $, esc,
// and applyFilters (which these reference at call time via the shared classic-script global
// scope). Canonical copy: ~/Projects/_shared/web/drill.js → each viewer's public/drill.js.
// Memory: all-data-points-href-to-deeper-data. Reference viewers: astek-landing, schumacher-internal.

// Build the URL for a given filter set — any count/atom becomes a real, shareable link.
function qstr(fil, q, pat) {
  const u = new URLSearchParams();
  for (const [k] of FIELDS) { if (fil[k]) u.set(k, fil[k]); }
  if (q) u.set('q', q); if (pat) u.set('pat', pat);
  const s = u.toString(); return s ? ('?' + s) : location.pathname;
}
// Read the URL's filter state back into FIL + the search inputs (deep-link / back-button).
function readURL() {
  const u = new URLSearchParams(location.search);
  for (const [k] of FIELDS) FIL[k] = u.get(k) || '';
  $('#q').value = u.get('q') || ''; $('#pattern').value = u.get('pat') || '';
}
// Reflect the current filter state into the URL (push = new history entry, else replace).
function writeURL(push) {
  const url = qstr(FIL, $('#q').value.trim(), $('#pattern').value.trim());
  history[push ? 'pushState' : 'replaceState']({}, '', url);
}
// drill(field,value,label,cls) → an <a> whose href IS the filtered view for that value.
// cmd/ctrl/middle-click opens it in a new tab; plain click filters in place (delegated listener).
function drill(field, val, label, cls) {
  if (val == null || val === '') return '';
  const href = qstr({ ...FIL, [field]: String(val) }, $('#q').value.trim(), $('#pattern').value.trim());
  return `<a class="drill ${cls || ''}" href="${href}" data-filter="${field}" data-v="${esc(val)}" title="Filter to ${esc(val)}">${label != null ? esc(label) : esc(val)}</a>`;
}
// Atom drill target: SET the filter to this value (drill in), vs pickF which TOGGLES.
function setF(k, v) { if (FIL[k] === String(v)) return; FIL[k] = String(v); applyFilters('push'); }

window.qstr = qstr; window.readURL = readURL; window.writeURL = writeURL; window.drill = drill; window.setF = setF;