slate icon indicating copy to clipboard operation
slate copied to clipboard

Cross-node decorate

Open mylvghb opened this issue 3 years ago • 5 comments

How to achieve cross-node decoration. This requirement is common in implementing find and highlight functions. For example: find text at the end of one node and at the head of another node。

image

When I search for "a comment" . I want to decorate the "a " of the preceding Text Node and the inline void Element Node in the middle and the " comment" of the following Text Node.

Final effect image:

image

mylvghb avatar Jul 23 '21 08:07 mylvghb

If I understand you correctly, the existing decoration mechanism already supports this—the decorate function returns a list of Ranges, which can cross node boundaries. Internally Slate splits the ranges at node boundaries to produce Leafs, then calls renderLeaf on each.

However I don't think there's a way to decorate void nodes. Since you render them yourself (in renderElement), renderLeaf is not called for them. You could render the decoration yourself, but you don't have access to the decorations data in renderElement. (I think it would make sense to pass it as an extra parameter.)

jaked avatar Aug 31 '21 17:08 jaked

@jaked The example Search Highlighting only supports search and decoration in one TextNode. image

mylvghb avatar Sep 01 '21 01:09 mylvghb

that's true, but it's not because decorations can't be cross-node.

To generate cross-node match ranges I think you'd need to do something like Editor.string, i.e. iterate through all the text nodes and concatenate them, but keep track of the path for each chunk of the concatenated string; then generate ranges for matches by looking up the paths of the endpoints.

jaked avatar Sep 01 '21 07:09 jaked

@jaked Tanks!

mylvghb avatar Sep 02 '21 01:09 mylvghb

Do you have an example of it?

harrydema avatar Jun 27 '23 15:06 harrydema