document.elementsFromPoint changed in Chrome 66 to include parent elements of shadow trees
Reported by
ho...@marcysutton.com,
May 15 2018
|
||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 Steps to reproduce the problem: 1. Assemble a stack of elements including nodes from shadow trees using document.elementsFromPoint. 2. Compare to Chrome 65, where the stack returned did not include parent nodes. 3. In Chrome 66, observe an infinite loop when you try to run the same code. What is the expected behavior? Chrome should not get into an infinite loop when assembling a stack of shadow and light dom elements. Changes to document.elementsFromPoint should be documented and communicated to developers to prevent such failures from occurring in code that uses Shadow DOM. What went wrong? There was a change to document.elementsFromPoint in Chrome 66 that started throwing an infinite loop in axe-core, the accessibility testing library powering Lighthouse. Previously, calling elementsFromPoint on a shadow dom tree would only return nodes from that tree. In Chrome 66, it started also returning parent nodes, so the logic to combine the two stacks caused an infinite loop. Because not every user will be in Chrome 66 necessarily, we had to update our code to work with both browser versions by bailing out if it gets put into such a loop. Did this work before? Yes Chrome 65 Does this work in other browsers? Yes Chrome version: 66.0.3359.170 Channel: stable OS Version: OS X 10.13.4 Flash Version: You can observe the bug report in axe-core here: https://github.com/dequelabs/axe-core/issues/856 You can also review the PR we included to stop the infinite loop here: https://github.com/dequelabs/axe-core/pull/861
,
May 15 2018
Also, the motivation for this kind of element stack assembly is color contrast evaluation.
,
May 16 2018
,
May 16 2018
This might be related: https://www.chromestatus.com/feature/6317470654660608 rakina@, could you take a look?
,
May 16 2018
Tried checking the issue on reported chrome version 66.0.3359.170 using Mac 10.13.1 with the below mentioned steps. 1. Launched chrome 2. Downloaded Index.html and opened it in a new tab. 3. Observed "Text" in black background strip. Attaching the screen shot for reference. @Reporter: We didn't see/observe chrome getting into infinite loop, As we are not very sure about the steps followed by us are correct in order to reproduce the issue, It would be highly helpful if mentioned the exact steps to be followed. Any further inputs from your end may be helpful. Thanks!
,
May 16 2018
++ Retriaged the issue by considering the console output in Devtools of the Index.html page. Able to reproduce the issue on reported chrome version 66.0.3359.170 and on the latest canary 68.0.3432.0 using Mac 10.13.1, Ubuntu 14.04 and Windows 10. Bisect Information: ==================== Last Good Build: 66.0.3331.0 First Bad Build: 66.0.3332.0 You are probably looking for a change made after 531838 (known good), but no later than 531839 (first known bad). CHANGELOG URL: https://chromium.googlesource.com/chromium/src/+log/3bc515d57274da3066b7122f6dcf47dc45af5123..bb3517a95aa758711ac11927e8f8ebf44f6a272b Suspecting: https://chromium.googlesource.com/chromium/src/+/bb3517a95aa758711ac11927e8f8ebf44f6a272b Review URL: https://chromium-review.googlesource.com/880741 Note: As this seems to be a recent regression, hence adding RB-Stable. Please remove if not applicable. Thanks!
,
May 16 2018
It does occur if you open the devtools console, my apologies for forgetting that step. Thanks for the quick replies!
,
May 16 2018
Hi there, thanks for filing the bug. Sorry for the confusion the change is making! It looks like elementsFromPoint did in fact only return nodes from its scope (aka under the same shadow root only) before, and now it can cross shadow boundary up until the document element. Sorry I did not notice the change in behavior, should've checked that first (there were no tests for elementsfrompoint on shadowroot before, I made some tests that expected the new behavior). I guess the question now is whether we should change it back to its previous behavior. There is no formal spec yet for the shadow root case, we only have the one for document: https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint and a statement in https://w3c.github.io/webcomponents/spec/shadow/#extensions-to-the-documentorshadowroot-mixin, so I don't know whether ShadowRoot.elementsFromPoint only return elements in the shadow root's scope, or return everything as it is currently. @hayato, what do you think?
,
May 17 2018
It looks the current behavior is collect, from the spec's perspective. > I guess the question now is whether we should change it back to its previous behavior. It's always difficult question, however, in general, we should be careful and should wait for more breakage reports. If there are no other breakage reports from other sites, and axe-core can be fixed (I am totally aware this is super painful and super-frustrating for users), maybe we shouldn't revert this change.
,
May 17 2018
#8, #9 - if the behavior is not clear, please, file an issue (a link here would be nice) against the specification so no one else has to guess...
,
May 17 2018
As this is regressed in M66 stable and we're very close to M67 stable promotion, we won't consider this as M67 Stable blocker. Pls let us know ASAP if there is any concern here. Thank you.
,
May 17 2018
,
May 18 2018
> #8, #9 - if the behavior is not clear, please, file an issue (a link here would be nice) against the specification so no one else has to guess... FYI. There is an filed issue on CSSOM view: https://github.com/w3c/csswg-drafts/issues/556#issuecomment-265371567 Apart from the topic on the issue, it looks clear to me that we should use retargeting algorithm here, according to note in the Shadow DOM spec: > Regarding elementFromPoint and elementsFromPoints, they should return the result of running the retargeting algorithm with context object and the original result as input.
,
May 20 2018
My Chrome extension "View background image" has the same problem. https://github.com/foooomio/view-background-image/issues/12 I disagree with the current behaivor. It is hard to tell inner elements from outer elements of Shadow DOM. For example, pick up my extension's processing flow: 1. Get the elements under mouse cursor by document.elementsFromPoint. 2. For each elements, get the background image. 3. If the element has a shadowRoot, apply this flow to it in place of document. The current behaivor causes an infinite loop at 3. For details, please see the code. https://github.com/foooomio/view-background-image/blob/bc04f7a529552b73f3fcbbbf6598fed2459466af/src/content.js With the previous behaivor, we can apply functions to either document or shadowRoot recursively. At present, we need workaround only for Shadow DOM. I don't think it is profitable. BTW, the result of shadowRoot.elementsFromPoint doesn't contain the whole of document.elementsFromPoint, such as html element. Is it correct?
,
May 22 2018
@ #14, Thanks for commenting. Can you give an example of cases where document.elementsFromPoint don't match shadowRoot.elementsFromPoint (excluding nodes in the shadow tree)? That's not expected from our WPT in https://cs.chromium.org/chromium/src/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html?q=third_party/WebKit/LayoutTests/external/wpt/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html&sq=package:chromium&g=0&l=1
,
May 24 2018
@ #15, Access https://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/#ex3aNameTag and run codes below on console. You will see shadowRoot.elementsFromPoint doesn't return html element. var element = $('#ex3aNameTag') var rect = element.getBoundingClientRect() document.elementsFromPoint(rect.x, rect.y) element.shadowRoot.elementsFromPoint(rect.x, rect.y) Anyway, this odd behavior will be resolved if shadowRoot.elementsFromPoint is restored.
,
Jul 10
@ #16, Sorry for the long delay in reply! Thanks for the example case, it really helps. There was a bug in the code that made it that way. I put out a CL (crrev.com/c/1131023) FYI, the case is special and not covered in the LayoutTests before. The situation is when the HTML element's height is shorter than the position of the hit-tested element so it doesn't get hit-tested. There's additional check for non-shadow root code so it still returns for the non-shadow root case. (I don't know if we actually should return the HTML element in that case, but maybe it's better to follow existing behavior of Document.elementsFromPoint?)
,
Jul 11
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/7809be6a01af457d8b17a8b1aa4a98fd3f8dca1b commit 7809be6a01af457d8b17a8b1aa4a98fd3f8dca1b Author: Rakina Zata Amni <rakina@chromium.org> Date: Wed Jul 11 08:07:49 2018 Make ShadowRoot.elementsFromPoint always return document element Currently in some cases, ShadowRoot.elementsFromPoint may not return the document element even when Document.elementsFromPoint returns the document element such as when the document element height is shorter than the hit-tested element's position. This CL fixes it by removing a check in TreeScope::ElementsFromHitTestResult. See example live case detailed in this comment: https://bugs.chromium.org/p/chromium/issues/detail?id=843215#c16 Bug: 843215 Change-Id: I5b774d1a091f3c3f72345c55bca188fad309ba58 Reviewed-on: https://chromium-review.googlesource.com/1131023 Commit-Queue: Rakina Zata Amni <rakina@chromium.org> Reviewed-by: Hayato Ito <hayato@chromium.org> Cr-Commit-Position: refs/heads/master@{#574104} [modify] https://crrev.com/7809be6a01af457d8b17a8b1aa4a98fd3f8dca1b/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html [modify] https://crrev.com/7809be6a01af457d8b17a8b1aa4a98fd3f8dca1b/third_party/blink/renderer/core/dom/tree_scope.cc
,
Jul 14
@ #17, Thank you for the fix. I also think it's better, aside from whether the behavior of Document.elementsFromPoint is correct or not. My concern is whether ShadowRoot.elementsFromPoint will get back to the previous behavior or not. Is the current behavior suitable for the retargeting algorithm?
,
Jul 17
We have no plan on changing the behavior back currently, but I agree that one might expect that shadowRoot.elementsFromPoint only return elements under the shadow root (like shadowRoot.styleSheets) though we also can see that shadowRoot.elementFromPoint might return an element that's not under the shadow root (For example, when a text node is a direct child of a shadow root, it will return the shadow host). I suggest you participate in the discussion at https://github.com/w3c/csswg-drafts/issues/556 as the decision of what makes sense might be better discussed there.
,
Jul 17
foooomio@
You can think the current behavior of {document,shadowroot}.elementsFromPoints as:
- Basically, return all elements in a tree of trees, however, the result should be adjusted so that elements which should not be *visible* from the context object should not be exposed to callers
The current behavior of {document,shadowroot}.elementsFromPoints are NOT:
- Return only elements under the context object's tree.
Regarding https://github.com/foooomio/view-background-image/blob/bc04f7a529552b73f3fcbbbf6598fed2459466af/src/content.js,
you might want to check `element.getRootNode() === shadowRoot` so that it doesn't cause an infinite loop.
,
Jul 21
Hayato@
Thank you for the advise. It does work well by checking `element.getRootNode()`. I appreciate it.
I understand that {document,shadowroot}.elementsFromPoint are almost the same, except that document's doesn't return elements inside shadow trees because they should not be visible from the outside. Is my understanding correct?
,
Jul 22
> I understand that {document,shadowroot}.elementsFromPoint are almost the same, except that document's doesn't return elements inside shadow trees because they should not be visible from the outside. Is my understanding correct?
Yes that's correct. Shadow root can see outside up to document root, but document can't see anything in shadow tree.
,
Jul 22
I got it. Thank you for your kind instruction. The current behavior is reasonable.
,
Jul 24
rakina@, I think we can close this issue. Please feel free to re-open if someone finds any wrong behavior. |
||||||||
►
Sign in to add a comment |
||||||||
Comment 1 by ho...@marcysutton.com
, May 15 2018