Problem/Motivation

jQueryUI has reached end of life so it is being deprecated for removal in Drupal. The drupal.tabbingmanager library depends on jqueryUI.

Proposed resolution

According to the comment in core.libraries.yml, jquery ui is only needed because it # Supplies the ':tabbable' pseudo selector.

Replace tabbingmanager's use of jQueryUI with the https://github.com/focus-trap/tabbable library, and add a shim so jQuery's use of the :tabbable selector uses this library. Tabbable is the only active library that provides the functionality needed.

Dependency eveluation for focus-trap/tabbable

Maintainership of the package
After about a year with little activity, https://github.com/stefcameron took over as maintainer, and it looks like it is in good hands. He has been very active responding to issues and keeping dependencies current. Tabbable is also a dependency of another library with the same maintainer https://github.com/focus-trap/focus-trap (something that could potentially replace tabbingmananger as a no-jquery equivalent).
Security policies of the package
No policy is currently posted, but I inquired about the policy and received an answer: https://github.com/focus-trap/tabbable/issues/136. Based on the response, it's possible that a policy will be posted soon after I type this, but I was satisfied with the content of the response. While it's unlikely a security release would receive a backport to earlier versions, the nature of the library means its unlikely for such vulnerabilities to occur. Were a backport absolutely necessary for Drupal, Tabbable's codebase is straightforward enough that it could be performed in a dedicated fork which wouldn't be ideal but is also: 1) unlikely 2) still less effort than an entirely custom solution.
Here's the maintainer's response"

I'm also maintaining focus-trap and focus-trap-react (all in the same org/family), so the only thing I can support is the currently released version. If there's a security issue in that version, then I'll certainly fix it by publishing a new version that addresses the vulnerability, but I will not support any previous versions. So if I eventually publish 6.0.0 and a security issue is found in 5.1.3, for example, and it's still in 6.0.0, then I will fix it in 6.0.1 or 6.1.0 (or possibly 7.0.0 if it requires breaking backward compatibility for some reason -- I would imagine this would be rare), but I will not also publish 5.1.4 or 5.2.1 to fix it.
I guess there could be a scenario where I'm in a pre-release on a new major and a security issue is discovered in the current 5.1.3 release. In that case, I'd try to fix it in the current non-pre-release, and bring that forward into the pre-release, but that's as far back as I would go (though I don't consider that going back because the latest release isn't a "full" release, it's still in pre-release stage, so I don't expect everyone to want to adopt a pre-release to get security fix).

Expected release and support cycles
No official schedule, but updated frequently to address issues or update dependencies. This is the full response from the maintainer regarding this:

This happens whenever there's something new to publish, regardless of the Semver bump. So far, that's only patches and minors. I did do a major when I took over, but I did that out of an abundance of caution because the project had stagnated for an entire year and I bumped all the dependencies and refactored the build, etc., when I took over. So I wanted to send a clear message there, that upgrading might cause issues.
But now, I haven't come across anything in this library that would warrant a major bump. If I did, I guess that would be a complete change to the API, or something like no longer recognizing a node as tabbable which was previously recognized as tabbable (for example). I don't think I would have a big release plan for that, though, given the size of the library. I would probably leverage a pre-release version, like 6.0.0-alpha.1, to test the waters in the community until it stabilizes, and then publish 6.0.0.

Code quality

The code itself is very concise and significantly more readable than some of the other libraries Drupal uses https://raw.githubusercontent.com/focus-trap/tabbable/v5.1.3/src/index.js. The variables and functions are well named and it is nicely formatted without readabily-compromising shortcuts. Even without docblocks/comments it's very clear what the code is doing.
The test coverage seems quite good: https://github.com/focus-trap/tabbable/tree/v5.1.3/test

Dependency Evaluation for CSS.escape

This polyfill is needed for tabbable to work properly with radio buttons that have name attributes containing special characters

Maintainership of the package
Maintained by https://github.com/mathiasbynens. He acknowledges this is a spare-time hobby project, but the handful of issues reported have been addressed quickly. It's the sort of polyfill that doesn't require much attention, so there's not much activity in general on the repo. This low-activity (including issues filed) contrasted against the 3 million NPM downloads per week suggests it is quite stable + there's a community interested in in continuing to work well. Also worth mentioning the maintainer replied to my security questions within hours.

Security policies of the package
No official policy is posted. The maintainer's response to security questions can be found here: https://github.com/mathiasbynens/CSS.escape/issues/15. I believe this is sufficient particularly since the functionality of this library isn't one that could introduce many vulnerabilities.

Expected release and support cycles
As-needed and rarely (if ever) needed.

Code quality
106 concise, readable lines with good comments.

Remaining tasks

Confirm that tabbingmanager only needs jquery.ui for ':tabbable' confirmed
Confirm there are existing tests that would fail if tabbingmanager didn't use jQueryUI -- if not, these should be added.Confirmed. Without jQueryUI several tests fail due to :tabbable not being a valid selector
Find an alternative solution - ideally this could leverage an existing library instead of something custom to Drupal. Found https://github.com/focus-trap/tabbable
Implement the solution.

User interface changes

API changes

Data model changes

Release notes snippet

The tabbable library has been added to replace the functionality provided by for jQuery UI's:tabbable selector. A shim has been provided so all existing of uses of the :tabbable selector now use tabbable to query tabbable elements.

CommentFileSizeAuthor
#84 interdiff_68-84.txt5.64 KBbnjmnm
#84 3113649-84.patch79.73 KBbnjmnm
#75 Cu7tbBd - Imgur.png126.19 KBilgnerfagundes
#68 interdiff_66-68.txt679 bytesbnjmnm
#68 3113649-68.patch81.53 KBbnjmnm
#66 3113649-66.patch81.52 KBbnjmnm
#66 interdiff_65-66.txt4.44 KBbnjmnm
#65 interdiff_63-65.txt27.97 KBbnjmnm
#65 3113649-65.patch77.63 KBbnjmnm
#63 3113649-63.patch76 KBbnjmnm
#63 interdiff_61-63.txt939 bytesbnjmnm
#61 3113649-61.patch76 KBbnjmnm
#61 interdiff_60-61.txt1.33 KBbnjmnm
#60 interdiff_59-60.txt927 bytesbnjmnm
#60 3113649-60.patch75.93 KBbnjmnm
#59 interdiff_57-59.txt2.21 MBbnjmnm
#59 3113649-59.patch75.93 KBbnjmnm
#53 interdiff_45-53.txt2.62 KBbnjmnm
#53 3113649-53.patch43.94 KBbnjmnm
#45 interdiff_41-45.txt18.45 KBbnjmnm
#45 3113649--45.patch42.61 KBbnjmnm
#41 3113649-41.patch25.29 KBbnjmnm
#41 interdiff_33-41.txt24.11 KBbnjmnm
#39 3113649-39.patch25 KBayushmishra206
#38 3113649-38.patch25 KBayushmishra206
#38 interdiff_33-38.txt589 bytesayushmishra206
#33 interdiff_25-33.txt806 bytesbnjmnm
#33 3113649-33.patch25 KBbnjmnm
#25 3113649-25.patch24.97 KBbnjmnm
#25 interdiff_22-25.txt1.24 KBbnjmnm
#22 3113649-22.patch24.97 KBbnjmnm
#22 interdiff_16-22.txt28.17 KBbnjmnm
#21 3113649-21.patch25.38 KBbnjmnm
#21 interdiff_16-21.txt28.05 KBbnjmnm
#16 interdiff__11--16.txt18.13 KBbnjmnm
#16 3113649-_16.patch26.46 KBbnjmnm
#13 3113649-13.patch15.3 KBayushmishra206
#13 interdiff_11-13.txt1.84 KBayushmishra206
#11 3113649-11.patch15.29 KBbnjmnm
#11 3113649-11_TEST-ONLY.patch6.69 KBbnjmnm
#11 interdiff_8-11.txt15.9 KBbnjmnm
#8 3113649_8.patch5.87 KBbnjmnm
#2 3113649-2.patch10.28 KBbnjmnm
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bnjmnm created an issue. See original summary.

bnjmnm’s picture

Version: 8.9.x-dev » 9.0.x-dev
FileSize
10.28 KB

Tabbable looks to be the best option. Not only does it seem to do its job well, but it's also the only option I could find that has had activity in the past 2 years.

In order to use tabbable, however, it would be necessary to create a UMD build. The version in development on master has introduced multiple builds, but currently there are only esm and cjs options. This is fairly easy to remedy, so I created a PR
https://github.com/davidtheclark/tabbable/pull/51
Maintainers look to be active so I'm hoping I will soon find out if there's willingness to include the umd build.

This patch uses the UMD build generated by the branch that I issued the pull request with.

xjm’s picture

Version: 9.0.x-dev » 9.1.x-dev

Too late to do this in 9.0.x now, so moving to 9.1.x. Thanks!

nod_’s picture

"Confirm that tabbingmanager only needs jquery.ui for ':tabbable'" I can confirm that :)

The library looks good, but as you can see the maintainer proposed you the maintainership :p

catch’s picture

Title: Remove drupal.tabbingmanager's jQueryUI dependency » Remove drupal.tabbingmanager's jQueryUI dependencyRemove drupal.tabbingmanager's jQueryUI dependencyRemove drupal.tabbingmanager's jQueryUI dependency
Related issues: +#3067261: [Plan] Remove jQuery UI components used by Drupal core and replace with a set of supported solutions
catch’s picture

