<commit_before>_ = require 'underscore'
_s = require 'underscore.string'
Backbone = require 'backbone'
sd = require('sharify').data
Search = require './collections/search.coffee'
mediator = require '../../lib/mediator.coffee'
analyticsHooks = require '../../lib/analytics_hooks.coffee'
{ modelNameAndIdToLabel } = require '../../lib/analytics_helpers.coffee'
itemTemplate = -> require('./templates/item.jade') arguments...
emptyItemTemplate = -> require('./templates/empty-item.jade') arguments...
CurrentUser = require '../../models/current_user.coffee'
SearchResult = require '../../models/search_result.coffee'

module.exports = class SearchBarView extends Backbone.View
  defaults:
    limit: 4
    autoselect: false
    displayKind: true
    displayEmptyItem: false
    shouldDisplaySuggestions: true

  initialize: (options) ->
    return unless @$el.length
    { @mode,
      @restrictType,
      @$input,
      @fairId,
      @includePrivateResults,
      @limit,
      @autoselect,
      @displayKind,
      @displayEmptyItem,
      @centeredHomepageSearch
      @shouldDisplaySuggestions } = _.defaults options, @defaults

    @$input ?= @$('input')
    throw new Error('Requires an input field') unless @$input?

    @search = new Search restrictType: @restrictType, mode: @mode, fairId: @fairId, size: @limit

    @on 'search:start', @indicateLoading
    @on 'search:complete', @concealLoading
    @on 'search:complete', @maybeHighlight
    @on 'search:complete', @displayFeedback
    @on 'search:opened', @displaySuggestions
    @on 'search:closed', @hideSuggestions
    @on 'search:cursorchanged', @ensureResult

    @setupTypeahead()
    @setupPlaceholder()

    @enableSpotlightAutocomplete = CurrentUser.orNull()?.hasLabFeature('Spotlight Search')
    @$spotlight = @$('#spotlight-search')
    @$spotlightInitialText = @$spotlight.find('#spotlight-search__initial-text')
    @$spotlightRemainingText = @$spotlight.find('#spotlight-search__remaining-text')

  events:
    'blur input': 'hideSpotlight'
    'keydown input': 'maybeHideSpotlight'
    'keyup input': 'checkSubmission'
    'focus input': 'trackFocusInput'
    'click .empty-item': 'emptyItemClick'
    'click #main-layout-search-bar-icon': 'iconClick'

  iconClick: (e) ->
    if @isEmpty()
      @$input.focus()
    else
      @emptyItemClick()

  trackFocusInput: ->
    analyticsHooks.trigger 'search:focus'

  checkSubmission: (e) ->
    @hideSuggestions()

    return if !(e.which is 13) or @selected?

    unless @isEmpty()
      @trigger 'search:entered', encodeURIComponent(@$input.val())

  maybeHideSpotlight: (e) ->
    @hideSpotlight() unless e.which is 37 or e.which is 39 # cursor left, right

  hideSpotlight: ->
    @$spotlight.css('z-index', '-1')

  showSpotlight: ->
    @$spotlight.css('z-index', '2')

  # Display spotlight result if:
  # - more than 4 characters have been typed AND
  # - query is an exact case-insensitive leading match of the search result AND
  # - query is more than 30% of the length of the search result
  shouldShowSpotlightSearch: (searchResult) ->
    currentQuery = @$input.val()
    currentQuery.length > 4 &&
      searchResult.toLowerCase().indexOf(currentQuery.toLowerCase()) is 0 &&
      (currentQuery.length / searchResult.length) >= 0.3

  displaySpotlightSearch: (result) ->
    return unless @enableSpotlightAutocomplete

    searchResult = new SearchResult(result).get('display')
    return @hideSpotlight() unless @shouldShowSpotlightSearch(searchResult)<commit_msg>Dont hide spotlight search if you continue typing it<commit_after>_ = require 'underscore'
_s = require 'underscore.string'
Backbone = require 'backbone'
sd = require('sharify').data
Search = require './collections/search.coffee'
mediator = require '../../lib/mediator.coffee'
analyticsHooks = require '../../lib/analytics_hooks.coffee'
{ modelNameAndIdToLabel } = require '../../lib/analytics_helpers.coffee'
itemTemplate = -> require('./templates/item.jade') arguments...
emptyItemTemplate = -> require('./templates/empty-item.jade') arguments...
CurrentUser = require '../../models/current_user.coffee'
SearchResult = require '../../models/search_result.coffee'

