Repository: ianstormtaylor/slate
File: packages/slate/src/interfaces/editor.ts (TypeScript)

Code before:
      */
      for (const dirtyPath of getDirtyPaths(editor)) {
        if (Node.has(editor, dirtyPath)) {
          const entry = Editor.node(editor, dirtyPath)
          const [node, _] = entry

          /*
            The default normalizer inserts an empty text node in this scenario, but it can be customised.
            So there is some risk here.

            As long as the normalizer only inserts child nodes for this case it is safe to do in any order;
            by definition adding children to an empty node can't cause other paths to change.
          */
          if (Element.isElement(node) && node.children.length === 0) {
            editor.normalizeNode(entry, { operation })
          }
        }
      }

      const initialDirtyPathsLength = getDirtyPaths(editor).length
      let iteration = 0

      while (getDirtyPaths(editor).length !== 0) {
        if (
          !editor.shouldNormalize({
            dirtyPaths: getDirtyPaths(editor),
            iteration,
            initialDirtyPathsLength,
            operation,
          })
        ) {
          return
        }

        const dirtyPath = popDirtyPath(editor)

        // If the node doesn't exist in the tree, it does not need to be normalized.
        if (Node.has(editor, dirtyPath)) {
          const entry = Editor.node(editor, dirtyPath)
          editor.normalizeNode(entry, { operation })
        }
        iteration++
      }
    })
  },

  /**
   * Get the parent node of a location.
   */

  parent(

Review comment (performance):
Not sure what the performance overhead of `getDirtyPaths` is, but it's not used by `shouldNormalize` and passing it here means it's done twice per iteration.

Code after:
      */
      for (const dirtyPath of getDirtyPaths(editor)) {
        if (Node.has(editor, dirtyPath)) {
          const entry = Editor.node(editor, dirtyPath)
          const [node, _] = entry

          /*
            The default normalizer inserts an empty text node in this scenario, but it can be customised.
            So there is some risk here.

            As long as the normalizer only inserts child nodes for this case it is safe to do in any order;
            by definition adding children to an empty node can't cause other paths to change.
          */
          if (Element.isElement(node) && node.children.length === 0) {
            editor.normalizeNode(entry, { operation })
          }
        }
      }

      let dirtyPaths = getDirtyPaths(editor)
      const initialDirtyPathsLength = dirtyPaths.length
      let iteration = 0

      while (dirtyPaths.length !== 0) {
        if (
          !editor.shouldNormalize({
            dirtyPaths,
            iteration,
            initialDirtyPathsLength,
            operation,
          })
        ) {
          return
        }

        const dirtyPath = popDirtyPath(editor)

        // If the node doesn't exist in the tree, it does not need to be normalized.
        if (Node.has(editor, dirtyPath)) {
          const entry = Editor.node(editor, dirtyPath)
          editor.normalizeNode(entry, { operation })
        }
        iteration++
        dirtyPaths = getDirtyPaths(editor)
      }
    })
  },

  /**
   * Get the parent node of a location.
   */