Priority: Major » Critical
Issue tags: +Drupal 10
bnjmnm’s picture

Title: Remove drupal.tabbingmanager's jQueryUI dependencyRemove drupal.tabbingmanager's jQueryUI dependencyRemove drupal.tabbingmanager's jQueryUI dependency » Remove drupal.tabbingmanager's jQueryUI dependency

My PR was committed and as of v5 was Tabbable supports UMD builds, so the library can again be considered.
https://github.com/focus-trap/tabbable/pull/51

bnjmnm’s picture

Status: Active » Needs review
FileSize
5.87 KB

This adds tabbable 5.1.0 and removes all usage of jQueryUI tabbable. A shim was added so jQuery can continue to use the :tabbable pseudo selector.

It seems like existing test coverage makes use of :tabbable in several tests (in fact, several failed while I was working on this). It's not yet clear to me if additional test coverage is even needed, but that can certainly be arranged.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

lauriii’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests
  1. +++ b/core/assets/vendor/tabbable/index.umd.min.js
    @@ -0,0 +1,6 @@
    +* tabbable 5.1.0
    

    Let's update this to the latest version

  2. +++ b/core/core.libraries.yml
    @@ -619,6 +619,24 @@ sortable:
    +    url: https://github.com/davidtheclark/tabbable/blob/5.1.0/LICENSE
    

    We should link to the license itself usign raw.githubusercontent.com.

  3. +++ b/core/core.libraries.yml
    @@ -619,6 +619,24 @@ sortable:
    +    assets/vendor/tabbable/index.umd.min.js: { weight: -1 }
    

    Did you have to build the library manually? If you did, let's add documentation that documents exact steps that need to be taken.

  4. +++ b/core/core.libraries.yml
    --- /dev/null
    +++ b/core/misc/jquery.ui.tabbable.shim.es6.js
    
    +++ b/core/misc/jquery.ui.tabbable.shim.es6.js
    @@ -0,0 +1,12 @@
    +    tabbable: function(element) {
    +      return isTabbable(element);
    +    },
    

    Shouldn't this be marked as deprecated?

bnjmnm’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
15.9 KB
6.69 KB
15.29 KB

This adds tests and addresses #101-3

Regarding #10.4, My preference is to not mark the use of :tabbable as deprecated as part of this issue, as the shim is not tied to jQueryUI at all, just jQuery. There are several other jQuery-specific pseudos like :visible, :disabled, etc. that will need to be deprecated as part of the jQuery removal efforts. I think deprecating :tabbable may work better if it is done at the same time as the other jQuery selectors. I've also seen anecdotal evidence that some people assume :tabbable is part of jQuery and not jQueryUI anyway.
Totally fine if that reasoning doesn't convince and the deprecation should happen. If it gets deprecated we'd either need to add the deprecation message to \Drupal\Tests\Listeners\DeprecationListenerTrait::getSkippedDeprecations or refactor some tests that still use :tabbable. Both options are reasonably straightforward to implement.

nod_’s picture

Status: Needs review » Needs work
  1. +++ b/core/core.libraries.yml
    @@ -624,6 +624,24 @@ sortable:
    +tabbable.shim:
    

    I'd call that one tabbable.jquery, not sure I'd keep "shim", in any case by itself it's not very descriptive.

  2. +++ b/core/modules/system/tests/modules/tabbable_test/tabbable_test.info.yml
    @@ -0,0 +1,5 @@
    +description: 'Module for the testing the :tabbable selector'
    

    The tests are only for the shim right? might be better to specify it

  3. +++ b/core/misc/collapse.js
    --- /dev/null
    +++ b/core/misc/jquery.ui.tabbable.shim.es6.js
    

    can probably call that one tabbable.jquery.es6.js, like you said it's not tied to jQueryUI

Works well, behaves as expected on IE11. We save a few KB of JS on most pages not having to load base jquery ui

ayushmishra206’s picture

Status: Needs work » Needs review
FileSize
1.84 KB
15.3 KB

Made the changes suggested in #12. Please review

nod_’s picture

Status: Needs review » Needs work

The shim file is missing file, and library names need to be changed everywhere.

lauriii’s picture

