<commit_before>#= require ./dom

# `Batman.DOM.events` contains the Batman.helpers used for binding to events. These aren't called by
# DOM directives, but are used to handle specific events by the `data-event-#{name}` helper.
Batman.DOM.events =
  click: (node, callback, context, eventName = 'click') ->
    Batman.DOM.addEventListener node, eventName, (event, args...) ->
      return if event.metaKey || event.ctrlKey

      Batman.DOM.preventDefault event
      return if not Batman.DOM.eventIsAllowed(eventName, event)

      callback node, event, args..., context

    if node.nodeName.toUpperCase() is 'A' and not node.href
      node.href = '#'

    node

  doubleclick: (node, callback, context) ->
    # The actual DOM event is called `dblclick`
    Batman.DOM.events.click node, callback, context, 'dblclick'

  change: (node, callback, context) ->
    eventNames = switch node.nodeName.toUpperCase()
      when 'TEXTAREA' then ['input', 'keyup', 'change']
      when 'INPUT'
        if node.type.toLowerCase() in Batman.DOM.textInputTypes
          oldCallback = callback
          callback = (node, event) ->
            return if event.type is 'keyup' and Batman.DOM.events.isEnter(event)
            oldCallback(node, event)
          ['input', 'keyup', 'change']
        else
          ['input', 'change']
      else ['change']

    for eventName in eventNames
      Batman.DOM.addEventListener node, eventName, (args...) ->
        callback node, args..., context

  isEnter: (ev) -> (13 <= ev.keyCode <= 14) || (13 <= ev.which <= 14) || ev.keyIdentifier is 'Enter' || ev.key is 'Enter'

  submit: (node, callback, context) ->
    if Batman.DOM.nodeIsEditable(node)
      Batman.DOM.addEventListener node, 'keydown', (args...) ->
        if Batman.DOM.events.isEnter(args[0])
          Batman.DOM._keyCapturingNode = node
      Batman.DOM.addEventListener node, 'keyup', (args...) ->
        if Batman.DOM.events.isEnter(args[0])
          if Batman.DOM._keyCapturingNode is node
            Batman.DOM.preventDefault args[0]
            callback node, args..., context
          Batman.DOM._keyCapturingNode = null
    else
      Batman.DOM.addEventListener node, 'submit', (args...) ->
        Batman.DOM.preventDefault args[0]
        callback node, args..., context

    node

  other: (node, eventName, callback, context) -> Batman.DOM.addEventListener node, eventName, (args...) -> callback node, args..., context

Batman.DOM.eventIsAllowed = (eventName, event) ->
  if delegate = Batman.currentApp?.shouldAllowEvent?[eventName]
    return false if delegate(event) is false

  return true
<commit_msg>Don't retain nodes in event listeners.<commit_after>#= require ./dom

# `Batman.DOM.events` contains the Batman.helpers used for binding to events. These aren't called by
# DOM directives, but are used to handle specific events by the `data-event-#{name}` helper.
Batman.DOM.events =
  click: (node, callback, context, eventName = 'click') ->
    Batman.DOM.addEventListener node, eventName, Batman.DOM.events.clickCallback(callback)

    if node.nodeName.toUpperCase() is 'A' and not node.href
        node.href = '#'

    node

  clickCallback: (callback) ->
    clickHandler = (event) ->
      return if event.metaKey || event.ctrlKey

      Batman.DOM.preventDefault event
      return if not Batman.DOM.eventIsAllowed(event.type, event)

      node = event.target
      callback node, event

    clickHandler.name = "clickHandler"
    clickHandler.functionName = "clickHandler"
    clickHandler

  doubleclick: (node, callback, context) ->
    # The actual DOM event is called `dblclick`
    Batman.DOM.events.click node, callback, context, 'dblclick'

  change: (node, callback, context) ->
    eventNames = switch node.nodeName.toUpperCase()
      when 'TEXTAREA' then ['input', 'keyup', 'change']
      when 'INPUT'
        if node.type.toLowerCase() in Batman.DOM.textInputTypes
          oldCallback = callback
          callback = (node, event) ->
            return if event.type is 'keyup' and Batman.DOM.events.isEnter(event)
            oldCallback(node, event)
          ['input', 'keyup', 'change']
        else
          ['input', 'change']
      else ['change']

    for eventName in eventNames
      Batman.DOM.addEventListener node, eventName, @changeCallback

  changeCallback: -> callback node, args..., context

  isEnter: (ev) -> (13 <= ev.keyCode <= 14) || (13 <= ev.which <= 14) || ev.keyIdentifier is 'Enter' || ev.key is 'Enter'

  submit: (node, callback, context) ->
    if Batman.DOM.nodeIsEditable(node)
      Batman.DOM.addEventListener node, 'keydown', @keyDownCallback
      Batman.DOM.addEventListener node, 'keyup',   @keyUpCallback
    else
      Batman.DOM.addEventListener node, 'submit',  @submitCallback
    node

  keyDownCallback: ->
    if Batman.DOM.events.isEnter(args[0])
      Batman.DOM._keyCapturingNode = node

  keyUpCallback: ->
    if Batman.DOM.events.isEnter(args[0])
      if Batman.DOM._keyCapturingNode is node
        Batman.DOM.preventDefault args[0]
        callback node, args..., context
      Batman.DOM._keyCapturingNode = null

  submitCallback: ->
    Batman.DOM.preventDefault args[0]
    callback node, args..., context

  other: (node, eventName, callback, context) ->
    Batman.DOM.addEventListener node, eventName, @otherCallback

  otherCallback: -> callback node, args..., context

Batman.DOM.eventIsAllowed = (eventName, event) ->
  if delegate = Batman.currentApp?.shouldAllowEvent?[eventName]
    return false if delegate(event) is false

  return true

{'fraction_non_alphanumeric': 0.12484259758949451, 'fraction_numerical': 0.004317323259579061, 'mean_word_length': 2.9516702203269367, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 32, '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': '7290090', 'n_tokens_mistral': 1662, 'n_tokens_neox': 1608, 'n_words': 458}