<% /**
* Copyright (C) 2008 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ %>
<%
/*
* "highlight" takes an array of search results and an array of search terms.
* For each search term, it strips the term to its stem and then it uses a regular expression to search
* for all matching similar words in each result and put them in a highlighted <span> element.
*
* An alternative way of doing this would be to take each word of the result and "stem" it, then compare it
* to each search term, but this was rejected because it is a) uglier than this (if that's even possible) and
* b) would take forever.
*
*/
var suffix = "able|ible|al|ial|ed|en|er|est|ful|ic|ing|ion|tion|ation|ition|ity|ty|ive|ative|itive|less|ly|ment|ness|ous|eous|ious|s|es|y";
var prefix = "anti|de|dis|en|em|fore|in|im|il|ir|inter|mid|mis|non|over|pre|re|semi|sub|super|trans|un|under";
core.text.stem();
// extract up to m words before the search term and n words after for context
function summarize(result, searchterm) {
var m = 15, n = 20;
retAr = [];
if(result == null)
return;
searchterm = Search.queryToArray(searchterm);
var stem = Stem.stem(searchterm[0]);
var summary = new RegExp("(\\w+\\W+){"+m+"}("+prefix+")?"+stem+"("+suffix+")?(\\W+\\w+){"+n+"}", "gi");
match = result.match(summary);
// if there is trailing header and footer
if(match)
for(var i=0; i<match.length; i++)
retAr.push( "..."+match[i]+"...");
summary = new RegExp("(\\w+\\W+){"+m+"}("+prefix+")?"+stem+"("+suffix+")?(\\W+\\w+){0,"+n+"}\$", "i");
match = result.match(summary);
// if there is trailing header
if(match)
retAr.push("..."+match[0]);
summary = new RegExp("^(\\w+\\W+){0,"+m+"}("+prefix+")?"+stem+"("+suffix+")?(\\W+\\w+){"+n+"}", "i");
match = result.match(summary);
// if there is trailing footer
if(match)
retAr.push(match[0]+"...");
// no trailing header or footer
summary = new RegExp("^(\\w+\\W+){0,"+m+"}("+prefix+")?"+stem+"("+suffix+")?(\\W+\\w+){0,"+n+"}\$", "i");
match = result.match(summary);
if(match)
retAr.push(match[0]);
return retAr;
}
Forum.root.controller();
Forum.root.html.forumheader("Forum | Search Results for \""+request.query+"\"");
Forum.root.data.thread();
Forum.root.html.form();
Forum.root.data.paging();
var query = request.query;
var threads = Search.search(db.forum.threads, query);
var paging = new Forum.data.Paging(threads, {pageSize: 20, minWindow: 5},
request);
var threads = paging.slice();
Forum.root.html.paging(paging);
var cursor = Search.search(db.forum.topics, query );
// Search bar
Forum.html.search();
%>
<h1>Forum</h1>
<script type="text/javascript">
var color = "none";
function toggleHighlight() {
var all = document.all ? document.all :
document.getElementsByTagName('span');
for (var e = 0; e < all.length; e++)
all[e].style.background = color;
color = color == "none" ? "#FBFAAB" : "none";
}
</script>
<div class="match_div">
<%
var query_enc = content.HTML.escape(query);
if(threads.length == 0 && cursor.length == 0){
%>
<div>No search results for "<%= query_enc %>".</div>
<%
}
else{
print("<div>Search results for \""+query_enc+"\" <input type=\"checkbox\" value=\"highlight\" onclick=\"toggleHighlight()\" checked>Highlight</div>");
if(cursor.length > 0) { %>
<div class="match_div">
<%
Forum.root.html.topictable("Matching topics:", null, cursor, null, [], {createThread: false, editUser: false, createTopic: false, thisid: null, highlight: query}); %>
</div>
<%
}
%>
<div class="match_div">
<%
if(threads.length > 0){ %>
<h1>Matching <%= allowModule.forum.threadName.toLowerCase() %>s:</h1>
<%
for(var i = 0; i < threads.length; i++){
var starti = i;
%>
<div class="threadbox">
<div class="title">
<%
var tops = Forum.html.topicStack(threads[i].topic);
for(var j=0; j<tops.length; j++) {
print('<a href="viewtopic?name='+URL.escape_queryargs(tops[j])+'">'+tops[j]+'</a> > ');
}
%>
<a href="viewtopic?name=<%= URL.escape_queryargs(threads[i].topic.name) %>"><%= threads[i].topic.name %></a> >
<a href="viewthread?id=<%= threads[i]._id+"&highlight="+query %>"><%= Forum.html.highlight(content.HTML.escape(threads[i].getTitle()), query) %></a>
</div>
<%
var snippets = Search.snippet(threads[i], query, threads[i].SEARCH_WEIGHTS);
for(var j=0; snippets != null && j < 4 && j < snippets.length; j++) {
if(snippets[j].text == snippets[j].object.title)
continue;
var prettyDate = snippets[j].object.ts.format("MMM d, yyyy '<span class=''time''>' h:mm")+snippets[j].object.ts.format("a").toLowerCase() +"</span>";
%>
<div class="content">
<div class="meta"><%= snippets[j].object.author_name %> on <%= prettyDate %></div></div>
<div class="snips">
<%
summary = summarize(snippets[j].text, query);
for(var k=0; k<summary.length; k++)
print(Forum.html.highlight(summary[k], query)+"<br />");
%>
</div>
</div>
<%
}
if(snippets && snippets.length > 4)
print("(First four shown, "+snippets.length+" matching posts in thread)");
%>
</div>
<%
}
}
else {
%>
No matches in <%= allowModule.forum.threadName.toLowerCase() %>s.
<%
}
}
%>
</div>
<input type="button" class="button" onclick="history.back()" value="Back">
</div>
<%
Forum.root.html.paging(paging);
htmlfooter();
%>