Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ enableGitInfo = true
description = "The Student-Run Computing Facility is a volunteer-run student society that provides free, useful and flexible computing and network services for Cambridge University staff and students of all degrees of ability."
repo = "https://github.com/srcf/docs"
repo_branch = "master"

[outputs]
home = ["HTML", "RSS", "JSON"]
10 changes: 9 additions & 1 deletion layouts/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
{{ define "main" }}
<div class="container p-3 py-md-5">
<h1>SRCF Documentation</h1>
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center">
<h1>SRCF Documentation</h1>

<form class="srcf-search">
<input type="search" class="form-control" id="srcf-search-input" placeholder="Search docs..." aria-label="Search docs for..." autocomplete="off"/>
<ul id="srcf-search-results" class="dropdown-menu d-block d-none"></ul>
</form>
</div>

<p class="fs-5 col-md-8">
Hello there! This is the Student-Run Computing Facility's documentation.
Our revamped docs contain all manner of useful pages, such as getting
Expand Down
7 changes: 7 additions & 0 deletions layouts/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{- $index := slice -}}
{{- range .Site.RegularPages -}}
{{- $cleanContents := .Plain | htmlUnescape -}}

{{- $index = $index | append (dict "title" .Title "contents" $cleanContents "headings" .Fragments.Headings "permalink" .Permalink) -}}
Comment thread
rsa33 marked this conversation as resolved.
Outdated
{{- end -}}
{{- $index | jsonify -}}
6 changes: 6 additions & 0 deletions layouts/partials/scripts.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/fuse.js@7.1.0/dist/fuse.min.js"
integrity="sha256-Igk09XYTSwRm2Z94bOIbE/h9MZsemuYzxV5o9vQcPJ0="
crossorigin="anonymous"
></script>
<script src="/js/copy-button.js"></script>
<script src="/js/search.js"></script>
<!-- <script src="/js/main.js"></script> -->
<!-- <script src="{{ .Site.Params.domain_web }}/_srcf/vendor/js/popper.min.js"></script>
<script src="{{ .Site.Params.domain_web }}/_srcf/vendor/js/bootstrap.min.js"></script> -->
11 changes: 5 additions & 6 deletions layouts/partials/subnav.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
<nav class="srcf-subnavbar py-2" aria-label="secondary navigation">
<div class="container-xxl d-flex align-items-md-center justify-content-end">
{{/*
<form class="srcf-search me-auto">
<input type="search" class="form-control" id="search-input" placeholder="Search docs..." aria-label="Search docs for..." autocomplete="off">
<form class="srcf-search ms-auto">
<input type="search" class="form-control" id="srcf-search-input" placeholder="Search docs..." aria-label="Search docs for..." autocomplete="off"/>
<ul id="srcf-search-results" class="dropdown-menu d-block d-none"></ul>
</form>
*/}}

{{ partial "subnav-categories" . }}

<button class="btn srcf-sidebar-toggle d-md-none py-0 px-1 ms-3 order-3 collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#srcf-docs-nav" aria-controls="srcf-docs-nav" aria-expanded="false" aria-label="Toggle docs navigation">
{{ partial "icons/expand.svg" (dict "class" "bi bi-expand" "width" "24" "height" "24") }}
{{ partial "icons/collapse.svg" (dict "class" "bi bi-collapse" "width" "24" "height" "24") }}
</button>
</div>
</nav>
</nav>
17 changes: 17 additions & 0 deletions static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,23 @@ docs-specific classes
box-shadow: 0 0 0 3px rgba(121, 82, 179, 0.25);
}

#srcf-search-results {
font-size: 1rem;
max-height: 80vh;
overflow: auto;
Comment thread
rsa33 marked this conversation as resolved.
Outdated
min-width: 244px; /* to match parent width */
}

#srcf-search-results a.active {
color: #1e2125;
background-color: #e9ecef;
}

#srcf-search-results .search-result-subheader {
display: block;
margin-top: -4px;
}

.srcf-sidebar-toggle {
color: #6c757d;
}
Expand Down
134 changes: 134 additions & 0 deletions static/js/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
window.addEventListener("DOMContentLoaded", function () {
const elSearchQuery = document.getElementById("srcf-search-input");
const elSearchResults = document.getElementById("srcf-search-results");
let selectedIndex = 0;
let fuse = null;

elSearchQuery.addEventListener("input", debounce(async function(event) {
if (!fuse) {
let searchIndex = await fetch("/index.json").then(response => response.json());
flattenIndex(searchIndex);

fuse = new Fuse(searchIndex, {
keys: [
{ name: "title", weight: 1 },
{ name: "headings.title", weight: 0.7 },
{ name: "contents", weight: 0.4 },
],
threshold: 0.4,
includeMatches: true,
minMatchCharLength: 3,
ignoreLocation: true,
});
}

const searchQuery = event.target.value;
console.log(searchQuery)
if (searchQuery.length > 2) {
elSearchResults.classList.remove("d-none");
executeSearch(searchQuery);
selectedIndex = 0;
updateSelected();
} else {
elSearchResults.classList.add("d-none");
}
}, 50));

elSearchQuery.addEventListener("keydown", function(event) {
const resultCount = elSearchResults.children.length;
if (event.key === "ArrowDown") {
event.preventDefault();
selectedIndex = (selectedIndex + 1) % resultCount;
updateSelected();
} else if (event.key === "ArrowUp") {
event.preventDefault();
selectedIndex = (selectedIndex - 1 + resultCount) % resultCount;
updateSelected();
} else if (event.key === "Enter") {
event.preventDefault();
elSearchResults.children[selectedIndex].click();
}
});

window.addEventListener("keydown", function(event) {
if (event.key === "/" && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
elSearchQuery.focus();
elSearchQuery.select();
}
});

window.addEventListener("mousedown", function(event) {
if (!elSearchResults.contains(event.target) && event.target !== elSearchQuery) {
elSearchResults.classList.add("d-none");
}
});

function debounce(fn, delay) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() => fn.apply(this, arguments), delay);
};
}

function updateSelected() {
for (let child of elSearchResults.children) {
child.classList.remove("active");
if (child === elSearchResults.children[selectedIndex]) {
child.classList.add("active");
}
}
}

function flattenIndex(index) {
function flattenHeadings(headings, result = []) {
for (const heading of headings) {
result.push({ id: heading.ID, title: heading.Title });
if (heading.Headings) {
flattenHeadings(heading.Headings, result);
}
}
return result;
}

index.forEach(item => item.headings = flattenHeadings(item.headings));
}

function executeSearch(searchQuery) {
var results = fuse.search(searchQuery);

elSearchResults.innerHTML = "";

if (results.length == 0) {
const elNoResults = document.createElement("div");
elNoResults.className = "dropdown-item disabled";
elNoResults.innerText = "No matches found";
elSearchResults.appendChild(elNoResults);
return;
}

results.forEach((result, index) => {
const elResult = document.createElement("a");
elResult.className = "dropdown-item";

elResult.href = result.item.permalink;

elResult.innerText = result.item.title;
if (result.matches && result.matches.length > 0 && result.matches[0].key === "headings.title") {
const subheader = document.createElement("small");
subheader.className = "text-muted search-result-subheader";
subheader.innerHTML = result.matches[0].value;
elResult.appendChild(subheader);
elResult.href += "#" + result.item.headings[result.matches[0].refIndex].id;
}

elResult.addEventListener("mouseenter", function() {
selectedIndex = index;
updateSelected();
});

elSearchResults.appendChild(elResult);
});
}
});