Skip to content

Commit

Permalink
search
Browse files Browse the repository at this point in the history
  • Loading branch information
kedashoe committed Feb 10, 2017
1 parent 50f4945 commit dcee0ed
Show file tree
Hide file tree
Showing 7 changed files with 163 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 @@
ESLINT = node_modules/.bin/eslint
BROWSERIFY = node_modules/.bin/browserify
UGLIFY = node_modules/.bin/uglifyjs
NPM = npm

CUSTOM = $(shell find custom -name '*.md' | sort)
VENDOR = ramda sanctuary sanctuary-def
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 @@ -46,7 +50,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.11.1</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 @@ -3165,5 +3172,6 @@ <h4 id="unlines"><code><a href="https://github.com/sanctuary-js/sanctuary/blob/v
<script src="vendor/sanctuary-def.js"></script>
<script src="vendor/sanctuary.js"></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 @@ -8,9 +8,12 @@
"sanctuary-logo": "1.0.0"
},
"devDependencies": {
"browserify": "14.0.x",
"envvar": "1.1.x",
"eslint": "2.9.x",
"hindley-milner-search": "0.1.x",
"marked": "0.3.5",
"sanctuary-style": "0.4.x"
"sanctuary-style": "0.4.x",
"uglify-js": "^2.7.5"
}
}
8 changes: 8 additions & 0 deletions scripts/generate
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,21 @@ def('toDocument',
<div id="css-main">
<h1 id="sanctuary">Sanctuary <small>v${version}</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>
${toc(content)}
${content}
</div>
<script src="vendor/ramda.js"></script>
<script src="vendor/sanctuary-def.js"></script>
<script src="vendor/sanctuary.js"></script>
<script src="behaviour.js"></script>
<script src="search.js"></script>
</body>
</html>
`);
Expand Down
8 changes: 8 additions & 0 deletions search.js

Large diffs are not rendered by default.

125 changes: 125 additions & 0 deletions src/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
var HMS = require('hindley-milner-search');

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',
};

function map(f, x) {
return Array.prototype.map.call(x, f);
}

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

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

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

// Node -> Node -> ()
function attachSigResult(container) {
return function(el) {
container.appendChild(el);
};
}

function findAndCloneSignatures(resultsContainer) {
var codes = document.getElementById('toc').querySelectorAll('li a code');
var as = map(getParent, codes);
var newEls = map(initSigResult, as);
return newEls;
}

// Node -> String
function extractSignatureText(el) {
return el.innerText.trim().replace(/\s+/g, ' ');
}

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

// Node -> ()
function clearChildren(container) {
while (container.childNodes.length > 0) {
container.removeChild(container.childNodes[0]);
}
}
function show(el) {
el.style.display = 'block';
}

function hide(el) {
el.style.display = 'none';
}

function showMatches(q, els, matches) {
if (matches.length === 0 && q.length > 0) {
show(state.containerNo);
}
else {
hide(state.containerNo);
}
clearChildren(state.container);
// if there is no query, do not show any matches
if (q.length > 0) {
for (var i = 0; i < matches.length; ++i) {
var match = matches[i];
var el = state.els[match.pointer];
state.container.appendChild(el);
}
}
}

function handleSearchKeyUp(e) {
var q = e.target.value;
if (q === state.prevSearch) {
return;
} else {
// if current search is substring of previous search and previous search has at least 1 word
// character, use previous matches as search space
// todo: we need to know how the search was parsed to properly do this
// eg, if the type changes, we need to reset everything:
// if q is 'a', will search for the name 'a'
// but if q becomes 'a -> a', will search for function
// should we move logic to HMS?
//var space = q.indexOf(state.prevSearch) === 0 && /(^| ).*\w/.test(state.prevSearch) ? state.matches : state.index;
var space = state.index;
state.prevSearch = q;
state.matches = HMS.search(space, 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 > div {
font-size: 75%;
}

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

0 comments on commit dcee0ed

Please sign in to comment.