Loading core/core.libraries.yml +1 −2 Original line number Diff line number Diff line Loading @@ -469,10 +469,9 @@ drupal.collapse: js: misc/details-summarized-content.js: {} misc/details-aria.js: {} misc/collapse.js: {} misc/details.js: {} dependencies: - core/jquery - core/modernizr - core/drupal - core/drupal.form - core/once Loading core/misc/collapse.jsdeleted 100644 → 0 +0 −155 Original line number Diff line number Diff line /** * @file * Polyfill for HTML5 details elements. */ (function ($, Modernizr, Drupal) { /** * The collapsible details object represents a single details element. * * @constructor Drupal.CollapsibleDetails * * @param {HTMLElement} node * The details element. */ function CollapsibleDetails(node) { this.$node = $(node); this.$node.data('details', this); // Expand details if there are errors inside, or if it contains an // element that is targeted by the URI fragment identifier. const anchor = window.location.hash && window.location.hash !== '#' ? `, ${window.location.hash}` : ''; if (this.$node.find(`.error${anchor}`).length) { this.$node.attr('open', true); } // Initialize and set up the summary polyfill. this.setupSummaryPolyfill(); } $.extend( CollapsibleDetails, /** @lends Drupal.CollapsibleDetails */ { /** * Holds references to instantiated CollapsibleDetails objects. * * @type {Array.<Drupal.CollapsibleDetails>} */ instances: [], }, ); $.extend( CollapsibleDetails.prototype, /** @lends Drupal.CollapsibleDetails# */ { /** * Initialize and setup summary markup. */ setupSummaryPolyfill() { // 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) .after(document.createTextNode(' ')); // .wrapInner() does not retain bound events. $('<a class="details-title"></a>') .attr('href', `#${this.$node.attr('id')}`) .prepend($summary.contents()) .appendTo($summary); $summary .append(this.$summary) .on('click', $.proxy(this.onSummaryClick, this)); }, /** * Handle summary clicks. * * @param {jQuery.Event} e * The event triggered. */ onSummaryClick(e) { this.toggle(); e.preventDefault(); }, /** * Toggle the visibility of a details element using smooth animations. */ toggle() { const isOpen = !!this.$node.attr('open'); const $summaryPrefix = this.$node.find( '> summary span.details-summary-prefix', ); if (isOpen) { $summaryPrefix.html(Drupal.t('Show')); } else { $summaryPrefix.html(Drupal.t('Hide')); } // Delay setting the attribute to emulate chrome behavior and make // details-aria.js work as expected with this polyfill. setTimeout(() => { this.$node.attr('open', !isOpen); }, 0); }, }, ); /** * Polyfill HTML5 details element. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach * Attaches behavior for the details element. */ Drupal.behaviors.collapse = { attach(context) { if (Modernizr.details) { return; } once('collapse', 'details', context).forEach((detail) => { // This class is used for styling purpose only. detail.classList.add('collapse-processed'); CollapsibleDetails.instances.push(new CollapsibleDetails(detail)); }); }, }; /** * Open parent details elements of a targeted page fragment. * * Opens all (nested) details element on a hash change or fragment link click * when the target is a child element, in order to make sure the targeted * element is visible. Aria attributes on the summary * are set by triggering the click event listener in details-aria.js. * * @param {jQuery.Event} e * The event triggered. * @param {jQuery} $target * The targeted node as a jQuery object. */ const handleFragmentLinkClickOrHashChange = (e, $target) => { $target.parents('details').not('[open]').find('> summary').trigger('click'); }; /** * Binds a listener to handle fragment link clicks and URL hash changes. */ $('body').on( 'formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange, ); // Expose constructor in the public space. Drupal.CollapsibleDetails = CollapsibleDetails; })(jQuery, Modernizr, Drupal); core/misc/details.js 0 → 100644 +31 −0 Original line number Diff line number Diff line /** * @file * Additional functionality for HTML5 details elements. */ (function ($) { /** * Open parent details elements of a targeted page fragment. * * Opens all (nested) details element on a hash change or fragment link click * when the target is a child element, in order to make sure the targeted * element is visible. Aria attributes on the summary * are set by triggering the click event listener in details-aria.js. * * @param {jQuery.Event} e * The event triggered. * @param {jQuery} $target * The targeted node as a jQuery object. */ const handleFragmentLinkClickOrHashChange = (e, $target) => { $target.parents('details').not('[open]').find('> summary').trigger('click'); }; /** * Binds a listener to handle fragment link clicks and URL hash changes. */ $('body').on( 'formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange, ); })(jQuery); core/modules/system/tests/src/Functional/Form/ElementsVerticalTabsTest.php +0 −15 Original line number Diff line number Diff line Loading @@ -49,21 +49,6 @@ protected function setUp(): void { $this->drupalLogin($this->adminUser); } /** * Ensures that vertical-tabs.js is included before collapse.js. * * Otherwise, collapse.js adds "SHOW" or "HIDE" labels to the tabs. */ public function testJavaScriptOrdering() { $this->drupalGet('form_test/vertical-tabs'); $content = $this->getSession()->getPage()->getContent(); $position1 = strpos($content, 'core/misc/vertical-tabs.js'); $position2 = strpos($content, 'core/misc/collapse.js'); $this->assertNotFalse($position1); $this->assertNotFalse($position2); $this->assertGreaterThan($position1, $position2, 'vertical-tabs.js is included before collapse.js'); } /** * Ensures that vertical tab markup is not shown if user has no tab access. */ Loading core/modules/system/tests/themes/test_theme/test_theme.info.yml +0 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ libraries-override: css: component: css/components/button.css: css/my-button.css css/components/collapse-processed.css: css/my-collapse-processed.css css/components/container-inline.css: /themes/my_theme/css/my-container-inline.css css/components/details.css: /themes/my_theme/css/my-details.css # Remove particular library assets. Loading Loading
core/core.libraries.yml +1 −2 Original line number Diff line number Diff line Loading @@ -469,10 +469,9 @@ drupal.collapse: js: misc/details-summarized-content.js: {} misc/details-aria.js: {} misc/collapse.js: {} misc/details.js: {} dependencies: - core/jquery - core/modernizr - core/drupal - core/drupal.form - core/once Loading
core/misc/collapse.jsdeleted 100644 → 0 +0 −155 Original line number Diff line number Diff line /** * @file * Polyfill for HTML5 details elements. */ (function ($, Modernizr, Drupal) { /** * The collapsible details object represents a single details element. * * @constructor Drupal.CollapsibleDetails * * @param {HTMLElement} node * The details element. */ function CollapsibleDetails(node) { this.$node = $(node); this.$node.data('details', this); // Expand details if there are errors inside, or if it contains an // element that is targeted by the URI fragment identifier. const anchor = window.location.hash && window.location.hash !== '#' ? `, ${window.location.hash}` : ''; if (this.$node.find(`.error${anchor}`).length) { this.$node.attr('open', true); } // Initialize and set up the summary polyfill. this.setupSummaryPolyfill(); } $.extend( CollapsibleDetails, /** @lends Drupal.CollapsibleDetails */ { /** * Holds references to instantiated CollapsibleDetails objects. * * @type {Array.<Drupal.CollapsibleDetails>} */ instances: [], }, ); $.extend( CollapsibleDetails.prototype, /** @lends Drupal.CollapsibleDetails# */ { /** * Initialize and setup summary markup. */ setupSummaryPolyfill() { // 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) .after(document.createTextNode(' ')); // .wrapInner() does not retain bound events. $('<a class="details-title"></a>') .attr('href', `#${this.$node.attr('id')}`) .prepend($summary.contents()) .appendTo($summary); $summary .append(this.$summary) .on('click', $.proxy(this.onSummaryClick, this)); }, /** * Handle summary clicks. * * @param {jQuery.Event} e * The event triggered. */ onSummaryClick(e) { this.toggle(); e.preventDefault(); }, /** * Toggle the visibility of a details element using smooth animations. */ toggle() { const isOpen = !!this.$node.attr('open'); const $summaryPrefix = this.$node.find( '> summary span.details-summary-prefix', ); if (isOpen) { $summaryPrefix.html(Drupal.t('Show')); } else { $summaryPrefix.html(Drupal.t('Hide')); } // Delay setting the attribute to emulate chrome behavior and make // details-aria.js work as expected with this polyfill. setTimeout(() => { this.$node.attr('open', !isOpen); }, 0); }, }, ); /** * Polyfill HTML5 details element. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach * Attaches behavior for the details element. */ Drupal.behaviors.collapse = { attach(context) { if (Modernizr.details) { return; } once('collapse', 'details', context).forEach((detail) => { // This class is used for styling purpose only. detail.classList.add('collapse-processed'); CollapsibleDetails.instances.push(new CollapsibleDetails(detail)); }); }, }; /** * Open parent details elements of a targeted page fragment. * * Opens all (nested) details element on a hash change or fragment link click * when the target is a child element, in order to make sure the targeted * element is visible. Aria attributes on the summary * are set by triggering the click event listener in details-aria.js. * * @param {jQuery.Event} e * The event triggered. * @param {jQuery} $target * The targeted node as a jQuery object. */ const handleFragmentLinkClickOrHashChange = (e, $target) => { $target.parents('details').not('[open]').find('> summary').trigger('click'); }; /** * Binds a listener to handle fragment link clicks and URL hash changes. */ $('body').on( 'formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange, ); // Expose constructor in the public space. Drupal.CollapsibleDetails = CollapsibleDetails; })(jQuery, Modernizr, Drupal);
core/misc/details.js 0 → 100644 +31 −0 Original line number Diff line number Diff line /** * @file * Additional functionality for HTML5 details elements. */ (function ($) { /** * Open parent details elements of a targeted page fragment. * * Opens all (nested) details element on a hash change or fragment link click * when the target is a child element, in order to make sure the targeted * element is visible. Aria attributes on the summary * are set by triggering the click event listener in details-aria.js. * * @param {jQuery.Event} e * The event triggered. * @param {jQuery} $target * The targeted node as a jQuery object. */ const handleFragmentLinkClickOrHashChange = (e, $target) => { $target.parents('details').not('[open]').find('> summary').trigger('click'); }; /** * Binds a listener to handle fragment link clicks and URL hash changes. */ $('body').on( 'formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange, ); })(jQuery);
core/modules/system/tests/src/Functional/Form/ElementsVerticalTabsTest.php +0 −15 Original line number Diff line number Diff line Loading @@ -49,21 +49,6 @@ protected function setUp(): void { $this->drupalLogin($this->adminUser); } /** * Ensures that vertical-tabs.js is included before collapse.js. * * Otherwise, collapse.js adds "SHOW" or "HIDE" labels to the tabs. */ public function testJavaScriptOrdering() { $this->drupalGet('form_test/vertical-tabs'); $content = $this->getSession()->getPage()->getContent(); $position1 = strpos($content, 'core/misc/vertical-tabs.js'); $position2 = strpos($content, 'core/misc/collapse.js'); $this->assertNotFalse($position1); $this->assertNotFalse($position2); $this->assertGreaterThan($position1, $position2, 'vertical-tabs.js is included before collapse.js'); } /** * Ensures that vertical tab markup is not shown if user has no tab access. */ Loading
core/modules/system/tests/themes/test_theme/test_theme.info.yml +0 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ libraries-override: css: component: css/components/button.css: css/my-button.css css/components/collapse-processed.css: css/my-collapse-processed.css css/components/container-inline.css: /themes/my_theme/css/my-container-inline.css css/components/details.css: /themes/my_theme/css/my-details.css # Remove particular library assets. Loading