-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Feature: Provide a variant of EditorState.read that sets activeEditor #6346
Description
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.