dom: Implement minimal IntersectionObserver workflow#35551
dom: Implement minimal IntersectionObserver workflow#35551gterzian merged 31 commits intoservo:mainfrom
Conversation
6bcc915 to
f63da18
Compare
|
I guess the changes is fairly complete for reviews. I am still analyzing the test and rechecking the logic and components, but it will be great to get overall review and discussions to make sure I am on the right track. |
gterzian
left a comment
There was a problem hiding this comment.
I haven't reviewed all the logic but to the question as to whether you are on the right track the answer is: yes.
| // > Let registration be the IntersectionObserverRegistration record in target’s internal | ||
| // > [[RegisteredIntersectionObservers]] slot whose observer property is equal to observer. | ||
| // We will clone now to prevent borrow error, and set the value in the end of the loop. | ||
| let registration = target |
There was a problem hiding this comment.
I'm not sure it makes sense to separate the info from the registration, because when implementing step 14 you will need the registration.
|
|
||
| /// IntersectionObserverRegistration but the fields other than observer is | ||
| /// separated to pass unrooted them with ease. | ||
| /// |
There was a problem hiding this comment.
I'm not sure this distinction makes sense, because in update_intersection_observations_steps you will need to eventually use both the registration and the info(when implementing what is now a todo).
To make this rootable, you need to use the example of #34194
There was a problem hiding this comment.
Sure! I believe making it rootable is correct in this scope. I have tried to implement it here bf85252.
After rechecking it, I am actually not sure whether it should have used cloned version or borrow in this case. I believe since observation step should avoid making changes to DOM tree (e.g. reflow), it would be better to use reference instead. a0e8794
8422a42 to
f118ce8
Compare
gterzian
left a comment
There was a problem hiding this comment.
Looks good to me overall.
Would be good to create a meta issue with a todo list reflecting all the todos in the code.
Perhaps someone more familiar with layout can also take a look? cc @mrobinson @mukilan
|
|
||
| /// Whether the observer is connected to the owner document. | ||
| /// An observer is connected if it is registered in intersection_observers list inside document. | ||
| is_connected: Cell<bool>, |
There was a problem hiding this comment.
This seems redundant because I think you can deduce that value from observation_targets.
components/script/script_thread.rs
Outdated
| // as well as those for which a rendering update would be unnecessary, | ||
| // but this isn't happening here. | ||
|
|
||
| // TODO(#31021): the filtering of docs is extended to not exclude the ones that |
There was a problem hiding this comment.
I don't think this is the right issue; If any it should be #31242
| /// > The root intersection rectangle for an IntersectionObserver is | ||
| /// > the rectangle we’ll use to check against the targets. | ||
| /// | ||
| /// NOTE: Firefox seems to only account for viewport/boundingBox area without not covered by |
There was a problem hiding this comment.
It would be useful to point out why FF's behavior is relevant here. I assume because we do the same?
There was a problem hiding this comment.
Currently, it is using the viewport that is quite different from the spec and other implementation. It is considering the scroll offset and not considering the size of the scrollbar. I really should add this into another todo also, individually on each impacted lines.
There was a problem hiding this comment.
I have checked this further, it seems that FF behavior make more sense. And, the spec was quite incomplete in this root intersection rectangle section. I believe it should consider clipping and probably several more steps similar to https://w3c.github.io/IntersectionObserver/#compute-the-intersection. I will check chromium's implementation too, as FF is not quite updated regarding several new features.
I will leave viewport addressing identical to element's client-width for now.
There was a problem hiding this comment.
Ok, thanks for all the research. For clarity, what I mean is that we should write the comment from the perspective of what Servo is doing, and then perhaps explain that this matches FF's behavior and that the spec has not settled down yet. SO basically the same content, but putting the focus on what we're trying to do.
There was a problem hiding this comment.
Thanks for pointing out. Sorry for the misunderstanding the intention.
| debug!("descendant of containing block chain is not implemented"); | ||
| } | ||
|
|
||
| // NOTE: Firefox skips these steps too, if target_rect or root_bounds is zero. |
There was a problem hiding this comment.
Following Gecko's behavior and skipping these steps if ... (writing from the point of what we're doing here, not what FF is doing).
There was a problem hiding this comment.
My bad it is more like an todo rather than a note as these is not implemented. It should also mention that it was for null value instead of zero (rectangle?).
I added it in ecc6743, I guess it is better to add it here since it does not make sense to assume null return from getBoundingBox as a zero rectangle.
| /// <https://w3c.github.io/IntersectionObserver/#document-intersectionobservertaskqueued> | ||
| intersection_observer_task_queued: Cell<bool>, | ||
| /// Active intersection observers that should be processed by this document. | ||
| intersection_observers: DomRefCell<Vec<Dom<IntersectionObserver>>>, |
There was a problem hiding this comment.
I think it would be good to link to https://w3c.github.io/IntersectionObserver/#run-the-update-intersection-observations-steps
and add the prose from step 1,
and also a note that this is discussed at w3c/IntersectionObserver#525
components/script/dom/document.rs
Outdated
| true | ||
| } | ||
|
|
||
| /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-intersectionobserver> |
There was a problem hiding this comment.
Here I don't think the link is useful, because it does not link to anything describing "adding an intersection observer". I think it would be better to point out that this does not follow the spec as per w3c/IntersectionObserver#525
(same below)
components/script/dom/document.rs
Outdated
| // > 2. Let notify list be a list of all IntersectionObservers whose root is in the DOM tree of document. | ||
| // > 3. For each IntersectionObserver object observer in notify list, run these steps: | ||
| // Iterating a copy of observer stored in the document to prevent borrow error. | ||
| for intersection_observer in self.intersection_observers.clone().borrow().iter() { |
There was a problem hiding this comment.
Can we avoid the cloning by making IntersectionObserver.callback an Rc<RefCell<>>, so that there's internal mutability?
Or at least we can move the cloning to inside invoke_callback so that we don't clone every observer.
There was a problem hiding this comment.
I am not sure, because a callback can modify the self.intersection_observers completely, by using disconnect(), observe(), and unobserve(). I should probably wrote about that in the comment too. We could filter the observer that won't invoke any callback and copy it before any iteration I guess.
There was a problem hiding this comment.
I see, good point! Thanks!
| } | ||
|
|
||
| /// Step 3.1-3.5 of <https://w3c.github.io/IntersectionObserver/#notify-intersection-observers-algo> | ||
| pub(crate) fn invoke_callback(&self) { |
There was a problem hiding this comment.
We should rename this method, because it doesn't always invoke the callback.
Maybe invoke_callback_if_necessary?
Thanks for the review! Sure, most of the todo should be summarized in the description. I would like to hear from the other, especially about the todos related to layout. If it seems reasonable we could create the meta issue based of that. |
dc66d04 to
1793841
Compare
Here is an example for ResizeObserver #31182 |
ddf5905 to
268d92d
Compare
|
Rebased to recent changes. @Loirooriol @mrobinson If you are not busy, could you please give a look as well? Thank you. (sorry for the ping) |
|
@stevennovaryo Could you rebase this PR again? |
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
I suppose these changes is better separated to other PRs. Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
Signed-off-by: stevennovaryo <[email protected]>
268d92d to
f6c5d49
Compare
Rebased, could we get this changes merged soon? Try |
Signed-off-by: stevennovaryo <[email protected]>
f6c5d49 to
8fa5559
Compare
|
|
||
| //! Copy of Stylo Gecko's [`style::values::specified::gecko::IntersectionObserverRootMargin`] implementation. | ||
| //! TODO: expose the object to servo as well in Stylo | ||
| //! TODO(stevennovaryo): when stylo's IntersectionObserverMargin is up, make a thin wrapper and remove copied codes |
There was a problem hiding this comment.
If you mean https://phabricator.services.mozilla.com/D237514, it's already available
There was a problem hiding this comment.
Updated, Thanks!
components/script/dom/window.rs
Outdated
| ) | ||
| } | ||
|
|
||
| // query content box without considering any reflow |
There was a problem hiding this comment.
Nit:
| // query content box without considering any reflow | |
| // Query content box without considering any reflow |
Signed-off-by: stevennovaryo <[email protected]>
Implement minimal IntersectionObserver processing model which includes the processing model algorithm, omitting the implementation documented in the tracking issue. Most of the major implementations would depends on other API/module.
WPT Result
We are not experiencing timeouts in the many of IntersectionObserver WPT tests that happens because no intersection is reported. Although the intersection reported is not accurate because of the aforementioned reasons. More of "first rAF" started to pass too, presumably because in the initial observations, many of the intersections cases is still not stimulated yet.
Test
/intersection-observer/nested-cross-origin-iframe.sub.htmlproduces quite flaky result, either betweenTIMEOUTorFAIL. Due toscrollIntoViewis yet to be implemented, test is supposed to fail. I guess it might be caused by the bad timing of event loop.Update: this test seems to be quite stable after several additional commits. Still could create a different issue for this specific test.
cc: @xiaochengh
Try
./mach build -ddoes not report any errors./mach test-tidydoes not report any errors