-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Implement NodeIterator #1092
Implement NodeIterator #1092
Conversation
This is really amazing work. Left some nitpicky comments, but major <3 for implementing this. Very clean overall. And I think the max-node-iterators thingy is a pretty reasonable solution. I asked in IRC if we should be trying to pass https://github.com/w3c/web-platform-tests/tree/13bff083fba249ed260966bca65319b1b35d3f34/dom/traversal/unfinished despite its "unfinished" name. Otherwise we should really consider submitting these test to web-platform-tests at some point. |
(DOM living)
Strictly both. If |
While Symbol performance is good, it is still a little bit slower than regular properties.
For debug-ability; It would be really annoying to have to use |
Hmm. I would rather not make it that easy to get at the internals. In browsers you can't get at them at all; ideally we'd use weak maps and hide them entirely, but they're too slow. So let's just use Are you sure amortized one-time symbol + repeated prop lookup is slower than repeated symbol lookup? |
http://jsperf.com/symbol-vs-prop-vs-def-prop/13 I did not test the "+ repeated prop lookup" part specifically though. Do you think it would be worth it to create a benchmark? |
I guess I don't mind too much. One day we'll figure out our overall story for private state and unify everything but in the meantime this is fine. |
Some of these are taken from xpath.js
Alright, i am done with the fixes. I played around some more with Symbol. NodeIterator no longer exposes any jsdom specific properties. I added a private class called |
Including test cases with 100% line and branch coverage (istanbul) Adds a new option "concurrentNodeIterators" which is needed because of a limitation in javascript (an intentional limitation by Ecma)
Merged; thanks so much! |
Using https://dom.spec.whatwg.org/#interface-nodeiterator
Related to #317
I wrote my own test cases, I used istanbul to verify coverage (line and branch coverage is 100%).
The most tricky part about
NodeIterator
is its behavior when you remove nodes it iterates over. Each activeNodeIterator
must be notified about every node that is removed ("removing steps").The DOM specification assumes implementations have control over object lifecycles (destructors, weak references, etc). To implement it properly, without leaks, you would need to use weak references between the
Document
andNodeIterator
s. We can not use such things in javascript (WeakMap and WeakSet are not adequate in this case) unless we would add a dependency on a compiled module (again :P). It looks like Ecma added this limitation on purpose to prevent side channel attacks.Instead, I added an option that specifies the maximum number of
NodeIterator
s that removing steps will occur for. If this limit is reached, the oldestNodeIterator
will no longer be tracked and it will start to throw whenever you try to access its state.I tried to work out an alternative by asynchronously resolving the state of
NodeIterator
s. jsdom would store a lot of data about removals & insertions applied on nodes and the NodeIterator would use that data the next time you access it. This is pretty complex, but more importantly it would be performance heavy because you would have to store a lot of state. Also the combination of iterating + modification would probably become something likeO(n^2)
instead ofO(n)
.