// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * An autocomplete library for javascript.
 * Public API
 * - _ac_install() install global handlers required for everything else to
 *   function.
 * - _ac_register(SC) register a store constructor (see below)
 * - _ac_isCompleting() true iff focus is in an auto complete box and the user
 *   has triggered completion with a keystroke, and completion has not been
 *   cancelled (programatically or otherwise).
 * - _ac_isCompleteListShowing() true if _as_isCompleting and the complete list
 *   is visible to the user.
 * - _ac_cancel() if completing, stop it, otherwise a no-op.
 *
 *
 * A quick example
 *     // an auto complete store
 *     var myFavoritestAutoCompleteStore = new _AC_SimpleStore(
 *       ['some', 'strings', 'to', 'complete']);
 *
 *     // a store constructor
 *     _ac_register(function (inputNode, keyEvent) {
 *         if (inputNode.id == 'my-auto-completing-check-box') {
 *           return myFavoritestAutoCompleteStore;
 *         }
 *         return null;
 *       });
 *
 *     <html>
 *       <head>
 *         <script type=text/javascript src=ac.js></script>
 *       </head>
 *       <body onload=_ac_install()>
 *         <!-- the constructor above looks at the id.  It could as easily
 *            - look at the class, name, or value.
 *            - The autocomplete=off stops browser autocomplete from
 *            - interfering with our autocomplete
 *           -->
 *         <input type=text id="my-auto-completing-check-box"
 *          autocomplete=off>
 *       </body>
 *     </html>
 *
 *
 * Concepts
 * - Store Constructor function
 *   A store constructor is a policy function with the signature
 *     _AC_Store myStoreConstructor(
 *       HtmlInputElement|HtmlTextAreaElement inputNode, Event keyEvent)
 *   When a key event is received on a text input or text area, the autocomplete
 *   library will try each of the store constructors in turn until it finds one
 *   that returns an AC_Store which will be used for auto-completion of that
 *   text box until focus is lost.
 *
 * - interface _AC_Store
 *   An autocomplete store encapsulates all operations that affect how a
 *   particular text node is autocompleted.  It has the following operations:
 *   - String completable(String inputValue, int caret)
 *     This method returns null if not completable or the section of inputValue
 *     that is subject to completion.  If autocomplete works on items in a
 *     comma separated list, then the input value "foo, ba" might yield "ba"
 *     as the completable chunk since it is separated from its predecessor by
 *     a comma.
 *     caret is the position of the text cursor (caret) in the text input.
 *   - _AC_Completion[] completions(String completable,
 *                                  _AC_Completion[] toFilter)
 *     This method returns null if there are no completions.  If toFilter is
 *     not null or undefined, then this method may assume that toFilter was
 *     returned as a set of completions that contain completable.
 *   - String substitute(String inputValue, int caret,
 *                       String completable, _AC_Completion completion)
 *     returns the inputValue with the given completion substituted for the
 *     given completable.  caret has the same meaning as in the
 *     completable operation.
 *   - String oncomplete(boolean completed, String key,
 *                       HTMLElement element, String text)
 *     This method is called when the user hits a completion key. The default
 *     value is to do nothing, but you can override it if you want. Note that
 *     key will be null if the user clicked on it to select
 *   - Boolean autoselectFirstRow()
 *     This method returns True by default, but subclasses can override it
 *     to make autocomplete fields that require the user to press the down
 *     arrow or do a mouseover once before any completion option is considered
 *     to be selected.
 *
 * - class _AC_SimpleStore
 *   An implementation of _AC_Store that completes a set of strings given at
 *   construct time in a text field with a comma separated value.
 *
 * - struct _AC_Completion
 *   a struct with two fields
 *   - String value : the plain text completion value
 *   - String html : the value, as html, with the completable in bold.
 *
 * Key Handling
 * Several keys affect completion in an autocompleted input.
 * ESC - the escape key cancels autocompleting.  The autocompletion will have
 *   no effect on the focused textbox until it loses focus, regains it, and
 *   a key is pressed.
 * ENTER - completes using the currently selected completion, or if there is
 *   only one, uses that completion.
 * UP ARROW - selects the completion above the current selection.
 * DOWN ARROW - selects the completion below the current selection.
 *
 *
 * CSS styles
 * The following CSS selector rules can be used to change the completion list
 * look:
 * #ac-list               style of the auto-complete list
 * #ac-list .selected     style of the selected item
 * #ac-list b             style of the matching text in a candidate completion
 *
 * Dependencies
 * The library depends on the following libraries:
 * javascript:base for definition of key constants and SetCursorPos
 * javascript:shapes for nodeBounds()
 */