Issue tags: +Needs followup
  1. It seems like we have at least ~10 usages of :tabbable so we should open issue for removing those and deprecating the shim.
  2. +++ b/core/misc/jquery.ui.tabbable.jquery.es6.js
    @@ -0,0 +1,22 @@
    + * Defines a backwards-compatible shim for the jQuery :tabbable selector.
    

    Nit: jQuery UI :tabbable selector. This is not specific to jQuery UI but this is a BC layer for the jQuery UI feature.

  3. +++ b/core/misc/jquery.ui.tabbable.jquery.es6.js
    @@ -0,0 +1,22 @@
    +      // jQueryUI :tabbable selector does not. This is due to this element type
    

    Nit: s/jQueryUI/jQuery UI

  4. Not a strong preference but I think it would be nice to keep shim in the file name. This would be consistent with jQuery Cookie and would explicitly document that the file is just a shim between jQuery and Tabbable.
bnjmnm’s picture

Status: Needs work » Needs review
FileSize
26.46 KB
18.13 KB

Built this from #11
Addresses #11 and #15 and keeping the "shim" in the filename/library to match the jQuery cookie shim - but adding jquery or changing jqueryui to jquery where applicable.

bnjmnm’s picture

nod_’s picture

Status: Needs review » Reviewed & tested by the community

Ok with me.

lauriii’s picture

Since we are adding a new library, we should do a dependency evaluation.

nod_’s picture

bnjmnm’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
28.05 KB
25.38 KB

Updated to 5.1.3. This required a small change to the shim & test as well.
Dependency evaluation on the way, I just filed https://github.com/focus-trap/tabbable/issues/136 to get information regarding security policies and will provide the evaluation after we get a response.

bnjmnm’s picture

#21 has some accidental junk in it. Ignore that patch and work from this one

bnjmnm’s picture

Issue summary: View changes

Added dependency evaluation.

lauriii’s picture

Status: Needs review » Needs work

The dependency evaluation looks good ✨

+++ b/core/misc/jquery.tabbable.shim.es6.js
@@ -0,0 +1,23 @@
+      // considers a details element without a summary tabbable. The jQueryUI

+++ b/core/tests/Drupal/Nightwatch/Tests/tabbableShimTest.js
@@ -0,0 +1,193 @@
+// Test to confirm the :tabbable shim returns the same values as jQueryUI :tabbable would.

Nit: s/jQueryUI/jQuery UI

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
1.24 KB
24.97 KB

My no-space jQueryUI/jQuery UI habit strikes again...

nod_’s picture

Status: Needs review » Reviewed & tested by the community

Looking good, still works on dialogs and all :)

xjm’s picture

I posted an additional question to https://github.com/focus-trap/tabbable/issues/136#issuecomment-722612968 since part of what we want to ensure is safe/coordinated disclosure for our production dependencies. I didn't add the usual question about whether they would notify us of an upcoming release because in the JavaScript ecosystem that's sort of like asking for unicorns.

catch’s picture

#27 was answered here: https://github.com/focus-trap/tabbable/issues/136#issuecomment-723484998

This all seems pretty good to me - main thing is the maintainer is responsive and friendly.

xjm’s picture

Agreed; +1.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
  1. +++ b/core/assets/vendor/tabbable/README.txt
    @@ -0,0 +1,15 @@
    +Drupal core uses the UMD build of tabbable.
    +To create this build:
    +Navigate to the root directory of the tabbable library.
    

    Is there a reason why we're not adding a build step into package.json? - like we've got for jqueryui.

  2. +++ b/core/misc/collapse.es6.js
    @@ -50,6 +50,12 @@
    +        // If this polyfill is in use, the browser does not recognize the
    +        // summary as a tabbable element. This must still be set to a negative
    +        // tabindex to prevent the isTabbable() method from the tabbable library
    +        // from returning true.
    +        $summary.attr('tabindex', '-1');
    

    Are we concerned that other contrib / custom JS is going to have to do the same thing? Or to ask this question the other way around do we always need to load the shim if we load the new tabbable library.

    I guess not because if something is relying on jquery's tabbable then they would be depending on jquery.ui and that loads the shim.

  3. +++ b/core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimTestController.php
    @@ -0,0 +1,26 @@
    +  }
    +}
    \ No newline at end of file
    
    ---------------------------------------------------------------------------------------------------------------------------------------------
    FOUND 2 ERRORS AFFECTING 1 LINE
    ---------------------------------------------------------------------------------------------------------------------------------------------
     26 | ERROR | [x] Expected 1 newline at end of file; 0 found
     26 | ERROR | [x] The closing brace for the class must have an empty line before it
    ---------------------------------------------------------------------------------------------------------------------------------------------
    

Setting to needs review for point 1. I'd address 3 on commit if point 1 turns out to be moot.

nod_’s picture

for 1. we don't need to launch a build step ourselves. When doing a yarn add tabbable, the node_modules/tabbable/dist/ folder will hold all the files we need (index.umd.min.js and index.umd.min.js.map).

