-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
123 lines (109 loc) · 4.04 KB
/
Copy pathscript.js
File metadata and controls
123 lines (109 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
function gbuClass(gbu) {
if (gbu === "Good") return "pill-gbu-good";
if (gbu === "Bad") return "pill-gbu-bad";
if (gbu === "Ugly") return "pill-gbu-ugly";
return "pill-gbu-mixed";
}
function renderSources(sources) {
return sources
.map((s) => {
const body = s.link
? `${escapeHtml(s.text)} <a href="${s.link}" target="_blank" rel="noopener">source ↗</a>`
: escapeHtml(s.text);
return `<li>${body}</li>`;
})
.join("");
}
function escapeHtml(str) {
const div = document.createElement("div");
div.textContent = str;
return div.innerHTML;
}
function renderRow(row) {
const actsHtml = row.acts.join(" · ");
return `
<article class="row-card">
<div class="row-card-head">
<span class="pill pill-facet">${escapeHtml(row.facet)}</span>
<span class="pill pill-tech">${escapeHtml(row.technology)}</span>
<span class="pill ${gbuClass(row.gbu)}">${escapeHtml(row.gbu)}</span>
</div>
<p class="row-summary">${escapeHtml(row.summary)}</p>
<p class="row-acts">HCI dimension: ${escapeHtml(actsHtml)}</p>
<ul class="row-sources">${renderSources(row.sources)}</ul>
</article>
`;
}
function populateFilters() {
const facetSelect = document.getElementById("filter-facet");
const gbuSelect = document.getElementById("filter-gbu");
const facets = [...new Set(TABLE_ROWS.map((r) => r.facet))];
facets.forEach((f) => {
const opt = document.createElement("option");
opt.value = f;
opt.textContent = f;
facetSelect.appendChild(opt);
});
const gbus = ["Good", "Bad", "Ugly", "Good or Bad"];
gbus.forEach((g) => {
const opt = document.createElement("option");
opt.value = g;
opt.textContent = g;
gbuSelect.appendChild(opt);
});
}
function matchesGbu(rowGbu, filterGbu) {
if (filterGbu === "all") return true;
if (filterGbu === "Good or Bad") return rowGbu === "Good or Bad";
// "Good" filter also surfaces mixed rows that include a good side, same for "Bad".
if (filterGbu === "Good") return rowGbu === "Good" || rowGbu === "Good or Bad";
if (filterGbu === "Bad") return rowGbu === "Bad" || rowGbu === "Good or Bad";
return rowGbu === filterGbu;
}
function applyFilters() {
const facet = document.getElementById("filter-facet").value;
const gbu = document.getElementById("filter-gbu").value;
const query = document.getElementById("filter-search").value.trim().toLowerCase();
const filtered = TABLE_ROWS.filter((row) => {
const facetOk = facet === "all" || row.facet === facet;
const gbuOk = matchesGbu(row.gbu, gbu);
const searchOk =
query === "" ||
row.summary.toLowerCase().includes(query) ||
row.technology.toLowerCase().includes(query) ||
row.facet.toLowerCase().includes(query);
return facetOk && gbuOk && searchOk;
});
const container = document.getElementById("table-rows");
const count = document.getElementById("result-count");
count.textContent = `Showing ${filtered.length} of ${TABLE_ROWS.length} entries`;
container.innerHTML = filtered.length
? filtered.map(renderRow).join("")
: '<div class="no-results">No entries match these filters.</div>';
}
function initTable() {
populateFilters();
applyFilters();
document.getElementById("filter-facet").addEventListener("change", applyFilters);
document.getElementById("filter-gbu").addEventListener("change", applyFilters);
document.getElementById("filter-search").addEventListener("input", applyFilters);
}
function initCopyCitation() {
const btn = document.getElementById("copy-citation");
const pre = document.getElementById("citation-text");
if (!btn || !pre) return;
btn.addEventListener("click", async () => {
try {
await navigator.clipboard.writeText(pre.textContent.trim());
const original = btn.textContent;
btn.textContent = "Copied!";
setTimeout(() => (btn.textContent = original), 1500);
} catch (e) {
// Clipboard API unavailable; user can select and copy manually.
}
});
}
document.addEventListener("DOMContentLoaded", () => {
initTable();
initCopyCitation();
});