restincode/index.html
mauvehed e2a1b469ea fix(ui): harden memorial data handling and search input
Use input event instead of keyup for search filtering to capture all
input methods. Add safeUrl helper to validate URLs against http/https
before DOM injection. Replace loose empty-string checks on array fields
with Array.isArray guards to prevent null/undefined throws.
2026-03-14 17:07:21 -05:00

136 lines
4.5 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<title>Rest In Code - An InfoSec and Hacker Memorial Site</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="author"
content="Site by Connie 'Sunfire' Hill; Content by Rest In Code contributors"
/>
<meta name="description" content="An InfoSec and Hacker Memorial Site" />
<meta
name="keywords"
content="memorial, hacker, hackers, infosec, information security, obituary"
/>
<link rel="stylesheet" href="style.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Inter:wght@400;500;600&display=swap"
rel="stylesheet"
/>
<link rel="shortcut icon" type="image/x-icon" href="/images/favicon.png" />
<script
src="https://code.jquery.com/jquery-3.7.0.min.js"
integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g="
crossorigin="anonymous"
></script>
<script>
$(function () {
$.getJSON("peoplelist.json", function (data) {
var peoplelist = data.people;
peoplelist.sort(function (a, b) {
if (a.displayname > b.displayname) return 1;
if (a.displayname < b.displayname) return -1;
return 0;
});
for (var p = 0; p < peoplelist.length; p++) {
var displayname = peoplelist[p]["displayname"];
var file = peoplelist[p]["filename"];
var card;
if (file == "") {
card =
'<div class="person-card no-link" data-name="' +
displayname.toLowerCase() +
'">' +
displayname +
"</div>";
} else {
card =
'<a href="memorial.html?name=' +
file +
'" class="person-card" data-name="' +
displayname.toLowerCase() +
'">' +
displayname +
"</a>";
}
$("#people-grid").append(card);
}
$(".loading-message").remove();
}).fail(function () {
$(".loading-message").replaceWith(
'<p class="error-message">Unable to load memorial list. Please try refreshing the page.</p>',
);
});
$("#people-search").on("input", function () {
var query = $(this).val().toLowerCase();
$(".person-card").each(function () {
var name = $(this).attr("data-name");
$(this).toggle(name.indexOf(query) !== -1);
});
});
});
</script>
</head>
<body>
<a href="#main-content" class="skip-link">Skip to content</a>
<header>
<h1 id="main-title">
RestInCode <span id="subtitle">Passed but not Forgotten</span>
</h1>
<p id="tagline">
A memorial site for Hackers and InfoSec people who have passed.
</p>
</header>
<section class="hero" id="main-content" aria-label="About RestInCode">
<p>
In a community and industry that many of us see as timeless, we are
quickly learning that is not the reality, as our dear friends and
colleagues more frequently move on. Our ideals, our research, and our
spirit persists. Unfortunately, our human shells can't keep up
sometimes. We seek to honor those who have touched security, technology,
and our lives.
</p>
<div class="people-search-wrapper">
<input
type="search"
id="people-search"
placeholder="Search memorials..."
aria-label="Search memorials"
/>
</div>
</section>
<div class="people-grid" id="people-grid">
<p class="loading-message">Loading memorials...</p>
</div>
<section class="contributing-section">
<p>
To contribute by adding new people, additional content, photos, or
pointing out inaccuracies, please visit our
<a
href="https://github.com/restincode/restincode/blob/master/CONTRIBUTING.md"
>Contributing guidelines</a
>.
</p>
</section>
<footer>
Memorial content belongs to its respective creators and rights holders. We
do our best to identify and credit them.
</footer>
</body>
</html>