Replaced ats3_testdrop with ats_testdrop to handle sending test drops to ATS4 server
/**+ −
* helper function to return a node containing the+ −
* search summary for a given text. keywords is a list+ −
* of stemmed words, hlwords is the list of normal, unstemmed+ −
* words. the first one is used to find the occurance, the+ −
* latter for highlighting it.+ −
*/+ −
+ −
jQuery.makeSearchSummary = function(text, keywords, hlwords) {+ −
var textLower = text.toLowerCase();+ −
var start = 0;+ −
$.each(keywords, function() {+ −
var i = textLower.indexOf(this.toLowerCase());+ −
if (i > -1)+ −
start = i;+ −
});+ −
start = Math.max(start - 120, 0);+ −
var excerpt = ((start > 0) ? '...' : '') ++ −
$.trim(text.substr(start, 240)) ++ −
((start + 240 - text.length) ? '...' : '');+ −
var rv = $('<div class="context"></div>').text(excerpt);+ −
$.each(hlwords, function() {+ −
rv = rv.highlightText(this, 'highlight');+ −
});+ −
return rv;+ −
}+ −
+ −
/**+ −
* Porter Stemmer+ −
*/+ −
var PorterStemmer = function() {+ −
+ −
var step2list = {+ −
ational: 'ate',+ −
tional: 'tion',+ −
enci: 'ence',+ −
anci: 'ance',+ −
izer: 'ize',+ −
bli: 'ble',+ −
alli: 'al',+ −
entli: 'ent',+ −
eli: 'e',+ −
ousli: 'ous',+ −
ization: 'ize',+ −
ation: 'ate',+ −
ator: 'ate',+ −
alism: 'al',+ −
iveness: 'ive',+ −
fulness: 'ful',+ −
ousness: 'ous',+ −
aliti: 'al',+ −
iviti: 'ive',+ −
biliti: 'ble',+ −
logi: 'log'+ −
};+ −
+ −
var step3list = {+ −
icate: 'ic',+ −
ative: '',+ −
alize: 'al',+ −
iciti: 'ic',+ −
ical: 'ic',+ −
ful: '',+ −
ness: ''+ −
};+ −
+ −
var c = "[^aeiou]"; // consonant+ −
var v = "[aeiouy]"; // vowel+ −
var C = c + "[^aeiouy]*"; // consonant sequence+ −
var V = v + "[aeiou]*"; // vowel sequence+ −
+ −
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0+ −
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1+ −
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1+ −
var s_v = "^(" + C + ")?" + v; // vowel in stem+ −
+ −
this.stemWord = function (w) {+ −
var stem;+ −
var suffix;+ −
var firstch;+ −
var origword = w;+ −
+ −
if (w.length < 3)+ −
return w;+ −
+ −
var re;+ −
var re2;+ −
var re3;+ −
var re4;+ −
+ −
firstch = w.substr(0,1);+ −
if (firstch == "y")+ −
w = firstch.toUpperCase() + w.substr(1);+ −
+ −
// Step 1a+ −
re = /^(.+?)(ss|i)es$/;+ −
re2 = /^(.+?)([^s])s$/;+ −
+ −
if (re.test(w))+ −
w = w.replace(re,"$1$2");+ −
else if (re2.test(w))+ −
w = w.replace(re2,"$1$2");+ −
+ −
// Step 1b+ −
re = /^(.+?)eed$/;+ −
re2 = /^(.+?)(ed|ing)$/;+ −
if (re.test(w)) {+ −
var fp = re.exec(w);+ −
re = new RegExp(mgr0);+ −
if (re.test(fp[1])) {+ −
re = /.$/;+ −
w = w.replace(re,"");+ −
}+ −
}+ −
else if (re2.test(w)) {+ −
var fp = re2.exec(w);+ −
stem = fp[1];+ −
re2 = new RegExp(s_v);+ −
if (re2.test(stem)) {+ −
w = stem;+ −
re2 = /(at|bl|iz)$/;+ −
re3 = new RegExp("([^aeiouylsz])\\1$");+ −
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");+ −
if (re2.test(w))+ −
w = w + "e";+ −
else if (re3.test(w)) {+ −
re = /.$/;+ −
w = w.replace(re,"");+ −
}+ −
else if (re4.test(w))+ −
w = w + "e";+ −
}+ −
}+ −
+ −
// Step 1c+ −
re = /^(.+?)y$/;+ −
if (re.test(w)) {+ −
var fp = re.exec(w);+ −
stem = fp[1];+ −
re = new RegExp(s_v);+ −
if (re.test(stem))+ −
w = stem + "i";+ −
}+ −
+ −
// Step 2+ −
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;+ −
if (re.test(w)) {+ −
var fp = re.exec(w);+ −
stem = fp[1];+ −
suffix = fp[2];+ −
re = new RegExp(mgr0);+ −
if (re.test(stem))+ −
w = stem + step2list[suffix];+ −
}+ −
+ −
// Step 3+ −
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;+ −
if (re.test(w)) {+ −
var fp = re.exec(w);+ −
stem = fp[1];+ −
suffix = fp[2];+ −
re = new RegExp(mgr0);+ −
if (re.test(stem))+ −
w = stem + step3list[suffix];+ −
}+ −
+ −
// Step 4+ −
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;+ −
re2 = /^(.+?)(s|t)(ion)$/;+ −
if (re.test(w)) {+ −
var fp = re.exec(w);+ −
stem = fp[1];+ −
re = new RegExp(mgr1);+ −
if (re.test(stem))+ −
w = stem;+ −
}+ −
else if (re2.test(w)) {+ −
var fp = re2.exec(w);+ −
stem = fp[1] + fp[2];+ −
re2 = new RegExp(mgr1);+ −
if (re2.test(stem))+ −
w = stem;+ −
}+ −
+ −
// Step 5+ −
re = /^(.+?)e$/;+ −
if (re.test(w)) {+ −
var fp = re.exec(w);+ −
stem = fp[1];+ −
re = new RegExp(mgr1);+ −
re2 = new RegExp(meq1);+ −
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");+ −
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))+ −
w = stem;+ −
}+ −
re = /ll$/;+ −
re2 = new RegExp(mgr1);+ −
if (re.test(w) && re2.test(w)) {+ −
re = /.$/;+ −
w = w.replace(re,"");+ −
}+ −
+ −
// and turn initial Y back to y+ −
if (firstch == "y")+ −
w = firstch.toLowerCase() + w.substr(1);+ −
return w;+ −
}+ −
}+ −
+ −
+ −
/**+ −
* Search Module+ −
*/+ −
var Search = {+ −
+ −
_index : null,+ −
_queued_query : null,+ −
_pulse_status : -1,+ −
+ −
init : function() {+ −
var params = $.getQueryParameters();+ −
if (params.q) {+ −
var query = params.q[0];+ −
$('input[@name="q"]')[0].value = query;+ −
this.performSearch(query);+ −
}+ −
},+ −
+ −
/**+ −
* Sets the index+ −
*/+ −
setIndex : function(index) {+ −
var q;+ −
this._index = index;+ −
if ((q = this._queued_query) !== null) {+ −
this._queued_query = null;+ −
Search.query(q);+ −
}+ −
},+ −
+ −
hasIndex : function() {+ −
return this._index !== null;+ −
},+ −
+ −
deferQuery : function(query) {+ −
this._queued_query = query;+ −
},+ −
+ −
stopPulse : function() {+ −
this._pulse_status = 0;+ −
},+ −
+ −
startPulse : function() {+ −
if (this._pulse_status >= 0)+ −
return;+ −
function pulse() {+ −
Search._pulse_status = (Search._pulse_status + 1) % 4;+ −
var dotString = '';+ −
for (var i = 0; i < Search._pulse_status; i++)+ −
dotString += '.';+ −
Search.dots.text(dotString);+ −
if (Search._pulse_status > -1)+ −
window.setTimeout(pulse, 500);+ −
};+ −
pulse();+ −
},+ −
+ −
/**+ −
* perform a search for something+ −
*/+ −
performSearch : function(query) {+ −
// create the required interface elements+ −
this.out = $('#search-results');+ −
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);+ −
this.dots = $('<span></span>').appendTo(this.title);+ −
this.status = $('<p style="display: none"></p>').appendTo(this.out);+ −
this.output = $('<ul class="search"/>').appendTo(this.out);+ −
+ −
$('#search-progress').text(_('Preparing search...'));+ −
this.startPulse();+ −
+ −
// index already loaded, the browser was quick!+ −
if (this.hasIndex())+ −
this.query(query);+ −
else+ −
this.setQuery(query);+ −
},+ −
+ −
query : function(query) {+ −
// stem the searchterms and add them to the+ −
// correct list+ −
var stemmer = new PorterStemmer();+ −
var searchterms = [];+ −
var excluded = [];+ −
var hlterms = [];+ −
var tmp = query.split(/\s+/);+ −
var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;+ −
for (var i = 0; i < tmp.length; i++) {+ −
// stem the word+ −
var word = stemmer.stemWord(tmp[i]).toLowerCase();+ −
// select the correct list+ −
if (word[0] == '-') {+ −
var toAppend = excluded;+ −
word = word.substr(1);+ −
}+ −
else {+ −
var toAppend = searchterms;+ −
hlterms.push(tmp[i].toLowerCase());+ −
}+ −
// only add if not already in the list+ −
if (!$.contains(toAppend, word))+ −
toAppend.push(word);+ −
};+ −
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));+ −
+ −
console.debug('SEARCH: searching for:');+ −
console.info('required: ', searchterms);+ −
console.info('excluded: ', excluded);+ −
+ −
// prepare search+ −
var filenames = this._index.filenames;+ −
var titles = this._index.titles;+ −
var terms = this._index.terms;+ −
var descrefs = this._index.descrefs;+ −
var modules = this._index.modules;+ −
var desctypes = this._index.desctypes;+ −
var fileMap = {};+ −
var files = null;+ −
var objectResults = [];+ −
var regularResults = [];+ −
$('#search-progress').empty();+ −
+ −
// lookup as object+ −
if (object != null) {+ −
for (var module in modules) {+ −
if (module.indexOf(object) > -1) {+ −
fn = modules[module];+ −
descr = _('module, in ') + titles[fn];+ −
objectResults.push([filenames[fn], module, '#module-'+module, descr]);+ −
}+ −
}+ −
for (var prefix in descrefs) {+ −
for (var name in descrefs[prefix]) {+ −
if (name.toLowerCase().indexOf(object) > -1) {+ −
match = descrefs[prefix][name];+ −
fullname = (prefix ? prefix + '.' : '') + name;+ −
descr = desctypes[match[1]] + _(', in ') + titles[match[0]];+ −
objectResults.push([filenames[match[0]], fullname, '#'+fullname, descr]);+ −
}+ −
}+ −
}+ −
}+ −
+ −
// sort results descending+ −
objectResults.sort(function(a, b) {+ −
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);+ −
});+ −
+ −
+ −
// perform the search on the required terms+ −
for (var i = 0; i < searchterms.length; i++) {+ −
var word = searchterms[i];+ −
// no match but word was a required one+ −
if ((files = terms[word]) == null)+ −
break;+ −
if (files.length == undefined) {+ −
files = [files];+ −
}+ −
// create the mapping+ −
for (var j = 0; j < files.length; j++) {+ −
var file = files[j];+ −
if (file in fileMap)+ −
fileMap[file].push(word);+ −
else+ −
fileMap[file] = [word];+ −
}+ −
}+ −
+ −
// now check if the files don't contain excluded terms+ −
for (var file in fileMap) {+ −
var valid = true;+ −
+ −
// check if all requirements are matched+ −
if (fileMap[file].length != searchterms.length)+ −
continue;+ −
+ −
// ensure that none of the excluded terms is in the+ −
// search result.+ −
for (var i = 0; i < excluded.length; i++) {+ −
if (terms[excluded[i]] == file ||+ −
$.contains(terms[excluded[i]] || [], file)) {+ −
valid = false;+ −
break;+ −
}+ −
}+ −
+ −
// if we have still a valid result we can add it+ −
// to the result list+ −
if (valid)+ −
regularResults.push([filenames[file], titles[file], '', null]);+ −
}+ −
+ −
// delete unused variables in order to not waste+ −
// memory until list is retrieved completely+ −
delete filenames, titles, terms;+ −
+ −
// now sort the regular results descending by title+ −
regularResults.sort(function(a, b) {+ −
var left = a[1].toLowerCase();+ −
var right = b[1].toLowerCase();+ −
return (left > right) ? -1 : ((left < right) ? 1 : 0);+ −
});+ −
+ −
// combine both+ −
var results = regularResults.concat(objectResults);+ −
+ −
// print the results+ −
var resultCount = results.length;+ −
function displayNextItem() {+ −
// results left, load the summary and display it+ −
if (results.length) {+ −
var item = results.pop();+ −
var listItem = $('<li style="display:none"></li>');+ −
listItem.append($('<a/>').attr(+ −
'href',+ −
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX ++ −
highlightstring + item[2]).html(item[1]));+ −
if (item[3]) {+ −
listItem.append($('<span> (' + item[3] + ')</span>'));+ −
Search.output.append(listItem);+ −
listItem.slideDown(5, function() {+ −
displayNextItem();+ −
});+ −
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {+ −
$.get('_sources/' + item[0] + '.txt', function(data) {+ −
listItem.append($.makeSearchSummary(data, searchterms, hlterms));+ −
Search.output.append(listItem);+ −
listItem.slideDown(5, function() {+ −
displayNextItem();+ −
});+ −
});+ −
} else {+ −
// no source available, just display title+ −
Search.output.append(listItem);+ −
listItem.slideDown(5, function() {+ −
displayNextItem();+ −
});+ −
}+ −
}+ −
// search finished, update title and status message+ −
else {+ −
Search.stopPulse();+ −
Search.title.text(_('Search Results'));+ −
if (!resultCount)+ −
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));+ −
else+ −
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));+ −
Search.status.fadeIn(500);+ −
}+ −
}+ −
displayNextItem();+ −
}+ −
}+ −
+ −
$(document).ready(function() {+ −
Search.init();+ −
});+ −