<commit_before>import Ember from 'ember';
import layout from '../templates/components/keyword-complete';

const {observer, computed, run, assert, K, $} = Ember;

const REGEX_WHITESPACE = /[\s\t]/,
  REGEX_KEYWORDS = /[0-9a-zA-Z_\.]/,
  KEYS = {
    BACKSPACE: 8,
    TAB: 9,
    ENTER: 13,
    SHIFT: 16,
    ESC: 27,
    ARROW_LEFT: 37,
    ARROW_UP: 38,
    ARROW_RIGHT: 39,
    ARROW_DOWN: 40
  };

/**
 * Function to set the caret position for a given element.
 * @param {HTMLInputElement|HTMLTextAreaElement} element
 * @param {Number} caretPosition
 */
function setCaretPosition(element, caretPosition) {
  element.focus();
  element.setSelectionRange(caretPosition, caretPosition);
}
/**
 * Function to read the current caret position for a given element
 * @param {HTMLInputElement|HTMLTextAreaElement} el
 * @returns {Number}
 */
function getCaretPosition(el) {
  return el.selectionStart;
}

/**
 * Input/Textarea wrapping component that adds listeners for keyboard interaction and yields data.
 *
 * @class KeywordComplete
 * @module ember-keyword-complete/components/keyword-complete
 * @extends Ember.Component
 * @public
 */
