source: flex_extract.git/for_developers/SphinxDoc/_build/html/_static/searchtools.js @ 25b14be

ctbtodev
Last change on this file since 25b14be was 25b14be, checked in by Anne Philipp <anne.philipp@…>, 6 years ago

changed whole tree structure of flex_extract to have better overview

  • Property mode set to 100644
File size: 24.9 KB
Line 
1/*
2 * searchtools.js_t
3 * ~~~~~~~~~~~~~~~~
4 *
5 * Sphinx JavaScript utilities for the full-text search.
6 *
7 * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
8 * :license: BSD, see LICENSE for details.
9 *
10 */
11
12
13/* Non-minified version JS is _stemmer.js if file is provided */ 
14/**
15 * Porter Stemmer
16 */
17var Stemmer = function() {
18
19  var step2list = {
20    ational: 'ate',
21    tional: 'tion',
22    enci: 'ence',
23    anci: 'ance',
24    izer: 'ize',
25    bli: 'ble',
26    alli: 'al',
27    entli: 'ent',
28    eli: 'e',
29    ousli: 'ous',
30    ization: 'ize',
31    ation: 'ate',
32    ator: 'ate',
33    alism: 'al',
34    iveness: 'ive',
35    fulness: 'ful',
36    ousness: 'ous',
37    aliti: 'al',
38    iviti: 'ive',
39    biliti: 'ble',
40    logi: 'log'
41  };
42
43  var step3list = {
44    icate: 'ic',
45    ative: '',
46    alize: 'al',
47    iciti: 'ic',
48    ical: 'ic',
49    ful: '',
50    ness: ''
51  };
52
53  var c = "[^aeiou]";          // consonant
54  var v = "[aeiouy]";          // vowel
55  var C = c + "[^aeiouy]*";    // consonant sequence
56  var V = v + "[aeiou]*";      // vowel sequence
57
58  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
59  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
60  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
61  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
62
63  this.stemWord = function (w) {
64    var stem;
65    var suffix;
66    var firstch;
67    var origword = w;
68
69    if (w.length < 3)
70      return w;
71
72    var re;
73    var re2;
74    var re3;
75    var re4;
76
77    firstch = w.substr(0,1);
78    if (firstch == "y")
79      w = firstch.toUpperCase() + w.substr(1);
80
81    // Step 1a
82    re = /^(.+?)(ss|i)es$/;
83    re2 = /^(.+?)([^s])s$/;
84
85    if (re.test(w))
86      w = w.replace(re,"$1$2");
87    else if (re2.test(w))
88      w = w.replace(re2,"$1$2");
89
90    // Step 1b
91    re = /^(.+?)eed$/;
92    re2 = /^(.+?)(ed|ing)$/;
93    if (re.test(w)) {
94      var fp = re.exec(w);
95      re = new RegExp(mgr0);
96      if (re.test(fp[1])) {
97        re = /.$/;
98        w = w.replace(re,"");
99      }
100    }
101    else if (re2.test(w)) {
102      var fp = re2.exec(w);
103      stem = fp[1];
104      re2 = new RegExp(s_v);
105      if (re2.test(stem)) {
106        w = stem;
107        re2 = /(at|bl|iz)$/;
108        re3 = new RegExp("([^aeiouylsz])\\1$");
109        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
110        if (re2.test(w))
111          w = w + "e";
112        else if (re3.test(w)) {
113          re = /.$/;
114          w = w.replace(re,"");
115        }
116        else if (re4.test(w))
117          w = w + "e";
118      }
119    }
120
121    // Step 1c
122    re = /^(.+?)y$/;
123    if (re.test(w)) {
124      var fp = re.exec(w);
125      stem = fp[1];
126      re = new RegExp(s_v);
127      if (re.test(stem))
128        w = stem + "i";
129    }
130
131    // Step 2
132    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
133    if (re.test(w)) {
134      var fp = re.exec(w);
135      stem = fp[1];
136      suffix = fp[2];
137      re = new RegExp(mgr0);
138      if (re.test(stem))
139        w = stem + step2list[suffix];
140    }
141
142    // Step 3
143    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
144    if (re.test(w)) {
145      var fp = re.exec(w);
146      stem = fp[1];
147      suffix = fp[2];
148      re = new RegExp(mgr0);
149      if (re.test(stem))
150        w = stem + step3list[suffix];
151    }
152
153    // Step 4
154    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
155    re2 = /^(.+?)(s|t)(ion)$/;
156    if (re.test(w)) {
157      var fp = re.exec(w);
158      stem = fp[1];
159      re = new RegExp(mgr1);
160      if (re.test(stem))
161        w = stem;
162    }
163    else if (re2.test(w)) {
164      var fp = re2.exec(w);
165      stem = fp[1] + fp[2];
166      re2 = new RegExp(mgr1);
167      if (re2.test(stem))
168        w = stem;
169    }
170
171    // Step 5
172    re = /^(.+?)e$/;
173    if (re.test(w)) {
174      var fp = re.exec(w);
175      stem = fp[1];
176      re = new RegExp(mgr1);
177      re2 = new RegExp(meq1);
178      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
179      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
180        w = stem;
181    }
182    re = /ll$/;
183    re2 = new RegExp(mgr1);
184    if (re.test(w) && re2.test(w)) {
185      re = /.$/;
186      w = w.replace(re,"");
187    }
188
189    // and turn initial Y back to y
190    if (firstch == "y")
191      w = firstch.toLowerCase() + w.substr(1);
192    return w;
193  }
194}
195
196
197
198/**
199 * Simple result scoring code.
200 */
201var Scorer = {
202  // Implement the following function to further tweak the score for each result
203  // The function takes a result array [filename, title, anchor, descr, score]
204  // and returns the new score.
205  /*
206  score: function(result) {
207    return result[4];
208  },
209  */
210
211  // query matches the full name of an object
212  objNameMatch: 11,
213  // or matches in the last dotted part of the object name
214  objPartialMatch: 6,
215  // Additive scores depending on the priority of the object
216  objPrio: {0:  15,   // used to be importantResults
217            1:  5,   // used to be objectResults
218            2: -5},  // used to be unimportantResults
219  //  Used when the priority is not in the mapping.
220  objPrioDefault: 0,
221
222  // query found in title
223  title: 15,
224  // query found in terms
225  term: 5
226};
227
228
229
230
231
232var splitChars = (function() {
233    var result = {};
234    var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
235         1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
236         2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
237         2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
238         3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
239         3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
240         4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
241         8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
242         11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
243         43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
244    var i, j, start, end;
245    for (i = 0; i < singles.length; i++) {
246        result[singles[i]] = true;
247    }
248    var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
249         [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
250         [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
251         [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
252         [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
253         [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
254         [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
255         [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
256         [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
257         [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
258         [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
259         [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
260         [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
261         [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
262         [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
263         [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
264         [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
265         [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
266         [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
267         [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
268         [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
269         [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
270         [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
271         [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
272         [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
273         [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
274         [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
275         [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
276         [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
277         [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
278         [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
279         [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
280         [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
281         [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
282         [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
283         [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
284         [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
285         [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
286         [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
287         [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
288         [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
289         [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
290         [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
291         [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
292         [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
293         [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
294         [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
295         [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
296         [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
297    for (i = 0; i < ranges.length; i++) {
298        start = ranges[i][0];
299        end = ranges[i][1];
300        for (j = start; j <= end; j++) {
301            result[j] = true;
302        }
303    }
304    return result;
305})();
306
307function splitQuery(query) {
308    var result = [];
309    var start = -1;
310    for (var i = 0; i < query.length; i++) {
311        if (splitChars[query.charCodeAt(i)]) {
312            if (start !== -1) {
313                result.push(query.slice(start, i));
314                start = -1;
315            }
316        } else if (start === -1) {
317            start = i;
318        }
319    }
320    if (start !== -1) {
321        result.push(query.slice(start));
322    }
323    return result;
324}
325
326
327
328
329/**
330 * Search Module
331 */
332var Search = {
333
334  _index : null,
335  _queued_query : null,
336  _pulse_status : -1,
337
338  init : function() {
339      var params = $.getQueryParameters();
340      if (params.q) {
341          var query = params.q[0];
342          $('input[name="q"]')[0].value = query;
343          this.performSearch(query);
344      }
345  },
346
347  loadIndex : function(url) {
348    $.ajax({type: "GET", url: url, data: null,
349            dataType: "script", cache: true,
350            complete: function(jqxhr, textstatus) {
351              if (textstatus != "success") {
352                document.getElementById("searchindexloader").src = url;
353              }
354            }});
355  },
356
357  setIndex : function(index) {
358    var q;
359    this._index = index;
360    if ((q = this._queued_query) !== null) {
361      this._queued_query = null;
362      Search.query(q);
363    }
364  },
365
366  hasIndex : function() {
367      return this._index !== null;
368  },
369
370  deferQuery : function(query) {
371      this._queued_query = query;
372  },
373
374  stopPulse : function() {
375      this._pulse_status = 0;
376  },
377
378  startPulse : function() {
379    if (this._pulse_status >= 0)
380        return;
381    function pulse() {
382      var i;
383      Search._pulse_status = (Search._pulse_status + 1) % 4;
384      var dotString = '';
385      for (i = 0; i < Search._pulse_status; i++)
386        dotString += '.';
387      Search.dots.text(dotString);
388      if (Search._pulse_status > -1)
389        window.setTimeout(pulse, 500);
390    }
391    pulse();
392  },
393
394  /**
395   * perform a search for something (or wait until index is loaded)
396   */
397  performSearch : function(query) {
398    // create the required interface elements
399    this.out = $('#search-results');
400    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
401    this.dots = $('<span></span>').appendTo(this.title);
402    this.status = $('<p style="display: none"></p>').appendTo(this.out);
403    this.output = $('<ul class="search"/>').appendTo(this.out);
404
405    $('#search-progress').text(_('Preparing search...'));
406    this.startPulse();
407
408    // index already loaded, the browser was quick!
409    if (this.hasIndex())
410      this.query(query);
411    else
412      this.deferQuery(query);
413  },
414
415  /**
416   * execute search (requires search index to be loaded)
417   */
418  query : function(query) {
419    var i;
420    var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
421
422    // stem the searchterms and add them to the correct list
423    var stemmer = new Stemmer();
424    var searchterms = [];
425    var excluded = [];
426    var hlterms = [];
427    var tmp = splitQuery(query);
428    var objectterms = [];
429    for (i = 0; i < tmp.length; i++) {
430      if (tmp[i] !== "") {
431          objectterms.push(tmp[i].toLowerCase());
432      }
433
434      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
435          tmp[i] === "") {
436        // skip this "word"
437        continue;
438      }
439      // stem the word
440      var word = stemmer.stemWord(tmp[i].toLowerCase());
441      // prevent stemmer from cutting word smaller than two chars
442      if(word.length < 3 && tmp[i].length >= 3) {
443        word = tmp[i];
444      }
445      var toAppend;
446      // select the correct list
447      if (word[0] == '-') {
448        toAppend = excluded;
449        word = word.substr(1);
450      }
451      else {
452        toAppend = searchterms;
453        hlterms.push(tmp[i].toLowerCase());
454      }
455      // only add if not already in the list
456      if (!$u.contains(toAppend, word))
457        toAppend.push(word);
458    }
459    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
460
461    // console.debug('SEARCH: searching for:');
462    // console.info('required: ', searchterms);
463    // console.info('excluded: ', excluded);
464
465    // prepare search
466    var terms = this._index.terms;
467    var titleterms = this._index.titleterms;
468
469    // array of [filename, title, anchor, descr, score]
470    var results = [];
471    $('#search-progress').empty();
472
473    // lookup as object
474    for (i = 0; i < objectterms.length; i++) {
475      var others = [].concat(objectterms.slice(0, i),
476                             objectterms.slice(i+1, objectterms.length));
477      results = results.concat(this.performObjectSearch(objectterms[i], others));
478    }
479
480    // lookup as search terms in fulltext
481    results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
482
483    // let the scorer override scores with a custom scoring function
484    if (Scorer.score) {
485      for (i = 0; i < results.length; i++)
486        results[i][4] = Scorer.score(results[i]);
487    }
488
489    // now sort the results by score (in opposite order of appearance, since the
490    // display function below uses pop() to retrieve items) and then
491    // alphabetically
492    results.sort(function(a, b) {
493      var left = a[4];
494      var right = b[4];
495      if (left > right) {
496        return 1;
497      } else if (left < right) {
498        return -1;
499      } else {
500        // same score: sort alphabetically
501        left = a[1].toLowerCase();
502        right = b[1].toLowerCase();
503        return (left > right) ? -1 : ((left < right) ? 1 : 0);
504      }
505    });
506
507    // for debugging
508    //Search.lastresults = results.slice();  // a copy
509    //console.info('search results:', Search.lastresults);
510
511    // print the results
512    var resultCount = results.length;
513    function displayNextItem() {
514      // results left, load the summary and display it
515      if (results.length) {
516        var item = results.pop();
517        var listItem = $('<li style="display:none"></li>');
518        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
519          // dirhtml builder
520          var dirname = item[0] + '/';
521          if (dirname.match(/\/index\/$/)) {
522            dirname = dirname.substring(0, dirname.length-6);
523          } else if (dirname == 'index/') {
524            dirname = '';
525          }
526          listItem.append($('<a/>').attr('href',
527            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
528            highlightstring + item[2]).html(item[1]));
529        } else {
530          // normal html builders
531          listItem.append($('<a/>').attr('href',
532            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
533            highlightstring + item[2]).html(item[1]));
534        }
535        if (item[3]) {
536          listItem.append($('<span> (' + item[3] + ')</span>'));
537          Search.output.append(listItem);
538          listItem.slideDown(5, function() {
539            displayNextItem();
540          });
541        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
542          var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
543          if (suffix === undefined) {
544            suffix = '.txt';
545          }
546          $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
547                  dataType: "text",
548                  complete: function(jqxhr, textstatus) {
549                    var data = jqxhr.responseText;
550                    if (data !== '' && data !== undefined) {
551                      listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
552                    }
553                    Search.output.append(listItem);
554                    listItem.slideDown(5, function() {
555                      displayNextItem();
556                    });
557                  }});
558        } else {
559          // no source available, just display title
560          Search.output.append(listItem);
561          listItem.slideDown(5, function() {
562            displayNextItem();
563          });
564        }
565      }
566      // search finished, update title and status message
567      else {
568        Search.stopPulse();
569        Search.title.text(_('Search Results'));
570        if (!resultCount)
571          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.'));
572        else
573            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
574        Search.status.fadeIn(500);
575      }
576    }
577    displayNextItem();
578  },
579
580  /**
581   * search for object names
582   */
583  performObjectSearch : function(object, otherterms) {
584    var filenames = this._index.filenames;
585    var docnames = this._index.docnames;
586    var objects = this._index.objects;
587    var objnames = this._index.objnames;
588    var titles = this._index.titles;
589
590    var i;
591    var results = [];
592
593    for (var prefix in objects) {
594      for (var name in objects[prefix]) {
595        var fullname = (prefix ? prefix + '.' : '') + name;
596        if (fullname.toLowerCase().indexOf(object) > -1) {
597          var score = 0;
598          var parts = fullname.split('.');
599          // check for different match types: exact matches of full name or
600          // "last name" (i.e. last dotted part)
601          if (fullname == object || parts[parts.length - 1] == object) {
602            score += Scorer.objNameMatch;
603          // matches in last name
604          } else if (parts[parts.length - 1].indexOf(object) > -1) {
605            score += Scorer.objPartialMatch;
606          }
607          var match = objects[prefix][name];
608          var objname = objnames[match[1]][2];
609          var title = titles[match[0]];
610          // If more than one term searched for, we require other words to be
611          // found in the name/title/description
612          if (otherterms.length > 0) {
613            var haystack = (prefix + ' ' + name + ' ' +
614                            objname + ' ' + title).toLowerCase();
615            var allfound = true;
616            for (i = 0; i < otherterms.length; i++) {
617              if (haystack.indexOf(otherterms[i]) == -1) {
618                allfound = false;
619                break;
620              }
621            }
622            if (!allfound) {
623              continue;
624            }
625          }
626          var descr = objname + _(', in ') + title;
627
628          var anchor = match[3];
629          if (anchor === '')
630            anchor = fullname;
631          else if (anchor == '-')
632            anchor = objnames[match[1]][1] + '-' + fullname;
633          // add custom score for some objects according to scorer
634          if (Scorer.objPrio.hasOwnProperty(match[2])) {
635            score += Scorer.objPrio[match[2]];
636          } else {
637            score += Scorer.objPrioDefault;
638          }
639          results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
640        }
641      }
642    }
643
644    return results;
645  },
646
647  /**
648   * search for full-text terms in the index
649   */
650  performTermsSearch : function(searchterms, excluded, terms, titleterms) {
651    var docnames = this._index.docnames;
652    var filenames = this._index.filenames;
653    var titles = this._index.titles;
654
655    var i, j, file;
656    var fileMap = {};
657    var scoreMap = {};
658    var results = [];
659
660    // perform the search on the required terms
661    for (i = 0; i < searchterms.length; i++) {
662      var word = searchterms[i];
663      var files = [];
664      var _o = [
665        {files: terms[word], score: Scorer.term},
666        {files: titleterms[word], score: Scorer.title}
667      ];
668
669      // no match but word was a required one
670      if ($u.every(_o, function(o){return o.files === undefined;})) {
671        break;
672      }
673      // found search word in contents
674      $u.each(_o, function(o) {
675        var _files = o.files;
676        if (_files === undefined)
677          return
678
679        if (_files.length === undefined)
680          _files = [_files];
681        files = files.concat(_files);
682
683        // set score for the word in each file to Scorer.term
684        for (j = 0; j < _files.length; j++) {
685          file = _files[j];
686          if (!(file in scoreMap))
687            scoreMap[file] = {}
688          scoreMap[file][word] = o.score;
689        }
690      });
691
692      // create the mapping
693      for (j = 0; j < files.length; j++) {
694        file = files[j];
695        if (file in fileMap)
696          fileMap[file].push(word);
697        else
698          fileMap[file] = [word];
699      }
700    }
701
702    // now check if the files don't contain excluded terms
703    for (file in fileMap) {
704      var valid = true;
705
706      // check if all requirements are matched
707      if (fileMap[file].length != searchterms.length)
708          continue;
709
710      // ensure that none of the excluded terms is in the search result
711      for (i = 0; i < excluded.length; i++) {
712        if (terms[excluded[i]] == file ||
713            titleterms[excluded[i]] == file ||
714            $u.contains(terms[excluded[i]] || [], file) ||
715            $u.contains(titleterms[excluded[i]] || [], file)) {
716          valid = false;
717          break;
718        }
719      }
720
721      // if we have still a valid result we can add it to the result list
722      if (valid) {
723        // select one (max) score for the file.
724        // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
725        var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
726        results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
727      }
728    }
729    return results;
730  },
731
732  /**
733   * helper function to return a node containing the
734   * search summary for a given text. keywords is a list
735   * of stemmed words, hlwords is the list of normal, unstemmed
736   * words. the first one is used to find the occurrence, the
737   * latter for highlighting it.
738   */
739  makeSearchSummary : function(text, keywords, hlwords) {
740    var textLower = text.toLowerCase();
741    var start = 0;
742    $.each(keywords, function() {
743      var i = textLower.indexOf(this.toLowerCase());
744      if (i > -1)
745        start = i;
746    });
747    start = Math.max(start - 120, 0);
748    var excerpt = ((start > 0) ? '...' : '') +
749      $.trim(text.substr(start, 240)) +
750      ((start + 240 - text.length) ? '...' : '');
751    var rv = $('<div class="context"></div>').text(excerpt);
752    $.each(hlwords, function() {
753      rv = rv.highlightText(this, 'highlighted');
754    });
755    return rv;
756  }
757};
758
759$(document).ready(function() {
760  Search.init();
761});
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG