diff --git a/core/misc/collapse.js b/core/misc/collapse.js index 1ad89f7..00b17e3 100644 --- a/core/misc/collapse.js +++ b/core/misc/collapse.js @@ -20,13 +20,21 @@ // Expand details if there are errors inside, or if it contains an // element that is targeted by the URI fragment identifier. var anchor = location.hash && location.hash !== '#' ? ', ' + location.hash : ''; - if (this.$node.find('.error' + anchor).length) { - this.$node.attr('open', true); + + this.$node.find('input, .error' + anchor).on('invalid', $.proxy(this.invalidHandler, this)); + + var $invalidTarget = this.$node.find('.error' + anchor); + if ($invalidTarget.length) { + $invalidTarget.trigger('invalid'); + } + + if (!Modernizr.details) { + // Initialize and setup the summary, + this.setupSummary(); + // Initialize and setup the legend. + this.setupLegend(); } - // Initialize and setup the summary, - this.setupSummary(); - // Initialize and setup the legend. - this.setupLegend(); + } $.extend(CollapsibleDetails, /** @lends Drupal.CollapsibleDetails */{ @@ -99,20 +107,28 @@ /** * Toggle the visibility of a details element using smooth animations. */ - toggle: function () { - var isOpen = !!this.$node.attr('open'); + toggle: function (isOpen) { + if (typeof isOpen == 'undefined') { + isOpen = !this.$node.attr('open'); + } var $summaryPrefix = this.$node.find('> summary span.details-summary-prefix'); if (isOpen) { - $summaryPrefix.html(Drupal.t('Show')); + $summaryPrefix.html(Drupal.t('Hide')); } else { - $summaryPrefix.html(Drupal.t('Hide')); + $summaryPrefix.html(Drupal.t('Show')); } // Delay setting the attribute to emulate chrome behavior and make // details-aria.js work as expected with this polyfill. setTimeout(function () { - this.$node.attr('open', !isOpen); + this.$node.attr('open', isOpen); }.bind(this), 0); + }, + /** + * Handle invalid event + */ + invalidHandler: function () { + this.toggle(true); } }); @@ -123,18 +139,17 @@ */ Drupal.behaviors.collapse = { attach: function (context) { - if (Modernizr.details) { - return; - } - var $collapsibleDetails = $(context).find('details').once('collapse').addClass('collapse-processed'); + var $collapsibleDetails = $(context).find('details').once('collapse'); if ($collapsibleDetails.length) { + if (!Modernizr.details) { + $collapsibleDetails.addClass('collapse-processed'); + } for (var i = 0; i < $collapsibleDetails.length; i++) { CollapsibleDetails.instances.push(new CollapsibleDetails($collapsibleDetails[i])); } } } }; - // Expose constructor in the public space. Drupal.CollapsibleDetails = CollapsibleDetails;