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

jQuery#find in 4.x will not work with the ShadyDOM polyfill in forced mode #5032

Open
blackjackyau opened this issue Apr 8, 2022 · 12 comments

Comments

@blackjackyau
Copy link

Description

https://codepen.io/blackjackyau/pen/popVgXy

On a shadydom polyfilled environment, the find() function from Jquery 3.5.0 version and above is not working correctly when there's more than one selector specified.
This behaviour can be seen from the codepen link provided where no result is return from $("#table").find('tr td')[0] but is return from $("#table").find('tr').find('td')[0]

Workaround

  • swap the load order of jquery and webcomponents ( to load shadydom polyfill first before jquery )

Link to test case

@jquery jquery deleted a comment Apr 11, 2022
@jquery jquery deleted a comment Apr 11, 2022
@jquery jquery deleted a comment Apr 11, 2022
@jquery jquery deleted a comment Apr 11, 2022
@jquery jquery deleted a comment Apr 11, 2022
@jquery jquery deleted a comment Apr 11, 2022
@mgol
Copy link
Member

mgol commented Jun 27, 2022

Thanks for the report. In general, libraries modifying native methods should be included first as otherwise there may be a mismatch between whatever jQuery manages to cache internally before the native methods are swapped.

In this case, the Shady polyfill doesn't seem to handle :scope properly in querySelectorAll, and since .find('tr td') in jQuery actually invokes .querySelectorAll(':scope tr td') on the element underneath, this breaks.

There's nothing jQuery can do here.

@mgol mgol closed this as completed Jun 27, 2022
@blackjackyau
Copy link
Author

@mgol It works with older JQuery version ( lower than 3.5.0 ) and it will work too by downgrading the sizzler library version from the latest JQuery.

As there's no changes on the shady polyfill library, hence it must be caused by the some new changes from the Sizzler library that breaking the behavior

@mgol
Copy link
Member

mgol commented Jul 1, 2022

Older versions of Sizzle didn't rely on :scope so much; newer do for performance reasons. So yes, something changed on the jQuery side but that doesn't change what I wrote above.

@blackjackyau
Copy link
Author

blackjackyau commented Jul 1, 2022

that explains. thanks

@mgol
Copy link
Member

mgol commented Jul 1, 2022

BTW, Sizzle actually does have a support check for :scope support; this is most likely why moving the Shady polyfill before jQuery works - at the point where jQuery does the support test, the polyfill is loaded and :scope doesn't work so Sizzle takes a note of that and doesn't use :scope later on. If the polyfill is loaded after jQuery, the Sizzle support test for :scope passes and that result is cached; then Shady changes querySelectorAll to a version where :scope doesn't work but Sizzle thinks it does.

It's worth noting here that the upcoming jQuery 4.0 doesn't do any support test for :scope; it just skips using it in IE where it's not supported and it assumes it's supported everywhere else. Therefore, the workaround of loading Shady first won't work with jQuery 4.0.0. I suggest raising this issue with the Shady maintainers as they're the ones that need to add support for :scope; all modern browsers support it.

@mgol
Copy link
Member

mgol commented Jul 1, 2022

I see there already is a similar issue so I just posted there: webcomponents/polyfills#480

@mgol mgol changed the title Jquery.find() method from version >= 3.5.0 is not working with ShadyDom polyfills jQuery#find in 4.x will not work with the ShadyDOM polyfill in forced mode Jul 18, 2022
@mgol mgol reopened this Jul 18, 2022
@mgol
Copy link
Member

mgol commented Jul 18, 2022

@blackjackyau We have a few questions. What does it exactly mean that the library is built with the assumption of the ShadyDOM polyfill? What does the polyfill have that the native APIs do not? What would it take to migrate the library to work with native Shadow DOM?

jQuery wants to avoid adding custom checks for non-standard broken environments unless the impact is large. Given that by default ShadyDOM won't apply in modern browsers, it's not yet clear to us whether the issue is big enough for jQuery to allow an escape hatch here.

@blackjackyau
Copy link
Author

blackjackyau commented Jul 20, 2022

@mgol our web component library does not use the shadow DOM styling (local) and it is still with the normal/standard/global styling with the help of ShadyDOM polyfill.

The web component library is now in the "maintenance" state and it might end up in a total rewrite someday in the future, but it will be huge effort to get there.

Appreciate if Jquery can provide a way for us to workaround it. Our current workaround is to "custom build" the Jquery with a lower version of Sizzler, and it is indeed not sustainable.

@mgol
Copy link
Member

mgol commented Jul 20, 2022

Why do you need a workaround currently, though? The issue I described will only manifest itself in jQuery 4.0. The one you reported here originally is caused by the polyfill being loaded after jQuery which is not a correct thing to do: polyfills should be loaded as early as possible as they affect the browser environment so changing this after some libraries have been loaded and could have already run support tests or cached some native built-ins is likely to cause issues in general.

@mgol mgol added the Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. label Jul 20, 2022
@blackjackyau
Copy link
Author

The application went into hanging ( infinite loop ) state after i switched the order ( polyfill before jquery ).
As I could not confirm totally if this is Jquery related and I could not reproduce it from a simple code pen project, I did not mention it here.

@mgol
Copy link
Member

mgol commented Jul 20, 2022

It'd be good to figure out what's causing the issue considering the hackiness of the current solution. If you can host the broken version somewhere, I could have a look. Of course, if it's a complete site and not a small repro this may be difficult but I'd be willing to try.

@timmywil timmywil removed the Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. label Aug 1, 2022
@bicknellr
Copy link

BTW, I just pushed releases of Shady DOM and our polyfill bundles that include a new setting that lets you opt in to a couple of new options for Shady DOM's implementation of querySelector / querySelectorAll, which have better support for :scope:

webcomponents/polyfills#480 (comment)

@mgol mgol removed the Needs info label Feb 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants