[Docs] Wire up the search feature.

This commit is contained in:
Chris Eppstein 2010-05-08 15:23:07 -07:00
parent c1c2d133a4
commit 9feb387321
6 changed files with 58 additions and 13 deletions

View File

@ -0,0 +1 @@
jQuery.url=function(){var segments={};var parsed={};var options={url:window.location,strictMode:false,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}};var parseUri=function(){str=decodeURI(options.url);var m=options.parser[options.strictMode?"strict":"loose"].exec(str);var uri={};var i=14;while(i--){uri[options.key[i]]=m[i]||""}uri[options.q.name]={};uri[options.key[12]].replace(options.q.parser,function($0,$1,$2){if($1){uri[options.q.name][$1]=$2}});return uri};var key=function(key){if(!parsed.length){setUp()}if(key=="base"){if(parsed.port!==null&&parsed.port!==""){return parsed.protocol+"://"+parsed.host+":"+parsed.port+"/"}else{return parsed.protocol+"://"+parsed.host+"/"}}return(parsed[key]==="")?null:parsed[key]};var param=function(item){if(!parsed.length){setUp()}return(parsed.queryKey[item]===null)?null:parsed.queryKey[item]};var setUp=function(){parsed=parseUri();getSegments()};var getSegments=function(){var p=parsed.path;segments=[];segments=parsed.path.length==1?{}:(p.charAt(p.length-1)=="/"?p.substring(1,p.length-1):path=p.substring(1)).split("/")};return{setMode:function(mode){strictMode=mode=="strict"?true:false;return this},setUrl:function(newUri){options.url=newUri===undefined?window.location:newUri;setUp();return this},segment:function(pos){if(!parsed.length){setUp()}if(pos===undefined){return segments.length}return(segments[pos]===""||segments[pos]===undefined)?null:segments[pos]},attr:key,param:param}}();

View File

@ -1,7 +1,34 @@
function search(term, callback) { function unique(arrayName)
var ids = index.terms[term] || index.approximate[term] || []; {
var items = $.map(ids, function(id){ return index.items[id]; }); var newArray = new Array();
callback(items) label: for (var i = 0; i < arrayName.length; i++)
{
for (var j = 0; j < newArray.length; j++)
{
if (newArray[j] == arrayName[i])
continue label;
}
newArray[newArray.length] = arrayName[i];
}
return newArray;
}
function search(query, callback) {
var terms = $.trim(query).replace(/[\W\s_]+/m,' ').toLowerCase().split(/\s+/);
var matching_ids = null;
for (var i = 0; i < terms.length; i++) {
var term = terms[i];
var exactmatch = index.terms[term] || [];
var approxmatch = index.approximate[term] || [];
var ids = unique(exactmatch.concat(approxmatch));
if (matching_ids) {
matching_ids = $.grep(matching_ids, function(id) {
return ids.indexOf(id) != -1;
});
} else {
matching_ids = ids;
}
}
callback($.map(matching_ids, function(id){ return index.items[id]; }))
} }
var index = <%= search_index.to_json %>; var index = <%= search_index.to_json %>;

View File

@ -5,9 +5,14 @@ body_id: search
--- ---
- content_for(:javascripts) do - content_for(:javascripts) do
%script(type="text/javascript" src="/docs/javascripts/search-data.js") %script(type="text/javascript" src="/docs/javascripts/search-data.js")
%script(type="text/javascript" src="/docs/javascripts/jquery.url.packed.js")
:javascript :javascript
$(function(){ $(function(){
$('input').keypress(function(){ if ($.url.param("q")) {
$('input#q').attr('value', $.url.param("q"));
search($.url.param("q"), displayResults);
}
$('input#q').keyup(function(){
search(this.value, displayResults); search(this.value, displayResults);
}); });
}) })
@ -22,7 +27,7 @@ body_id: search
$('ol#results').html("<li class='none'>Nothing found.</li>"); $('ol#results').html("<li class='none'>Nothing found.</li>");
} }
} }
%input{:type => "text", :placeholder=>"Search"} %input#q{:type => "text", :placeholder=>"Search"}
%ol#results %ol#results
%li.none Please enter a search term. %li.none Please enter a search term.

View File

@ -15,4 +15,14 @@
#ex3 dd #ex3 dd
+radial-gradient(color-stops(#FFF, #F00 5px, #0C0, #00C 25px), center center) +radial-gradient(color-stops(#FFF, #F00 5px, #0C0, #00C 25px), center center)
body#search
#page
+box-sizing(border)
text-align: center
input
width: 50%
font-size: 3em
ol
list-style-position: inside
margin-left: 25%
text-align: left

View File

@ -30,10 +30,10 @@
Current Version: Current Version:
%a.number(href="/docs/CHANGELOG/")= compass_version %a.number(href="/docs/CHANGELOG/")= compass_version
#search-docs #search-docs
%form %form{:action => "/docs/search/", :method => "GET"}
%p %p
%label{:for => "search"} search %label{:for => "search"} search
%input#search{:name => "search", :type => "text", :value => "", :placeholder => "doesn't work yet"} %input#search{:name => "q", :type => "text", :value => ""}
- if @item[:content_for_module_nav] - if @item[:content_for_module_nav]
%nav#module-nav= @item[:content_for_module_nav] %nav#module-nav= @item[:content_for_module_nav]
#page= yield #page= yield

View File

@ -38,7 +38,7 @@ def search_terms_for(item)
content = item.rep_named(:default).compiled_content content = item.rep_named(:default).compiled_content
doc = Nokogiri::HTML(content) doc = Nokogiri::HTML(content)
full_text = doc.css("p, h1, h2, h3, h4, h5, h6").map{|el| el.inner_text}.join(" ") full_text = doc.css("p, h1, h2, h3, h4, h5, h6").map{|el| el.inner_text}.join(" ")
"#{item[:title]} #{item[:meta_description]} #{full_text}".gsub(/[\W\s]+/m,' ').downcase.split(/\s+/).uniq - STOP_WORDS "#{item[:title]} #{item[:meta_description]} #{full_text}".gsub(/[\W\s_]+/m,' ').downcase.split(/\s+/).uniq - STOP_WORDS
else else
[] []
end end
@ -53,18 +53,20 @@ def search_index
} }
@items.each do |item| @items.each do |item|
search_terms_for(item).each do |term| search_terms_for(item).each do |term|
idx["terms"][term] = [] idx["terms"][term] ||= []
idx["terms"][term] << id idx["terms"][term] << id
(0...term.length).each do |c| (0...term.length).each do |c|
subterm = term[0...c] subterm = term[0...c]
# puts "Indexing: #{subterm}"
idx["approximate"][subterm] ||= [] idx["approximate"][subterm] ||= []
unless idx["approximate"][subterm].include?(id) unless idx["approximate"][subterm].include?(id)
idx["approximate"][subterm] << id idx["approximate"][subterm] << id
end end
end end
# puts "Indexed: #{term}"
end end
idx["items"][id] = { idx["items"][id] = {
"url" => item.identifier, "url" => "/docs#{item.identifier}",
"title" => item[:title], "title" => item[:title],
"crumb" => item[:crumb] "crumb" => item[:crumb]
} }