This repository has been archived on 2025-01-19. You can view files and clone it, but cannot push or open issues or pull requests.
drupalcampbristol/web/core/misc/tabbingmanager.js
2018-11-23 12:29:20 +00:00

159 lines
4.1 KiB
JavaScript

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