From 7a21759c3e4a89a612131b93881fc070e154905b Mon Sep 17 00:00:00 2001
From: Dave Long <dave@longwaveconsulting.com>
Date: Wed, 17 Apr 2024 22:15:34 +0100
Subject: [PATCH] Issue #3278625 by catch, Taran2L: Remove jquery.tabbable.shim

---
 core/core.libraries.yml                       |  13 +-
 core/misc/jquery.tabbable.shim.js             |  17 -
 ...bleShimDialogIntegrationTestController.php |  32 --
 .../Controller/TabbableShimTestController.php |  30 --
 .../tabbable_shim_test.info.yml               |   5 -
 .../tabbable_shim_test.routing.yml            |  15 -
 .../Nightwatch/Tests/tabbableShimTest.js      | 335 ------------------
 7 files changed, 2 insertions(+), 445 deletions(-)
 delete mode 100644 core/misc/jquery.tabbable.shim.js
 delete mode 100644 core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimDialogIntegrationTestController.php
 delete mode 100644 core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimTestController.php
 delete mode 100644 core/modules/system/tests/modules/tabbable_shim_test/tabbable_shim_test.info.yml
 delete mode 100644 core/modules/system/tests/modules/tabbable_shim_test/tabbable_shim_test.routing.yml
 delete mode 100644 core/tests/Drupal/Nightwatch/Tests/tabbableShimTest.js

diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index 275a3ac685df..907fb4c7fefd 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -484,8 +484,8 @@ drupal.autocomplete:
     - core/drupal
     - core/drupalSettings
     - core/drupal.ajax
-    - core/tabbable.jquery.shim
     - core/drupal.jquery.position
+    - core/tabbable
 
 drupal.batch:
   version: VERSION
@@ -561,8 +561,8 @@ drupal.dialog:
     - core/drupalSettings
     - core/drupal.debounce
     - core/drupal.displace
-    - core/tabbable.jquery.shim
     - core/drupal.jquery.position
+    - core/tabbable
 
 drupal.dialog.ajax:
   version: VERSION
@@ -867,15 +867,6 @@ transliteration:
   js:
     assets/vendor/transliteration/bundle.umd.min.js: { minified: true }
 
-tabbable.jquery.shim:
-  version: VERSION
-  js:
-    misc/jquery.tabbable.shim.js: {}
-  dependencies:
-    - core/drupal
-    - core/tabbable
-    - core/jquery
-
 internal.underscore:
   # Internal library. Do not depend on it outside core nor add new core usage.
   # The library will be removed as soon as the following issues are fixed:
