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

Update RST spec to include a parent and/or sibling pointer(s) #1085

Open
aweary opened this issue Aug 20, 2017 · 10 comments
Open

Update RST spec to include a parent and/or sibling pointer(s) #1085

aweary opened this issue Aug 20, 2017 · 10 comments
Labels
discussion feature request Issues asking for stuff that would be semver-minor

Comments

@aweary
Copy link
Collaborator

aweary commented Aug 20, 2017

*and possibly a parent pointer.

Currently, the RST spec only allows one form of traversal: from root to leaf. This isn't ideal, since we occasionally need to check some predicate for either a sibling node. I suggest we add a nextSibling pointer, so we can traverse siblings as a singly linked list (prevSibling could be included but I haven't found it super useful yet)

I did some work with a similar tree format and found that it wasn't too hard to add these pointers.

As an example of an existing pain point, think about adjacent sibling selectors. Currently, we need to find the parent of the node (if we don't already have a reference to it that means we need a reference to the root node and have to traverse the ~whole tree in the worst case) and iterate through the children.

With a nextSibling pointer we could just do a constant-time operation by running the predicate against node.nextSibling. It also makes general sibling selectors easier.

I'm not sure if a parent pointer would be useful yet, but it could be 🤔

@aweary
Copy link
Collaborator Author

aweary commented Aug 20, 2017

If we agree that this is an acceptable change to the RST spec I can include the changes to the adapters and spec alongside the work I'm doing integrating a CSS parser with the RST traversal stuff.

@ljharb
Copy link
Member

ljharb commented Aug 21, 2017

Would adding a parent pointer preclude the need for sibling iterators? It might be less complex then enforcing the idea of a finite and non-repeating list of ordered siblings.

@aweary
Copy link
Collaborator Author

aweary commented Aug 21, 2017

In what situations could an RST represent a set of child nodes that aren't finite, unique and ordered? I think even if an element was repeated it would be represented by a unique node, but I'm not sure.

Having just a parent pointer would be a find compromise though. It would still require a linear search for sibling selectors but that's probably not too costly in most cases.

@ljharb
Copy link
Member

ljharb commented Aug 21, 2017

All three seem reasonable fwiw (nextSibling, prevSibling, parent) but it'd be nice to minimize the API surface :-)

@aweary
Copy link
Collaborator Author

aweary commented Aug 30, 2017

While working on #1086 I found that the only time I needed to get the parent was to get a sibling, and I never had to match a previous sibling since CSS selectors only match following siblings.

So I think we could get away with just nextSibling unless there are other APIs that would benefit from prevSibling or parent?

@ljharb
Copy link
Member

ljharb commented Aug 30, 2017

If we have next, I think we need prev. I'm less concerned about parent tho, since theoretically you got to a node from the parent.

@nfcampos
Copy link
Collaborator

Without a parent link how do you implement https://github.com/airbnb/enzyme/blob/master/docs/api/ShallowWrapper/parent.md ? By starting from the root and following children until you get to the current node?

@aweary
Copy link
Collaborator Author

aweary commented Aug 31, 2017

@nfcampos that's exactly how it does it: https://github.com/airbnb/enzyme/blob/master/packages/enzyme/src/RSTTraversal.js#L74-L76

I was only thinking about it in the context of the selector API, but a parent pointer would definitely be helpful here. Since it's an internal API used only by adapters, maybe it's OK to increase the API surface and add all three? prevSibling is the least useful, but it does make sense to include it if we have nextSibling (which is really useful).

@ljharb
Copy link
Member

ljharb commented Sep 1, 2017

Sounds like there's use cases for all three then.

@lelandrichardson, thoughts?

@aweary aweary changed the title Update RST spec to include a nextSibling pointer Update RST spec to include a parent and/or sibling pointer(s) Sep 13, 2017
@lelandrichardson
Copy link
Collaborator

@aweary i worry about adding these types of things when JS doesn't have weak references. I think it also makes actually building an RST much more complicated. Since this is just traversal stuff, It'd be nice if any logic around prev/next sibling etc was contained inside enzyme. If we wanted to transform an RST into a structure that had these pointers, that might make sense... but i also am not sure i'm convinced that this is a good idea.

@ljharb ljharb added discussion feature request Issues asking for stuff that would be semver-minor labels Jul 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion feature request Issues asking for stuff that would be semver-minor
Projects
None yet
Development

No branches or pull requests

4 participants