Problem/Motivation
We can now add selectors using jQuery: https://api.jquery.com/category/selectors/jquery-selector-extensions/
At the same time, jQuery itself recommends optimizing them:
https://learn.jquery.com/performance/optimize-selectors/
Therefore, an important step is to use only vanilla selectors and deprecate the Sizzle style.
Proposed resolution
Similar to
https://git.drupalcode.org/project/drupal/-/blob/11.x/core/misc/dialog/d...
We'll add a temporary function that will still work but throw messages if the selector is invalid.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#...
| Comment | File | Size | Author |
|---|
Issue fork drupal-3568777
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
finnsky commentedComment #5
nicxvan commentedThere are a bunch of failures still.
How do we know which ones are supposed to be deprecated and are there any that could flow through this code path that should not be deprecated?
Comment #6
finnsky commentedComment #7
finnsky commentedComment #8
finnsky commentedRebased
I don't think there's any point in constantly fixing the Asset Size Test. I'm leaving the task in Needs Review even with a failed test. This test can be fixed before committing.
Comment #9
finnsky commentedFixed Asset Size Test
Comment #10
smustgrave commentedWondering if this should be pushed to 13, we found out removing existing deprecation from ajax.js is breaking things so may wan to be safe.
Comment #11
finnsky commentedLooking at the review dynamics, you can safely postpone it until 15 :)
Comment #12
smustgrave commentedWhy 15?
Comment #13
finnsky commentedSorry! Sad joke.
I have several similar MRs. And they're being reviewed very slowly.
They're not really needed right now, but without them, it seems like it would be difficult to complete, say, a replacement for the jQuery UI Dialog.
Comment #14
nicxvan commentedThat can certainly be frustrating!
I read the attached docs and https://www.scaler.com/topics/jquery/sizzle-selector/
And with the refactor I understand what is happening here well enough to review properly now I think.
I have one more comment, I think we can return in the try and fall back to jquery in the catch after setting the deprecation message.
That way we don't duplicate the selector.
Also there is a performance test conflict, once those two issues are resolved I think this is ready.
Comment #15
finnsky commentedI added a comment and removed the unnecessary function.
We should return the same expected jQuery selectors. We'll just make sure the syntax is no longer sizzle.
In version 12, this will allow us to switch to vanilla ones.
Comment #16
finnsky commented@nicxvan
This is context of current idea
https://git.drupalcode.org/project/drupal/-/merge_requests/8751#note_387911
Comment #17
smustgrave commented@nicxvan thoughts? I don't think I'm a good resource for javascript review. Also the current javascript deprecation removals we are doing is breaking so much.
Comment #18
nicxvan commentedThis needs a rebase, but I think this is ready once that is done
Sorry I missed 16, but that answers my last question.
Just a note, I'm not super strong with JS either, but this seems useful.
Comment #19
smustgrave commentedThanks @nicxvan
Comment #20
finnsky commentedComment #21
nicxvan commentedI'm so sorry, I think this needs a change record with a link to it in the notice right?
I created a stub cr but I think you might need to add examples.
One other thing I realized, we should create a follow up issue with some notes about how to clean this up since it's a bit out of the ordinary e.g delete deprecateSizzleSelector and probably remove jquery from those calls.
Ping me in slack when this is ready for review again.
Comment #22
finnsky commentedComment #23
finnsky commentedAdded follow up https://www.drupal.org/project/drupal/issues/3582096
and updated CR.
Please review!
Comment #24
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #25
finnsky commentedComment #26
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #27
finnsky commentedComment #28
nicxvan commentedI reviewed this again, I think it's ready, but there is another performance test conflict.
Comment #29
prudloff commentedSwitching entirely to document.querySelector() would also improve security because $() is an XSS sink (if the selector starts with
<it parses it as HTML...).Comment #30
nicxvan commentedOk the conflict was resolved, I think this is ready now!
Comment #31
alexpottWe should have a test that proves this is working and can be caught by our test infra.
Comment #32
finnsky commentedComment #34
nicxvan commentedYeah I should have caught that it didn't have an actual test.
Comment #35
finnsky commentedIt was probably a good idea to write a test.
Because with it, I caught a couple of syntax errors in other tests.
Comment #36
nicxvan commentedThanks for adding that, I should have noticed it was missing earlier!
It looks great to me!
I can't run test only, but this is a feature request not a bug fix so that will fail anyway since it's a new code path.
This looks ready to me!
Read through the CR again and it looks good as well.
Comment #37
alexpottI think the current deprecation method
results in doing multiple dom queries... i.e.
document.querySelector(selector);will always be followed byreturn $(selector);so we do the CSS query twice. I commented on the MR with a suggestion about how to get round this... not sure of the impact.Comment #38
finnsky commented@alexpott
Please try this in browser console. Right in this page :)
I have 20%. User will not see it at all.
Comment #39
finnsky commentedWe're not "querying twice". The first document.querySelector(selector)
call is only a syntax probe — to tell whether the input is valid CSS or
Sizzle-only, and decide whether to emit a deprecation. Its result is
discarded: no nodes are returned to the caller, no jQuery object is built
from them, no events/data are attached. The actual query happens once,
inside $(selector).
The probe costs ~100ns per call, and only in dev/tests: in production
deprecations are suppressed via drupalSettings.suppressDeprecationErrors,
so if even those 100ns matter, an early return is enough:
In production this is exactly $(selector); in dev/tests behaviour is
unchanged.
Comment #40
alexpott@finnsky great points... my brain had missed the early
If there are reason this is not written like this:
1 return and less duplicated code? Also I think the deprecation message should link to the CR.
Comment #41
alexpottFixing link in the issue summary.
Comment #42
finnsky commentedSorry, let me add that!
You're fine :)
Comment #43
finnsky commentedComment #44
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #45
finnsky commentedComment #46
alexpott@finnsky I really like this change - this is a good idea and great work on the tests.
A couple of questions:
Comment #47
finnsky commentedI don't know. I think it should have been done at 11 :)
Well, this means AJAX in 12 can be rewritten practically without jQuery. This will be very helpful, for example, in Dialog Native and everywhere else.
Comment #48
alexpottThanks for #47. So the aims are as I thought - rewrite AJAX without jQuery... that's going to happen in 12... so we'll be supporting jQuery for the length of D12 cycle - so practically this deprecation will only be able to be enforced in Drupal 13 right?
Comment #49
finnsky commentedYes! But we'll be able to write document.querySelector() instead of $() in 12.
Regardless of whether jQuery is present on the page. This has nothing to do with it at all!
This has to do with script waits. The AJAX script and everything related to it now only waits for a string.
Comment #50
alexpottOkay given the tiny changes for core JS I guess deprecating for Drupal 12 is okay and getting this done will probably make it easier to continue to remove jQuery in D12 in other parts of the JS ecosystem.