Skip to content

Commit

Permalink
search
Browse files Browse the repository at this point in the history
  • Loading branch information
kedashoe authored and davidchambers committed Apr 14, 2017
1 parent 48c1193 commit 6acbe96
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 3 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
BROWSERIFY = node_modules/.bin/browserify
ESLINT = node_modules/.bin/eslint
NPM = npm
UGLIFY = node_modules/.bin/uglifyjs

CUSTOM = $(shell find custom -name '*.md' | sort)
VENDOR = ramda sanctuary sanctuary-def sanctuary-type-classes sanctuary-type-identifiers
VENDOR_CHECKS = $(patsubst %,check-%-version,$(VENDOR))
FILES = favicon.png index.html $(patsubst %,vendor/%.js,$(VENDOR))
FILES = favicon.png index.html search.js $(patsubst %,vendor/%.js,$(VENDOR))


.PHONY: all
Expand All @@ -22,6 +24,8 @@ vendor/ramda.js: node_modules/ramda/dist/ramda.js
vendor/%.js: node_modules/%/index.js
cp '$<' '$@'

search.js: src/search.js
$(BROWSERIFY) '$<' | $(UGLIFY) > '$@'

.PHONY: $(VENDOR_CHECKS)
$(VENDOR_CHECKS): check-%-version:
Expand All @@ -47,7 +51,7 @@ lint:
--config node_modules/sanctuary-style/eslint-es3.json \
--env es3 \
--env browser \
-- behaviour.js
-- behaviour.js src/search.js
make clean
make
git diff --exit-code
Expand Down
8 changes: 8 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
<div id="css-main">
<h1 id="sanctuary">Sanctuary <small>v0.12.2</small></h1>
<p id="tagline">Refuge from unsafe JavaScript</p>
<div>
<input type="text" id="search-input" placeholder="search" />
</div>
<div id="search-results">
<div id="no-matches" style="display:none;">No matches</div>
<div id="yes-matches"></div>
</div>

<ul id="toc">
<li>
Expand Down Expand Up @@ -3956,5 +3963,6 @@ <h4 id="splitOn"><code><a href="https://github.com/sanctuary-js/sanctuary/blob/v
window.S = window.sanctuary;
</script>
<script src="behaviour.js"></script>
<script src="search.js"></script>
</body>
</html>
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
"sanctuary-type-identifiers": "1.0.0"
},
"devDependencies": {
"browserify": "14.0.x",
"envvar": "1.1.x",
"eslint": "3.19.x",
"hindley-milner-search": "0.1.x",
"marked": "0.3.5",
"sanctuary-style": "0.5.x"
"sanctuary-style": "0.5.x",
"uglify-js": "2.7.x"
}
}
8 changes: 8 additions & 0 deletions scripts/generate
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,13 @@ def('toDocument',
<div id="css-main">
<h1 id="sanctuary">Sanctuary <small>v${version}</small></h1>
<p id="tagline">${tagline}</p>
<div>
<input type="text" id="search-input" placeholder="search" />
</div>
<div id="search-results">
<div id="no-matches" style="display:none;">No matches</div>
<div id="yes-matches"></div>
</div>
${toc(content)}
${content}
</div>
Expand All @@ -406,6 +413,7 @@ ${content}
window.S = window.sanctuary;
</script>
<script src="behaviour.js"></script>
<script src="search.js"></script>
</body>
</html>
`);
Expand Down
2 changes: 2 additions & 0 deletions search.js

Large diffs are not rendered by default.

138 changes: 138 additions & 0 deletions src/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
(function() {

'use strict';

/* global require */

var HMS = require('hindley-milner-search');

var S = window.S.create({checkTypes: false, env: window.S.env});

var state = {
// [Node], the dom elements we will be showing/hiding when user searches
els: null,
// Node, container for results
container: null,
// Node, container for notification if there are no matches
containerNo: null,
// [Signature], the signatures as compiled by HMS
index: [],
// [Signature], most recent matches
matches: [],
// String, most recent user input
prevSearch: 'placeholder'
};

// map :: (a -> b) -> [a] -> [b]
var map = S.curry2(function map(f, xs) {
return Array.prototype.map.call(xs, function(x) { return f(x); });
});

// getParent :: Node -> Node
function getParent(el) {
return el.parentNode;
}

// initSigResult :: Node -> Node
function initSigResult(apiLink) {
var el = document.createElement('div');
var clone = apiLink.cloneNode(true);
el.appendChild(clone);
el.className = 'search-result';
return el;
}

// firstChild :: Node -> Node
function firstChild(el) {
return el.childNodes[0];
}

// getAttribute :: String -> Node -> String
var getAttribute = S.curry2(function getAttribute(key, el) {
return el.getAttribute(key);
});

// uniqWith :: (a -> String) -> [a] -> [a]
var uniqWith = S.curry2(function uniqWith(f, xs) {
var lookup = {};
var ys = [];
for (var i = 0; i < xs.length; i += 1) {
var x = xs[i];
var val = f(x);
if (!(val in lookup)) {
lookup[val] = 1;
ys.push(x);
}
}
return ys;
});

// initSigNodes :: Node -> [Node]
function initSigNodes(resultsContainer) {
var codes = document.getElementById('toc').querySelectorAll('li a code');
return S.pipe([
map(S.compose(initSigResult, getParent)),
uniqWith(S.compose(getAttribute('href'), firstChild))
], codes);
}

// extractSignatureText :: Node -> String
var extractSignatureText = S.pipe([
S.prop('innerText'),
S.words,
S.unwords
]);

// initState :: Node -> IO ()
function initState(resultsContainer) {
state.container = document.getElementById('yes-matches');
state.containerNo = document.getElementById('no-matches');
state.els = initSigNodes(resultsContainer);
state.index = HMS.index(map(extractSignatureText, state.els));
}

// clearChildren :: Node -> IO ()
function clearChildren(container) {
while (container.childNodes.length > 0) {
container.removeChild(container.childNodes[0]);
}
}

// setNoMatchesVisibility :: (String, [Match], Node) -> IO ()
function setNoMatchesVisibility(q, matches, el) {
el.style.display = matches.length === 0 && q.length > 0 ? 'block' : 'none';
}

// showMatches :: (String, [Node], [Match]) -> IO ()
function showMatches(q, els, matches) {
setNoMatchesVisibility(q, matches, state.containerNo);
clearChildren(state.container);
// if there is no query, do not show any matches
if (q.length > 0) {
matches.forEach(function(match) {
var el = state.els[match.pointer];
state.container.appendChild(el);
});
}
}

// handleSearchKeyUp :: Event -> IO ()
function handleSearchKeyUp(e) {
var q = e.target.value;
if (q === state.prevSearch) {
return;
} else {
state.prevSearch = q;
state.matches = HMS.search(state.index, q);
showMatches(q, state.els, state.matches);
}
}

window.addEventListener('DOMContentLoaded', function() {
initState(document.getElementById('search-results'));
var searchInput = document.getElementById('search-input');
searchInput.focus();
searchInput.addEventListener('keyup', handleSearchKeyUp);
});

}());
4 changes: 4 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ a code {
top: -0.05em;
}

#search-results .search-result {
font-size: 75%;
}

pre {
margin: 1.334em 0;
padding: 0;
Expand Down

0 comments on commit 6acbe96

Please sign in to comment.