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