Repository: facebook/react
File: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js (JavaScript)

Code before:
function removeEventListenerFromChild(
  child: Instance,
  type: string,
  listener: EventListener,
  optionsOrUseCapture?: EventListenerOptionsOrUseCapture,
): boolean {
  child.removeEventListener(type, listener, optionsOrUseCapture);
  return false;
}
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.focus = function (
  this: FragmentInstanceType,
  focusOptions?: FocusOptions,
): void {
  traverseFragmentInstance(
    this._fragmentFiber,
    setFocusIfFocusable,
    focusOptions,
  );
};
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.focusLast = function (
  this: FragmentInstanceType,
  focusOptions?: FocusOptions,
) {
  traverseFragmentInstanceReverse(
    this._fragmentFiber,
    setFocusIfFocusable,
    focusOptions,
  );
};
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.blur = function (this: FragmentInstanceType): void {
  // TODO: When we have a parent element reference, we can skip traversal if the fragment's parent
  //   does not contain document.activeElement
  traverseFragmentInstance(
    this._fragmentFiber,
    blurActiveElementWithinFragment,
  );
};
function blurActiveElementWithinFragment(child: Instance): boolean {
  // TODO: We can get the activeElement from the parent outside of the loop when we have a reference.
  const ownerDocument = child.ownerDocument;
  if (child === ownerDocument.activeElement) {
    // $FlowFixMe[prop-missing]
    child.blur();
    return true;
  }
  return false;
}
// $FlowFixMe[prop-missing]

Review comment (suggestion):
Alternatively this could be a bit simpler to reuse the `traverseFragmentInstance` to collect the child nodes and then loop through them applying focus. The tradeoff would be an array allocation and an additional pass through the list, though I don't expect this to get hit too hard and we'd likely break early on the second loop.

Code after:
  child: Instance,
  type: string,
  listener: EventListener,
  optionsOrUseCapture?: EventListenerOptionsOrUseCapture,
): boolean {
  child.removeEventListener(type, listener, optionsOrUseCapture);
  return false;
}
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.focus = function (
  this: FragmentInstanceType,
  focusOptions?: FocusOptions,
): void {
  traverseFragmentInstance(
    this._fragmentFiber,
    setFocusIfFocusable,
    focusOptions,
  );
};
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.focusLast = function (
  this: FragmentInstanceType,
  focusOptions?: FocusOptions,
) {
  const children: Array<Instance> = [];
  traverseFragmentInstance(this._fragmentFiber, collectChildren, children);
  for (let i = children.length - 1; i >= 0; i--) {
    const child = children[i];
    if (setFocusIfFocusable(child, focusOptions)) {
      break;
    }
  }
};
function collectChildren(
  child: Instance,
  collection: Array<Instance>,
): boolean {
  collection.push(child);
  return false;
}
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.blur = function (this: FragmentInstanceType): void {
  // TODO: When we have a parent element reference, we can skip traversal if the fragment's parent
  //   does not contain document.activeElement
  traverseFragmentInstance(
    this._fragmentFiber,
    blurActiveElementWithinFragment,
  );
};
function blurActiveElementWithinFragment(child: Instance): boolean {
  // TODO: We can get the activeElement from the parent outside of the loop when we have a reference.