Skip to content

Commit

Permalink
Dev edition: add back jump-to search
Browse files Browse the repository at this point in the history
Closes whatwg#2779. This depends on whatwg/html-build#114. The styles and scripts are based on https://github.com/benschwarz/developers.whatwg.org/tree/97ff943a8f5b8fe38f78e224b4b44b472ccefb57, but adapted and modernized, with some bugs fixed and behaviors tweaked.
  • Loading branch information
Juan Olvera authored and domenic committed Jul 13, 2017
1 parent acf5b2b commit cfb8b9e
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 1 deletion.
134 changes: 134 additions & 0 deletions dev/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
'use strict';
// Find-as-you-type search

(function() {

const search = document.getElementById('search');
const query = document.getElementById('query');
const resultsList = document.getElementById('results');
const maxResults = 10;

const UP_KEY_CODE = 38;
const DOWN_KEY_CODE = 40;

let jsonResponses = [];

fetch('search-index.json')
.then(response => response.json())
.then(data => jsonResponses = data)
.catch(err => console.error('Error loading search-index.json'));

function resultTemplate(result) {
return `<li><a href="${result.url}">${result.text} <span>Section ${result.section}</span></a></li>`;
}

function findSections(word, responses) {
// If input is empty, show nothing.
if (!word) {
return [];
}

return responses
.filter((response) => {
const regex = new RegExp(word, 'gi');
return response.text.match(regex);
})
.map(response => resultTemplate(response))
.slice(0, maxResults).join('');
}

function renderResults(results) {
resultsList.innerHTML = findSections(results, jsonResponses);
}

query.addEventListener('input', (event) => {
renderResults(event.target.value);
});

// Move between query and results with keyboard
document.addEventListener('keydown', (event) => {
const current = getCurrentNavigationElement();
if (!current) {
return;
}

const keyCode = event.keyCode;
let element;
if (keyCode === UP_KEY_CODE) {
element = getPreviousNavigationElement(current);
}
if (keyCode === DOWN_KEY_CODE) {
element = getNextNavigationElement(current);
}

if (element) {
element.focus();
event.preventDefault();
}
});

// Focus element on mouse over
resultsList.addEventListener('mousemove', (event) => {
const target = event.target;
if (target && target.nodeName === 'A') {
target.focus();
}
});

// If we go back from other place and click on the input, do the search again.
query.addEventListener('click', event => renderResults(query.value));

// When click on search area focus on input
search.addEventListener('click', event => query.focus());

// Slash to search '/'
document.addEventListener('keyup', (event) => {
if (event.keyCode === 191) {
query.focus();
}
});

// Clean results when click outside the search bar
document.addEventListener('click', (event) => {
if (event.target !== query) {
renderResults('');
}
});

function getCurrentNavigationElement() {
const active = document.activeElement;
if (active === query) {
return active;
}

const parent = active.parentNode;
if (parent) {
const grandparent = parent.parentNode;
if (grandparent === resultsList) {
return active;
}
}
return null;
}

function getNextNavigationElement(currentEl) {
if (currentEl === query) {
return resultsList.querySelector('a');
}

const nextLI = currentEl.parentNode.nextSibling;
return nextLI ? nextLI.firstChild : query;
}

function getPreviousNavigationElement(currentEl) {
const allResults = resultsList.querySelectorAll('a');

if (currentEl === query) {
return allResults.length > 0 ? allResults[allResults.length - 1] : null;
}

const prevLI = currentEl.parentNode.previousSibling;
return prevLI ? prevLI.firstChild : query;
}

})();
84 changes: 83 additions & 1 deletion dev/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,19 @@ header#head {
position: relative;
}

header#head hgroup {
width: 580px;
}

header#head h1 {
line-height: 1em;
font-family: "M+2pheavy", "Helvetica Neue", Arial, Helvetica, sans-serif;
font-weight: bold;
color: black;
}

header#head a:link, header.head a:visited {
header#head a.logo, header#head a.logo:visited,
header#head hgroup a:link, header#head hgroup a:visited {
border-bottom: 0;
}

Expand All @@ -383,6 +388,65 @@ header#head .logo {
top: -20px;
}

/* Search bar */

#search {
position: absolute;
top: 0;
right: 0;
}

#search, #search input {
width: 150px;
}

#search ol {
z-index: 1;
position: absolute;
right: 0;
width: 25em;
list-style: none;
background-color: #eee;
border-radius: 0.2em;
box-shadow: 0 0 1em rgba(0, 0, 0, 0.75);
}

#search ol li {
text-align: left;
}

#search ol li:first-of-type a:focus {
border-top-left-radius: 0.2em;
border-top-right-radius: 0.2em;
}

#search ol li:last-of-type a:focus {
border-bottom-left-radius: 0.2em;
border-bottom-right-radius: 0.2em;
}

#search ol li a {
display: block;
padding: 0.2em 0.4em;
color: #222;
}

#search ol li a:focus {
color: white;
background-color: #3c790a;
}

#search ol li a:focus span {
color: rgba(255, 255, 255, 0.7);
}

#search ol li a span {
display: block;
color: #555;
font-size: 0.7em;
font-style: italic;
}

/* Nav and table of contents */

body > nav {
Expand Down Expand Up @@ -487,4 +551,22 @@ html:not(.index) ol.toc ol {
top: auto;
margin-left: 0.5em;
}

/* Search */
#search {
position: relative;
display: block;
width: 100%;
}

#search input,
#search ol {
margin: 0 auto;
width: 90%;
}

#search ol {
position: relative;
box-shadow: none;
}
}
6 changes: 6 additions & 0 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@
</style>
</head>
<body>
<script w-nohtml src="search.js" async></script>
<script w-nodev src="/html-dfn.js" async></script>
<script w-nodev src="https://resources.whatwg.org/file-issue.js" async data-file-issue-url="https://github.com/whatwg/html/issues/new"></script>
<header class="head with-buttons" id="head">
Expand Down Expand Up @@ -252,6 +253,11 @@
<a class="feedback" href="https://whatwg.org/newbug"><span data-x=""><strong>Open an Issue</strong> <code data-x="">whatwg.org/newbug</code></span></a>
</div>
</nav>

<div id="search" w-nohtml>
<input name="query" type="search" placeholder="Search. Press '/'" autocomplete="off" id="query">
<ol id="results"></ol>
</div>
</header>

<hr w-nodev w-nosplit>
Expand Down

0 comments on commit cfb8b9e

Please sign in to comment.