Skip to content

Feature: Provide a variant of EditorState.read that sets activeEditor #6346

@etrepum

Description

@etrepum

Description

EditorState.read can only use $functions that don't depend on activeEditor which ends up leading users to use Editor.update even for fundamentally read-only operations. A common use case would be $getNodeFromDOMNode or $getNodeFromDOM or to avoid having explicit LexicalEditor parameters for $functions ($generateHtmlFromNodes, $getHtmlContent, etc.).

We should have a way to set the activeEditor with an additional argument to EditorState.read.

There should also be a version of read directly from the LexicalEditor for symmetry with update. This would also provide an opportunity to optionally get the _pendingEditorState so that users can "read their own writes" from an update before reconciliation has occurred.

The public API changes would be as follows:

export interface EditorReadOptions {
  // Not sure whether the best default would be to
  // use pending or the latest reconciled state
  pending?: boolean;
}

class LexicalEditor {
  // …
  read<V>(callbackFn: () => V, options: EditorReadOptions = {): V {
    const editorState = (options.pending && this._pendingEditorState) || this.getEditorState();
    return editorState.read(callbackFn, { activeEditor: this });
  }
}
export interface EditorStateReadOptions {
  editor?: LexicalEditor | null;
}

class EditorState {
  // …
  read<V>(callbackFn: () => V, options?: EditorStateReadOptions): V {
    // Changes would be required to internal readEditorState to support this
    // Using editor as first argument for symmetry with lexical-devtools lexicalForExtension internal API
    return readEditorState(options && options.editor || null, this, callbackFn);
  }
}

Impact

Users would have a simpler to explain model for what a $function can do, as most would transition from using editor.update for read-only operations to editor.read and people will also likely prefer editor.read to editor.getEditorState().read.

The extra argument to EditorState.read would mostly be an implementation detail that I don't think most people would use, but it keeps the code path very similar to the current paradigm.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementImprovement over existing feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions