lunr-8.x-1.0/js/search.worker.js

js/search.worker.js
/**
 * @file
 * Provides Worker callbacks to not block the main thread.
 */

/**
 * Loads an index to initialize a search.
 *
 * @param {object} data
 *   The event data.
 * @param {string} data.lunrPath
 *   The path to the lunr library, in case it needs loaded.
 * @param {string} data.indexPath
 *   The path to the index file.
 * @param {string} data.id
 *   The lunr search ID.
 */
function loadIndex(data) {
  if (!this.scripts_loaded) {
    this.importScripts(data.lunrPath);
    this.scripts_loaded = true;
  }
  var request = new XMLHttpRequest();
  var self = this;
  request.addEventListener('load', function() {
    self.indexes = self.indexes || {};
    self.indexes[data.id] = lunr.Index.load(JSON.parse(this.responseText));
    postMessage({type: 'loadIndexComplete', id: data.id});
  });
  request.open('GET', data.indexPath);
  request.send();
}

/**
 * Performs a search and returns results to the client.
 *
 * @param {object} data
 *   The event data.
 * @param {string} data.search
 *   The search string.
 * @param {object} data.fields
 *   An object mapping index field names to values.
 * @param {string} data.id
 *   The lunr search ID.
 */
function search(data) {
  // Due to a limitation in Lunr that does not allow clause groups, we have to
  // make two queries and combine the results.
  // This is because a query string like:
  // > foo bar +type:baz
  // Will return results that do not contain "foo" or "bar", but do have the
  // "type" field set to "baz".
  // We could change the string to:
  // > +foo +bar +type:baz
  // But that would only show results that contain "foo" and "bar".
  // What we really want is something like this:
  // > +(foo bar) +type:baz
  // Which would be (foo OR bar) AND type:baz, but that isn't possible.
  var results = this.indexes[data.id].search(data.search);
  if (Object.keys(data.fields).length) {
    var queryParts = [];
    for (var key in data.fields) {
      if (data.fields[key] === '') {
        continue;
      }
      var operator = typeof data.operators[key] ? data.operators[key] : 'AND';
      data.fields[key].split(' ').forEach(function (value) {
        value = value.trim().length ? value : '*';
        var prefix = '+';
        if (operator === 'OR') {
          prefix = '';
        }
        queryParts.push(prefix + key + ':' + value);
      });
    }
    var results2 = this.indexes[data.id].search(queryParts.join(' '));
    results = results.filter(function (result1) {
      return results2.some(function (result2) {
        return result2.ref === result1.ref;
      })
    });
  }
  this.postMessage({type: 'searchComplete', results, id: data.id});
}

/**
 * Listens to search events.
 */
this.addEventListener('message', function(event){
  switch (event.data.type) {
    case 'loadIndex':
      loadIndex(event.data);
      break;
    case 'search':
      search(event.data);
      break;
    default:
      throw new Error('Unknown message sent to lunr search worker.');
  }
});

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc