<commit_before>class Select extends SimpleModule

  opts:
    el: null
    items: null
    cls: ""
    onItemRender: $.noop
    placeholder: ""
    allowInput: false

  @i18n:
    "zh-CN":
      all_options: "所有选项"
      clear_selection: "清除选择"
      loading: "正在加载数据"
    "en":
      all_options: "All options"
      clear_selection: "Clear Selection"
      loading: "loading"

  @_tpl:
    select: """
      <div class="simple-select">
        <span class="link-expand" title="#{@::_t('all_options')}">
          <i class="fa fa-caret-down"></i>
        </span>
        <span class="link-clear" title="#{@::_t('clear_selection')}">
          <i class="fa fa-times"></i>
        </span>
        <div class="select-list">
          <div class="loading">#{@::_t('loading')}...</div>
        </div>
      </div>
    """

    input: """
      <input type="text" class="select-result" autocomplete="off">
    """

    item: """
      <div class="select-item">
        <a href="javascript:;" class="label"><span></span></a>
      </div>
    """


  _init: ->
    unless @opts.el
      throw "simple select: option el is required"
      return

    @opts.el.data("select")?.destroy()
    @_render()
    @_bind()


  _render: ->
    @el = $(@opts.el).hide()
    @select = $(Select._tpl.select)
      .data("select", @)
      .addClass(@opts.cls)
      .insertAfter @el
    @input = $(Select._tpl.input)
      .attr("placeholder", @el.data("placeholder") or @opts.placeholder)
      .prependTo @select
    @list = @select.find ".select-list"

    if @opts.items
      items = @opts.items
    else
      items = @el.find("option").map ->
        return $.extend
          label: $(@).text().trim()
          _value: $(@).attr 'value'
        , $(@).data()
      .get()

    @setItems items

    if @el.is('select') and @opts.allowInput
      @el.append('<option />')


  _expand: (expand) ->
    if expand is false
      @input.removeClass "expanded"
      @list.hide()
    else
      @input.addClass "expanded"
      @list.show() if @items.length > 0
      @_scrollToSelected() if @_selectedIndex > -1


  _scrollToSelected: ->
    return if @_selectedIndex < 0
    $selectedEl = @list.find(".select-item").eq @_selectedIndex
    @list.scrollTop $selectedEl.position().top


  _bind: ->
    @select.find(".link-clear").on "mousedown", (e) =>
      @clearSelection()
      return false

    @select.find(".link-expand").on "mousedown", (e) =>
      @_expand !@input.hasClass("expanded")
      @input.focus() unless @_focused
      return false

    @list.on "mousedown", (e) =>
      if simple.util.browser.msie
        @_scrollMousedown = true
        setTimeout =>
          @input.focus()
        , 0
      return false
    .on "mousewheel", (e, delta) ->
      $(@).scrollTop($(@).scrollTop() - 25 * delta)
      return false
    .on "mousedown", ".select-item", (e) =>
      index = @list.find(".select-item").index $(e.currentTarget)
      @selectItem index
      @input.blur()
      return false

    @input.on "keydown.select", (e) =>
      @_keydown(e)
    .on "keyup.select", (e) =>
      @_keyup(e)
    .on "blur.select", (e) =>
      @_blur(e)
    .on "focus.select", (e) =>
      @_focus(e)


  _keydown: (e) ->
    return unless @items and @items.length
    return if @triggerHandler(e) is false

    if e.which is 40 or e.which is 38  # up and down
      unless @input.hasClass "expanded"
        @_expand()
        $itemEls = @list.find(".select-item").show()
        $itemEls.first().addClass("selected") if @_selectedIndex < 0

      else
        $selectedEl = @list.find ".select-item.selected"
        unless $selectedEl.length
          @list.find(".select-item:first").addClass "selected"
          return

        if e.which is 38
          $prevEl = $selectedEl.prevAll(".select-item:visible:first")
          if $prevEl.length
            $selectedEl.removeClass "selected"
            $prevEl.addClass "selected"
        else if e.which is 40
          $nextEl = $selectedEl.nextAll(".select-item:visible:first")
          if $nextEl.length
            $selectedEl.removeClass "selected"
            $nextEl.addClass "selected"

    else if e.which is 13  # enter
      e.preventDefault()
      if @input.hasClass "expanded"
        $selectedEl = @list.find ".select-item.selected"
        if $selectedEl.length
          index = @list.find(".select-item").index $selectedEl
          @selectItem index
          return
      else if @_selectedIndex > -1
        @selectItem @_selectedIndex

      if @opts.allowInput
        @el.val ''
        @trigger 'select', [{label: @input.val(), _value: -1}]
        return

      @clearSelection()
      return false

    else if e.which is 27  # esc
      e.preventDefault()
      @input.blur()

    else if e.which is 27  # backspace
      @clearSelection() if @select.hasClass "selected"
      @_expand() unless @input.hasClass "expanded"


  _keyup: (e) ->
    return false if $.inArray(e.which, [13, 40, 38, 9, 27]) > -1

    if @_keydownTimer
      clearTimeout(@_keydownTimer)
      @_keydownTimer = null

    $itemEls = @list.find ".select-item"
    @_keydownTimer = setTimeout =>
      @_expand() unless @input.hasClass "expanded"
      if @select.hasClass "selected"<commit_msg>bug fix<commit_after>class Select extends SimpleModule

  opts:
    el: null
    items: null
    cls: ""
    onItemRender: $.noop
    placeholder: ""
    allowInput: false

  @i18n:
    "zh-CN":
      all_options: "所有选项"
      clear_selection: "清除选择"
      loading: "正在加载数据"
    "en":
      all_options: "All options"
      clear_selection: "Clear Selection"
      loading: "loading"

  @_tpl:
    select: """
      <div class="simple-select">
        <span class="link-expand" title="#{@::_t('all_options')}">
          <i class="fa fa-caret-down"></i>
        </span>
        <span class="link-clear" title="#{@::_t('clear_selection')}">
          <i class="fa fa-times"></i>
        </span>
        <div class="select-list">
          <div class="loading">#{@::_t('loading')}...</div>
        </div>
      </div>
    """

    input: """
      <input type="text" class="select-result" autocomplete="off">
    """

    item: """
      <div class="select-item">
        <a href="javascript:;" class="label"><span></span></a>
      </div>
    """


  _init: ->
    unless @opts.el
      throw "simple select: option el is required"
      return

    @opts.el.data("select")?.destroy()
    @_render()
    @_bind()


  _render: ->
    @el = $(@opts.el).hide()
    @select = $(Select._tpl.select)
      .data("select", @)
      .addClass(@opts.cls)
      .insertAfter @el
    @input = $(Select._tpl.input)
      .attr("placeholder", @el.data("placeholder") or @opts.placeholder)
      .prependTo @select
    @list = @select.find ".select-list"

    if @opts.items
      items = @opts.items
    else
      items = @el.find("option").map ->
        return $.extend
          label: $(@).text().trim()
          _value: $(@).attr 'value'
        , $(@).data()
      .get()

    @setItems items

    if @el.is('select') and @opts.allowInput
      @el.append('<option />')


  _expand: (expand) ->
    if expand is false
      @input.removeClass "expanded"
      @list.hide()
    else
      @input.addClass "expanded"
      @list.show() if @items.length > 0
      @_scrollToSelected() if @_selectedIndex > -1


  _scrollToSelected: ->
    return if @_selectedIndex < 0
    $selectedEl = @list.find(".select-item").eq @_selectedIndex
    @list.scrollTop $selectedEl.position().top


  _bind: ->
    @select.find(".link-clear").on "mousedown", (e) =>
      @clearSelection()
      return false

    @select.find(".link-expand").on "mousedown", (e) =>
      @_expand !@input.hasClass("expanded")
      @input.focus() unless @_focused
      return false

    @list.on "mousedown", (e) =>
      if simple.util.browser.msie
        @_scrollMousedown = true
        setTimeout =>
          @input.focus()
        , 0
      return false
    .on "mousewheel", (e, delta) ->
      $(@).scrollTop($(@).scrollTop() - 25 * delta)
      return false
    .on "mousedown", ".select-item", (e) =>
      index = @list.find(".select-item").index $(e.currentTarget)
      @selectItem index
      @input.blur()
      return false

    @input.on "keydown.select", (e) =>
      @_keydown(e)
    .on "keyup.select", (e) =>
      @_keyup(e)
    .on "blur.select", (e) =>
      @_blur(e)
    .on "focus.select", (e) =>
      @_focus(e)


  _keydown: (e) ->
    return unless @items and @items.length
    return if @triggerHandler(e) is false

    if e.which is 40 or e.which is 38  # up and down
      unless @input.hasClass "expanded"
        @_expand()
        $itemEls = @list.find(".select-item").show()
        $itemEls.first().addClass("selected") if @_selectedIndex < 0

      else
        $selectedEl = @list.find ".select-item.selected"
        unless $selectedEl.length
          @list.find(".select-item:first").addClass "selected"
          return

        if e.which is 38
          $prevEl = $selectedEl.prevAll(".select-item:visible:first")
          if $prevEl.length
            $selectedEl.removeClass "selected"
            $prevEl.addClass "selected"
        else if e.which is 40
          $nextEl = $selectedEl.nextAll(".select-item:visible:first")
          if $nextEl.length
            $selectedEl.removeClass "selected"
            $nextEl.addClass "selected"

    else if e.which is 13  # enter
      e.preventDefault()
      if @input.hasClass "expanded"
        $selectedEl = @list.find ".select-item.selected"
        if $selectedEl.length
          index = @list.find(".select-item").index $selectedEl
          @selectItem index
          return false
      else if @_selectedIndex > -1
        @selectItem @_selectedIndex

      if @opts.allowInput
        @el.val ''
        @trigger 'select', [{label: @input.val(), _value: -1}]
        return false

      @clearSelection()
      return false

    else if e.which is 27  # esc
      e.preventDefault()
      @input.blur()

    else if e.which is 27  # backspace
      @clearSelection() if @select.hasClass "selected"
      @_expand() unless @input.hasClass "expanded"


  _keyup: (e) ->
    return false if $.inArray(e.which, [13, 40, 38, 9, 27]) > -1

    if @_keydownTimer
      clearTimeout(@_keydownTimer)
      @_keydownTimer = null

    $itemEls = @list.find ".select-item"
    @_keydownTimer = setTimeout =>
      @_expand() unless @input.hasClass "expanded"
      if @select.hasClass "selected"
{'fraction_non_alphanumeric': 0.16057142857142856, 'fraction_numerical': 0.006666666666666667, 'mean_word_length': 2.1995734308348567, 'pattern_counts': {'":': 4, '<': 51, '<?xml version=': 0, '>': 93, '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': '3902117', 'n_tokens_mistral': 3508, 'n_tokens_neox': 3391, 'n_words': 760}