Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SuperEditor] - Make all DocumentNodes immutable (Resolves #2166) #2384

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

matthew-carroll
Copy link
Contributor

@matthew-carroll matthew-carroll commented Oct 21, 2024

[SuperEditor] - Make all DocumentNodes immutable (Resolves #2166)

For undo/redo and edit transactions to be trustable, the document and its nodes need to be immutable from outside the Editor. This PR makes that conversion.

Replacing nodes

By making nodes immutable, each node can no longer be directly updated for things like changing text, indent, etc. Instead, every time a change is made to a node, the previous node must be replaced by the new node in the document. For that reason, a lot of the changes in this PR is focused on switching from direct node manipulation to document node replacement.

This also means that tests need to re-query nodes throughout the test. We should avoid storing nodes as intermediate values in tests, whenever we can, so that we don't accidentally try to look for changes on the same immutable node.

New copy methods

Moving from direct editing of a node to node replacement, we need the ability to copyWith() changes. Unfortunately, there's not a clean solution to this because Dart doesn't support method overloading. As a result, to deal with subclasses, we have to declare things like copyTextNodeWith(), copyParagraphWith(), and copyTaskWith(). Moreover, each subclass needs to adjust the superclass copy method so that subclass instances don't lose some of their data when the parent class' copy method is called.

@matthew-carroll
Copy link
Contributor Author

FYI @miguelcmedeiros @brian-superlist @jmatth @Jethro87 - This PR will likely break some things for you. The fixes should be pretty simple and straight forward, but some changes will likely be necessary for you.

Changing document nodes to immutable brings us one step closer to capturing snapshots for undo/redo.

Copy link
Collaborator

@angelosilvestre angelosilvestre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a single comment.

@@ -375,49 +418,31 @@ abstract class DocumentNode implements ChangeNotifier {
}

/// Returns all metadata attached to this [DocumentNode].
Map<String, dynamic> get metadata => _metadata;
Map<String, dynamic> get metadata => Map.from(_metadata);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to create a new map that copies all items each time? If we just want to prevent modifications, could we use UnmodifiableMapView instead?

From the docs:

View of a Map that disallow modifying the map.

A wrapper around a Map that forwards all members to the map provided in the constructor, except for operations
that modify the map. Modifying operations throw instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SuperEditor] - Make DocumentNodes immutable
2 participants