<commit_before>import Ember from 'ember'
const {run, typeOf} = Ember
import {Component, EventsProxyMixin} from 'ember-frost-core'
import {PropTypes} from 'ember-prop-types'
import Pikaday from 'pikaday'

import layout from '../templates/components/frost-date-picker'
import PikadayOptions from '../utils/pikaday-options'

export default Component.extend(EventsProxyMixin, {

  // == Dependencies ==========================================================

  // == Keyword Properties ====================================================

  layout,

  // == PropTypes =============================================================

  propTypes: {
    // Pikaday has a number of options, see utils/pikaday-options

    // Options
    isIconVisible: PropTypes.bool,
    value: PropTypes.string.isRequired,

    // Events
    onChange: PropTypes.func.isRequired
  },

  getDefaultProps () {
    return {
      // Options for Pikaday
      theme: 'frost-theme',

      // Options
      isIconVisible: true
    }
  },

  // == Computed Properties ===================================================

  // == Functions =============================================================

  _assignPikadayOption (pikadayOptions, el, value, type) {
    if (value) {
      if (type === 'callback') {
        pikadayOptions[el] = run.bind(this, value)
      } else {
        pikadayOptions[el] = value
      }
    }
  },

  // Named to match the event from Pikaday
  _onSelect () {
    const value = this.$('input').val()
    this.onChange(value)
  },

  // == DOM Events ============================================================

  // == Lifecycle Hooks =======================================================

  didInsertElement () {
    this._super(...arguments)

    run.scheduleOnce('sync', this, function () {
      const pikadayOptions = {
        field: this.$('input')[0],
        onSelect: run.bind(this, this._onSelect)
      }

      // Bind any other applicable local values and functions into the Pikaday options
      PikadayOptions.forEach(option => {
        switch (typeOf(option)) {
          case 'object':
            this._assignPikadayOption(pikadayOptions, option.label, this.get(option.ref), option.type)
            break
          case 'string':
            this._assignPikadayOption(pikadayOptions, option, this.get(option))
            break
        }
      })

      // Create the Pikaday element
      this.set('pikadayElement', new Pikaday(pikadayOptions))
    })
  },

  willDestroyElement () {
    this.get('pikadayElement').destroy()
    this._super(...arguments)
  }

  // == Actions ===============================================================

})<commit_msg>Fixed pikaday memory leak with `_onKeyChange`<commit_after>import Ember from 'ember'
const {run, typeOf} = Ember
import {Component, EventsProxyMixin} from 'ember-frost-core'
import {PropTypes} from 'ember-prop-types'
import Pikaday from 'pikaday'

import layout from '../templates/components/frost-date-picker'
import PikadayOptions from '../utils/pikaday-options'

export default Component.extend(EventsProxyMixin, {

  // == Dependencies ==========================================================

  // == Keyword Properties ====================================================

  layout,

  // == PropTypes =============================================================

  propTypes: {
    // Pikaday has a number of options, see utils/pikaday-options

    // Options
    isIconVisible: PropTypes.bool,
    value: PropTypes.string.isRequired,

    // Events
    onChange: PropTypes.func.isRequired
  },

  getDefaultProps () {
    return {
      // Options for Pikaday
      theme: 'frost-theme',

      // Options
      isIconVisible: true
    }
  },

  // == Computed Properties ===================================================

  // == Functions =============================================================

  _assignPikadayOption (pikadayOptions, el, value, type) {
    if (value) {
      if (type === 'callback') {
        pikadayOptions[el] = run.bind(this, value)
      } else {
        pikadayOptions[el] = value
      }
    }
  },

  // Named to match the event from Pikaday
  _onSelect () {
    const value = this.$('input').val()
    this.onChange(value)
  },

  // == DOM Events ============================================================

  // == Lifecycle Hooks =======================================================

  didInsertElement () {
    this._super(...arguments)

    run.scheduleOnce('sync', this, function () {
      const pikadayOptions = {
        field: this.$('input')[0],
        onSelect: run.bind(this, this._onSelect)
      }

      // Bind any other applicable local values and functions into the Pikaday options
      PikadayOptions.forEach(option => {
        switch (typeOf(option)) {
          case 'object':
            this._assignPikadayOption(pikadayOptions, option.label, this.get(option.ref), option.type)
            break
          case 'string':
            this._assignPikadayOption(pikadayOptions, option, this.get(option))
            break
        }
      })

      // Create the Pikaday element
      this.set('pikadayElement', new Pikaday(pikadayOptions))
    })
  },

  willDestroyElement () {
    // TODO: This will not be necessary once https://github.com/dbushell/Pikaday/issues/630 is fixed - @dafortin 2017.06.08
    document.removeEventListener('keydown', this.get('pikadayElement')._onKeyChange)
    this.get('pikadayElement').destroy()
    this._super(...arguments)
  }

  // == Actions ===============================================================

})
{'fraction_non_alphanumeric': 0.27019796682718034, 'fraction_numerical': 0.002318530408418049, 'mean_word_length': 3.213373403456048, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 1, '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': '7133685', 'n_tokens_mistral': 1610, 'n_tokens_neox': 1474, 'n_words': 319}