export default Ember.Component.extend({
  /**
   * Async suggestion loading debounce interval.
   * @property loadDebounceInterval
   * @type Number
   * @default 300
   * @public
   */
  loadDebounceInterval: 300,

  /**
   * Minimum query length before suggestion loading is triggered.
   * This values can be overwritten on a per data-source basis, by setting `minQueryLength` for a data source.
   * @property minQueryLength
   * @type Number
   * @default 2
   * @public
   */
  minQueryLength: 2,

  /**
   * Object that represents all available data sources for the keyword completion.
   * The datasource value object must contain a method to extract a string from a given suggestion.
   * This `extractDataString(suggestion)` will be used once an suggestion was chosen to be used.
   * In addition a `loadSuggestion(query)` must be present that returns a promise that resolves
   * an array of suggestion for the passed `query` string.
   * An additional `component` property can be set that is later used in the `keyword-complete-tooltip-item`
   * if the component is not in block form.
   * @property dataSources
   * @type Object
   * @default {}
   * @public
   * @example
   * component.set('dataSources', {
   *  '@': {
   *     component: 'user-item',
   *     extractDataString(item) {
   *       return `@${item.nick}`;
   *     },
   *     loadSuggestions(query) {
   *       const queryLower = query.substring(1).toLowerCase();
   *       return RSVP.resolve(ENV.APP.USERS.filter(item => item.nick.toLowerCase().startsWith(queryLower)));
   *     }
   *  }
   * });
   */
  dataSources: {},

  /**
   * Autocompletion target text (usually same value as the target value).
   * @property text
   * @type String
   * @default ''
   * @public
   */
  text: '',

  /**
   * Target element selector (Should select an input or textarea).
   * @property target
   * @type String
   * @default ''
   * @example '#message-textarea'
   * @public
   */
  target: '',

  // layout fields
  layout: layout,
  classNames: ['auto-complete'],

  // private values (shouldn't be changed externally)
  caretPosition: 0,
  caretStart: null,
  caretEnd: null,
  selectionIdx: -1,

  suggestions: [],
  keywordRegex: REGEX_KEYWORDS,
  currentSourceKey: null,

  _keyPressHandler: K,
  _keyDownHandler: K,
  _tooltipCloseHandler: K,
  _loadSuggestionsId: -1,

  /**
   * Computed property that represents the current keyword suggestion query.
   * @property filterQuery
   * @type String
   * @default ''
   * @example '@embe'
   * @private
   */
  filterQuery: computed('text', 'caretStart', 'caretEnd', function () {
    let query = '',
      text = this.get('text'),
      start = this.get('caretStart'),
      end = this.get('caretEnd');

    if (start !== null) {
      if (end !== null) {
        query = text.substring(start, end);
      } else {
        query = text.substring(start, this.get('caretPosition'));
      }
    }
    return query;
  }),
<commit_msg>Remove deprecated Ember.K<commit_after>import Ember from 'ember';
import layout from '../templates/components/keyword-complete';

const {
  observer,
  computed,
  run,
  assert,
  $
} = Ember;

const REGEX_WHITESPACE = /[\s\t]/,
  REGEX_KEYWORDS = /[0-9a-zA-Z_\.]/,
  KEYS = {
    BACKSPACE: 8,
    TAB: 9,
    ENTER: 13,
    SHIFT: 16,
    ESC: 27,
    ARROW_LEFT: 37,
    ARROW_UP: 38,
    ARROW_RIGHT: 39,
    ARROW_DOWN: 40
  };

/**
 * Function to set the caret position for a given element.
 * @param {HTMLInputElement|HTMLTextAreaElement} element
 * @param {Number} caretPosition
 */
function setCaretPosition(element, caretPosition) {
  element.focus();
  element.setSelectionRange(caretPosition, caretPosition);
}
/**
 * Function to read the current caret position for a given element
 * @param {HTMLInputElement|HTMLTextAreaElement} el
 * @returns {Number}
 */
function getCaretPosition(el) {
  return el.selectionStart;
}

/**
 * Input/Textarea wrapping component that adds listeners for keyboard interaction and yields data.
 *
 * @class KeywordComplete
 * @module ember-keyword-complete/components/keyword-complete
 * @extends Ember.Component
 * @public
 */
export default Ember.Component.extend({
  /**
   * Async suggestion loading debounce interval.
   * @property loadDebounceInterval
   * @type Number
   * @default 300
   * @public
   */
  loadDebounceInterval: 300,

  /**
   * Minimum query length before suggestion loading is triggered.
   * This values can be overwritten on a per data-source basis, by setting `minQueryLength` for a data source.
   * @property minQueryLength
   * @type Number
   * @default 2
   * @public
   */
  minQueryLength: 2,

  /**
   * Object that represents all available data sources for the keyword completion.
   * The datasource value object must contain a method to extract a string from a given suggestion.
   * This `extractDataString(suggestion)` will be used once an suggestion was chosen to be used.
   * In addition a `loadSuggestion(query)` must be present that returns a promise that resolves
   * an array of suggestion for the passed `query` string.
   * An additional `component` property can be set that is later used in the `keyword-complete-tooltip-item`
   * if the component is not in block form.
   * @property dataSources
   * @type Object
   * @default {}
   * @public
   * @example
   * component.set('dataSources', {
   *  '@': {
   *     component: 'user-item',
   *     extractDataString(item) {
   *       return `@${item.nick}`;
   *     },
   *     loadSuggestions(query) {
   *       const queryLower = query.substring(1).toLowerCase();
   *       return RSVP.resolve(ENV.APP.USERS.filter(item => item.nick.toLowerCase().startsWith(queryLower)));
   *     }
   *  }
   * });
   */
  dataSources: {},

  /**
   * Autocompletion target text (usually same value as the target value).
   * @property text
   * @type String
   * @default ''
   * @public
   */
  text: '',

  /**
   * Target element selector (Should select an input or textarea).
   * @property target
   * @type String
   * @default ''
   * @example '#message-textarea'
   * @public
   */
  target: '',

  // layout fields
  layout: layout,
  classNames: ['auto-complete'],

  // private values (shouldn't be changed externally)
  caretPosition: 0,
  caretStart: null,
  caretEnd: null,
  selectionIdx: -1,

  suggestions: [],
  keywordRegex: REGEX_KEYWORDS,
  currentSourceKey: null,

  _keyPressHandler() {},
  _keyDownHandler() {},
  _tooltipCloseHandler() {},
  _loadSuggestionsId: -1,

  /**
   * Computed property that represents the current keyword suggestion query.
   * @property filterQuery
   * @type String
   * @default ''
   * @example '@embe'
   * @private
   */
  filterQuery: computed('text', 'caretStart', 'caretEnd', function () {
    let query = '',
      text = this.get('text'),
      start = this.get('caretStart'),
      end = this.get('caretEnd');

    if (start !== null) {
      if (end !== null) {
        query = text.substring(start, end);
      } else {
        query = text.substring(start, this.get('caretPosition'));
      }
    }
    return query;
  }),

{'fraction_non_alphanumeric': 0.12240689069513527, 'fraction_numerical': 0.0072789033119010065, 'mean_word_length': 3.067094227923039, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '2998098', 'n_tokens_mistral': 2608, 'n_tokens_neox': 2504, 'n_words': 736}