query : function()

in versions/1.1.0/_static/searchtools_custom.js [346:580]


  query : function(query) {
    var i;
    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"];

    // stem the searchterms and add them to the correct list
    var stemmer = new Stemmer();
    var searchterms = [];
    var excluded = [];
    var hlterms = [];
    var tmp = query.split(/\s+/);
    var objectterms = [];
    for (i = 0; i < tmp.length; i++) {
      if (tmp[i] !== "") {
          objectterms.push(tmp[i].toLowerCase());
      }

      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
          tmp[i] === "") {
        // skip this "word"
        continue;
      }
      // stem the word
      var word = stemmer.stemWord(tmp[i].toLowerCase());
      var toAppend;
      // select the correct list
      if (word[0] == '-') {
        toAppend = excluded;
        word = word.substr(1);
      }
      else {
        toAppend = searchterms;
        hlterms.push(tmp[i].toLowerCase());
      }
      // only add if not already in the list
      if (!$u.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 terms = this._index.terms;
    var titleterms = this._index.titleterms;

    // array of [filename, title, anchor, descr, score]
    var results = [];
    $('#search-progress').empty();

    // lookup as object
    for (i = 0; i < objectterms.length; i++) {
      var others = [].concat(objectterms.slice(0, i),
                             objectterms.slice(i+1, objectterms.length));
      results = results.concat(this.performObjectSearch(objectterms[i], others));
    }

    // lookup as search terms in fulltext
    results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));

    // let the scorer override scores with a custom scoring function
    if (Scorer.score) {
      for (i = 0; i < results.length; i++)
        results[i][4] = Scorer.score(results[i]);
    }

    // now sort the results by score (in opposite order of appearance, since the
    // display function below uses pop() to retrieve items) and then
    // alphabetically
    results.sort(function(a, b) {
      var left = a[4];
      var right = b[4];
      if (left > right) {
        return 1;
      } else if (left < right) {
        return -1;
      } else {
        // same score: sort alphabetically
        left = a[1].toLowerCase();
        right = b[1].toLowerCase();
        return (left > right) ? -1 : ((left < right) ? 1 : 0);
      }
    });

    //Render result for preview
    if(isPreview) {
        var prevNum = 0;
        $('#search-preview').children().remove();
        if(results.length == 0) {
          $('#search-preview').append('<p>' + 'No suggestion for your query.' + '</p>');
        }
        else {
          $('#search-preview').append('<p>' + 'Suggestions for your query. Press enter to see full results.' + '</p>');
          $('#search-preview').append('<ul id="preview-list"></ul>');
          while(prevNum < 10 && results.length > 0) {
            var item = results.pop();
            if(item[0].endsWith('.md')) {
              item[0] = item[0].substring(0, item[0].length - 3);
            }
            var listItem = $('<li></li>');
            if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
              // dirhtml builder
              var dirname = item[0] + '/';
              if (dirname.match(/\/index\/$/)) {
                dirname = dirname.substring(0, dirname.length-6);
              } else if (dirname == 'index/') {
                dirname = '';
              }
              listItem.append($('<a/>').attr('href',
                DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
                highlightstring + item[2]).html(item[1]));
            } else {
                // normal html builders
                var baseURL = window.location.protocol + '//' + window.location.hostname + '/';
                var urlHref = window.location.href;
                let urlSplits = urlHref.split("/");
                let versionString = '';
                for (var idx = 0; idx < urlSplits.length; ++idx) {
                    if(urlSplits[idx] == 'versions') {
                        versionString = 'versions/' + urlSplits[idx + 1] + '/';
                        break;
                    }
                }
                baseURL = baseURL.concat(versionString);
                listItem.append($('<a/>').attr('href',
                baseURL + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
                highlightstring + item[2]).html(item[1]));
            }
            var html = listItem.children().html();
            listItem.children().html(html.replace(RegExp(query, 'gi'), '<strong>$&</strong>'));
            $('#preview-list').append(listItem);
            if(prevNum < 9 && results.length > 0) $('#preview-list').append('<hr>');
            prevNum++;
          }
        }
        $('#search-preview').show();
        return;
    }
    else $('#search-preview').hide();

    // for debugging
    //Search.lastresults = results.slice();  // a copy
    //console.info('search results:', Search.lastresults);

    // print the results, at most 100 results.
    if(results.length > 100) results = results.slice(results.length - 100, results.length);
    var resultCount = results.length;
    function displayNextItem() {
      // results left, load the summary and display it
      if (results.length) {
        var item = results.pop();
        if(item[0].endsWith('.md')) {
          item[0] = item[0].substring(0, item[0].length - 3);
        }
        var listItem = $('<li style="display:none"></li>');
        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
          // dirhtml builder
          var dirname = item[0] + '/';
          if (dirname.match(/\/index\/$/)) {
            dirname = dirname.substring(0, dirname.length-6);
          } else if (dirname == 'index/') {
            dirname = '';
          }
          listItem.append($('<a/>').attr('href',
            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
            highlightstring + item[2]).html(item[1]));
        } else {
          // normal html builders
          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) {
          $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.md.txt',
                  dataType: "text",
                  complete: function(jqxhr, textstatus) {
                    var data = jqxhr.responseText;
                    if (data !== '' && data !== undefined) {
                      listItem.append(Search.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();
        //Add pagination
        if(resultCount > 0) {
          var numPerPage = 10;
          var pageEnd =  Math.trunc(resultCount/numPerPage);
          if(resultCount % numPerPage != 0) pageEnd++;
          $('#search-results').children().slice(0, 3).remove();
          $('#search-results').append('<ul id="searchPage" class="pagination"></ul>');
          for(var k = 0; k < pageEnd; ++k) {
            var page = $('<li class="page-item"><a class="page-link" href="#">' + (k + 1) + '</a></li>');
            page.click(function () {
                $('#search-results > ul.search').children().hide();
                var pageNum = parseInt($(this).children().first().html())
                $('#search-results > ul.search').children().slice((pageNum - 1) * numPerPage, pageNum * numPerPage).show();
                $('#searchPage').children().removeClass('active');
                $(this).addClass('active');
            });
            $('ul.pagination').append(page);
          }
          $('#search-results > ul.search').children().hide();
          $('#search-results > ul.search').children().slice(0, numPerPage).show();
          $('#searchPage').children().first().addClass('active');
        }
        Search.title.text(_('Search Results'));
        if (!resultCount)
          Search.status.text(_('Your search did not match any documents in this version of the documentation. You can use the dropdown selector in the navigation bar to try another version. 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();
  },