function collectFocusableElements(element, nodes) {
  // If not an element or not visible, no need to explore children.
  if (!isVisibleElement(element)) {
    return false;
  }

  const el = /** @type {HTMLElement} */ (element);
  const tabIndex = getTabindex(el);
  let needsSort = tabIndex > 0;
  if (tabIndex >= 0) {
    nodes.push(el);
  }

  const childNodes = /** @type {Element[]} */ (getChildNodes(el));
  for (let i = 0; i < childNodes.length; i += 1) {
    needsSort = collectFocusableElements(childNodes[i], nodes) || needsSort;
  }
  return needsSort;
}
Recursive function that traverses the children of the target node and finds
elements that can receive focus. Mutates the nodes property for performance.

@param {Element} element
@param {HTMLElement[]} nodes
@returns {boolean} whether the returned node list should be sorted. This happens when
                   there is an element with tabindex > 0