introduce a "refs" concept
See original GitHub issueDo you want to request a feature or report a bug?
Idea.
What’s the current behavior?
Right now the Point
model in Slate has “paths” and “keys” (in addition to “offsets”) to reference a location in the document. Paths are generally more performant, since you can use them to traverse directly to a node. Whereas keys need to be looked up by searching through the entire tree. (We cache keys to try to alleviate this issue, but the caches are invalidated often.)
Ideally we’d use paths in many more places, but the problem with paths is that you can’t guarantee they aren’t stale after an operation is applied because it may have been invalidated by insert_node/remove_node/etc.
operations. The same goes for offsets as well as paths, since insert_text/remove_text
operations could invalidate an offset as well.
But we might be able to create editor-specific objects to alleviate this…
What’s the expected behavior?
We could create a mutable Pointer
model that referenced a point in the editor’s document. When you create it, you pass in the Point
you’re wanting to keep an up-to-date reference to.
const pointer = new Pointer(point)
Then, whenever a new operation is applied to the editor, it updates all of the pointers it’s keeping track of, so that they aren’t stale. And at any time in the future, you can access pointer.path
or pointer.offset
and it will be guaranteed not to be stale.
const { path, offset } = pointer
This could alleviate a lot of the current uses of keys. Even renderNode
would be able to receive a Pointer
instance since its mutable and referentially equal. (It can’t receive the path
right now because every time the path changed it would force a re-render.)
However, this could also help for asynchronous commands, like inserting images, where you need to perform some asynchronous work (eg. uploading the image) before you insert it, and you need to make sure that the insertion point stays updated as more editing happens.
Also if anyone has a better name than “pointer” I’m all ears!
Issue Analytics
- State:
- Created 5 years ago
- Reactions:6
- Comments:17 (16 by maintainers)
Top GitHub Comments
@ianstormtaylor Hi, I am thinking something like this:
We can see query and pointRef share things in common as following ways:
editor.query(q) => node|any
editor.find(pointRef) => node
Both are just asking for a result, and neither has side effect.So we can think a pointRef as a kind of query. We can merge them in one interface, like
I think the gaining is that we do not need to introduce a new model explicitly. If we think pointRef as a query, we can use query as the single source of asking values from editor.
Another problem is that
pointRef.current
is changed according to the editor change, which is implicit. Personally, I feel makingget
a mutable value (and whose mutation is changed by callingeditor.doSomething
rather thanpointRef.doSomething
) makes the pointRef.current hard to predict.When passing an pointRef around, we do not explicitly pass the editor as another argument; it would be hard to track where editor it is when one pass pointRef to another function.
@Dundercover we wouldn’t, we’d ideally want to keep a
PathRef
I think.