diff --git a/core/misc/jquery.tabbable.shim.js b/core/misc/jquery.tabbable.shim.js
deleted file mode 100644
index cce6815c2467..000000000000
--- a/core/misc/jquery.tabbable.shim.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * @file
- * Defines a backwards-compatible shim for the jQuery UI :tabbable selector.
- */
-
-(($, Drupal, { isTabbable }) => {
-  $.extend($.expr[':'], {
-    tabbable(element) {
-      Drupal.deprecationError({
-        message:
-          'The :tabbable selector is deprecated in Drupal 9.2.0 and will be removed in Drupal 11.0.0. Use the core/tabbable library instead. See https://www.drupal.org/node/3183730',
-      });
-
-      return isTabbable(element);
-    },
-  });
-})(jQuery, Drupal, window.tabbable);
diff --git a/core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimDialogIntegrationTestController.php b/core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimDialogIntegrationTestController.php
deleted file mode 100644
index 6be67334b30a..000000000000
--- a/core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimDialogIntegrationTestController.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-namespace Drupal\tabbable_shim_test\Controller;
-
-use Drupal\Core\Controller\ControllerBase;
-
-/**
- * For testing the jQuery :tabbable shim as used in a dialog.
- */
-class TabbableShimDialogIntegrationTestController extends ControllerBase {
-
-  /**
-   * Provides a page with the jQuery UI dialog library for testing .
-   *
-   * @return array
-   *   The render array.
-   */
-  public function build() {
-    return [
-      'container' => [
-        '#type' => 'container',
-        '#attributes' => [
-          'id' => 'tabbable-dialog-test-container',
-        ],
-      ],
-      '#attached' => [
-        'library' => ['core/drupal.dialog'],
-      ],
-    ];
-  }
-
-}
diff --git a/core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimTestController.php b/core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimTestController.php
deleted file mode 100644
index 82b2b7800921..000000000000
--- a/core/modules/system/tests/modules/tabbable_shim_test/src/Controller/TabbableShimTestController.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-namespace Drupal\tabbable_shim_test\Controller;
-
-use Drupal\Core\Controller\ControllerBase;
-
-/**
- * For testing the jQuery :tabbable shim.
- */
-class TabbableShimTestController extends ControllerBase {
-
-  /**
-   * Provides a page with the tabbingManager library for testing :tabbable.
-   *
-   * @return array
-   *   The render array.
-   */
-  public function build() {
-    return [
-      'container' => [
-        '#type' => 'container',
-        '#attributes' => [
-          'id' => 'tabbable-test-container',
-        ],
-      ],
-      '#attached' => ['library' => ['core/drupal.autocomplete']],
-    ];
-  }
-
-}
diff --git a/core/modules/system/tests/modules/tabbable_shim_test/tabbable_shim_test.info.yml b/core/modules/system/tests/modules/tabbable_shim_test/tabbable_shim_test.info.yml
deleted file mode 100644
index 4689243d510c..000000000000
--- a/core/modules/system/tests/modules/tabbable_shim_test/tabbable_shim_test.info.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-name: 'Tabbable Shim Test'
-type: module
-description: 'Module for the testing the :tabbable selector shim'
-package: Testing
-version: VERSION
diff --git a/core/modules/system/tests/modules/tabbable_shim_test/tabbable_shim_test.routing.yml b/core/modules/system/tests/modules/tabbable_shim_test/tabbable_shim_test.routing.yml
deleted file mode 100644
index 0be12dfb2f6b..000000000000
--- a/core/modules/system/tests/modules/tabbable_shim_test/tabbable_shim_test.routing.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-tabbable_test_page:
-  path: '/tabbable-shim-test'
-  defaults:
-    _controller: '\Drupal\tabbable_shim_test\Controller\TabbableShimTestController::build'
-    _title: 'Tabbable testing'
-  requirements:
-    _access: 'TRUE'
-
-tabbable_dialog_integration_test_page:
-  path: '/tabbable-shim-dialog-integration-test'
-  defaults:
-    _controller: '\Drupal\tabbable_shim_test\Controller\TabbableShimDialogIntegrationTestController::build'
-    _title: 'Tabbable dialog integration testing'
-  requirements:
-    _access: 'TRUE'
diff --git a/core/tests/Drupal/Nightwatch/Tests/tabbableShimTest.js b/core/tests/Drupal/Nightwatch/Tests/tabbableShimTest.js
deleted file mode 100644
index c76026d6ff89..000000000000
--- a/core/tests/Drupal/Nightwatch/Tests/tabbableShimTest.js
+++ /dev/null
@@ -1,335 +0,0 @@
-// Testing the shimmed jQuery UI :tabbable selector.
-
-// Test confirming the :tabbable shim returns the same values as jQuery UI
-// :tabbable.
-//
-// An array of objects with the following properties:
-//   - element: the element to test
-//   - tabbable: the number of items the :tabbable selector should return when
-//     the element is the only item in the container being queried.
-const tabbableTestScenarios = [
-  {
-    element: '<div>',
-    tabbable: 0,
-  },
-  {
-    element: '<div tabindex="0">',
-    tabbable: 1,
-  },
-  {
-    element: '<div tabindex="0" hidden>',
-    tabbable: 0,
-  },
-  {
-    element: '<div tabindex="0" style="display:none;">',
-    tabbable: 0,
-  },
-  {
-    element: '<div href="#">',
-    tabbable: 0,
-  },
-  {
-    element: '<a>',
-    tabbable: 0,
-  },
-  {
-    element: '<a href="#">',
-    tabbable: 1,
-  },
-  {
-    element: '<a tabindex="0">',
-    tabbable: 1,
-  },
-  {
-    element: '<a tabindex="-1">',
-    tabbable: 0,
-  },
-  {
-    element: '<input type="hidden">',
-    tabbable: 0,
-  },
-  {
-    element: '<input type="hidden" tabindex="0">',
-    tabbable: 0,
-  },
-  {
-    element: '<input type="hidden" tabindex="1">',
-    tabbable: 0,
-  },
-  {
-    element:
-      '<details><summary>Summary is now tabbable because IE is not supported anymore</summary>Hooray</details>',
-    tabbable: 1,
-  },
-  {
-    element:
-      '<details>A details without a summary should be :tabbable</details>',
-    tabbable: 1,
-  },
-  {
-    element: '<ul><li>List item</li></ul>',
-    tabbable: 0,
-  },
-  {
-    element: '<ul><li tabindex="0">List item</li></ul>',
-    tabbable: 1,
-  },
-];
-
-// Element types to add to the test scenarios.
-const elementTypesUsedByTabbableTest = [
-  'input-button',
-  'input-checkbox',
-  'input-color',
-  'input-date',
-  'input-datetime-local',
-  'input-email',
-  'input-file',
-  'input-image',
-  'input-month',
-  'input-number',
-  'input-password',
-  'input-radio',
-  'input-range',
-  'input-reset',
-  'input-search',
-  'input-submit',
-  'input-tel',
-  'input-text',
-  'input-time',
-  'input-url',
-  'input-week',
-  'select',
-  'button',
-  'textarea',
-];
-
-// Create multiple test scenarios.
-
-// For each element type being tested, create multiple variations with different
-// attributes and store them in the `element:` property. The `tabbable:` property
-// is the number of elements in `element:` that would match the :tabbable
-// selector.
-// Tha variations include:
-// - The element with no additional attributes.
-// - Separate scenarios for tabindex 0, 1, and -1.
-// - With the hidden attribute
-// - With `style="display:none;"`
-// - With `style="visibility: hidden;"`
-elementTypesUsedByTabbableTest.forEach((item) => {
-  let elementType = item;
-  let selfClose = '';
-  let type = '';
-  if (item.indexOf('-') > 0) {
-    [elementType, type] = item.split('-');
-    type = ` type="${type}"`;
-    selfClose = ' /';
-  }
-
-  tabbableTestScenarios.push({
-    element: `<${elementType}${type}${selfClose}>`,
-    tabbable: 1,
-  });
-  tabbableTestScenarios.push({
-    element: `<${elementType}${type} tabindex="0"${selfClose}>`,
-    tabbable: 1,
-  });
-  tabbableTestScenarios.push({
-    element: `<${elementType}${type} tabindex="1"${selfClose}>`,
-    tabbable: 1,
-  });
-  tabbableTestScenarios.push({
-    element: `<${elementType}${type} tabindex="-1"${selfClose}>`,
-    tabbable: 0,
-  });
-  tabbableTestScenarios.push({
-    element: `<${elementType}${type} hidden${selfClose}>`,
-    tabbable: 0,
-  });
-  tabbableTestScenarios.push({
-    element: `<${elementType}${type} style="display:none;"${selfClose}>`,
-    tabbable: 0,
-  });
-  tabbableTestScenarios.push({
-    element: `<${elementType}${type} style="visibility: hidden;"${selfClose}>`,
-    tabbable: 0,
-  });
-});
-
-// The default options for items in dialogIntegrationTestScenarios.
-const defaultDialogOptions = {
-  buttons: [
-    {
-      text: 'Ok',
-      click: () => {},
-    },
-  ],
-};
-
-// Contains scenarios for testing dialog's use of the :tabbable selector.
-// These are based on the "focus tabbable" tests within jQuery UI
-// @see
-//   https://github.com/jquery/jquery-ui/blob/1.12.1/tests/unit/dialog/core.js
-const dialogIntegrationTestScenarios = [
-  {
-    info: 'An element that was focused previously.',
-    markup: '<div><input><input></div>',
-    options: {},
-    // eslint-disable-next-line object-shorthand, func-names
-    testActions: function ($element) {
-      const $input = $element
-        .find('input:last')
-        .trigger('focus')
-        .trigger('blur');
-      $element.dialog('instance')._focusTabbable();
-      return $input[0];
-    },
-  },
-  {
-    info: 'First element inside the dialog matching [autofocus]',
-    markup: '<div><input><input autofocus></div>',
-    options: defaultDialogOptions,
-    // eslint-disable-next-line object-shorthand, func-names
-    testActions: function ($element) {
-      return $element.find('input')[1];
-    },
-  },
-  {
-    info: 'Tabbable element inside the content element',
-    markup: '<div><input><input></div>',
-    options: defaultDialogOptions,
-    // eslint-disable-next-line object-shorthand, func-names
-    testActions: function ($element) {
-      return $element.find('input')[0];
-    },
-  },
-  {
-    info: 'Tabbable element inside the buttonpane',
-    markup: '<div>text</div>',
-    options: defaultDialogOptions,
-    // eslint-disable-next-line object-shorthand, func-names
-    testActions: function ($element) {
-      return $element.dialog('widget').find('.ui-dialog-buttonpane button')[0];
-    },
-  },
-  {
-    info: 'The close button',
-    markup: '<div>text</div>',
-    options: {},
-    // eslint-disable-next-line object-shorthand, func-names
-    testActions: function ($element) {
-      return $element
-        .dialog('widget')
-        .find('.ui-dialog-titlebar .ui-dialog-titlebar-close')[0];
-    },
-  },
-  {
-    info: 'The dialog itself',
-    markup: '<div>text</div>',
-    options: { autoOpen: false },
-    // eslint-disable-next-line object-shorthand, func-names
-    testActions: function ($element) {
-      $element.dialog('widget').find('.ui-dialog-titlebar-close').hide();
-      $element.dialog('open');
-      return $element.parent()[0];
-    },
-  },
-  {
-    info: 'Focus starts on second input',
-    markup: '<div><input><input autofocus></div>',
-    options: {
-      // eslint-disable-next-line object-shorthand, func-names
-      open: function () {
-        const inputs = jQuery(this).find('input');
-        inputs.last().on('keydown', function (event) {
-          event.preventDefault();
-          inputs.first().trigger('focus');
-        });
-      },
-    },
-    // eslint-disable-next-line object-shorthand, func-names
-    testActions: function ($element) {
-      const inputs = $element.find('input');
-      return inputs[1];
-    },
-  },
-];
-
-module.exports = {
-  '@tags': ['core'],
-  before(browser) {
-    browser.drupalInstall().drupalInstallModule('tabbable_shim_test');
-  },
-  after(browser) {
-    browser.drupalUninstall();
-  },
-  'test tabbable': (browser) => {
-    browser
-      .drupalRelativeURL('/tabbable-shim-test')
-      .waitForElementPresent('#tabbable-test-container', 1000);
-
-    tabbableTestScenarios.forEach((iteration) => {
-      browser.execute(
-        // eslint-disable-next-line func-names, prefer-arrow-callback
-        function (scenario) {
-          const $container = jQuery('#tabbable-test-container');
-          $container.empty();
-          $container.append(jQuery(scenario.element));
-
-          return {
-            expected: scenario.tabbable,
-            actual: $container.find(':tabbable').length,
-            element: scenario.element,
-          };
-        },
-        [iteration],
-        (result) => {
-          browser.assert.ok(typeof result.value.actual === 'number');
-          browser.assert.ok(typeof result.value.expected === 'number');
-          browser.assert.equal(
-            result.value.actual,
-            result.value.expected,
-            `Expected :tabbable to return ${result.value.expected} for element ${result.value.element}`,
-          );
-        },
-      );
-    });
-    browser.assert.deprecationErrorExists(
-      'The :tabbable selector is deprecated in Drupal 9.2.0 and will be removed in Drupal 11.0.0. Use the core/tabbable library instead. See https://www.drupal.org/node/3183730',
-    );
-    browser.drupalLogAndEnd({ onlyOnError: false });
-  },
-  'test tabbable dialog integration': (browser) => {
-    browser
-      .drupalRelativeURL('/tabbable-shim-dialog-integration-test')
-      .waitForElementPresent('#tabbable-dialog-test-container', 1000);
-
-    dialogIntegrationTestScenarios.forEach((iteration) => {
-      browser.execute(
-        // eslint-disable-next-line func-names
-        function (scenario, testActions) {
-          // Create the jQuery element that will be used in the test steps.
-          const $element = jQuery(scenario.markup).dialog(scenario.options);
-
-          // Convert the testActions string into a function. testActions is a
-          // string due to functions being removed from objects passed to
-          // browser.execute().
-          // The expectedActiveElement function performs steps specific to a test
-          // iteration, then returns the element expected to be active after
-          // those steps.
-          // eslint-disable-next-line no-new-func
-          const expectedActiveElement = new Function(`return ${testActions}`)();
-          return expectedActiveElement($element) === document.activeElement;
-        },
-        [iteration, iteration.testActions.toString()],
-        (result) => {
-          browser.assert.equal(result.value, true, iteration.info);
-        },
-      );
-    });
-    browser.assert.deprecationErrorExists(
-      'The :tabbable selector is deprecated in Drupal 9.2.0 and will be removed in Drupal 11.0.0. Use the core/tabbable library instead. See https://www.drupal.org/node/3183730',
-    );
-    browser.drupalLogAndEnd({ onlyOnError: false });
-  },
-};
-- 
GitLab