xooie 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  });