forked from meteor/meteor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Search-as-you-type for docs.meteor.com
Conflicts: docs/client/data.js
- Loading branch information
Sashko Stubailo
committed
Dec 5, 2014
1 parent
76745d2
commit 6493d6a
Showing
8 changed files
with
288 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<template name="search"> | ||
{{#if searchOpen}} | ||
<div class="search-overlay"> | ||
<div class="search-box"> | ||
<a href="#" class="close-search"><span class="hotkey">[esc]</span> ×</a> | ||
<h3>Search Documentation</h3> | ||
<input type="text" class="search-query" /> | ||
</div> | ||
<ul class="search-results"> | ||
{{#each searchResults}} | ||
<li> | ||
<strong>{{longname}}</strong>: {{#markdown}}{{summary}}{{/markdown}} | ||
</li> | ||
{{else}} | ||
No search results found. | ||
{{/each}} | ||
</ul> | ||
</div> | ||
{{/if}} | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
APICollection = new Meteor.Collection(null); | ||
|
||
_.each(DocsData, function (val) { | ||
// XXX only insert things that are actually in the docs | ||
if (val.kind !== "namespace") { | ||
APICollection.insert(val); | ||
} | ||
}); | ||
|
||
Session.setDefault("searchOpen", false); | ||
Session.set("searchQuery", ""); | ||
|
||
$(document).on("keydown", function (event) { | ||
if (event.which === 27) { | ||
Session.set("searchOpen", false); | ||
} | ||
}); | ||
|
||
$(document).on("keypress", function (event) { | ||
if (event.which && (event.which !== 13) && (event.which !== 32)) { | ||
if (! Session.get("searchOpen")) { | ||
Session.set("searchOpen", true); | ||
|
||
Tracker.flush(); | ||
$(".search-query").val(""); | ||
$(".search-query").focus(); | ||
} | ||
} | ||
}); | ||
|
||
var updateQuery = _.throttle(function () { | ||
Session.set("searchQuery", $(".search-query").val()); | ||
|
||
Tracker.afterFlush(function () { | ||
var currentSelected = $(".search-results .selected"); | ||
if (! currentSelected.length) { | ||
selectListItem($(".search-results li").first()); | ||
} | ||
}); | ||
}, 200); | ||
|
||
var selectListItem = function ($newSelected) { | ||
var currentSelected = $(".search-results .selected"); | ||
currentSelected.removeClass("selected"); | ||
|
||
if ($newSelected.length) { | ||
$newSelected.addClass("selected"); | ||
|
||
// scroll to make sure everything is inside the viewport | ||
var searchResults = $(".search-results"); | ||
|
||
// make sure it's inside the visible area | ||
var viewportTop = searchResults.offset().top; | ||
var viewportHeight = searchResults.height(); | ||
var elTop = $newSelected.offset().top; | ||
var elHeight = $newSelected.height(); | ||
|
||
// check if bottom is below visible part | ||
if (elTop + elHeight > viewportTop + viewportHeight) { | ||
var amount = searchResults.scrollTop() + | ||
(elTop + elHeight - (viewportTop + viewportHeight)); | ||
searchResults.scrollTop(amount); | ||
} | ||
|
||
// check if top is above visible section | ||
if (elTop < viewportTop) { | ||
searchResults.scrollTop(searchResults.scrollTop() + elTop - viewportTop); | ||
} | ||
} | ||
}; | ||
|
||
Template.search.events({ | ||
"keyup input": updateQuery, | ||
"click .close-search": function () { | ||
Session.set("searchOpen", false); | ||
return false; | ||
}, | ||
"keydown": function (event, template) { | ||
var currentSelected = template.$(".search-results .selected"); | ||
|
||
if (event.which === 13) { | ||
// enter pressed, go to the selected item | ||
Session.set("searchQuery", $(".search-query").val()); | ||
|
||
Tracker.afterFlush(function () { | ||
if (! currentSelected.length) { | ||
currentSelected = template.$(".search-results li").first(); | ||
} | ||
|
||
if (currentSelected.length) { | ||
var selectedName = Blaze.getView(currentSelected.get(0)).dataVar.get().longname; | ||
var id = nameToId[selectedName] || selectedName.replace(/[.#]/g, "-"); | ||
var url = "#/full/" + id; | ||
window.location.replace(url); | ||
Session.set("searchOpen", false); | ||
} | ||
}); | ||
|
||
// exit function | ||
return; | ||
} | ||
|
||
var change = 0; | ||
if (event.which === 38) { | ||
// up | ||
change = -1; | ||
} else if (event.which === 40) { | ||
// down | ||
change = 1; | ||
} | ||
|
||
if (change !== 0) { | ||
if (change === 1) { | ||
if (currentSelected.length) { | ||
selectListItem(currentSelected.next()); | ||
} else { | ||
selectListItem(template.$(".search-results li").first()); | ||
} | ||
} else { | ||
if (currentSelected.length) { | ||
selectListItem(currentSelected.prev()); | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} | ||
}); | ||
|
||
var dedup = function (arr) { | ||
var ids = {}; | ||
var output = []; | ||
|
||
_.each(arr, function (innerArray) { | ||
_.each(innerArray, function (item) { | ||
if (! ids.hasOwnProperty(item._id)) { | ||
ids[item._id] = true; | ||
output.push(item); | ||
} | ||
}); | ||
}); | ||
|
||
return output; | ||
}; | ||
|
||
Template.search.helpers({ | ||
searchResults: function () { | ||
if (Session.get("searchQuery")) { | ||
var regex = new RegExp(Session.get("searchQuery"), "i"); | ||
|
||
var nameMatches = APICollection.find({ longname: {$regex: regex}}).fetch(); | ||
var summaryMatches = APICollection.find({ summary: {$regex: regex}}).fetch(); | ||
|
||
return dedup([nameMatches, summaryMatches]); | ||
} | ||
}, | ||
searchOpen: function () { | ||
return Session.get("searchOpen"); | ||
} | ||
}); |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters