Issue #3113649 by bnjmnm, ayushmishra206, ilgnerfagundes, lauriii, nod_, xjm, catch, alexpott, Kristen Pol: Remove drupal.tabbingmanager's jQueryUI dependency
parent
cbccba94b6
commit
daf10a0695
|
@ -20,7 +20,8 @@
|
|||
"Modernizr": true,
|
||||
"Popper": true,
|
||||
"Sortable": true,
|
||||
"CKEDITOR": true
|
||||
"CKEDITOR": true,
|
||||
"tabbable": true
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */
|
||||
;(function(root, factory) {
|
||||
// https://github.com/umdjs/umd/blob/master/returnExports.js
|
||||
if (typeof exports == 'object') {
|
||||
// For Node.js.
|
||||
module.exports = factory(root);
|
||||
} else if (typeof define == 'function' && define.amd) {
|
||||
// For AMD. Register as an anonymous module.
|
||||
define([], factory.bind(root, root));
|
||||
} else {
|
||||
// For browser globals (not exposing the function separately).
|
||||
factory(root);
|
||||
}
|
||||
}(typeof global != 'undefined' ? global : this, function(root) {
|
||||
|
||||
if (root.CSS && root.CSS.escape) {
|
||||
return root.CSS.escape;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom/#serialize-an-identifier
|
||||
var cssEscape = function(value) {
|
||||
if (arguments.length == 0) {
|
||||
throw new TypeError('`CSS.escape` requires an argument.');
|
||||
}
|
||||
var string = String(value);
|
||||
var length = string.length;
|
||||
var index = -1;
|
||||
var codeUnit;
|
||||
var result = '';
|
||||
var firstCodeUnit = string.charCodeAt(0);
|
||||
while (++index < length) {
|
||||
codeUnit = string.charCodeAt(index);
|
||||
// Note: there’s no need to special-case astral symbols, surrogate
|
||||
// pairs, or lone surrogates.
|
||||
|
||||
// If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
|
||||
// (U+FFFD).
|
||||
if (codeUnit == 0x0000) {
|
||||
result += '\uFFFD';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
|
||||
// U+007F, […]
|
||||
(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
|
||||
// If the character is the first character and is in the range [0-9]
|
||||
// (U+0030 to U+0039), […]
|
||||
(index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
|
||||
// If the character is the second character and is in the range [0-9]
|
||||
// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
|
||||
(
|
||||
index == 1 &&
|
||||
codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
|
||||
firstCodeUnit == 0x002D
|
||||
)
|
||||
) {
|
||||
// https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
|
||||
result += '\\' + codeUnit.toString(16) + ' ';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
// If the character is the first character and is a `-` (U+002D), and
|
||||
// there is no second character, […]
|
||||
index == 0 &&
|
||||
length == 1 &&
|
||||
codeUnit == 0x002D
|
||||
) {
|
||||
result += '\\' + string.charAt(index);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the character is not handled by one of the above rules and is
|
||||
// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
|
||||
// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
|
||||
// U+005A), or [a-z] (U+0061 to U+007A), […]
|
||||
if (
|
||||
codeUnit >= 0x0080 ||
|
||||
codeUnit == 0x002D ||
|
||||
codeUnit == 0x005F ||
|
||||
codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
|
||||
codeUnit >= 0x0041 && codeUnit <= 0x005A ||
|
||||
codeUnit >= 0x0061 && codeUnit <= 0x007A
|
||||
) {
|
||||
// the character itself
|
||||
result += string.charAt(index);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, the escaped character.
|
||||
// https://drafts.csswg.org/cssom/#escape-a-character
|
||||
result += '\\' + string.charAt(index);
|
||||
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
if (!root.CSS) {
|
||||
root.CSS = {};
|
||||
}
|
||||
|
||||
root.CSS.escape = cssEscape;
|
||||
return cssEscape;
|
||||
|
||||
}));
|
File diff suppressed because one or more lines are too long
|
@ -31,7 +31,6 @@
|
|||
"../position",
|
||||
"../safe-active-element",
|
||||
"../safe-blur",
|
||||
"../tabbable",
|
||||
"../unique-id",
|
||||
"../version",
|
||||
"../widget"
|
||||
|
|
|
@ -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.
|
||||
|
||||
Ensure that dependencies have been installed:
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
Build files for production:
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
|
||||
This will create an index.umd.min.js file in dist/ that can be used in Drupal.
|
|
@ -0,0 +1,6 @@
|
|||
/*!
|
||||
* tabbable 5.1.6
|
||||
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):(e="undefined"!=typeof globalThis?globalThis:e||self,function(){var n=e.tabbable,r=e.tabbable={};t(r),r.noConflict=function(){return e.tabbable=n,r}}())}(this,(function(e){"use strict";var t=["input","select","textarea","a[href]","button","[tabindex]","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable="false"])',"details>summary:first-of-type","details"],n=t.join(","),r="undefined"==typeof Element?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,o=function(e,t,o){var i=Array.prototype.slice.apply(e.querySelectorAll(n));return t&&r.call(e,n)&&i.unshift(e),i=i.filter(o)},i=function(e){var t=parseInt(e.getAttribute("tabindex"),10);return isNaN(t)?function(e){return"true"===e.contentEditable}(e)?0:"AUDIO"!==e.nodeName&&"VIDEO"!==e.nodeName&&"DETAILS"!==e.nodeName||null!==e.getAttribute("tabindex")?e.tabIndex:0:t},a=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},u=function(e){return"INPUT"===e.tagName},c=function(e){return function(e){return u(e)&&"radio"===e.type}(e)&&!function(e){if(!e.name)return!0;var t,n=e.form||e.ownerDocument,r=function(e){return n.querySelectorAll('input[type="radio"][name="'+e+'"]')};if("undefined"!=typeof window&&void 0!==window.CSS&&"function"==typeof window.CSS.escape)t=r(window.CSS.escape(e.name));else try{t=r(e.name)}catch(e){return console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s",e.message),!1}var o=function(e,t){for(var n=0;n<e.length;n++)if(e[n].checked&&e[n].form===t)return e[n]}(t,e.form);return!o||o===e}(e)},l=function(e){return!(e.disabled||function(e){return u(e)&&"hidden"===e.type}(e)||function(e){if("hidden"===getComputedStyle(e).visibility)return!0;var t=r.call(e,"details>summary:first-of-type")?e.parentElement:e;if(r.call(t,"details:not([open]) *"))return!0;for(;e;){if("none"===getComputedStyle(e).display)return!0;e=e.parentElement}return!1}(e)||function(e){return"DETAILS"===e.tagName&&Array.prototype.slice.apply(e.children).some((function(e){return"SUMMARY"===e.tagName}))}(e))},d=function(e){return!(!l(e)||c(e)||i(e)<0)},f=t.concat("iframe").join(",");e.focusable=function(e,t){return o(e,(t=t||{}).includeContainer,l)},e.isFocusable=function(e){if(!e)throw new Error("No node provided");return!1!==r.call(e,f)&&l(e)},e.isTabbable=function(e){if(!e)throw new Error("No node provided");return!1!==r.call(e,n)&&d(e)},e.tabbable=function(e,t){var n=[],r=[];return o(e,(t=t||{}).includeContainer,d).forEach((function(e,t){var o=i(e);0===o?n.push(e):r.push({documentOrder:t,tabIndex:o,node:e})})),r.sort(a).map((function(e){return e.node})).concat(n)},Object.defineProperty(e,"__esModule",{value:!0})}));
|
||||
//# sourceMappingURL=index.umd.min.js.map
|
File diff suppressed because one or more lines are too long
|
@ -22,6 +22,16 @@ ckeditor:
|
|||
js:
|
||||
assets/vendor/ckeditor/ckeditor.js: { preprocess: false, minified: true }
|
||||
|
||||
css.escape:
|
||||
remote: https://github.com/mathiasbynens/CSS.escape
|
||||
version: "1.5.1"
|
||||
license:
|
||||
name: MIT
|
||||
url: https://raw.githubusercontent.com/mathiasbynens/CSS.escape/v1.5.1/LICENSE-MIT.txt
|
||||
gpl-compatible: true
|
||||
js:
|
||||
assets/vendor/css-escape/css.escape.js: { weight: -20 }
|
||||
|
||||
drupal:
|
||||
version: VERSION
|
||||
js:
|
||||
|
@ -95,7 +105,6 @@ drupal.autocomplete:
|
|||
assets/vendor/jquery.ui/ui/widgets/autocomplete-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/labels-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/widgets/menu-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/tabbable-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/data-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/disable-selection-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/escape-selector-min.js: { weight: -11.8, minified: true }
|
||||
|
@ -126,6 +135,7 @@ drupal.autocomplete:
|
|||
- core/drupal
|
||||
- core/drupalSettings
|
||||
- core/drupal.ajax
|
||||
- core/tabbable.jquery.shim
|
||||
|
||||
drupal.array.find:
|
||||
version: VERSION
|
||||
|
@ -200,7 +210,6 @@ drupal.dialog:
|
|||
assets/vendor/jquery.ui/ui/form-reset-mixin-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/labels-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/widgets/mouse-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/tabbable-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/data-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/disable-selection-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/form-min.js: { weight: -11.8, minified: true }
|
||||
|
@ -235,6 +244,7 @@ drupal.dialog:
|
|||
- core/drupalSettings
|
||||
- core/drupal.debounce
|
||||
- core/drupal.displace
|
||||
- core/tabbable.jquery.shim
|
||||
|
||||
drupal.dialog.ajax:
|
||||
version: VERSION
|
||||
|
@ -338,37 +348,11 @@ drupal.tabbingmanager:
|
|||
version: VERSION
|
||||
js:
|
||||
misc/tabbingmanager.js: {}
|
||||
# The remaining JavaScript assets previously came from core/jquery.ui, a
|
||||
# deprecated library. These assets are used to provide the :tabbable pseudo
|
||||
# selector to core's JavaScript. It should be possible to remove them once
|
||||
# :tabbable is provided via a non-jQuery UI based library.
|
||||
# All weights are based on on the requirements defined within each file.
|
||||
# @todo replace with solution found in https://drupal.org/node/3113649
|
||||
assets/vendor/jquery.ui/ui/labels-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/tabbable-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/disable-selection-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/form-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/escape-selector-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/focusable-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/ie-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/jquery-1-7-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/keycode-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/plugin-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/safe-active-element-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/safe-blur-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/scroll-parent-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/unique-id-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/version-min.js: { weight: -11.9, minified: true }
|
||||
# All CSS assets previously came from core/jquery.ui, a deprecated library.
|
||||
# @todo replace with solution found in https://drupal.org/node/3113649
|
||||
css:
|
||||
component:
|
||||
assets/vendor/jquery.ui/themes/base/core.css: { weight: -11.8 }
|
||||
theme:
|
||||
assets/vendor/jquery.ui/themes/base/theme.css: { weight: -11.8 }
|
||||
dependencies:
|
||||
- core/jquery
|
||||
- core/drupal
|
||||
- core/tabbable
|
||||
- core/tabbable.jquery.shim
|
||||
|
||||
drupal.tabledrag:
|
||||
version: VERSION
|
||||
|
@ -528,7 +512,6 @@ jquery.ui:
|
|||
gpl-compatible: true
|
||||
js:
|
||||
assets/vendor/jquery.ui/ui/labels-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/tabbable-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/data-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/disable-selection-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/escape-selector-min.js: { weight: -11.8, minified: true }
|
||||
|
@ -550,6 +533,7 @@ jquery.ui:
|
|||
assets/vendor/jquery.ui/themes/base/theme.css: { weight: -11.8 }
|
||||
dependencies:
|
||||
- core/jquery
|
||||
- core/tabbable.jquery.shim
|
||||
deprecated: &jquery_ui_unused_deprecated The "%library_id%" asset library is deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. See https://www.drupal.org/node/3067969
|
||||
|
||||
jquery.ui.autocomplete:
|
||||
|
@ -598,7 +582,6 @@ jquery.ui.dialog:
|
|||
assets/vendor/jquery.ui/ui/form-reset-mixin-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/labels-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/widgets/mouse-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/tabbable-min.js: { weight: -11.7, minified: true }
|
||||
assets/vendor/jquery.ui/ui/data-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/disable-selection-min.js: { weight: -11.8, minified: true }
|
||||
assets/vendor/jquery.ui/ui/escape-selector-min.js: { weight: -11.8, minified: true }
|
||||
|
@ -627,6 +610,7 @@ jquery.ui.dialog:
|
|||
assets/vendor/jquery.ui/themes/base/theme.css: { weight: -11.8 }
|
||||
dependencies:
|
||||
- core/jquery
|
||||
- core/tabbable.jquery.shim
|
||||
deprecated: *jquery_ui_unused_deprecated
|
||||
|
||||
jquery.ui.draggable:
|
||||
|
@ -754,6 +738,26 @@ sortable:
|
|||
js:
|
||||
assets/vendor/sortable/Sortable.min.js: { minified: true }
|
||||
|
||||
tabbable:
|
||||
remote: https://github.com/focus-trap/tabbable
|
||||
version: "5.1.6"
|
||||
license:
|
||||
name: MIT
|
||||
url: https://raw.githubusercontent.com/focus-trap/tabbable/v5.1.6/LICENSE
|
||||
gpl-compatible: true
|
||||
js:
|
||||
assets/vendor/tabbable/index.umd.min.js: { weight: -1, minified: true }
|
||||
dependencies:
|
||||
- core/css.escape
|
||||
|
||||
tabbable.jquery.shim:
|
||||
version: VERSION
|
||||
js:
|
||||
misc/jquery.tabbable.shim.js: {}
|
||||
dependencies:
|
||||
- core/tabbable
|
||||
- core/jquery
|
||||
|
||||
underscore:
|
||||
remote: https://github.com/jashkenas/underscore
|
||||
version: "1.11.0"
|
||||
|
|
|
@ -50,6 +50,11 @@
|
|||
// Turn the summary into a clickable link.
|
||||
const $summary = this.$node.find('> summary');
|
||||
|
||||
// If this polyfill is in use, the browser does not recognize
|
||||
// <summary> as a focusable element. The tabindex is set to -1 so the
|
||||
// tabbable library does not incorrectly identify it as tabbable.
|
||||
$summary.attr('tabindex', '-1');
|
||||
|
||||
$('<span class="details-summary-prefix visually-hidden"></span>')
|
||||
.append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show'))
|
||||
.prependTo($summary)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
$.extend(CollapsibleDetails.prototype, {
|
||||
setupSummaryPolyfill: function setupSummaryPolyfill() {
|
||||
var $summary = this.$node.find('> summary');
|
||||
$summary.attr('tabindex', '-1');
|
||||
$('<span class="details-summary-prefix visually-hidden"></span>').append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show')).prependTo($summary).after(document.createTextNode(' '));
|
||||
$('<a class="details-title"></a>').attr('href', "#".concat(this.$node.attr('id'))).prepend($summary.contents()).appendTo($summary);
|
||||
$summary.append(this.$summary).on('click', $.proxy(this.onSummaryClick, this));
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* @file
|
||||
* Defines a backwards-compatible shim for the jQuery UI :tabbable selector.
|
||||
*/
|
||||
|
||||
(($, Drupal, { isTabbable }) => {
|
||||
$.extend($.expr[':'], {
|
||||
tabbable(element) {
|
||||
// The tabbable library considers the summary element tabbable, and also
|
||||
// considers a details element without a summary tabbable. The jQuery UI
|
||||
// :tabbable selector does not. This is due to those element types being
|
||||
// inert in IE/Edge.
|
||||
// @see https://allyjs.io/data-tables/focusable.html
|
||||
if (element.tagName === 'SUMMARY' || element.tagName === 'DETAILS') {
|
||||
const tabIndex = element.getAttribute('tabIndex');
|
||||
if (tabIndex === null || tabIndex < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return isTabbable(element);
|
||||
},
|
||||
});
|
||||
})(jQuery, Drupal, window.tabbable);
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal, _ref) {
|
||||
var isTabbable = _ref.isTabbable;
|
||||
$.extend($.expr[':'], {
|
||||
tabbable: function tabbable(element) {
|
||||
if (element.tagName === 'SUMMARY' || element.tagName === 'DETAILS') {
|
||||
var tabIndex = element.getAttribute('tabIndex');
|
||||
|
||||
if (tabIndex === null || tabIndex < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return isTabbable(element);
|
||||
}
|
||||
});
|
||||
})(jQuery, Drupal, window.tabbable);
|
|
@ -0,0 +1,32 @@
|
|||
<?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/jquery.ui.dialog'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?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.tabbingmanager']],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
name: 'Tabbable Shim Test'
|
||||
type: module
|
||||
description: 'Module for the testing the :tabbable selector shim'
|
||||
package: Testing
|
||||
version: VERSION
|
|
@ -0,0 +1,15 @@
|
|||
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'
|
|
@ -58,7 +58,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
$libraries_to_check = [
|
||||
'drupal.autocomplete',
|
||||
'drupal.dialog',
|
||||
'drupal.tabbingmanager',
|
||||
'jquery.ui',
|
||||
'jquery.ui.autocomplete',
|
||||
'jquery.ui.button',
|
||||
|
@ -138,7 +137,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/widgets/autocomplete-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/widgets/menu-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/themes/base/autocomplete.css',
|
||||
'core/assets/vendor/jquery.ui/themes/base/menu.css',
|
||||
'core/assets/vendor/jquery.ui/ui/widgets/controlgroup-min.js',
|
||||
|
@ -373,7 +371,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -407,7 +404,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -429,31 +425,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/widgets/dialog-min.js',
|
||||
],
|
||||
],
|
||||
'drupal.tabbingmanager' => [
|
||||
'library' => 'drupal.tabbingmanager',
|
||||
'expected_css' => [
|
||||
'core/assets/vendor/jquery.ui/themes/base/core.css',
|
||||
'core/assets/vendor/jquery.ui/themes/base/theme.css',
|
||||
],
|
||||
'expected_js' => [
|
||||
'core/assets/vendor/jquery.ui/ui/data-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/disable-selection-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/form-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/focusable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/ie-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/keycode-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/plugin-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/safe-active-element-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/safe-blur-min.js',
|
||||
],
|
||||
],
|
||||
'jquery.ui' => [
|
||||
'library' => 'jquery.ui',
|
||||
'expected_css' => [
|
||||
|
@ -467,7 +438,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -494,7 +464,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -526,7 +495,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -560,7 +528,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -596,7 +563,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -624,7 +590,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -651,7 +616,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -678,7 +642,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -706,7 +669,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -722,8 +684,8 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
// A few instances of multiple libraries being checked simultaneously are
|
||||
// here to ensure that multiple libraries requesting the same asset does
|
||||
// not impact the expected loading order.
|
||||
'drupal.tabbingmanager|jquery.ui|jquery.ui.widget' => [
|
||||
'library' => 'drupal.tabbingmanager|jquery.ui|jquery.ui.widget',
|
||||
'jquery.ui|jquery.ui.widget' => [
|
||||
'library' => 'jquery.ui|jquery.ui.widget',
|
||||
'expected_css' => [
|
||||
'core/assets/vendor/jquery.ui/themes/base/core.css',
|
||||
'core/assets/vendor/jquery.ui/themes/base/theme.css',
|
||||
|
@ -735,7 +697,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -768,7 +729,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
@ -792,8 +752,8 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/widgets/dialog-min.js',
|
||||
],
|
||||
],
|
||||
'jquery.ui.widget|jquery.ui.resizable|jquery.ui.position|jquery.ui.mouse|jquery.ui.menu|jquery.ui.dialog|jquery.ui.button|jquery.ui.autocomplete|jquery.ui|drupal.tabbingmanager|drupal.dialog|drupal.autocomplete' => [
|
||||
'library' => 'jquery.ui.widget|jquery.ui.resizable|jquery.ui.position|jquery.ui.mouse|jquery.ui.menu|jquery.ui.dialog|jquery.ui.button|jquery.ui.autocomplete|jquery.ui|drupal.tabbingmanager|drupal.dialog|drupal.autocomplete',
|
||||
'jquery.ui.widget|jquery.ui.resizable|jquery.ui.position|jquery.ui.mouse|jquery.ui.menu|jquery.ui.dialog|jquery.ui.button|jquery.ui.autocomplete|jquery.ui|drupal.dialog|drupal.autocomplete' => [
|
||||
'library' => 'jquery.ui.widget|jquery.ui.resizable|jquery.ui.position|jquery.ui.mouse|jquery.ui.menu|jquery.ui.dialog|jquery.ui.button|jquery.ui.autocomplete|jquery.ui|drupal.dialog|drupal.autocomplete',
|
||||
'expected_css' => [
|
||||
'core/assets/vendor/jquery.ui/themes/base/core.css',
|
||||
'core/assets/vendor/jquery.ui/themes/base/resizable.css',
|
||||
|
@ -812,7 +772,6 @@ class JqueryUiLibraryAssetsTest extends BrowserTestBase {
|
|||
'core/assets/vendor/jquery.ui/ui/labels-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/jquery-1-7-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/scroll-parent-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/tabbable-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/unique-id-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/version-min.js',
|
||||
'core/assets/vendor/jquery.ui/ui/escape-selector-min.js',
|
||||
|
|
|
@ -20,10 +20,10 @@ class DeprecatedJqueryUiAssetsTest extends KernelTestBase {
|
|||
/** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
|
||||
$library_discovery = $this->container->get('library.discovery');
|
||||
$deprecated_jquery_ui_libraries = [
|
||||
'jquery.ui' => '1396fab9268ee2cce47df6ac3e4781c8',
|
||||
'jquery.ui' => '291c28f873a71cd6b3116218d1f5da22',
|
||||
'jquery.ui.autocomplete' => '153f2836f8f2da39767208b6e09cb5b4',
|
||||
'jquery.ui.button' => 'ad23e5de0fa1de1f511d10ba2e10d2dd',
|
||||
'jquery.ui.dialog' => '2027aab39332607b62288c4d20c01f83',
|
||||
'jquery.ui.dialog' => '729090e5ddcd8563ddade80c3dabc87c',
|
||||
'jquery.ui.draggable' => 'af0f2bdc8aa4ade1e3de8042f31a9312',
|
||||
'jquery.ui.menu' => '7d0c4d57f43d2f881d2cd5e5b79effbb',
|
||||
'jquery.ui.mouse' => '626bb203807fa2cdc62510412685df4a',
|
||||
|
|
|
@ -0,0 +1,338 @@
|
|||
// 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>I am not :tabbable because IE does not support it</summary>This is unfortunate</details>',
|
||||
tabbable: 0,
|
||||
},
|
||||
{
|
||||
element:
|
||||
'<details>A details without a summary should also not be :tabbable</details>',
|
||||
tabbable: 0,
|
||||
},
|
||||
{
|
||||
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().drupalLoginAsAdmin(() => {
|
||||
browser
|
||||
.drupalRelativeURL('/admin/modules')
|
||||
.setValue('input[type="search"]', 'Tabbable Shim Test')
|
||||
.waitForElementVisible(
|
||||
'input[name="modules[tabbable_shim_test][enable]"]',
|
||||
1000,
|
||||
)
|
||||
.click('input[name="modules[tabbable_shim_test][enable]"]')
|
||||
.click('input[type="submit"]');
|
||||
});
|
||||
},
|
||||
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.equal(
|
||||
result.value.actual,
|
||||
result.value.expected,
|
||||
`Expected :tabbable to return ${result.value.expected} for element ${result.value.element}`,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
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.drupalLogAndEnd({ onlyOnError: false });
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue