Chris@0: /** Chris@0: * DO NOT EDIT THIS FILE. Chris@0: * See the following change record for more information, Chris@0: * https://www.drupal.org/node/2815083 Chris@0: * @preserve Chris@0: **/ Chris@0: Chris@0: (function ($, Drupal) { Chris@0: function TabbingManager() { Chris@0: this.stack = []; Chris@0: } Chris@0: Chris@17: function TabbingContext(options) { Chris@17: $.extend(this, { Chris@17: level: null, Chris@17: Chris@17: $tabbableElements: $(), Chris@17: Chris@17: $disabledElements: $(), Chris@17: Chris@17: released: false, Chris@17: Chris@17: active: false Chris@17: }, options); Chris@17: } Chris@17: Chris@0: $.extend(TabbingManager.prototype, { Chris@0: constrain: function constrain(elements) { Chris@0: var il = this.stack.length; Chris@0: for (var i = 0; i < il; i++) { Chris@0: this.stack[i].deactivate(); Chris@0: } Chris@0: Chris@0: var $elements = $(elements).find(':tabbable').addBack(':tabbable'); Chris@0: Chris@0: var tabbingContext = new TabbingContext({ Chris@0: level: this.stack.length, Chris@0: $tabbableElements: $elements Chris@0: }); Chris@0: Chris@0: this.stack.push(tabbingContext); Chris@0: Chris@0: tabbingContext.activate(); Chris@0: Chris@0: $(document).trigger('drupalTabbingConstrained', tabbingContext); Chris@0: Chris@0: return tabbingContext; Chris@0: }, Chris@0: release: function release() { Chris@0: var toActivate = this.stack.length - 1; Chris@0: while (toActivate >= 0 && this.stack[toActivate].released) { Chris@0: toActivate--; Chris@0: } Chris@0: Chris@0: this.stack.splice(toActivate + 1); Chris@0: Chris@0: if (toActivate >= 0) { Chris@0: this.stack[toActivate].activate(); Chris@0: } Chris@0: }, Chris@0: activate: function activate(tabbingContext) { Chris@0: var $set = tabbingContext.$tabbableElements; Chris@0: var level = tabbingContext.level; Chris@0: Chris@0: var $disabledSet = $(':tabbable').not($set); Chris@0: Chris@0: tabbingContext.$disabledElements = $disabledSet; Chris@0: Chris@0: var il = $disabledSet.length; Chris@0: for (var i = 0; i < il; i++) { Chris@0: this.recordTabindex($disabledSet.eq(i), level); Chris@0: } Chris@0: Chris@0: $disabledSet.prop('tabindex', -1).prop('autofocus', false); Chris@0: Chris@0: var $hasFocus = $set.filter('[autofocus]').eq(-1); Chris@0: Chris@0: if ($hasFocus.length === 0) { Chris@0: $hasFocus = $set.eq(0); Chris@0: } Chris@0: $hasFocus.trigger('focus'); Chris@0: }, Chris@0: deactivate: function deactivate(tabbingContext) { Chris@0: var $set = tabbingContext.$disabledElements; Chris@0: var level = tabbingContext.level; Chris@0: var il = $set.length; Chris@0: for (var i = 0; i < il; i++) { Chris@0: this.restoreTabindex($set.eq(i), level); Chris@0: } Chris@0: }, Chris@0: recordTabindex: function recordTabindex($el, level) { Chris@0: var tabInfo = $el.data('drupalOriginalTabIndices') || {}; Chris@0: tabInfo[level] = { Chris@0: tabindex: $el[0].getAttribute('tabindex'), Chris@0: autofocus: $el[0].hasAttribute('autofocus') Chris@0: }; Chris@0: $el.data('drupalOriginalTabIndices', tabInfo); Chris@0: }, Chris@0: restoreTabindex: function restoreTabindex($el, level) { Chris@0: var tabInfo = $el.data('drupalOriginalTabIndices'); Chris@0: if (tabInfo && tabInfo[level]) { Chris@0: var data = tabInfo[level]; Chris@0: if (data.tabindex) { Chris@0: $el[0].setAttribute('tabindex', data.tabindex); Chris@0: } else { Chris@0: $el[0].removeAttribute('tabindex'); Chris@0: } Chris@0: if (data.autofocus) { Chris@0: $el[0].setAttribute('autofocus', 'autofocus'); Chris@0: } Chris@0: Chris@0: if (level === 0) { Chris@0: $el.removeData('drupalOriginalTabIndices'); Chris@0: } else { Chris@0: var levelToDelete = level; Chris@0: while (tabInfo.hasOwnProperty(levelToDelete)) { Chris@0: delete tabInfo[levelToDelete]; Chris@0: levelToDelete++; Chris@0: } Chris@0: $el.data('drupalOriginalTabIndices', tabInfo); Chris@0: } Chris@0: } Chris@0: } Chris@0: }); Chris@0: Chris@0: $.extend(TabbingContext.prototype, { Chris@0: release: function release() { Chris@0: if (!this.released) { Chris@0: this.deactivate(); Chris@0: this.released = true; Chris@0: Drupal.tabbingManager.release(this); Chris@0: Chris@0: $(document).trigger('drupalTabbingContextReleased', this); Chris@0: } Chris@0: }, Chris@0: activate: function activate() { Chris@0: if (!this.active && !this.released) { Chris@0: this.active = true; Chris@0: Drupal.tabbingManager.activate(this); Chris@0: Chris@0: $(document).trigger('drupalTabbingContextActivated', this); Chris@0: } Chris@0: }, Chris@0: deactivate: function deactivate() { Chris@0: if (this.active) { Chris@0: this.active = false; Chris@0: Drupal.tabbingManager.deactivate(this); Chris@0: Chris@0: $(document).trigger('drupalTabbingContextDeactivated', this); Chris@0: } Chris@0: } Chris@0: }); Chris@0: Chris@0: if (Drupal.tabbingManager) { Chris@0: return; Chris@0: } Chris@0: Chris@0: Drupal.tabbingManager = new TabbingManager(); Chris@0: })(jQuery, Drupal);