Repository: excalidraw/excalidraw
File: src/frame.ts (TypeScript)

Code before:
    ExcalidrawElement[]
  >();

  for (const element of elements) {
    const frameId = isFrameElement(element) ? element.id : element.frameId;
    if (frameId && !frameElementsMap.has(frameId)) {
      frameElementsMap.set(frameId, getFrameElements(elements, frameId));
    }
  }

  return frameElementsMap;
};

export const getFrameElements = (
  allElements: ExcalidrawElementsIncludingDeleted,
  frameId: string,
) => allElements.filter((element) => element.frameId === frameId);

export const getElementsInResizingFrame = (
  allElements: ExcalidrawElementsIncludingDeleted,
  frame: ExcalidrawFrameElement,
  appState: AppState,
): ExcalidrawElement[] => {
  const prevElementsInFrame = getFrameElements(allElements, frame.id);
  const nextElementsInFrame = new Set<ExcalidrawElement>(prevElementsInFrame);

  const elementsCompletelyInFrame = new Set([
    ...getElementsCompletelyInFrame(allElements, frame),
    ...prevElementsInFrame.filter((element) =>
      isElementContainingFrame(allElements, element, frame),
    ),
  ]);

  const elementsNotCompletelyInFrame = prevElementsInFrame.filter(
    (element) => !elementsCompletelyInFrame.has(element),
  );

  // for elements that are completely in the frame
  // if they are part of some groups, then those groups are still
  // considered to belong to the frame
  const groupsToKeep = new Set<string>(
    Array.from(elementsCompletelyInFrame).flatMap(
      (element) => element.groupIds,
    ),
  );

  for (const element of elementsNotCompletelyInFrame) {
    if (!FrameGeometry.isElementIntersectingFrame(element, frame)) {
      if (element.groupIds.length === 0) {
        nextElementsInFrame.delete(element);
      }

Review comment (refactor):
I don't like the introduced dependency on `Scene` here. Either I'll rewrite it, or remove this support completely for now as the `includeBoundArrows` is only used during frame duplication and I think we could survive it for a while.

But, we may need this for rendering slides in E+ /cc @maielo 

Code after:
    ExcalidrawElement[]
  >();

  for (const element of elements) {
    const frameId = isFrameElement(element) ? element.id : element.frameId;
    if (frameId && !frameElementsMap.has(frameId)) {
      frameElementsMap.set(frameId, getFrameElements(elements, frameId));
    }
  }

  return frameElementsMap;
};

export const getFrameElements = (
  allElements: ExcalidrawElementsIncludingDeleted,
  frameId: string,
  opts?: { includeBoundArrows?: boolean },
) => {
  return allElements.filter((element) => {
    if (element.frameId === frameId) {
      return true;
    }
    if (opts?.includeBoundArrows && element.type === "arrow") {
      const bindingId = element.startBinding?.elementId;
      if (bindingId) {
        const boundElement = Scene.getScene(element)?.getElement(bindingId);
        if (boundElement?.frameId === frameId) {
          return true;
        }
      }
    }
    return false;
  });
};

export const getElementsInResizingFrame = (
  allElements: ExcalidrawElementsIncludingDeleted,
  frame: ExcalidrawFrameElement,
  appState: AppState,
): ExcalidrawElement[] => {
  const prevElementsInFrame = getFrameElements(allElements, frame.id);
  const nextElementsInFrame = new Set<ExcalidrawElement>(prevElementsInFrame);

  const elementsCompletelyInFrame = new Set([
    ...getElementsCompletelyInFrame(allElements, frame),
    ...prevElementsInFrame.filter((element) =>
      isElementContainingFrame(allElements, element, frame),
    ),
  ]);

  const elementsNotCompletelyInFrame = prevElementsInFrame.filter(