<commit_before>/* global DropLab */

(() => {
  class FilteredSearchDropdownManager {
    constructor() {
      this.tokenizer = gl.FilteredSearchTokenizer;
      this.filteredSearchInput = document.querySelector('.filtered-search');

      this.setupMapping();

      this.cleanupWrapper = this.cleanup.bind(this);
      document.addEventListener('page:fetch', this.cleanupWrapper);
    }

    cleanup() {
      if (this.droplab) {
        this.droplab.destroy();
        this.droplab = null;
      }

      this.setupMapping();

      document.removeEventListener('page:fetch', this.cleanupWrapper);
    }

    setupMapping() {
      this.mapping = {
        author: {
          reference: null,
          gl: 'DropdownUser',
          element: document.querySelector('#js-dropdown-author'),
        },
        assignee: {
          reference: null,
          gl: 'DropdownUser',
          element: document.querySelector('#js-dropdown-assignee'),
        },
        milestone: {
          reference: null,
          gl: 'DropdownNonUser',
          extraArguments: ['milestones.json', '%'],
          element: document.querySelector('#js-dropdown-milestone'),
        },
        label: {
          reference: null,
          gl: 'DropdownNonUser',
          extraArguments: ['labels.json', '~'],
          element: document.querySelector('#js-dropdown-label'),
        },
        hint: {
          reference: null,
          gl: 'DropdownHint',
          element: document.querySelector('#js-dropdown-hint'),
        },
      };
    }

    static addWordToInput(tokenName, tokenValue = '') {
      const input = document.querySelector('.filtered-search');
      const inputValue = input.value;
      const word = `${tokenName}:${tokenValue}`;

      // Get the string to replace
      const selectionStart = input.selectionStart;
      const { left, right } = gl.DropdownUtils.getInputSelectionPosition(input);

      input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right)}`;
      gl.FilteredSearchDropdownManager.updateInputCaretPosition(selectionStart, input);
    }

    static updateInputCaretPosition(selectionStart, input) {
      // Reset the position
      // Sometimes can end up at end of input
      input.setSelectionRange(selectionStart, selectionStart);

      const inputValue = input.value;
      const { right } = gl.DropdownUtils.getInputSelectionPosition(input);

      input.setSelectionRange(right, right);
    }

    updateCurrentDropdownOffset() {
      this.updateDropdownOffset(this.currentDropdown);
    }

    updateDropdownOffset(key) {
      if (!this.font) {
        this.font = window.getComputedStyle(this.filteredSearchInput).font;
      }

      const inputText = gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim();
      const filterIconPadding = 27;
      const offset = gl.text.getTextWidth(inputText, this.font) + filterIconPadding;

      this.mapping[key].reference.setOffset(offset);
    }

    load(key, firstLoad = false) {
      const mappingKey = this.mapping[key];
      const glClass = mappingKey.gl;
      const element = mappingKey.element;
      let forceShowList = false;

      if (!mappingKey.reference) {
        const dl = this.droplab;
        const defaultArguments = [null, dl, element, this.filteredSearchInput, key];
        const glArguments = defaultArguments.concat(mappingKey.extraArguments || []);

        // Passing glArguments to `new gl[glClass](<arguments>)`
        mappingKey.reference = new (Function.prototype.bind.apply(gl[glClass], glArguments))();
      }

      if (firstLoad) {
        mappingKey.reference.init();
      }<commit_msg>Places dropdown at cursor position<commit_after>/* global DropLab */

(() => {
  class FilteredSearchDropdownManager {
    constructor() {
      this.tokenizer = gl.FilteredSearchTokenizer;
      this.filteredSearchInput = document.querySelector('.filtered-search');

      this.setupMapping();

      this.cleanupWrapper = this.cleanup.bind(this);
      document.addEventListener('page:fetch', this.cleanupWrapper);
    }

    cleanup() {
      if (this.droplab) {
        this.droplab.destroy();
        this.droplab = null;
      }

      this.setupMapping();

      document.removeEventListener('page:fetch', this.cleanupWrapper);
    }

    setupMapping() {
      this.mapping = {
        author: {
          reference: null,
          gl: 'DropdownUser',
          element: document.querySelector('#js-dropdown-author'),
        },
        assignee: {
          reference: null,
          gl: 'DropdownUser',
          element: document.querySelector('#js-dropdown-assignee'),
        },
        milestone: {
          reference: null,
          gl: 'DropdownNonUser',
          extraArguments: ['milestones.json', '%'],
          element: document.querySelector('#js-dropdown-milestone'),
        },
        label: {
          reference: null,
          gl: 'DropdownNonUser',
          extraArguments: ['labels.json', '~'],
          element: document.querySelector('#js-dropdown-label'),
        },
        hint: {
          reference: null,
          gl: 'DropdownHint',
          element: document.querySelector('#js-dropdown-hint'),
        },
      };
    }

    static addWordToInput(tokenName, tokenValue = '') {
      const input = document.querySelector('.filtered-search');
      const inputValue = input.value;
      const word = `${tokenName}:${tokenValue}`;

      // Get the string to replace
      const selectionStart = input.selectionStart;
      const { left, right } = gl.DropdownUtils.getInputSelectionPosition(input);

      input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right)}`;
      gl.FilteredSearchDropdownManager.updateInputCaretPosition(selectionStart, input);
    }

    static updateInputCaretPosition(selectionStart, input) {
      // Reset the position
      // Sometimes can end up at end of input
      input.setSelectionRange(selectionStart, selectionStart);

      const inputValue = input.value;
      const { right } = gl.DropdownUtils.getInputSelectionPosition(input);

      input.setSelectionRange(right, right);
    }

    updateCurrentDropdownOffset() {
      this.updateDropdownOffset(this.currentDropdown);
    }

    updateDropdownOffset(key) {
      if (!this.font) {
        this.font = window.getComputedStyle(this.filteredSearchInput).font;
      }

      const input = this.filteredSearchInput;
      const inputText = input.value.slice(0, input.selectionStart);
      const filterIconPadding = 27;
      const offset = gl.text.getTextWidth(inputText, this.font) + filterIconPadding;

      this.mapping[key].reference.setOffset(offset);
    }

    load(key, firstLoad = false) {
      const mappingKey = this.mapping[key];
      const glClass = mappingKey.gl;
      const element = mappingKey.element;
      let forceShowList = false;

      if (!mappingKey.reference) {
        const dl = this.droplab;
        const defaultArguments = [null, dl, element, this.filteredSearchInput, key];
        const glArguments = defaultArguments.concat(mappingKey.extraArguments || []);

        // Passing glArguments to `new gl[glClass](<arguments>)`
        mappingKey.reference = new (Function.prototype.bind.apply(gl[glClass], glArguments))();
      }

      if (firstLoad) {
        mappingKey.reference.init();
      }
{'fraction_non_alphanumeric': 0.12280701754385964, 'fraction_numerical': 0.0009519923840609275, 'mean_word_length': 2.651439920556107, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '5109964', 'n_tokens_mistral': 2021, 'n_tokens_neox': 1974, 'n_words': 366}