We got to change the way we manage js dependencies because it's hard to keep them up to date. If I'd change anything I'd remove the readme because I don't think we should be building the lib ourselves for this one, broader topic though #2658650: [META] Optimize Frontend Workflow in Core Development, #2873160: Implement core management of 3rd-party FE libraries

bnjmnm’s picture

#30.1

Is there a reason why we're not adding a build step into package.json? - like we've got for jqueryui.

build:jqueryui in package.json runs Drupal-specific steps to create a custom build.
Tabbable can be built with the defaults so there's no need to have a build step in core. The readme (requested in #10) is largely there to confirm that the file used in core is created via a standard yarn install; yarn build;, as the repo does not contain the built files.

bnjmnm’s picture

Needed a reroll and this takes care of #30 as well.

zrpnr’s picture

Status: Needs review » Reviewed & tested by the community

The sniffer errors pointed out in #30.3 were addressed in #33, and the reroll cleanly applies to latest 9.2.x. Looks like this is good to be back at RTBC.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 33: 3113649-33.patch, failed testing. View results

bnjmnm’s picture

Status: Needs work » Reviewed & tested by the community

This got kicked back to needs work due to a test fail in #33, but this was an unrelated test known to intermittently fail. Moving back to the RTBC set in #34 (not a review of my own work 🙂)

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/core.libraries.yml
@@ -624,6 +624,24 @@ sortable:
+  version: "5.1.3"

I think this looks great except there's a new release of tabbable. Feel free to move this back to RTBC after updating to the latest version of the library.

ayushmishra206’s picture

Status: Needs work » Needs review
FileSize
589 bytes
25 KB

Made the update suggested in #37. Please review and RTBC.

ayushmishra206’s picture

FileSize
25 KB

Previous patch didnt have the changes for some reason. Here's the update.

lauriii’s picture

Status: Needs review » Needs work
+++ b/core/assets/vendor/tabbable/index.umd.min.js
@@ -0,0 +1,6 @@
+* tabbable 5.1.3

We also have to update the library using the instructions in the tabbable README which can be found in the patch.

bnjmnm’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
24.11 KB
25.29 KB
lauriii’s picture

Issue tags: +Needs change record

I think we still need a change record. We should at least mention that there's now a new library that can be used for checking whether an element is tabbable or not.

bnjmnm’s picture

Issue summary: View changes
Issue tags: -Needs change record

Change record and release notes snippet added.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
bnjmnm’s picture

Status: Needs work » Needs review
FileSize
42.61 KB
18.45 KB

A bit more than a reroll was required due to how #3113400: Deprecate more jQuery UI library definitions changes library definitions, so setting this to Needs Review instead of RTBC.

lauriii’s picture

Should we remove jQuery UI tabbable files from core as part of the patch since we don't have any references to it anymore after this patch?

bnjmnm’s picture

Re #46

Should we remove jQuery UI tabbable files from core as part of the patch since we don't have any references to it anymore after this patch?

