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