<commit_before>import Mixin from '@ember/object/mixin';
import { observer } from '@ember/object';
import { on } from '@ember/object/evented';
import { bind, later } from '@ember/runloop';
import $ from 'jquery';

export default Mixin.create({
  init() {
    this._super(...arguments);

    this.set('boundClickoutHandler', bind(this, this.clickoutHandler));
    this.set('boundEscapeHandler', bind(this, this.escapeHandler));
  },

  onOpen() {},
  onClose() {},

  dropdownExpanded: false,

  dropdownToggleSelector: '.rl-dropdown-toggle',

  dropdownSelector: '.rl-dropdown',

  closingEventNamespace: 'rl-dropdown',

  closeOnEscape: true,

  actions: {
    toggleDropdown() {
      this.toggleProperty('dropdownExpanded');

      if (this.dropdownExpanded) {
        this.onOpen();
      } else {
        this.onClose();
      }
    },

    openDropdown() {
      this.set('dropdownExpanded', true);
      this.onOpen();
    },

    closeDropdown() {
      this.set('dropdownExpanded', false);
      this.onClose();
    },
  },

  manageClosingEvents: on(
    'didInsertElement',
    observer('dropdownExpanded', function() {
      let namespace = this.closingEventNamespace;
      let clickEventName = `click.${namespace}`;
      let focusEventName = `focusin.${namespace}`;
      let touchEventName = `touchstart.${namespace}`;
      let escapeEventName = `keydown.${namespace}`;
      let component = this;
      let $document = $(document);

      if (this.dropdownExpanded) {
        /* Add clickout handler with 1ms delay, to allow opening the dropdown
         * by clicking e.g. a checkbox and binding to dropdownExpanded, without
         * having the handler close the dropdown immediately. */
        later(() => {
          $document.bind(clickEventName, { component }, component.boundClickoutHandler);
          $document.bind(focusEventName, { component }, component.boundClickoutHandler);
          $document.bind(touchEventName, { component }, component.boundClickoutHandler);
        }, 1);

        if (this.closeOnEscape) {
          $document.bind(escapeEventName, { component }, component.boundEscapeHandler);
        }
      } else {
        $document.unbind(clickEventName, component.boundClickoutHandler);
        $document.unbind(focusEventName, component.boundClickoutHandler);
        $document.unbind(touchEventName, component.boundClickoutHandler);
        $document.unbind(escapeEventName, component.boundEscapeHandler);
      }
    }),
  ),

  unbindClosingEvents: on('willDestroyElement', function() {
    let namespace = this.closingEventNamespace;
    let $document = $(document);

    $document.unbind(`click.${namespace}`, this.boundClickoutHandler);
    $document.unbind(`focusin.${namespace}`, this.boundClickoutHandler);
    $document.unbind(`touchstart.${namespace}`, this.boundClickoutHandler);
    $document.unbind(`keydown.${namespace}`, this.boundEscapeHandler);
  }),

  clickoutHandler(event) {
    let { component } = event.data;
    let $c = component.$();
    let $target = $(event.target);

    /* There is an issue when the click triggered a dom change in the
     * dropdown that unloaded the target element. The ancestry of the target
     * can no longer be determined. We can check if html is still an ancestor
     * to determine if this has happened. The safe option then seems to be to
     * not close the dropdown, as occasionaly not closing the dropdown when it
     * should have closed, seems to be less bad for usability than occasionaly
     * closing the dropdown when it should not have closed.
     */
    if (
      component.get('dropdownExpanded') &&
      $target.closest('html').length &&
      !(
        $target.closest($c.find(component.get('dropdownToggleSelector'))).length ||<commit_msg>Auto merge of #2039 - Turbo87:jquery-dropdown, r=locks<commit_after>import Mixin from '@ember/object/mixin';
import { observer } from '@ember/object';
import { on } from '@ember/object/evented';
import { bind, later } from '@ember/runloop';
import $ from 'jquery';

export default Mixin.create({
  init() {
    this._super(...arguments);

    this.set('boundClickoutHandler', bind(this, this.clickoutHandler));
    this.set('boundEscapeHandler', bind(this, this.escapeHandler));
  },

  onOpen() {},
  onClose() {},

  dropdownExpanded: false,

  dropdownToggleSelector: '.rl-dropdown-toggle',

  dropdownSelector: '.rl-dropdown',

  closingEventNamespace: 'rl-dropdown',

  closeOnEscape: true,

  actions: {
    toggleDropdown() {
      this.toggleProperty('dropdownExpanded');

      if (this.dropdownExpanded) {
        this.onOpen();
      } else {
        this.onClose();
      }
    },

    openDropdown() {
      this.set('dropdownExpanded', true);
      this.onOpen();
    },

    closeDropdown() {
      this.set('dropdownExpanded', false);
      this.onClose();
    },
  },

  manageClosingEvents: on(
    'didInsertElement',
    observer('dropdownExpanded', function() {
      let namespace = this.closingEventNamespace;
      let clickEventName = `click.${namespace}`;
      let focusEventName = `focusin.${namespace}`;
      let touchEventName = `touchstart.${namespace}`;
      let escapeEventName = `keydown.${namespace}`;
      let component = this;
      let $document = $(document);

      if (this.dropdownExpanded) {
        /* Add clickout handler with 1ms delay, to allow opening the dropdown
         * by clicking e.g. a checkbox and binding to dropdownExpanded, without
         * having the handler close the dropdown immediately. */
        later(() => {
          $document.bind(clickEventName, { component }, component.boundClickoutHandler);
          $document.bind(focusEventName, { component }, component.boundClickoutHandler);
          $document.bind(touchEventName, { component }, component.boundClickoutHandler);
        }, 1);

        if (this.closeOnEscape) {
          $document.bind(escapeEventName, { component }, component.boundEscapeHandler);
        }
      } else {
        $document.unbind(clickEventName, component.boundClickoutHandler);
        $document.unbind(focusEventName, component.boundClickoutHandler);
        $document.unbind(touchEventName, component.boundClickoutHandler);
        $document.unbind(escapeEventName, component.boundEscapeHandler);
      }
    }),
  ),

  unbindClosingEvents: on('willDestroyElement', function() {
    let namespace = this.closingEventNamespace;
    let $document = $(document);

    $document.unbind(`click.${namespace}`, this.boundClickoutHandler);
    $document.unbind(`focusin.${namespace}`, this.boundClickoutHandler);
    $document.unbind(`touchstart.${namespace}`, this.boundClickoutHandler);
    $document.unbind(`keydown.${namespace}`, this.boundEscapeHandler);
  }),

  clickoutHandler(event) {
    let { component } = event.data;
    let $c = $(component.element);
    let $target = $(event.target);

    /* There is an issue when the click triggered a dom change in the
     * dropdown that unloaded the target element. The ancestry of the target
     * can no longer be determined. We can check if html is still an ancestor
     * to determine if this has happened. The safe option then seems to be to
     * not close the dropdown, as occasionaly not closing the dropdown when it
     * should have closed, seems to be less bad for usability than occasionaly
     * closing the dropdown when it should not have closed.
     */
    if (
      component.get('dropdownExpanded') &&
      $target.closest('html').length &&
      !(
        $target.closest($c.find(component.get('dropdownToggleSelector'))).length ||
{'fraction_non_alphanumeric': 0.12546125461254612, 'fraction_numerical': 0.0013178703215603585, 'mean_word_length': 3.3094832481544576, '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': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6700742', 'n_tokens_mistral': 2148, 'n_tokens_neox': 2079, 'n_words': 517}