This crossed my mind and this was the path I took to deciding against (and it's possible this is flawed)

  • Removing felt a little scope-creepy
  • I wasn't 100% what the correct process would be since this is in assets/vendor, is a custom fork, but the library definition isn't referencing the fork and #3093175: Document version numbering system for forked jQuery UI components hasn't landed.
  • This would mess with the tests that already have several governance hurdles to get in[#3093172]
  • Since jQuery UI is planned for removal in Drupal 10 already, any technical debt from leaving the file will be addressed soon enough, so it didn't seem significant enough to justify the scope expansion and the additional work it would require such as updating tests, and blocking this on version numbering policy.

@nod_ mentioned in Drupal slack that he felt similarly.

catch’s picture

fwiw I agree with leaving it in. In the event that someone is using it directly somehow, it's better for them to find out when they port to Drupal 10 than a random minor release, plus all the points in #47.

lauriii’s picture

I don't have strong opinion to either direction but I thought it would make sense to remove the file since that's the process we followed in #2550717: [JS] Replace jQuery.cookie with JS-cookie and provide a BC layer too. In my opinion, it would be fine to draw a line that a specific file is not an API but a library is.

We also removed jQuery UI components in #3087685: Remove deprecated jQuery UI components and fork remaining source code into core without having tests or rolling a new release, so if we wanted to do so here, we probably could.

xjm’s picture

@lauriii #3087685: Remove deprecated jQuery UI components and fork remaining source code into core was only committed to 9.0.x and #2550717: [JS] Replace jQuery.cookie with JS-cookie and provide a BC layer provided a BC layer. I agree with @catch that we should leave the file in place in a minor release (but indicate that it's deprecated) and only remove it in 10.0.x.

lauriii’s picture

What would we do if there was a security vulnerability in code in jQuery UI components that are not being used by core anymore? If we assume people could be using it, shouldn't we also provide security coverage for it? How are we planning to handle testing those components that are not used by core? All very hypothetical at this point, especially with the tabbingmanager but if we set the precedent in this issue, there could be other jQuery components that are riskier.

The patch in this issue provides BC layer similar to #2550717: [JS] Replace jQuery.cookie with JS-cookie and provide a BC layer so I believe they are comparable. Only difference is that this patch requires making some modifications to jQuery UI code.

bnjmnm’s picture

#52 is a pretty convincing reason to remove the file so here's that change.

Providing a patch, but be aware that it won't Custom Commands tests until #3189547: Custom Commands indent: command not found on patches with nightwatch changes is resolved. Until that issue is fixed, any patch that includes changes to nightwatch tests will fail due to a command in commit-code-check.sh that only runs with Nightwatch changes, and isn't available in the container running the tests.

Status: Needs review » Needs work

The last submitted patch, 53: 3113649-53.patch, failed testing. View results

xjm’s picture

Status: Needs work » Needs review
lauriii’s picture

Status: Needs review » Needs work

Seems like there's still reference to tabbable from jQuery UI dialog widget which probably should be removed. That also raised a question; should we introduce intergration tests to jQuery UI widgets that are using shims? That could be useful if we ever have to make changes to the shim.

bnjmnm’s picture

#56

Seems like there's still reference to tabbable from jQuery UI dialog widget which probably should be removed.

Are you referring to the _focusTabbable: function in dialog.js? If it's that, it's something being addressed in the followup #3179734: Refactor uses of the :tabbable selector and deprecate it (the most recent patch overrides it, but another patch could remove the original too).

Or perhaps it's referring to the define() calls in the AMD section which I admittedly ignore since it isn't really called.

Wherever it happens to be, happy to address in the most suitable issue.

That also raised a question; should we introduce intergration tests to jQuery UI widgets that are using shims? That could be useful if we ever have to make changes to the shim.

At first glance this seems excessive since the nightwatch tests added are already testing every possible use of the :tabbable selector that I can think of, I can't think of how the integration tests would cover anything that isn't indirectly covered already, but I may be missing something obvious.

lauriii’s picture

I don't have strong concerns on leaving the references in AMD definition but I thought it would be consistent with what we have done so far, and would leave the files in a bit cleaner state. I pinged @nod_ to see what he thinks.

We do have extensive unit tests for the shim. Regardless of that, it is useful to have some integration tests to ensure that the integration between different units works. The test could be very minimal, just proving that the integration between the shim and jQuery UI works.

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
75.93 KB
2.21 MB

Re #58

  • Removed the tabbable AMD definition. This required a jQuery UI rebuild so the patch is much larger than the previous one, but thankfully most of this new K does not need reviewing, it's just the compiled jQuery Ui.
  • Added dialog integration tests based on the tests in jQuery UI .
    All but one item in the "focus tabbable" tests step7(), could be translated to Nightwatch without much fuss, so those 6 tests were added.
bnjmnm’s picture

Needed to fix a few PHPCS issues to get custom commands to pass.

bnjmnm’s picture

Addressed todos since #3191497: core/jquery.ui.dialog is missing core/jquery assets landed

Also needed to add the tabbable shim as a dependency to core/jquery.ui.dialog, which would typically be included in a core/jquery.ui dependency, which will potentially be added back t core/jquery.ui.dialog after #3192804: Possibly undoing most of jquery.ui.dialog's dependency-detachment

Status: Needs review » Needs work

The last submitted patch, 61: 3113649-61.patch, failed testing. View results

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
939 bytes
76 KB

Had to update the hash based on the jquery.ui.dialog library definition.

lauriii’s picture

+++ b/core/tests/Drupal/Nightwatch/Tests/tabbableShimTest.js
@@ -0,0 +1,331 @@
+          const stuff = new Function(`return ${testActions}`)();
+          const expectedActiveElement = stuff($element);

Why do we need to create this self invoking function here? Maybe we could rename the variable to be more descriptive and add a comment

bnjmnm’s picture

#64

Why do we need to create this self invoking function here? Maybe we could rename the variable to be more descriptive and add a comment

Added a comment for that. I had to try several things before I found something that work, and it looks like I forgot to comment & provide proper names once I discovered a solution 🙂.

Also updated tabbable to the latest version and rephrased a few comments.

bnjmnm’s picture

Added a CSS.escape polyfill for IE11 based on the tabbable readme:

Note: When used with any version of IE, CSS.escape needs a polyfill for tabbable to work properly with radio buttons that have name attributes containing special characters.
lauriii’s picture

Status: Needs review » Needs work
  1. +++ b/core/core.libraries.yml
    @@ -22,6 +22,16 @@ ckeditor:
    +    assets/vendor/css-escape/css.escape.js: { weight: -2 }
    

    Polyfills have usually used weight: -20. Is there any particular reason for it to be different for this?

  2. +++ b/core/core.libraries.yml
    @@ -126,6 +135,7 @@ drupal.autocomplete:
    +    - core/le.jquery.shim
    

    This should probably be core/tabbable.jquery.shim.

  3. We should dependency evaluate CSS.escape too.
  4. Can we write another change record about the changes to our library definitions? These changes could have an impact on themes that are overriding these libraries using libraries-override.
bnjmnm’s picture

Status: Needs work » Needs review
FileSize
81.53 KB
679 bytes
bnjmnm’s picture

Issue summary: View changes

Added CSS.Escape dependency evaluation to issue summary. Still looking into how to best go about #67.4

Kristen Pol’s picture

Maybe I missed it but is there manual testing needed for this? I searched the comments and didn't see how it was tested manually if it was done. Or, does the automated tests cover everything?

bnjmnm’s picture

@Kristen Pol thanks for asking about manual testing in #70! Now that you mention it, manual testing certainly couldn't hurt. Here are the steps that come to mind:

  • For both off-canvas dialogs and modals:
  1. Confirm the first element that receives focus after opening is the same in HEAD vs this patch
  2. Confirm that tabbing is constrained within the dialog/modal the same in HEAD vs this patch
  • Open a modal from an off-canvas dialog. One way to do this is edit a block in layout builder that uses CKEditor, then use CKEditor to open a image/media embed modal. Confirm that tabbing is constrained to the modal when it opens, and the constraining returns to the dialog when the modal closes. If this doesn't work, compare to HEAD to confirm if it's an issue with this patch or a problem in HEAD specific to the steps performed in the manual tests. If the latter, file a followup and tag with accessiblity.
  • bnjmnm’s picture

    Updated this CR to include the tabbingmanager changes: [#3156376]

    Created an additional CR for the CSS.escape polyfill: [#3196522]

    lauriii’s picture

    Status: Needs review » Reviewed & tested by the community

    I think this is ready for a review from another committer. I reviewed the patch one more time, tested it manually using the steps provided in #71 and reviewed the CR's, and all looked good for me 👌

    nod_’s picture

    I reviewed the patch, checked the change notices, went through the step in #71 with IE11 (except the ckeditor from the offcanvas, which i didn't find how to trigger to be honest, even with the steps 🤷) And it's all good, RTBC +1

    ilgnerfagundes’s picture

    FileSize
    126.19 KB

    I reviewed the patch again, and it looks all right, I followed the instructions in # 71. RTBC +1

    lauriii’s picture

    Discussed with @xjm and agreed that some of the libraries changes are potentially disruptive. Tagging for release manager review to give them a chance to give feedback.

    lauriii’s picture

    Adding more background for #76.

    I discussed #51 with @xjm to make sure that she would be fine with the current approach. That comment documents a recommendation from the release managers to keep the files previously referenced by the libraries in the code base until the next major release. That comment references #2550717: [JS] Replace jQuery.cookie with JS-cookie and provide a BC layer and states that it was acceptable to remove the files there because there was a shim that provided full BC. Because this issue is using the same approach, I suggested on #52 that we would use the same approach here.

    As we discussed this, I mentioned that I believe that the changes to library definitions made by this issue (and other jQuery UI related issues), have much higher potential of being disruptive than removing files from core to some users. The libraries system uses file paths as the identifier for alters and overrides.

    For example, before #3113400: Deprecate more jQuery UI library definitions and this issue, someone could have replaced the jQuery UI tabbable with custom code with the following configuration:

    libraries-override:
      core/jquery.ui:
        js:
          assets/vendor/jquery.ui/ui/tabbable-min.js: js/custom-tabbable.js
    

    As a result of these changes, tabbable-min.js is no longer part of the library definition, meaning that any overrides to that file no longer take effect until they have updated to overriding an asset file that is defined in the library definition. I don't think it's likely that many sites would be impacted by this but I mentioned that if we are concerned by this, #3113400: Deprecate more jQuery UI library definitions would have much higher risk of being disruptive because it applies even broader scope of changes to the library definitions.

    The same behavior impacts CSS and we have added BC layers to Stable to handle changes to CSS library definitions. See stable_library_info_alter for an example of that. Theoretically we could provide similar BC layer to JavaScript, but that would be more complex because we would have to check if a specific file is being overridden and then make some more involved changes to the libraries definitions based on that.

    If we decide to keep the file in place, we should discuss what we would do if there was a security vulnerability in jQuery UI components that are not being used by core anymore and how are we planning to handle testing those components that are not used by core. It sounds like this is not unique to this issue, so maybe there's already precedent to this.

    xjm’s picture

    Issue tags: +9.2.0 release notes

    If we decide to keep the file in place, we should discuss what we would do if there was a security vulnerability in jQuery UI components that are not being used by core anymore and how are we planning to handle testing those components that are not used by core. It sounds like this is not unique to this issue, so maybe there's already precedent to this.

    Correct; that is not blocking because we already are providing security coverage for the jQuery UI code in core.

    xjm’s picture

    There are quite a few references to tabbable in contrib. Will all these modules need to change their code? It's not clear to me from the change record on the addition of tabbable.

    lauriii’s picture

    I checked the search results from #79.

    Some of the results are unrelated uses of tabbable word for other purposes. Bootstrap theme is using it as a classname for targeting horizontal tabs which doesn't have any connection to jQuery UI :tabbable selector.

    There are some results that are more related. Some of the search results are AMD module definitions from a copy of jQuery UI as well as some other jQuery UI components defining it as a dependency using AMD. However, Drupal is not using AMD for JavaScript module loading so these can be ignored.

    I'm surprised how few references the :tabbable selector has in contrib. However, even these wouldn't have to be changed yet since the shim is not deprecated. This means the change record is only informing users that a new library is added so that developers writing new code could take advantage of the newly added library.

    TL;DR is that I don't expect that any of the contrib modules listed in #79 would have to implement changes after this gets committed.

    YesCT’s picture

    I was debugging an issue with mherchel with https://www.drupal.org/project/anchor_link module

    While debugging, we used the chrome browser inspector tools network tab to Block request URL for various js files. When I blocked core/assets/vendor/jquery.ui/ui/tabbable-min.js the bug went away.

    And a potential fix (using custom code) is https://www.drupal.org/project/drupal/issues/3065095#comment-14010068

    We thought since this issue is refactoring things, that the bug with anchor_link module might be useful as a testing use case ... or inspire a test ... for the work on this issue.

    bnjmnm’s picture

    Perhaps I'm misunderstanding #81, but here's my thoughts:

    It's unlikely that #81 in the scope of this issue, but there would need to be additional information beyond reporting a bug goes away when the file is attached. The potential fix linked to doesn't reference tabbable at all.

    I'm not sure what the anchor_link issue mentioned is, but blocking this file could potentially address the specific bug in #3065095: CKEditor native dialogs not clickable inside of jQuery UI dialogs by breaking Dialog initialization before it completes. Removing this file would result in an error closer to the end of the initialization process, after it has been created and it attempts to move focus inside the dialog. The error may stop initialization before it hits the JS causing the bug.

    xjm’s picture

    If we decide to keep the file in place, we should discuss what we would do if there was a security vulnerability in jQuery UI components that are not being used by core anymore and how are we planning to handle testing those components that are not used by core. It sounds like this is not unique to this issue, so maybe there's already precedent to this.

    I think this would be the equivalent of a security issue not exposed by core itself; only contrib relying on the deprecated file would be affected. So any potential security issue would only be against those contrib modules, and they could either fix it within the module itself or just replace the deprecated file usage with the correct/supported usage of the tabbingmanager library.

    Edit: That said, #80 seems fine, so we're back to just whether to retain the file or not.

    bnjmnm’s picture

    This updates tabbingmanager to the newest version: 5.1.6. Most of the changes in this version are to files not used by core, so the interdiff will show that nothing has changed other than the version number.

    I also brought back the jQuery UI tabbable files as that decision is blocking this issue, and it's something that can be addressed in a followup: #3201595: possibly remove jQuery UI tabbable files?.

    lauriii’s picture

    Based on #83 and #51 it seems like the current approach of leaving the file in would be fine to the release managers. I'm removing the needs release manager review tag since I was the only one pushing back on keeping the file, and it seems like all of the other concerns have been addressed. While I don't necessarily think that the current solution is ideal, I'm fine with it being the way it is as long as it helps us move forward on this. We can always remove the file later in #3201595: possibly remove jQuery UI tabbable files?.

    nod_’s picture

    Checked the latest patch, still working as expected. RTBC+1

    alexpott’s picture

    Status: Reviewed & tested by the community » Fixed

    This looks really good. One less use of jquery ftw. We've now managed to defer deleting the file and we can make that decision in #3201595: possibly remove jQuery UI tabbable files?.

    Dependency evaluations are complete and we have a change record and release note.

    Committed daf10a0 and pushed to 9.2.x. Thanks!

    • alexpott committed daf10a0 on 9.2.x
      Issue #3113649 by bnjmnm, ayushmishra206, ilgnerfagundes, lauriii, nod_...

    Status: Fixed » Closed (fixed)

    Automatically closed - issue fixed for 2 weeks with no activity.