module.exports = class SearchBarView extends Backbone.View
  defaults:
    limit: 4
    autoselect: false
    displayKind: true
    displayEmptyItem: false
    shouldDisplaySuggestions: true

  initialize: (options) ->
    return unless @$el.length
    { @mode,
      @restrictType,
      @$input,
      @fairId,
      @includePrivateResults,
      @limit,
      @autoselect,
      @displayKind,
      @displayEmptyItem,
      @centeredHomepageSearch
      @shouldDisplaySuggestions } = _.defaults options, @defaults

    @$input ?= @$('input')
    throw new Error('Requires an input field') unless @$input?

    @search = new Search restrictType: @restrictType, mode: @mode, fairId: @fairId, size: @limit

    @on 'search:start', @indicateLoading
    @on 'search:complete', @concealLoading
    @on 'search:complete', @maybeHighlight
    @on 'search:complete', @displayFeedback
    @on 'search:opened', @displaySuggestions
    @on 'search:closed', @hideSuggestions
    @on 'search:cursorchanged', @ensureResult

    @setupTypeahead()
    @setupPlaceholder()

    @enableSpotlightAutocomplete = CurrentUser.orNull()?.hasLabFeature('Spotlight Search')
    @$spotlight = @$('#spotlight-search')
    @$spotlightInitialText = @$spotlight.find('#spotlight-search__initial-text')
    @$spotlightRemainingText = @$spotlight.find('#spotlight-search__remaining-text')

  events:
    'blur input': 'hideSpotlight'
    'keydown input': 'maybeHideSpotlight'
    'keyup input': 'checkSubmission'
    'focus input': 'trackFocusInput'
    'click .empty-item': 'emptyItemClick'
    'click #main-layout-search-bar-icon': 'iconClick'

  iconClick: (e) ->
    if @isEmpty()
      @$input.focus()
    else
      @emptyItemClick()

  trackFocusInput: ->
    analyticsHooks.trigger 'search:focus'

  checkSubmission: (e) ->
    @hideSuggestions()

    return if !(e.which is 13) or @selected?

    unless @isEmpty()
      @trigger 'search:entered', encodeURIComponent(@$input.val())

  maybeHideSpotlight: (e) ->
    return if e.which is 37 or e.which is 39 # cursor left, right

    letterPressed = String.fromCharCode(e.which).toLowerCase()
    if letterPressed is @$spotlightRemainingText.text().charAt(0).toLowerCase()
      return @shiftLetter(letterPressed)

    @hideSpotlight()

  shiftLetter: (letter) ->
    shiftedInitialText = "#{@$spotlightInitialText.text()}#{letter}"
    @$spotlightInitialText.text(shiftedInitialText)
    @$spotlightRemainingText.text(@$spotlightRemainingText.text().slice(1))

  hideSpotlight: ->
    @$spotlight.css('z-index', '-1')

  showSpotlight: ->
    @$spotlight.css('z-index', '2')

  # Display spotlight result if:
  # - more than 4 characters have been typed AND
  # - query is an exact case-insensitive leading match of the search result AND
  # - query is more than 30% of the length of the search result
  shouldShowSpotlightSearch: (searchResult) ->
    currentQuery = @$input.val()
    currentQuery.length > 4 &&
      searchResult.toLowerCase().indexOf(currentQuery.toLowerCase()) is 0 &&
      (currentQuery.length / searchResult.length) >= 0.3

  displaySpotlightSearch: (result) ->
    return unless @enableSpotlightAutocomplete

    searchResult = new SearchResult(result).get('display')
    return @hideSpotlight() unless @shouldShowSpotlightSearch(searchResult)
{'fraction_non_alphanumeric': 0.1356635864470336, 'fraction_numerical': 0.004553368153207446, 'mean_word_length': 3.913157894736842, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 30, 'https://': 0, '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': '6604842', 'n_tokens_mistral': 2342, 'n_tokens_neox': 2235, 'n_words': 516}