tabbingmanager.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /**
  2. * DO NOT EDIT THIS FILE.
  3. * See the following change record for more information,
  4. * https://www.drupal.org/node/2815083
  5. * @preserve
  6. **/
  7. (function ($, Drupal) {
  8. function TabbingManager() {
  9. this.stack = [];
  10. }
  11. function TabbingContext(options) {
  12. $.extend(this, {
  13. level: null,
  14. $tabbableElements: $(),
  15. $disabledElements: $(),
  16. released: false,
  17. active: false
  18. }, options);
  19. }
  20. $.extend(TabbingManager.prototype, {
  21. constrain: function constrain(elements) {
  22. var il = this.stack.length;
  23. for (var i = 0; i < il; i++) {
  24. this.stack[i].deactivate();
  25. }
  26. var $elements = $(elements).find(':tabbable').addBack(':tabbable');
  27. var tabbingContext = new TabbingContext({
  28. level: this.stack.length,
  29. $tabbableElements: $elements
  30. });
  31. this.stack.push(tabbingContext);
  32. tabbingContext.activate();
  33. $(document).trigger('drupalTabbingConstrained', tabbingContext);
  34. return tabbingContext;
  35. },
  36. release: function release() {
  37. var toActivate = this.stack.length - 1;
  38. while (toActivate >= 0 && this.stack[toActivate].released) {
  39. toActivate--;
  40. }
  41. this.stack.splice(toActivate + 1);
  42. if (toActivate >= 0) {
  43. this.stack[toActivate].activate();
  44. }
  45. },
  46. activate: function activate(tabbingContext) {
  47. var $set = tabbingContext.$tabbableElements;
  48. var level = tabbingContext.level;
  49. var $disabledSet = $(':tabbable').not($set);
  50. tabbingContext.$disabledElements = $disabledSet;
  51. var il = $disabledSet.length;
  52. for (var i = 0; i < il; i++) {
  53. this.recordTabindex($disabledSet.eq(i), level);
  54. }
  55. $disabledSet.prop('tabindex', -1).prop('autofocus', false);
  56. var $hasFocus = $set.filter('[autofocus]').eq(-1);
  57. if ($hasFocus.length === 0) {
  58. $hasFocus = $set.eq(0);
  59. }
  60. $hasFocus.trigger('focus');
  61. },
  62. deactivate: function deactivate(tabbingContext) {
  63. var $set = tabbingContext.$disabledElements;
  64. var level = tabbingContext.level;
  65. var il = $set.length;
  66. for (var i = 0; i < il; i++) {
  67. this.restoreTabindex($set.eq(i), level);
  68. }
  69. },
  70. recordTabindex: function recordTabindex($el, level) {
  71. var tabInfo = $el.data('drupalOriginalTabIndices') || {};
  72. tabInfo[level] = {
  73. tabindex: $el[0].getAttribute('tabindex'),
  74. autofocus: $el[0].hasAttribute('autofocus')
  75. };
  76. $el.data('drupalOriginalTabIndices', tabInfo);
  77. },
  78. restoreTabindex: function restoreTabindex($el, level) {
  79. var tabInfo = $el.data('drupalOriginalTabIndices');
  80. if (tabInfo && tabInfo[level]) {
  81. var data = tabInfo[level];
  82. if (data.tabindex) {
  83. $el[0].setAttribute('tabindex', data.tabindex);
  84. } else {
  85. $el[0].removeAttribute('tabindex');
  86. }
  87. if (data.autofocus) {
  88. $el[0].setAttribute('autofocus', 'autofocus');
  89. }
  90. if (level === 0) {
  91. $el.removeData('drupalOriginalTabIndices');
  92. } else {
  93. var levelToDelete = level;
  94. while (tabInfo.hasOwnProperty(levelToDelete)) {
  95. delete tabInfo[levelToDelete];
  96. levelToDelete++;
  97. }
  98. $el.data('drupalOriginalTabIndices', tabInfo);
  99. }
  100. }
  101. }
  102. });
  103. $.extend(TabbingContext.prototype, {
  104. release: function release() {
  105. if (!this.released) {
  106. this.deactivate();
  107. this.released = true;
  108. Drupal.tabbingManager.release(this);
  109. $(document).trigger('drupalTabbingContextReleased', this);
  110. }
  111. },
  112. activate: function activate() {
  113. if (!this.active && !this.released) {
  114. this.active = true;
  115. Drupal.tabbingManager.activate(this);
  116. $(document).trigger('drupalTabbingContextActivated', this);
  117. }
  118. },
  119. deactivate: function deactivate() {
  120. if (this.active) {
  121. this.active = false;
  122. Drupal.tabbingManager.deactivate(this);
  123. $(document).trigger('drupalTabbingContextDeactivated', this);
  124. }
  125. }
  126. });
  127. if (Drupal.tabbingManager) {
  128. return;
  129. }
  130. Drupal.tabbingManager = new TabbingManager();
  131. })(jQuery, Drupal);