/**
 * install global handlers required for the rest of the module to function.
 */
function _ac_install() {
  ac_addHandler_(document.body, 'onkeydown', ac_keyevent_);
  ac_addHandler_(document.body, 'onkeypress', ac_keyevent_);
}

/**
 * register a store constructor
 * @param storeConstructor a function like
 *   _AC_Store myStoreConstructor(HtmlInputElement|HtmlTextArea, Event)
 */
function _ac_register(storeConstructor) {
  // check that not already registered
  for (let i = ac_storeConstructors.length; --i >= 0;) {
    if (ac_storeConstructors[i] === storeConstructor) {
      return;
    }
  }
  ac_storeConstructors.push(storeConstructor);
}

/**
 * may be attached as an onfocus handler to a text input to popup autocomplete
 * immediately on the box gaining focus.
 */
function _ac_onfocus(event) {
  ac_keyevent_(event);
}

/**
 * true iff the autocomplete widget is currently active.
 */
function _ac_isCompleting() {
  return !!ac_store && !ac_suppressCompletions;
}

/**
 * true iff the completion list is displayed.
 */
function _ac_isCompleteListShowing() {
  return !!ac_store && !ac_suppressCompletions && ac_completions &&
    ac_completions.length;
}

/**
 * cancel any autocomplete in progress.
 */
function _ac_cancel() {
  ac_suppressCompletions = true;
  ac_updateCompletionList(false);
}

/** add a handler without whacking any existing handler. @private */
function ac_addHandler_(node, handlerName, handler) {
  const oldHandler = node[handlerName];
  if (!oldHandler) {
    node[handlerName] = handler;
  } else {
    node[handlerName] = ac_fnchain_(node[handlerName], handler);
  }
  return oldHandler;
}

/** cancel the event. @private */
function ac_cancelEvent_(event) {
  if ('stopPropagation' in event) {
    event.stopPropagation();
  } else {
    event.cancelBubble = true;
  }

  // This is handled in IE by returning false from the handler
  if ('preventDefault' in event) {
    event.preventDefault();
  }
}

/** Call two functions, a and b, and return false if either one returns
    false.  This is used as a primitive way to attach multiple event
    handlers to an element without using addEventListener().   This
    library predates the availablity of addEventListener().
    @private
*/
function ac_fnchain_(a, b) {
  return function() {
    const ar = a.apply(this, arguments);
    const br = b.apply(this, arguments);

    // NOTE 1: (undefined && false) -> undefined
    // NOTE 2: returning FALSE from a onkeypressed cancels it,
    //         returning UNDEFINED does not.
    // As such, we specifically look for falses here
    if (ar === false || br === false) {
      return false;
    } else {
      return true;
    }
  };
}

