_requestHandler(query, offset) {

    const time = Date.now();

    // Keep track of most recently fired query so we can ignore responses
    // coming in late
    if (this.latestQuery === undefined || this.latestQuery < time)
      this.latestQuery = time;

    this.results = [];
    query = query.trim();

    // Nothing to do - clear out the display & abort
    if (!query) {
      this.adapter.disableSpinner();
      this.render();
      return;
    }

    // Turn on spinner
    this.adapter.enableSpinner();

    const language = this.adapter.nativeToWikidata[config.language] || config.language;

    // Build union filter of excluded item classes
    const excludedClassesStr = this.adapter.excludedItemClasses.reduce((str, qNumber) => {
      if (!str)
        str = `{ ?item wdt:P31 wd:${qNumber} }`;
      else
        str += `\n      UNION { ?item wdt:P31 wd:${qNumber} }`;
      return str;
    }, '');

    let offsetStr = '',
      isFirstPage;

    if (offset) {
      offsetStr = `bd:serviceParam mwapi:continue ${offset} .\n`;
      isFirstPage = false;
    } else {
      isFirstPage = true;
      // Keep track of the exact offsets used on previous pages, since
      // they vary due to client-side filtering
      this.prevStack = [];
    }

    // String will be inside quotes, so let's make sure it can't get out :)
    const escapedQuery = query.replace(/(["\\])/g, '\\$&');

    // See https://www.mediawiki.org/wiki/Wikidata_query_service/User_Manual/MWAPI
    // for more info about what's going on here.
    const sparqlQuery = `SELECT * WHERE {
     FILTER NOT EXISTS {
      ${excludedClassesStr}
      }  SERVICE wikibase:mwapi {
          bd:serviceParam wikibase:api "EntitySearch" .
          bd:serviceParam wikibase:endpoint "www.wikidata.org" .
          bd:serviceParam mwapi:search "${escapedQuery}" .
          bd:serviceParam mwapi:language "${language}" .
          bd:serviceParam mwapi:uselang "${language}" .
          bd:serviceParam mwapi:limit ${this.adapter.fetchResults} .
          ${offsetStr}
          ?item wikibase:apiOutputItem mwapi:item .
          ?url wikibase:apiOutput "@url" .
          ?label wikibase:apiOutput "@label" .
          ?matchText wikibase:apiOutput "match/@text"  .
          ?description wikibase:apiOutput "@description" .
          ?ordinal wikibase:apiOrdinal true
        }
    }
    ORDER BY ?ordinal`;

    $.get({
        url: this.adapter.queryServiceBaseURL,
        dataType: 'json',
        data: {
          query: sparqlQuery,
          format: 'json'
        },
        timeout: this.adapter.queryServiceTimeout
      })
      .done(data => {
        // Don't update if a more recent query has superseded this one
        if (time < this.latestQuery)
          return;

        this.adapter.disableSpinner();
        this.results = [];

        if (typeof data !== 'object' || !data.results ||
          !data.results.bindings || !data.results.bindings.length) {
          // Render blank results and error, abort
          this.render();
          this.renderNoResults();
          return;
        }
        let i = 0;
        for (let item of data.results.bindings) {
          this.results.push(this.extractRow(item, query));
          i++;
          if (i == this.adapter.displayResults)
            break;
        }
        this.render();


        // Remember we intentionally tell the MW API to send a bit more than we
        // need, since some of it may have been filtered out by the SPARQL
        // query conditions. If we still got back more than we display, we
        // can now render the pagination. Alternatively, if this is already
        // a pagination request, the user should be able to go back as well :)
        const thereAreMoreResults = data.results.bindings.length >
          this.adapter.displayResults;

        if (thereAreMoreResults || !isFirstPage)
          this.renderNav({
            thereAreMoreResults,
            isFirstPage,
            bindings: data.results.bindings,
            offset,
            queryString: query
          });

      })
      .fail(_error => {
        // Show generic error
        $('#generic-action-error').removeClass('hidden');
        window.libreviews.repaintFocusedHelp();
        // Turn off spinner
        this.adapter.disableSpinner();
      });
  }
/**
   * Send an autocomplete request to the Wikidata query service and render
   * the result using the autocomplete widget.
   *
   * @param {String} query
   *  the query string
   * @param {Number} [offset]
   *  the offset from which to continue a previous query.
   */
Send an autocomplete request to the Wikidata query service and render
the result using the autocomplete widget.

@param {String} query
the query string
@param {Number} [offset]
the offset from which to continue a previous query.
Send an autocomplete request to the Wikidata query service and render the result using the autocomplete widget . @param { String } query the query string @param { Number } [ offset ] the offset from which to continue a previous query .
_requestHandler(query, offset) {
    const time = Date.now();
    if (this.latestQuery === undefined || this.latestQuery < time)
      this.latestQuery = time;
    this.results = [];
    query = query.trim();
    if (!query) {
      this.adapter.disableSpinner();
      this.render();
      return;
    }
    this.adapter.enableSpinner();
    const language = this.adapter.nativeToWikidata[config.language] || config.language;
    const excludedClassesStr = this.adapter.excludedItemClasses.reduce((str, qNumber) => {
      if (!str)
        str = `{ ?item wdt:P31 wd:${qNumber} }`;
      else
        str += `\n      UNION { ?item wdt:P31 wd:${qNumber} }`;
      return str;
    }, '');
    let offsetStr = '',
      isFirstPage;
    if (offset) {
      offsetStr = `bd:serviceParam mwapi:continue ${offset} .\n`;
      isFirstPage = false;
    } else {
      isFirstPage = true;
      this.prevStack = [];
    }
    const escapedQuery = query.replace(/(["\\])/g, '\\$&');
    const sparqlQuery = `SELECT * WHERE {
     FILTER NOT EXISTS {
      ${excludedClassesStr}
      }  SERVICE wikibase:mwapi {
          bd:serviceParam wikibase:api "EntitySearch" .
          bd:serviceParam wikibase:endpoint "www.wikidata.org" .
          bd:serviceParam mwapi:search "${escapedQuery}" .
          bd:serviceParam mwapi:language "${language}" .
          bd:serviceParam mwapi:uselang "${language}" .
          bd:serviceParam mwapi:limit ${this.adapter.fetchResults} .
          ${offsetStr}
          ?item wikibase:apiOutputItem mwapi:item .
          ?url wikibase:apiOutput "@url" .
          ?label wikibase:apiOutput "@label" .
          ?matchText wikibase:apiOutput "match/@text"  .
          ?description wikibase:apiOutput "@description" .
          ?ordinal wikibase:apiOrdinal true
        }
    }
    ORDER BY ?ordinal`;
    $.get({
        url: this.adapter.queryServiceBaseURL,
        dataType: 'json',
        data: {
          query: sparqlQuery,
          format: 'json'
        },
        timeout: this.adapter.queryServiceTimeout
      })
      .done(data => {
        if (time < this.latestQuery)
          return;
        this.adapter.disableSpinner();
        this.results = [];
        if (typeof data !== 'object' || !data.results ||
          !data.results.bindings || !data.results.bindings.length) {
          this.render();
          this.renderNoResults();
          return;
        }
        let i = 0;
        for (let item of data.results.bindings) {
          this.results.push(this.extractRow(item, query));
          i++;
          if (i == this.adapter.displayResults)
            break;
        }
        this.render();
        const thereAreMoreResults = data.results.bindings.length >
          this.adapter.displayResults;
        if (thereAreMoreResults || !isFirstPage)
          this.renderNav({
            thereAreMoreResults,
            isFirstPage,
            bindings: data.results.bindings,
            offset,
            queryString: query
          });
      })
      .fail(_error => {
        $('#generic-action-error').removeClass('hidden');
        window.libreviews.repaintFocusedHelp();
        this.adapter.disableSpinner();
      });
  }
_requestHandler ( query , offset ) { const time = Date . now ( ) ; if ( this . latestQuery === undefined || this . latestQuery < time ) this . latestQuery = time ; this . results = [ ] ; query = query . trim ( ) ; if ( ! query ) { this . adapter . disableSpinner ( ) ; this . render ( ) ; return ; } this . adapter . enableSpinner ( ) ; const language = this . adapter . nativeToWikidata [ config . language ] || config . language ; const excludedClassesStr = this . adapter . excludedItemClasses . reduce ( ( str , qNumber ) => { if ( ! str ) str = ` ${ qNumber } ` ; else str += ` \n ${ qNumber } ` ; return str ; } , '' ) ; let offsetStr = '' , isFirstPage ; if ( offset ) { offsetStr = ` ${ offset } \n ` ; isFirstPage = false ; } else { isFirstPage = true ; this . prevStack = [ ] ; } const escapedQuery = query . replace ( / (["\\]) / g , '\\$&' ) ; const sparqlQuery = ` ${ excludedClassesStr } ${ escapedQuery } ${ language } ${ language } ${ this . adapter . fetchResults } ${ offsetStr } ` ; $ . get ( { url : this . adapter . queryServiceBaseURL , dataType : 'json' , data : { query : sparqlQuery , format : 'json' } , timeout : this . adapter . queryServiceTimeout } ) . done ( data => { if ( time < this . latestQuery ) return ; this . adapter . disableSpinner ( ) ; this . results = [ ] ; if ( typeof data !== 'object' || ! data . results || ! data . results . bindings || ! data . results . bindings . length ) { this . render ( ) ; this . renderNoResults ( ) ; return ; } let i = 0 ; for ( let item of data . results . bindings ) { this . results . push ( this . extractRow ( item , query ) ) ; i ++ ; if ( i == this . adapter . displayResults ) break ; } this . render ( ) ; const thereAreMoreResults = data . results . bindings . length > this . adapter . displayResults ; if ( thereAreMoreResults || ! isFirstPage ) this . renderNav ( { thereAreMoreResults , isFirstPage , bindings : data . results . bindings , offset , queryString : query } ) ; } ) . fail ( _error => { $ ( '#generic-action-error' ) . removeClass ( 'hidden' ) ; window . libreviews . repaintFocusedHelp ( ) ; this . adapter . disableSpinner ( ) ; } ) ; }
Send an autocomplete request to the Wikidata query service and render
 the result using the autocomplete widget.
Send an autocomplete request to the Wikidata query service and render the result using the autocomplete widget .
// Keep track of most recently fired query so we can ignore responses // coming in late // Nothing to do - clear out the display & abort // Turn on spinner // Build union filter of excluded item classes // Keep track of the exact offsets used on previous pages, since // they vary due to client-side filtering // String will be inside quotes, so let's make sure it can't get out :) // See https://www.mediawiki.org/wiki/Wikidata_query_service/User_Manual/MWAPI // for more info about what's going on here. // Don't update if a more recent query has superseded this one // Render blank results and error, abort // Remember we intentionally tell the MW API to send a bit more than we // need, since some of it may have been filtered out by the SPARQL // query conditions. If we still got back more than we display, we // can now render the pagination. Alternatively, if this is already // a pagination request, the user should be able to go back as well :) // Show generic error // Turn off spinner