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. $.extend(TabbingManager.prototype, {
  12. constrain: function constrain(elements) {
  13. var il = this.stack.length;
  14. for (var i = 0; i < il; i++) {
  15. this.stack[i].deactivate();
  16. }
  17. var $elements = $(elements).find(':tabbable').addBack(':tabbable');
  18. var tabbingContext = new TabbingContext({
  19. level: this.stack.length,
  20. $tabbableElements: $elements
  21. });
  22. this.stack.push(tabbingContext);
  23. tabbingContext.activate();
  24. $(document).trigger('drupalTabbingConstrained', tabbingContext);
  25. return tabbingContext;
  26. },
  27. release: function release() {
  28. var toActivate = this.stack.length - 1;
  29. while (toActivate >= 0 && this.stack[toActivate].released) {
  30. toActivate--;
  31. }
  32. this.stack.splice(toActivate + 1);
  33. if (toActivate >= 0) {
  34. this.stack[toActivate].activate();
  35. }
  36. },
  37. activate: function activate(tabbingContext) {
  38. var $set = tabbingContext.$tabbableElements;
  39. var level = tabbingContext.level;
  40. var $disabledSet = $(':tabbable').not($set);
  41. tabbingContext.$disabledElements = $disabledSet;
  42. var il = $disabledSet.length;
  43. for (var i = 0; i < il; i++) {
  44. this.recordTabindex($disabledSet.eq(i), level);
  45. }
  46. $disabledSet.prop('tabindex', -1).prop('autofocus', false);
  47. var $hasFocus = $set.filter('[autofocus]').eq(-1);
  48. if ($hasFocus.length === 0) {
  49. $hasFocus = $set.eq(0);
  50. }
  51. $hasFocus.trigger('focus');
  52. },
  53. deactivate: function deactivate(tabbingContext) {
  54. var $set = tabbingContext.$disabledElements;
  55. var level = tabbingContext.level;
  56. var il = $set.length;
  57. for (var i = 0; i < il; i++) {
  58. this.restoreTabindex($set.eq(i), level);
  59. }
  60. },
  61. recordTabindex: function recordTabindex($el, level) {
  62. var tabInfo = $el.data('drupalOriginalTabIndices') || {};
  63. tabInfo[level] = {
  64. tabindex: $el[0].getAttribute('tabindex'),
  65. autofocus: $el[0].hasAttribute('autofocus')
  66. };
  67. $el.data('drupalOriginalTabIndices', tabInfo);
  68. },
  69. restoreTabindex: function restoreTabindex($el, level) {
  70. var tabInfo = $el.data('drupalOriginalTabIndices');
  71. if (tabInfo && tabInfo[level]) {
  72. var data = tabInfo[level];
  73. if (data.tabindex) {
  74. $el[0].setAttribute('tabindex', data.tabindex);
  75. } else {
  76. $el[0].removeAttribute('tabindex');
  77. }
  78. if (data.autofocus) {
  79. $el[0].setAttribute('autofocus', 'autofocus');
  80. }
  81. if (level === 0) {
  82. $el.removeData('drupalOriginalTabIndices');
  83. } else {
  84. var levelToDelete = level;
  85. while (tabInfo.hasOwnProperty(levelToDelete)) {
  86. delete tabInfo[levelToDelete];
  87. levelToDelete++;
  88. }
  89. $el.data('drupalOriginalTabIndices', tabInfo);
  90. }
  91. }
  92. }
  93. });
  94. function TabbingContext(options) {
  95. $.extend(this, {
  96. level: null,
  97. $tabbableElements: $(),
  98. $disabledElements: $(),
  99. released: false,
  100. active: false
  101. }, options);
  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);