/** key press handler.  @private */
function ac_keyevent_(event) {
  event = event || window.event;

  const source = getTargetFromEvent(event);
  const isInput = 'INPUT' == source.tagName &&
    source.type.match(/^text|email$/i);
  const isTextarea = 'TEXTAREA' == source.tagName;
  if (!isInput && !isTextarea) return true;

  const key = event.key;
  const isDown = event.type == 'keydown';
  const isShiftKey = event.shiftKey;
  let storeFound = true;

  if ((source !== ac_focusedInput) || (ac_store === null)) {
    ac_focusedInput = source;
    storeFound = false;
    if (ENTER_KEYNAME !== key && ESC_KEYNAME !== key) {
      for (let i = 0; i < ac_storeConstructors.length; ++i) {
        const store = (ac_storeConstructors[i])(source, event);
        if (store) {
          ac_store = store;
          ac_store.setAvoid(event);
          ac_oldBlurHandler = ac_addHandler_(
              ac_focusedInput, 'onblur', _ac_ob);
          storeFound = true;
          break;
        }
      }

      // There exists an odd condition where an edit box with autocomplete
      // attached can be removed from the DOM without blur being called
      // In which case we are left with a store around that will try to
      // autocomplete the next edit box to receive focus. We need to clean
      // this up

      // If we can't find a store, force a blur
      if (!storeFound) {
        _ac_ob(null);
      }
    }
    // ac-table rows need to be removed when switching to another input.
    ac_updateCompletionList(false);
  }
  // If the user typed Esc when the auto-complete menu was not shown,
  // then blur the input text field so that the user can use keyboard
  // shortcuts.
  const acList = document.getElementById('ac-list');
  if (ESC_KEYNAME == key &&
      (!acList || acList.style.display == 'none')) {
    ac_focusedInput.blur();
  }

  if (!storeFound) return true;

  const isCompletion = ac_store.isCompletionKey(key, isDown, isShiftKey);
  const hasResults = ac_completions && (ac_completions.length > 0);
  let cancelEvent = false;

  if (isCompletion && hasResults) {
    // Cancel any enter keystrokes if something is selected so that the
    // browser doesn't go submitting the form.
    cancelEvent = (!ac_suppressCompletions && !!ac_completions &&
                      (ac_selected != -1));
    window.setTimeout(function() {
      if (ac_store) {
        ac_handleKey_(key, isDown, isShiftKey);
      }
    }, 0);
  } else if (!isCompletion) {
    // Don't want to also blur the field. Up and down move the cursor (in
    // Firefox) to the start/end of the field. We also don't want that while
    // the list is showing.
    cancelEvent = (key == ESC_KEYNAME ||
                  key == DOWN_KEYNAME ||
                  key == UP_KEYNAME);

    window.setTimeout(function() {
      if (ac_store) {
        ac_handleKey_(key, isDown, isShiftKey);
      }
    }, 0);
  } else { // implicit if (isCompletion && !hasResults)
    if (ac_store.oncomplete) {
      ac_store.oncomplete(false, key, ac_focusedInput, undefined);
    }
  }

  if (cancelEvent) {
    ac_cancelEvent_(event);
  }

  return !cancelEvent;
}

/** Autocomplete onblur handler. */
function _ac_ob(event) {
  if (ac_focusedInput) {
    ac_focusedInput.onblur = ac_oldBlurHandler;
  }
  ac_store = null;
  ac_focusedInput = null;
  ac_everTyped = false;
  ac_oldBlurHandler = null;
  ac_suppressCompletions = false;
  ac_updateCompletionList(false);
}

/** @constructor */
function _AC_Store() {
}
/** returns the chunk of the input to treat as completable. */
_AC_Store.prototype.completable = function(inputValue, caret) {
  console.log('UNIMPLEMENTED completable');
};
/** returns the chunk of the input to treat as completable. */
_AC_Store.prototype.completions = function(prefix, tofilter) {
  console.log('UNIMPLEMENTED completions');
};
/** returns the chunk of the input to treat as completable. */
_AC_Store.prototype.oncomplete = function(completed, key, element, text) {
  // Call the onkeyup handler so that choosing an autocomplete option has
  // the same side-effect as typing.  E.g., exposing the next row of input
  // fields.
  element.dispatchEvent(new Event('keyup'));
  _ac_ob();
};
/** substitutes a completion for a completable in a text input's value. */
_AC_Store.prototype.substitute =
  function(inputValue, caret, completable, completion) {
    console.log('UNIMPLEMENTED substitute');
  };
/** true iff hitting a comma key should complete. */
_AC_Store.prototype.commaCompletes = true;
/**
 * true iff the given keystroke should cause a completion (and be consumed in
 * the process.
 */
_AC_Store.prototype.isCompletionKey = function(key, isDown, isShiftKey) {
  if (!isDown && (ENTER_KEYNAME === key ||
                  (COMMA_KEYNAME == key && this.commaCompletes))) {
    return true;
  }
  if (TAB_KEYNAME === key && !isShiftKey) {
    // IE doesn't fire an event for tab on click in a text field, and firefox
    // requires that the onkeypress event for tab be consumed or it navigates
    // to next field.
    return false;
    // JER: return isDown == BR_IsIE();
  }
  return false;
};

