<commit_before>'use strict';

define([
  'jquery', 'handlebars', 'api'
], function ($, hb, api) {

/**
  * Defines modules for search features such as autocomplete, youtube & soundcloud
  * based music search
  *
  */

function AutoCompletor (searchBar, driver) {
  // Search form
  this.searchBar = searchBar;

  // View which holds resulting autocompleted words
  this.wordList = $('#autocomplete-words');

  // Class which will be applied to suggested strings
  this.itemClass = 'autocomplete-items';

  // Used to clear word list when some string is removed completely so that input
  // field becomes empty.
  this.lastInputLen = 0;

  this.handleKeyEvent = function (query, event) {
    var that = this;

    if (that.lastInputLen > 0 && query.length === 0) {
      // Clear items as existing string has been removed
      that.clearItems();
    }

    if (query.length > 0) {
      driver.fetch(query, function (parsedResult) {
        // `parsedResult` should be a list of suggested strings.
        var i, maxResult = 10;

        that.clearItems();

        // Update view with the result
        for (i = 0; i < parsedResult.length; i++) {
          $('<ul />', {
            class: that.itemClass,
            text: parsedResult[i]
          }).appendTo(that.wordList);

          if (i === maxResult) {
            break;
          }
        }

        that.lastInputLen = query.length;
      });
    } else {
      that.lastInputLen = 0;
    }
  };

  this.clearItems = function () {
    $('.' + this.itemClass).remove();
  };
};

function YoutubeDriver () {
  this.baseUrl = 'https://clients1.google.com/complete/search';

  // Send HTTP request to get autocompletion result.
  this.fetch = function (query, successCb) {
    var that = this;

    $.ajax({
      url: this.baseUrl,
      type: 'GET',
      dataType: 'jsonp',
      data: {client: 'youtube', q: query},
      success: function (resp) {
        successCb(that.parseResp(resp));
      }
    });
  };

  // Parse jsonp result from youtube search api
  this.parseResp = function (rawResp) {
    var words = rawResp[1], parsed = [], i;
    for (i = 0; i < words.length; i++) {
      parsed.push(words[i][0]);
    }
    return parsed;
  };
};

function SearchManager () {
  this.searchBar = $('#search-input');

  this.autoCompletor = new AutoCompletor(this.searchBar, new YoutubeDriver());

  this.init = function () {
    // Bind events to search bar.
    var that = this, searchBar = $('#search-input');

    searchBar.keyup(function (e) {
      var query = $(this).val();

      // 13 is keycode for `enter`
      if (e.which === 13) {
        that.autoCompletor.clearItems();
        that.search(query);
      } else {
        that.autoCompletor.handleKeyEvent(query, e);
      }
    });
  };

  this.search = function (query) {
    var that = this;
    // send request to execute search asynchronously
    if (that.searching) {
      // If a user press enter again while waiting for search result.
      return;
    }

    that.searching = true;
    $.ajax({
      url: api.Router.getPath('searchAsync'),
      type: 'POST',
      dataType: 'json',
      data: JSON.stringify({q: query}),
      contentType: 'application/json; charset=utf-8',<commit_msg>fixed blinking autocompletion box when showing search result<commit_after>'use strict';

define([
  'jquery', 'handlebars', 'api'
], function ($, hb, api) {

/**
  * Defines modules for search features such as autocomplete, youtube & soundcloud
  * based music search
  *
  */

function AutoCompletor (searchBar, driver) {
  // Search form
  this.searchBar = searchBar;

  // View which holds resulting autocompleted words
  this.wordList = $('#autocomplete-words');

  // Class which will be applied to suggested strings
  this.itemClass = 'autocomplete-items';

  // Used to clear word list when some string is removed completely so that input
  // field becomes empty.
  this.lastInputLen = 0;

  this.handleKeyEvent = function (query, event) {
    var that = this;

    if (that.lastInputLen > 0 && query.length === 0) {
      // Clear items as existing string has been removed
      that.clearItems();
    }

    if (query.length > 0 && that.lastInputLen !== query.length) {
      // In case that word list is hidden bacause of search result.
      that.showWordList();

      // If there is a change in query string
      driver.fetch(query, function (parsedResult) {
        // `parsedResult` should be a list of suggested strings.
        var i, maxResult = 10;

        that.clearItems();

        // Update view with the result
        for (i = 0; i < parsedResult.length; i++) {
          $('<ul />', {
            class: that.itemClass,
            text: parsedResult[i]
          }).appendTo(that.wordList);

          if (i === maxResult) {
            break;
          }
        }

        that.lastInputLen = query.length;
      });
    } else if (query.length === 0) {
      that.lastInputLen = 0;
    }
  };

  this.clearItems = function () {
    $('.' + this.itemClass).remove();
  };

  this.showWordList = function () {
    this.wordList.show();
  };

  this.hideWordList = function () {
    this.wordList.hide();
  };
};

function YoutubeDriver () {
  this.baseUrl = 'https://clients1.google.com/complete/search';

  // Send HTTP request to get autocompletion result.
  this.fetch = function (query, successCb) {
    var that = this;

    $.ajax({
      url: that.baseUrl,
      type: 'GET',
      dataType: 'jsonp',
      data: {client: 'youtube', q: query},
      success: function (resp) {
        successCb(that.parseResp(resp));
      }
    });
  };

  // Parse jsonp result from youtube search api
  this.parseResp = function (rawResp) {
    var words = rawResp[1], parsed = [], i;
    for (i = 0; i < words.length; i++) {
      parsed.push(words[i][0]);
    }
    return parsed;
  };
};

function SearchManager () {
  this.searchBar = $('#search-input');

  this.autoCompletor = new AutoCompletor(this.searchBar, new YoutubeDriver());

  this.init = function () {
    // Bind events to search bar.
    var that = this, searchBar = $('#search-input');

    searchBar.keyup(function (e) {
      var query = $(this).val();

      // 13 is keycode for `enter`
      if (e.which === 13) {
        that.autoCompletor.hideWordList();
        that.search(query);
      } else {
        that.autoCompletor.handleKeyEvent(query, e);
      }
    });
  };

  this.search = function (query) {
    var that = this;
    // send request to execute search asynchronously
    if (that.searching) {
      // If a user press enter again while waiting for search result.
      return;
    }

    that.searching = true;
    $.ajax({
      url: api.Router.getPath('searchAsync'),
      type: 'POST',
      dataType: 'json',
      data: JSON.stringify({q: query}),
      contentType: 'application/json; charset=utf-8',
{'fraction_non_alphanumeric': 0.13796120752515678, 'fraction_numerical': 0.005104273005687618, 'mean_word_length': 2.365063788027478, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1852993', 'n_tokens_mistral': 2160, 'n_tokens_neox': 2060, 'n_words': 585}