xooie 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,263 +21,298 @@
21
21
  * As of v1.0 this widget has been deprecated. Use the more semantically appropriate
22
22
  * [[Xooie.Tooltip]], [[Xooie.Menu]], [[Xooie.Tab]], or [[Xooie.Accordion]] classes instead.
23
23
  **/
24
- define('xooie/widgets/dropdown', ['jquery', 'xooie/widgets/base'], function($, Base) {
24
+ define('xooie/widgets/dropdown', ['jquery', 'xooie/widgets/base', 'xooie/helpers'], function ($, Base, helpers) {
25
+ 'use strict';
25
26
 
27
+ function parseWhich(which) {
28
+ if (typeof which === 'string') {
29
+ which = which.split(',');
30
+ return which.map(function (string) { return parseInt(string, 10); });
31
+ }
26
32
 
27
- var parseWhich = function(which) {
28
- if (typeof which === 'string') {
29
- which = which.split(',');
30
- return which.map(function(string){ return parseInt(string, 10); });
31
- } else if (typeof which === 'number') {
32
- return [which];
33
- }
33
+ if (typeof which === 'number') {
34
+ return [which];
35
+ }
34
36
 
35
- return which;
36
- };
37
+ return which;
38
+ }
37
39
 
38
40
  /**
39
- * Xooie.Dropdown(element[, addons])
40
- * - element (Element | String): A jQuery-selected element or string selector for the root element of this widget
41
- * - addons (Array): An optional collection of [[Xooie.Addon]] classes to be instantiated with this widget
42
- *
43
- * Instantiates a new Dropdown widget. Creates event handlers to manage activating and deactivating the expanders.
44
- * Also adds methods to manipulate aria roles.
45
- **/
46
- var Dropdown = Base.extend(function() {
47
- var self = this,
48
- handles = self.getHandle(),
49
- expanders = self.getExpander();
41
+ * Xooie.Dropdown(element[, addons])
42
+ * - element (Element | String): A jQuery-selected element or string selector for the root element of this widget
43
+ * - addons (Array): An optional collection of [[Xooie.Addon]] classes to be instantiated with this widget
44
+ *
45
+ * Instantiates a new Dropdown widget. Creates event handlers to manage activating and deactivating the expanders.
46
+ * Also adds methods to manipulate aria roles.
47
+ **/
48
+ var Dropdown = Base.extend(function () {
49
+ var self, handles, expanders;
50
+
51
+ self = this;
52
+ handles = self.getHandle();
53
+ expanders = self.getExpander();
54
+
55
+ this.handlers = {
56
+ off: function (event) {
57
+ var check = false;
58
+
59
+ if (!helpers.isUndefined(event.data.not)) {
60
+ check = $(event.data.not).is($(this)) || $(event.target).parents(event.data.not).length > 0;
61
+ }
50
62
 
51
- this.handlers = {
52
- off: function(event){
53
- if ((typeof event.data.not !== 'undefined' && ($(event.data.not).is($(this)) || $(event.target).parents(event.data.not).length > 0)) || (typeof event.data.which !== 'undefined' && event.data.which.indexOf(event.which) === -1) || ($(event.target).is(self.getExpander(event.data.index)) || $(event.target).parents(self.dropdownExpanderSelector()).length > 0) && !$(event.target).is($(this))) {
54
- return true;
55
- }
63
+ if (!helpers.isUndefined(event.data.which)) {
64
+ check = check || event.data.which.indexOf(event.which) === -1;
65
+ }
56
66
 
57
- event.preventDefault();
67
+ check = check || ($(event.target).is(self.getExpander(event.data.index)) || $(event.target).parents(self.dropdownExpanderSelector()).length > 0);
68
+ check = check && !$(event.target).is($(this));
58
69
 
59
- self.collapse(event.data.index, event.data);
60
- },
70
+ if (check) {
71
+ return true;
72
+ }
61
73
 
62
- on: function(event){
63
- var index = event.data.index || parseInt($(this).attr('data-dropdown-index'), 10),
64
- delay = event.data.delay,
65
- handle = $(this);
74
+ event.preventDefault();
66
75
 
67
- if ((typeof event.data.not !== 'undefined' && ($(event.data.not).is($(this)) || $(event.target).parents(event.data.not).length > 0)) || typeof event.data.which !== 'undefined' && event.data.which.indexOf(event.which) === -1) {
68
- return true;
69
- }
76
+ self.collapse(event.data.index, event.data);
77
+ },
70
78
 
71
- event.preventDefault();
79
+ on: function (event) {
80
+ var index, check;
72
81
 
73
- self.expand(index, event.data);
74
- }
75
- };
82
+ index = event.data.index || parseInt($(this).attr('data-dropdown-index'), 10);
76
83
 
77
- this.timers = {
78
- expand: [],
79
- collapse: [],
80
- throttle: []
81
- };
84
+ if (!helpers.isUndefined(event.data.not)) {
85
+ check = $(event.data.not).is($(this));
86
+ check = check || $(event.target).parents(event.data.not).length > 0;
87
+ }
82
88
 
83
- this.addHandlers('on');
89
+ check = check || (!helpers.isUndefined(event.data.which) && event.data.which.indexOf(event.which) === -1);
84
90
 
85
- this.root().on({
86
- dropdownExpand: function(event, index){
87
- self.removeHandlers('on', index);
91
+ if (check) {
92
+ return true;
93
+ }
88
94
 
89
- self.addHandlers('off', index);
95
+ event.preventDefault();
90
96
 
91
- $(this).attr('aria-selected', true);
92
- self.getExpander(index).attr('aria-hidden', false);
93
- },
97
+ self.expand(index, event.data);
98
+ }
99
+ };
94
100
 
95
- dropdownCollapse: function(event, index){
96
- self.removeHandlers('off', index);
101
+ this.timers = {
102
+ expand: [],
103
+ collapse: [],
104
+ throttle: []
105
+ };
97
106
 
98
- self.addHandlers('on', index);
107
+ this.addHandlers('on');
99
108
 
100
- $(this).attr('aria-selected', false);
101
- self.getExpander(index).attr('aria-hidden', true);
102
- }
103
- }, this.dropdownHandleSelector());
109
+ this.root().on({
110
+ dropdownExpand: function (event, index) {
111
+ self.removeHandlers('on', index);
104
112
 
105
- this.root().on('xooie-init.dropdown xooie-refresh.dropdown', function(){
106
- handles.each(function(index){
107
- var handle = $(this),
108
- expander = expanders.eq(index);
113
+ self.addHandlers('off', index);
109
114
 
115
+ $(this).attr('aria-selected', true);
116
+ self.getExpander(index).attr('aria-hidden', false);
110
117
 
111
- handle.attr({
112
- 'data-dropdown-index': index,
113
- 'aria-selected': false
114
- });
115
- expander.attr({
116
- 'data-dropdown-index': index,
117
- 'aria-hidden': true
118
- });
119
- });
120
- });
118
+ event.preventDefault();
119
+ },
121
120
 
122
- expanders.on('mouseover focus', function(){
123
- var index = parseInt($(this).attr('data-dropdown-index'), 10);
121
+ dropdownCollapse: function (event, index) {
122
+ self.removeHandlers('off', index);
124
123
 
125
- if (self.timers.collapse[index]){
126
- self.timers.collapse[index] = clearTimeout(self.timers.collapse[index]);
124
+ self.addHandlers('on', index);
127
125
 
128
- $(this).on('mouseleave blur', {index: index}, function(event){
129
- self.collapse(event.data.index, 0);
130
- $(this).unbind(event);
131
- });
132
- }
133
- });
126
+ $(this).attr('aria-selected', false);
127
+ self.getExpander(index).attr('aria-hidden', true);
134
128
 
135
- });
129
+ event.preventDefault();
130
+ }
131
+ }, this.dropdownHandleSelector());
136
132
 
137
- Dropdown.define('namespace', 'dropdown');
133
+ this.root().on('xooie-init.dropdown xooie-refresh.dropdown', function () {
134
+ handles.each(function (index) {
135
+ var handle, expander;
138
136
 
139
- Dropdown.define('throttleDelay', 300);
137
+ handle = $(this);
138
+ expander = expanders.eq(index);
140
139
 
141
- Dropdown.define('triggers', {
142
- on: {
143
- focus: {
144
- delay: 0
145
- }
146
- },
147
- off: {
148
- blur: {
149
- delay: 0
150
- }
151
- }
140
+ handle.attr({
141
+ 'data-dropdown-index': index,
142
+ 'aria-selected': false
143
+ });
144
+ expander.attr({
145
+ 'data-dropdown-index': index,
146
+ 'aria-hidden': true
147
+ });
148
+ });
152
149
  });
153
150
 
154
- Dropdown.defineReadOnly('dropdownHandleSelector', '[data-role="dropdown-handle"]');
151
+ expanders.on('mouseover focus', function () {
152
+ var index = parseInt($(this).attr('data-dropdown-index'), 10);
155
153
 
156
- Dropdown.defineReadOnly('dropdownExpanderSelector', '[data-role="dropdown-content"]');
154
+ if (self.timers.collapse[index]) {
155
+ self.timers.collapse[index] = clearTimeout(self.timers.collapse[index]);
157
156
 
158
- Dropdown.defineReadOnly('activeDropdownClass', 'is-dropdown-active');
157
+ $(this).on('mouseleave blur', {index: index}, function (event) {
158
+ self.collapse(event.data.index, 0);
159
+ $(this).unbind(event);
160
+ });
161
+ }
162
+ });
163
+ });
159
164
 
160
- Dropdown.prototype.getTriggerHandle = function(triggerData, index){
161
- var handles = this.getHandle(index);
165
+ Dropdown.define('namespace', 'dropdown');
162
166
 
163
- if (triggerData.selector) {
164
- return triggerData.selector === 'document' ? $(document) : $(triggerData.selector);
165
- } else {
166
- return handles;
167
- }
168
- };
167
+ Dropdown.define('throttleDelay', 300);
168
+
169
+ Dropdown.define('triggers', {
170
+ on: {
171
+ focus: {
172
+ delay: 0
173
+ }
174
+ },
175
+ off: {
176
+ blur: {
177
+ delay: 0
178
+ }
179
+ }
180
+ });
181
+
182
+ Dropdown.defineReadOnly('dropdownHandleSelector', '[data-role="dropdown-handle"]');
169
183
 
170
- Dropdown.prototype.addHandlers = function(state, index){
171
- var trigger, handle, triggerData, countName;
184
+ Dropdown.defineReadOnly('dropdownExpanderSelector', '[data-role="dropdown-content"]');
172
185
 
173
- triggerData = this.triggers()[state];
186
+ Dropdown.defineReadOnly('activeDropdownClass', 'is-dropdown-active');
174
187
 
175
- for (trigger in triggerData) {
176
- if (typeof triggerData[trigger].which !== 'undefined') {
177
- triggerData[trigger].which = parseWhich(triggerData[trigger].which);
178
- }
188
+ Dropdown.prototype.getTriggerHandle = function (triggerData, index) {
189
+ var handles = this.getHandle(index);
179
190
 
180
- countName = [trigger,state,'count'].join('-');
191
+ if (triggerData.selector) {
192
+ return triggerData.selector === 'document' ? $(document) : $(triggerData.selector);
193
+ }
194
+ return handles;
195
+ };
181
196
 
182
- handle = this.getTriggerHandle(triggerData[trigger], index);
197
+ Dropdown.prototype.addHandlers = function (state, index) {
198
+ var trigger, handle, triggerData, countName;
183
199
 
184
- handle.data(countName, handle.data(countName) + 1 || 1);
200
+ triggerData = this.triggers()[state];
185
201
 
186
- handle.on(trigger, $.extend({delay: 0, index: index}, triggerData[trigger]), this.handlers[state]);
202
+ for (trigger in triggerData) {
203
+ if (triggerData.hasOwnProperty(trigger)) {
204
+ if (!helpers.isUndefined(triggerData[trigger].which)) {
205
+ triggerData[trigger].which = parseWhich(triggerData[trigger].which);
187
206
  }
188
- };
189
207
 
190
- Dropdown.prototype.removeHandlers = function(state, index){
191
- var trigger, handle, triggerData, countName, eventCount;
208
+ countName = [trigger, state, 'count'].join('-');
192
209
 
193
- triggerData = this.triggers()[state];
210
+ handle = this.getTriggerHandle(triggerData[trigger], index);
194
211
 
195
- for (trigger in triggerData) {
196
- handle = this.getTriggerHandle(triggerData[trigger], index);
212
+ handle.data(countName, handle.data(countName) + 1 || 1);
197
213
 
198
- countName = [trigger,state,'count'].join('-');
214
+ handle.on(trigger, $.extend({delay: 0, index: index}, triggerData[trigger]), this.handlers[state]);
215
+ }
216
+ }
217
+ };
199
218
 
200
- eventCount = handle.data(countName) - 1;
219
+ Dropdown.prototype.removeHandlers = function (state, index) {
220
+ var trigger, handle, triggerData, countName, eventCount;
201
221
 
202
- if (eventCount <= 0) {
203
- handle.unbind(trigger, this.handlers[state]);
222
+ triggerData = this.triggers()[state];
204
223
 
205
- handle.data(countName, 0);
206
- } else {
207
- handle.data(countName, eventCount);
208
- }
209
- }
210
- };
224
+ for (trigger in triggerData) {
225
+ if (triggerData.hasOwnProperty(trigger)) {
226
+ handle = this.getTriggerHandle(triggerData[trigger], index);
211
227
 
212
- Dropdown.prototype.getHandle = function(index){
213
- var handles = this.root().find(this.dropdownHandleSelector());
228
+ countName = [trigger, state, 'count'].join('-');
214
229
 
215
- return (typeof index !== 'undefined' && index >= 0) ? handles.eq(index) : handles;
216
- };
230
+ eventCount = handle.data(countName) - 1;
217
231
 
218
- Dropdown.prototype.getExpander = function(index){
219
- var selectorString;
232
+ if (eventCount <= 0) {
233
+ handle.unbind(trigger, this.handlers[state]);
220
234
 
221
- if (typeof index === 'undefined' || isNaN(index)) {
222
- selectorString = this.dropdownExpanderSelector();
235
+ handle.data(countName, 0);
223
236
  } else {
224
- selectorString = this.dropdownExpanderSelector() + '[data-dropdown-index="' + index + '"]';
237
+ handle.data(countName, eventCount);
225
238
  }
239
+ }
240
+ }
241
+ };
226
242
 
227
- return this.root().find(selectorString);
228
- };
243
+ Dropdown.prototype.getHandle = function (index) {
244
+ var handles = this.root().find(this.dropdownHandleSelector());
229
245
 
230
- Dropdown.prototype.setState = function(index, data, active){
231
- if (typeof index === 'undefined' || isNaN(index)) {
232
- return;
233
- }
246
+ return (!helpers.isUndefined(index) && index >= 0) ? handles.eq(index) : handles;
247
+ };
234
248
 
235
- var state = active ? 'expand' : 'collapse',
236
- counterState = active ? 'collapse' : 'expand',
237
- delay = data.delay;
249
+ Dropdown.prototype.getExpander = function (index) {
250
+ var selectorString;
238
251
 
239
- this.timers[counterState][index] = clearTimeout(this.timers[counterState][index]);
252
+ if (helpers.isUndefined(index) || isNaN(index)) {
253
+ selectorString = this.dropdownExpanderSelector();
254
+ } else {
255
+ selectorString = this.dropdownExpanderSelector() + '[data-dropdown-index="' + index + '"]';
256
+ }
240
257
 
241
- if (this.timers.throttle[index] || this.timers[state][index]) {
242
- return;
243
- }
258
+ return this.root().find(selectorString);
259
+ };
244
260
 
245
- this.timers[state][index] = setTimeout(function(i, _state, _active, _data) {
246
- var expander = this.getExpander(i),
247
- handle = this.getHandle(i),
248
- self = this;
261
+ Dropdown.prototype.setState = function (index, data, active) {
262
+ if (helpers.isUndefined(index) || isNaN(index)) {
263
+ return;
264
+ }
249
265
 
250
- this.timers[_state][i] = clearTimeout(this.timers[_state][i]);
266
+ var state, counterState, delay;
251
267
 
252
- expander.toggleClass(this.activeDropdownClass(), _active);
253
- this.getHandle(i).toggleClass(this.activeDropdownClass(), _active);
268
+ state = active ? 'expand' : 'collapse';
269
+ counterState = active ? 'collapse' : 'expand';
270
+ delay = data.delay;
254
271
 
255
- if (_active){
256
- handle.trigger('dropdownExpand', [i, _data]);
257
- } else {
258
- handle.trigger('dropdownCollapse', [i, _data]);
259
- }
272
+ this.timers[counterState][index] = clearTimeout(this.timers[counterState][index]);
260
273
 
261
- if (this.throttleDelay() > 0){
262
- this.timers.throttle[i] = setTimeout(function(){
263
- self.timers.throttle[i] = clearTimeout(self.timers.throttle[i]);
264
- }, this.throttleDelay());
265
- }
274
+ if (this.timers.throttle[index] || this.timers[state][index]) {
275
+ return;
276
+ }
266
277
 
267
- }.bind(this, index, state, active, data), delay);
268
- };
278
+ this.timers[state][index] = setTimeout(function (i, _state, _active, _data) {
279
+ var expander, handle, self;
269
280
 
270
- Dropdown.prototype.expand = function(index, data) {
271
- if (!this.getHandle(index).hasClass(this.activeDropdownClass())) {
272
- this.setState(index, data, true);
273
- }
274
- };
281
+ expander = this.getExpander(i);
282
+ handle = this.getHandle(i);
283
+ self = this;
275
284
 
276
- Dropdown.prototype.collapse = function(index, data) {
277
- if (this.getHandle(index).hasClass(this.activeDropdownClass())) {
278
- this.setState(index, data, false);
279
- }
280
- };
285
+ this.timers[_state][i] = clearTimeout(this.timers[_state][i]);
286
+
287
+ expander.toggleClass(this.activeDropdownClass(), _active);
288
+ this.getHandle(i).toggleClass(this.activeDropdownClass(), _active);
289
+
290
+ if (_active) {
291
+ handle.trigger('dropdownExpand', [i, _data]);
292
+ } else {
293
+ handle.trigger('dropdownCollapse', [i, _data]);
294
+ }
295
+
296
+ if (this.throttleDelay() > 0) {
297
+ this.timers.throttle[i] = setTimeout(function () {
298
+ self.timers.throttle[i] = clearTimeout(self.timers.throttle[i]);
299
+ }, this.throttleDelay());
300
+ }
301
+
302
+ }.bind(this, index, state, active, data), delay);
303
+ };
304
+
305
+ Dropdown.prototype.expand = function (index, data) {
306
+ if (!this.getHandle(index).hasClass(this.activeDropdownClass())) {
307
+ this.setState(index, data, true);
308
+ }
309
+ };
310
+
311
+ Dropdown.prototype.collapse = function (index, data) {
312
+ if (this.getHandle(index).hasClass(this.activeDropdownClass())) {
313
+ this.setState(index, data, false);
314
+ }
315
+ };
281
316
 
282
- return Dropdown;
317
+ return Dropdown;
283
318
  });