_AC_Store.prototype.setAvoid = function(event) {
  if (event && event.avoidValues) {
    ac_avoidValues = event.avoidValues;
  } else {
    ac_avoidValues = this.computeAvoid();
  }
  ac_avoidValues = ac_avoidValues.map((val) => val.toLowerCase());
};

/* Subclasses may implement this to compute values to avoid
   offering in the current input field, i.e., because those
   values are already used. */
_AC_Store.prototype.computeAvoid = function() {
  return [];
};


function _AC_AddItemToFirstCharMap(firstCharMap, ch, s) {
  let l = firstCharMap[ch];
  if (!l) {
    l = firstCharMap[ch] = [];
  } else if (l[l.length - 1].value == s) {
    return;
  }
  l.push(new _AC_Completion(s, null, ''));
}

/**
 * an _AC_Store implementation suitable for completing lists of email
 * addresses.
 * @constructor
 */
function _AC_SimpleStore(strings, opt_docStrings) {
  this.firstCharMap_ = {};

  for (let i = 0; i < strings.length; ++i) {
    let s = strings[i];
    if (!s) {
      continue;
    }
    if (opt_docStrings && opt_docStrings[s]) {
      s = s + ' ' + opt_docStrings[s];
    }

    const parts = s.split(/\W+/);
    for (let j = 0; j < parts.length; ++j) {
      if (parts[j]) {
        _AC_AddItemToFirstCharMap(
            this.firstCharMap_, parts[j].charAt(0).toLowerCase(), strings[i]);
      }
    }
  }

  // The maximimum number of results that we are willing to show
  this.countThreshold = 2500;
  this.docstrings = opt_docStrings || {};
}
_AC_SimpleStore.prototype = new _AC_Store();
_AC_SimpleStore.prototype.constructor = _AC_SimpleStore;

_AC_SimpleStore.prototype.completable =
  function(inputValue, caret) {
  // complete after the last comma not inside ""s
    let start = 0;
    let state = 0;
    for (let i = 0; i < caret; ++i) {
      const ch = inputValue.charAt(i);
      switch (state) {
        case 0:
          if ('"' == ch) {
            state = 1;
          } else if (',' == ch || ' ' == ch) {
            start = i + 1;
          }
          break;
        case 1:
          if ('"' == ch) {
            state = 0;
          }
          break;
      }
    }
    while (start < caret &&
         ' \t\r\n'.indexOf(inputValue.charAt(start)) >= 0) {
      ++start;
    }
    return inputValue.substring(start, caret);
  };


/** Simple function to create a <span> with matching text in bold.
 */
function _AC_CreateSpanWithMatchHighlighted(match) {
  const span = document.createElement('span');
  span.appendChild(document.createTextNode(match[1] || ''));
  const bold = document.createElement('b');
  span.appendChild(bold);
  bold.appendChild(document.createTextNode(match[2]));
  span.appendChild(document.createTextNode(match[3] || ''));
  return span;
};


/**
 * Get all completions matching the given prefix.
 * @param {string} prefix The prefix of the text to autocomplete on.
 * @param {List.<string>?} toFilter Optional list to filter on. Otherwise will
 *     use this.firstCharMap_ using the prefix's first character.
 * @return {List.<_AC_Completion>} The computed list of completions.
 */
