Skip to content

Commit

Permalink
Search-as-you-type for docs.meteor.com
Browse files Browse the repository at this point in the history
Conflicts:
	docs/client/data.js
  • Loading branch information
Sashko Stubailo committed Dec 5, 2014
1 parent 76745d2 commit 6493d6a
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 35 deletions.
6 changes: 1 addition & 5 deletions docs/client/api-box.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ var apiData = function (options) {
options = {name: options};
}

var root = DocsData;

_.each(options.name.split("."), function (pathSegment) {
root = root[pathSegment];
});
var root = DocsData[options.name];

if (! root) {
console.log("API Data not found: " + options.name);
Expand Down
2 changes: 1 addition & 1 deletion docs/client/data.js

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions docs/client/docs.less
Original file line number Diff line number Diff line change
Expand Up @@ -606,3 +606,93 @@ pre {
display: none;
}
}

.search-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 3;
background: white;

overflow: hidden;

.close-search {
float: right;
font-size: 2em;

.hotkey {
font-size: 0.6em;
color: #777;
vertical-align: middle;
}

text-decoration: none;

&:hover {
text-decoration: none;
background: none;
}
}

.search-box {
margin: 40px;

h3 {
font-size: 2em;
}

input {
font-size: 2em;
padding: 0.5em 0;
background: transparent;
border: none;
border-bottom: 2px solid #777;
width: 80%;

&:focus {
outline: 0;
}
}
}

.search-results {
margin: 40px;

position: absolute;
bottom: 0;
left: 0;
right: 0;
top: 170px;

overflow-y: scroll;
list-style: none;

padding: 0;

li {
font-size: 1em;
margin-bottom: 0.5em;
padding: 10px;
white-space: nowrap;

p {
margin: 0;
display: inline;
}

strong {
font-weight: bold;
}

&.selected {
background: yellow;
}
}
}
}

.menu-icon {
height: 0.6em;
}
3 changes: 2 additions & 1 deletion docs/client/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

<body>
<div class="body {{openSidebar}}">
{{> search}}
<div id="nav">
{{> sidebar}}
</div>
Expand Down Expand Up @@ -46,7 +47,7 @@ <h1>

<template name="topBar">
<div class="top-bar">
<div class="open-sidebar">&#9776;</div>
<div class="open-sidebar"><img src="menu.png" class="menu-icon" /></div>
<h1>
<img src="/logo.png" class="logo" alt="Meteor" /> 1.0 Docs
</h1>
Expand Down
20 changes: 20 additions & 0 deletions docs/client/search.html
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> &times;</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>
160 changes: 160 additions & 0 deletions docs/client/search.js
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");
}
});
Binary file added docs/public/menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 14 additions & 28 deletions scripts/admin/jsdoc/docdata-jsdoc-template/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
var _ = require("underscore");

var names = [];
var dataContents = {};

/**
* Get a tag dictionary from the tags field on the object, for custom fields
Expand All @@ -27,31 +28,17 @@
return tagDict;
};

var addToTree = function (root, location, data) {
var path = location.split(".");
var addToData = function (location, data) {
_.extend(data, getTagDict(data));

_.each(path, function (segment) {
if (! (segment in root)) {
root[segment] = {};
}

root = root[segment];
});

for (var prop in data) {
if (data.hasOwnProperty(prop)) {
root[prop] = data[prop];
}
}

root.comment = undefined;
root.meta = undefined;
root.___id = undefined;
root.___s = undefined;
root.tags = undefined;

_.extend(root, getTagDict(data));
data.comment = undefined;
data.meta = undefined;
data.___id = undefined;
data.___s = undefined;
data.tags = undefined;

names.push(location);
dataContents[location] = data;
};

/**
Expand All @@ -61,22 +48,21 @@
*/
exports.publish = function(taffyData) {
var data = helper.prune(taffyData);
var docTree = {};

var namespaces = helper.find(data, {kind: "namespace"});

// prepare all of the namespaces
_.each(namespaces, function (namespace) {
if (namespace.summary) {
addToTree(docTree, namespace.longname, namespace);
addToData(namespace.longname, namespace);
}
});

var properties = helper.find(data, {kind: "member"});

_.each(properties, function (property) {
if (property.summary) {
addToTree(docTree, property.longname, property);
addToData(property.longname, property);
}
});

Expand Down Expand Up @@ -117,11 +103,11 @@
// takes up too much room
delete func.comment;

addToTree(docTree, func.longname, func);
addToData(func.longname, func);
});

// write full docs JSON
var jsonString = JSON.stringify(docTree);
var jsonString = JSON.stringify(dataContents);
var jsString = "DocsData = " + jsonString + ";";
jsString = "// This file is automatically generated by JSDoc; regenerate it with scripts/admin/jsdoc/jsdoc.sh\n" + jsString;
var docsDataFilename = "docs/client/data.js";
Expand Down

0 comments on commit 6493d6a

Please sign in to comment.