_AC_SimpleStore.prototype.completions = function(prefix) {
  if (!prefix) {
    return [];
  }
  toFilter = this.firstCharMap_[prefix.charAt(0).toLowerCase()];

  // Since we use prefix to build a regular expression, we need to escape RE
  // characters. We match '-', '{', '$' and others in the prefix and convert
  // them into "\-", "\{", "\$".
  const regexForRegexCharacters = /([\^*+\-\$\\\{\}\(\)\[\]\#?\.])/g;
  const modifiedPrefix = prefix.replace(regexForRegexCharacters, '\\$1');

  // Match the modifiedPrefix anywhere as long as it is either at the very
  // beginning "Th" -> "The Hobbit", or comes immediately after a word separator
  // such as "Ga" -> "The-Great-Gatsby".
  const patternRegex = '^(.*\\W)?(' + modifiedPrefix + ')(.*)';
  const pattern = new RegExp(patternRegex, 'i' /* ignore case */);

  // We keep separate lists of possible completions that were generated
  // by matching a value or generated by matching a docstring.  We return
  // a concatenated list so that value matches all come before docstring
  // matches.
  const completions = [];
  const docCompletions = [];

  if (toFilter) {
    const toFilterLength = toFilter.length;
    for (let i = 0; i < toFilterLength; ++i) {
      const docStr = this.docstrings[toFilter[i].value];
      let compSpan = null;
      let docSpan = null;
      const matches = toFilter[i].value.match(pattern);
      const docMatches = docStr && docStr.match(pattern);
      if (matches) {
        compSpan = _AC_CreateSpanWithMatchHighlighted(matches);
        if (docStr) docSpan = document.createTextNode(docStr);
      } else if (docMatches) {
        compSpan = document.createTextNode(toFilter[i].value);
        docSpan = _AC_CreateSpanWithMatchHighlighted(docMatches);
      }

      if (compSpan) {
        const newCompletion = new _AC_Completion(
            toFilter[i].value, compSpan, docSpan);

        if (matches) {
          completions.push(newCompletion);
        } else {
          docCompletions.push(newCompletion);
        }
        if (completions.length + docCompletions.length > this.countThreshold) {
          break;
        }
      }
    }
  }

  return completions.concat(docCompletions);
};

// Normally, when the user types a few characters, we aggressively
// select the first possible completion (if any).  When the user
// hits ENTER, that first completion is substituted.  When that
// behavior is not desired, override this to return false.
_AC_SimpleStore.prototype.autoselectFirstRow = function() {
  return true;
};

// Comparison function for _AC_Completion
function _AC_CompareACCompletion(a, b) {
  // convert it to lower case and remove all leading junk
  const aval = a.value.toLowerCase().replace(/^\W*/, '');
  const bval = b.value.toLowerCase().replace(/^\W*/, '');

  if (a.value === b.value) {
    return 0;
  } else if (aval < bval) {
    return -1;
  } else {
    return 1;
  }
}

_AC_SimpleStore.prototype.substitute =
function(inputValue, caret, completable, completion) {
  return inputValue.substring(0, caret - completable.length) +
    completion.value + ', ' + inputValue.substring(caret);
};

/**
 * a possible completion.
 * @constructor
 */
function _AC_Completion(value, compSpan, docSpan) {
  /** plain text. */
  this.value = value;
  if (typeof compSpan == 'string') compSpan = document.createTextNode(compSpan);
  this.compSpan = compSpan;
  if (typeof docSpan == 'string') docSpan = document.createTextNode(docSpan);
  this.docSpan = docSpan;
}
_AC_Completion.prototype.toString = function() {
  return '(AC_Completion: ' + this.value + ')';
};

/** registered store constructors.  @private */
var ac_storeConstructors = [];
/**
 * the focused text input or textarea whether store is null or not.
 * A text input may have focus and this may be null iff no key has been typed in
 * the text input.
 */
var ac_focusedInput = null;
/**
 * null or the autocomplete store used to complete ac_focusedInput.
 * @private
 */
var ac_store = null;
/** store handler from ac_focusedInput. @private */
var ac_oldBlurHandler = null;
/**
 * true iff user has indicated completions are unwanted (via ESC key)
 * @private
 */
var ac_suppressCompletions = false;
/**
 * chunk of completable text seen last keystroke.
 * Used to generate ac_completions.
 * @private
 */
let ac_lastCompletable = null;
/** an array of _AC_Completions.  @private */
var ac_completions = null;
/** -1 or in [0, _AC_Completions.length).  @private */
var ac_selected = -1;

/** Maximum number of options displayed in menu. @private */
const ac_max_options = 100;

/** Don't offer these values because they are already used. @private */
let ac_avoidValues = [];

/**
 * handles all the key strokes, updating the completion list, tracking selected
 * element, performing substitutions, etc.
 * @private
 */
function ac_handleKey_(key, isDown, isShiftKey) {
  // check completions
  ac_checkCompletions();
  let show = true;
  const numCompletions = ac_completions ? ac_completions.length : 0;
  // handle enter and tab on key press and the rest on key down
  if (ac_store.isCompletionKey(key, isDown, isShiftKey)) {
    if (ac_selected < 0 && numCompletions >= 1 &&
        ac_store.autoselectFirstRow()) {
      ac_selected = 0;
    }
    if (ac_selected >= 0) {
      const backupInput = ac_focusedInput;
      const completeValue = ac_completions[ac_selected].value;
      ac_complete();
      if (ac_store.oncomplete) {
        ac_store.oncomplete(true, key, backupInput, completeValue);
      }
    }
  } else {
    switch (key) {
      case ESC_KEYNAME: // escape
      // JER?? ac_suppressCompletions = true;
        ac_selected = -1;
        show = false;
        break;
      case UP_KEYNAME: // up
        if (isDown) {
        // firefox fires arrow events on both down and press, but IE only fires
        // then on press.
          ac_selected = Math.max(numCompletions >= 0 ? 0 : -1, ac_selected - 1);
        }
        break;
      case DOWN_KEYNAME: // down
        if (isDown) {
          ac_selected = Math.min(
              ac_max_options - 1, Math.min(numCompletions - 1, ac_selected + 1));
        }
        break;
    }

    if (isDown) {
      switch (key) {
        case ESC_KEYNAME:
        case ENTER_KEYNAME:
        case UP_KEYNAME:
        case DOWN_KEYNAME:
        case RIGHT_KEYNAME:
        case LEFT_KEYNAME:
        case TAB_KEYNAME:
        case SHIFT_KEYNAME:
        case BACKSPACE_KEYNAME:
        case DELETE_KEYNAME:
          break;
        default: // User typed some new characters.
          ac_everTyped = true;
      }
    }
  }

  if (ac_focusedInput) {
    ac_updateCompletionList(show);
  }
}

/**
 * called when an option is clicked on to select that option.
 */
function _ac_select(optionIndex) {
  ac_selected = optionIndex;
  ac_complete();
  if (ac_store.oncomplete) {
    ac_store.oncomplete(true, null, ac_focusedInput, ac_focusedInput.value);
  }

  // check completions
  ac_checkCompletions();
  ac_updateCompletionList(true);
}

function _ac_mouseover(optionIndex) {
  ac_selected = optionIndex;
  ac_updateCompletionList(true);
}

/** perform the substitution of the currently selected item. */
function ac_complete() {
  const caret = ac_getCaretPosition_(ac_focusedInput);
  const completion = ac_completions[ac_selected];

  ac_focusedInput.value = ac_store.substitute(
      ac_focusedInput.value, caret,
      ac_lastCompletable, completion);
  // When the prefix starts with '*' we want to return the complete set of all
  // possible completions. We treat the ac_lastCompletable value as empty so
  // that the caret is correctly calculated (i.e. the caret should not consider
  // placeholder values like '*member').
  let new_caret = caret + completion.value.length;
  if (!ac_lastCompletable.startsWith('*')) {
    // Only consider the ac_lastCompletable length if it does not start with '*'
    new_caret = new_caret - ac_lastCompletable.length;
  }
  // If we inserted something ending in two quotation marks, position
  // the cursor between the quotation marks. If we inserted a complete term,
  // skip over the trailing space so that the user is ready to enter the next
  // term.  If we inserted just a search operator, leave the cursor immediately
  // after the colon or equals and don't skip over the space.
  if (completion.value.substring(completion.value.length - 2) == '""') {
    new_caret--;
  } else if (completion.value.substring(completion.value.length - 1) != ':' &&
             completion.value.substring(completion.value.length - 1) != '=') {
    new_caret++; // To account for the comma.
    new_caret++; // To account for the space after the comma.
  }
  ac_selected = -1;
  ac_completions = null;
  ac_lastCompletable = null;
  ac_everTyped = false;
  SetCursorPos(window, ac_focusedInput, new_caret);
}

/**
 * True if the user has ever typed any actual characters in the currently
 * focused text field.  False if they have only clicked, backspaced, and
 * used the arrow keys.
 */
var ac_everTyped = false;

/**
 * maintains ac_completions, ac_selected, ac_lastCompletable.
 * @private
 */
function ac_checkCompletions() {
  if (ac_focusedInput && !ac_suppressCompletions) {
    const caret = ac_getCaretPosition_(ac_focusedInput);
    const completable = ac_store.completable(ac_focusedInput.value, caret);

    // If we already have completed, then our work here is done.
    if (completable == ac_lastCompletable) {
      return;
    }

    ac_completions = null;
    ac_selected = -1;

    const oldSelected =
      ((ac_selected >= 0 && ac_selected < ac_completions.length) ?
        ac_completions[ac_selected].value : null);
    ac_completions = ac_store.completions(completable);
    // Don't offer options for values that the user has already used
    // in another part of the current form.
    ac_completions = ac_completions.filter((comp) =>
      FindInArray(ac_avoidValues, comp.value.toLowerCase()) === -1);

    ac_selected = oldSelected ? 0 : -1;
    ac_lastCompletable = completable;
    return;
  }
  ac_lastCompletable = null;
  ac_completions = null;
  ac_selected = -1;
}

/**
 * maintains the completion list GUI.
 * @private
 */
function ac_updateCompletionList(show) {
  let clist = document.getElementById('ac-list');
  const input = ac_focusedInput;
  if (input) {
    input.setAttribute('aria-activedescendant', 'ac-status-row-none');
  }
  let tableEl;
  let tableBody;
  if (show && ac_completions && ac_completions.length) {
    if (!clist) {
      clist = document.createElement('DIV');
      clist.id = 'ac-list';
      clist.style.position = 'absolute';
      clist.style.display = 'none';
      // with 'listbox' and 'option' roles, screenreader narrates total
      // number of options eg. 'New = issue has not .... 1 of 9'
      document.body.appendChild(clist);
      tableEl = document.createElement('table');
      tableEl.setAttribute('cellpadding', 0);
      tableEl.setAttribute('cellspacing', 0);
      tableEl.id = 'ac-table';
      tableEl.setAttribute('role', 'presentation');
      tableBody = document.createElement('tbody');
      tableBody.id = 'ac-table-body';
      tableEl.appendChild(tableBody);
      tableBody.setAttribute('role', 'listbox');
      clist.appendChild(tableEl);
      input.setAttribute('aria-controls', 'ac-table');
      input.setAttribute('aria-haspopup', 'grid');
    } else {
      tableEl = document.getElementById('ac-table');
      tableBody = document.getElementById('ac-table-body');
      while (tableBody.childNodes.length) {
        tableBody.removeChild(tableBody.childNodes[0]);
      }
    }

    // If no choice is selected, then select the first item, if desired.
    if (ac_selected < 0 && ac_store && ac_store.autoselectFirstRow()) {
      ac_selected = 0;
    }

    let headerCount= 0;
    for (let i = 0; i < Math.min(ac_max_options, ac_completions.length); ++i) {
      if (ac_completions[i].heading) {
        var rowEl = document.createElement('tr');
        tableBody.appendChild(rowEl);
        const cellEl = document.createElement('th');
        rowEl.appendChild(cellEl);
        cellEl.setAttribute('colspan', 2);
        if (headerCount) {
          cellEl.appendChild(document.createElement('br'));
        }
        cellEl.appendChild(
            document.createTextNode(ac_completions[i].heading));
        headerCount++;
      } else {
        var rowEl = document.createElement('tr');
        tableBody.appendChild(rowEl);
        if (i == ac_selected) {
          rowEl.className = 'selected';
        }
        rowEl.id = `ac-status-row-${i}`;
        rowEl.setAttribute('data-index', i);
        rowEl.setAttribute('role', 'option');
        rowEl.addEventListener('mousedown', function(event) {
          event.preventDefault();
        });
        rowEl.addEventListener('mouseup', function(event) {
          let target = event.target;
          while (target && target.tagName != 'TR') {
            target = target.parentNode;
          }
          const idx = Number(target.getAttribute('data-index'));
          try {
            _ac_select(idx);
          } finally {
            return false;
          }
        });
        rowEl.addEventListener('mouseover', function(event) {
          let target = event.target;
          while (target && target.tagName != 'TR') {
            target = target.parentNode;
          }
          const idx = Number(target.getAttribute('data-index'));
          _ac_mouseover(idx);
        });
        const valCellEl = document.createElement('td');
        rowEl.appendChild(valCellEl);
        if (ac_completions[i].compSpan) {
          valCellEl.appendChild(ac_completions[i].compSpan);
        }
        const docCellEl = document.createElement('td');
        rowEl.appendChild(docCellEl);
        if (ac_completions[i].docSpan &&
            ac_completions[i].docSpan.textContent) {
          docCellEl.appendChild(document.createTextNode(' = '));
          docCellEl.appendChild(ac_completions[i].docSpan);
        }
      }
    }

    // position
    const inputBounds = nodeBounds(ac_focusedInput);
    clist.style.left = inputBounds.x + 'px';
    clist.style.top = (inputBounds.y + inputBounds.h) + 'px';

    window.setTimeout(ac_autoscroll, 100);
    input.setAttribute('aria-activedescendant', `ac-status-row-${ac_selected}`);
    // Note - we use '' instead of 'block', since 'block' has odd effects on
    // the screen in IE, and causes scrollbars to resize
    clist.style.display = '';
  } else {
    tableBody = document.getElementById('ac-table-body');
    if (clist && tableBody) {
      clist.style.display = 'none';
      while (tableBody.childNodes.length) {
        tableBody.removeChild(tableBody.childNodes[0]);
      }
    }
  }
}

// TODO(jrobbins): make arrow keys and mouse not conflict if they are
// used at the same time.


/** Scroll the autocomplete menu to show the currently selected row. */
function ac_autoscroll() {
  const acList = document.getElementById('ac-list');
  const acSelRow = acList.getElementsByClassName('selected')[0];
  const acSelRowTop = acSelRow ? acSelRow.offsetTop : 0;
  const acSelRowHeight = acSelRow ? acSelRow.offsetHeight : 0;


  const EXTRA = 8; // Go an extra few pixels so the next row is partly exposed.

  if (!acList || !acSelRow) return;

  // Autoscroll upward if the selected item is above the visible area,
  // else autoscroll downward if the selected item is below the visible area.
  if (acSelRowTop < acList.scrollTop) {
    acList.scrollTop = acSelRowTop - EXTRA;
  } else if (acSelRowTop + acSelRowHeight + EXTRA >
             acList.scrollTop + acList.offsetHeight) {
    acList.scrollTop = (acSelRowTop + acSelRowHeight -
                        acList.offsetHeight + EXTRA);
  }
}


/** the position of the text caret in the given text field.
 *
 * @param textField an INPUT node with type=text or a TEXTAREA node
 * @return an index in [0, textField.value.length]
 */
function ac_getCaretPosition_(textField) {
  if ('INPUT' == textField.tagName) {
    let caret = textField.value.length;

    // chrome/firefox
    if (undefined != textField.selectionStart) {
      caret = textField.selectionEnd;

      // JER: Special treatment for issue status field that makes all
      // options show up more often
      if (textField.id.startsWith('status')) {
        caret = textField.selectionStart;
      }
      // ie
    } else if (document.selection) {
      // get an empty selection range
      const range = document.selection.createRange();
      const origSelectionLength = range.text.length;
      // Force selection start to 0 position
      range.moveStart('character', -caret);
      // the caret end position is the new selection length
      caret = range.text.length;

      // JER: Special treatment for issue status field that makes all
      // options show up more often
      if (textField.id.startsWith('status')) {
        // The amount that the selection grew when we forced start to
        // position 0 is == the original start position.
        caret = range.text.length - origSelectionLength;
      }
    }

    return caret;
  } else {
    // a textarea

    return GetCursorPos(window, textField);
  }
}

function getTargetFromEvent(event) {
  let targ = event.target || event.srcElement;
  if (targ.shadowRoot) {
    // Find the element within the shadowDOM.
    const path = event.path || event.composedPath();
    targ = path[0];
  }
  return targ;
}
