xooie 0.0.17.pre → 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjU5YmQyYzFiMWZjYjExMmE1MTU2YmE2MzJiYTYxMzRmZDBkNjdjYQ==
5
+ data.tar.gz: !binary |-
6
+ MTc0ZGNiYTFlMThmMjkzMTQ0YzZiNjBjYjk4YjQwMzJmNGJkZmZkMA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ M2M2Yjg2OWVlYjYxOTRiZDhjMzdmMGFlMmRhYjAzNzY3ZDYzNzA0MzYxMDA0
10
+ YmNjYWMyOWQ1MDUyZDc4M2RiOGFhNzYyZWZiMzY2Njg5YTMxNzg3OTMxYjVl
11
+ YWQ5MjcwMTNhYTI5MGE4MmViNDUxOWFiZDk0NWM5Y2ZjNzFiM2Y=
12
+ data.tar.gz: !binary |-
13
+ NmJkYTZiMWIxMWQzNDYwZDUwNTBlOGYzNWNkY2VjMjgzYjNkMzQwNjY0NmM2
14
+ YjYxN2U3NjljNDE0NTlhOTRiNjdmMWEyNGUwYjhjMGYzOTcwNzFiNzMzYzMy
15
+ Mjg1OTY4NzVkM2YyNWEzNjcyNmM1MWNlODQwNjlmN2FhOTI4ZmQ=
data/README.md CHANGED
@@ -30,6 +30,12 @@ Xooie will work by just loading xooie.js on your page; all other files will be l
30
30
 
31
31
  Instantiation happens automatically when the page is loaded. All HTML elements tagged with the "data-widget-type" attribute will offer the associated Xooie widget functionality.
32
32
 
33
+ 1.x vs 0.1.x:
34
+ ---
35
+ v1.0 is our official release of Xooie. All new feature development & bug fixes occur on [master](https://github.com/Comcast/Xooie) & are released from a release_1_x branch (e.g. [release_1_1](https://github.com/Comcast/Xooie/tree/release_1_1)). So if you're just getting started with Xooie, be sure to grab the latest 1.x version.
36
+
37
+ If you were already using a pre-1.0 release of Xooie, there is a [release_0_1_x branch](https://github.com/Comcast/Xooie/tree/release_0_1_x) that is updated with bug fixes only. Any 0.1.x release is from the pre-1.0 Xooie development work.
38
+
33
39
  Documentation:
34
40
  ---
35
41
  Carousel
@@ -45,7 +45,7 @@ define('xooie/carousel', ['jquery', 'xooie/base'], function($, Base) {
45
45
  this.positionUpdaters = {
46
46
 
47
47
  "item": function(quantity, direction) {
48
- var items = self.content.children(),
48
+ var items = self.content.children(':visible'),
49
49
  bias, offset,
50
50
  position = self.wrapper.scrollLeft(),
51
51
  i;
@@ -73,7 +73,7 @@ define('xooie/carousel', ['jquery', 'xooie/base'], function($, Base) {
73
73
 
74
74
  "px": function(quantity, direction) {
75
75
  var position;
76
-
76
+
77
77
  if (typeof direction === 'undefined') {
78
78
  position = 0;
79
79
  direction = 1;
@@ -199,7 +199,7 @@ define('xooie/carousel', ['jquery', 'xooie/base'], function($, Base) {
199
199
  //It is possible that images may load after the carousel has instantiated/
200
200
  //Also, this can be used for lazy-loading images
201
201
  //TODO: This can be problematic, since it is triggering update dimensions for each image load
202
- this.content.find('img').on('load', this.updateDimensions.bind(this));
202
+ this.content.find('img').first().on('load', this.updateDimensions.bind(this));
203
203
 
204
204
  carouselElements = carouselElements.add(this.root);
205
205
  });
@@ -244,7 +244,7 @@ define('xooie/carousel', ['jquery', 'xooie/base'], function($, Base) {
244
244
  };
245
245
 
246
246
  Carousel.prototype.currentItem = function(bias) {
247
- var i, items = this.content.children(),
247
+ var i, items = this.content.children(':visible'),
248
248
  position, itemWidth;
249
249
 
250
250
  if (typeof bias === 'undefined') {
@@ -366,7 +366,7 @@ define('xooie/carousel', ['jquery', 'xooie/base'], function($, Base) {
366
366
  if (this.isScrolling) {
367
367
  self.wrapper.stop(true,true);
368
368
  }
369
-
369
+
370
370
  callback();
371
371
 
372
372
  };
@@ -0,0 +1,83 @@
1
+ /*
2
+ * Copyright 2012 Comcast
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ define('xooie/event_handler', ['jquery', 'xooie/helpers'], function($, helpers) {
18
+
19
+ var EventHandler = function(namespace) {
20
+ this.namespace = namespace;
21
+
22
+ this.handlers = {};
23
+
24
+ this._callbacks = {};
25
+ };
26
+
27
+ function format(type, namespace) {
28
+ if (!namespace) {
29
+ return type;
30
+ } else {
31
+ return type + '.' + namespace;
32
+ }
33
+ }
34
+
35
+ EventHandler.prototype.add = function(type, method) {
36
+ var self = this,
37
+ formattedType, t;
38
+
39
+ if (helpers.isObject(type) && helpers.isUndefined(method)) {
40
+ for(t in type) {
41
+ if (helpers.isFunction(type[t])) {
42
+ this.add(t, type[t]);
43
+ }
44
+ }
45
+
46
+ return;
47
+ }
48
+
49
+ formattedType = format(type, this.namespace);
50
+
51
+ if (helpers.isUndefined(this.handlers[formattedType])) {
52
+ this.handlers[formattedType] = function(e) {
53
+ self.fire(e, this, arguments);
54
+ };
55
+ }
56
+
57
+ if (helpers.isUndefined(this._callbacks[type])) {
58
+ this._callbacks[type] = $.Callbacks('unique');
59
+ }
60
+
61
+ this._callbacks[type].add(method);
62
+ };
63
+
64
+ EventHandler.prototype.clear = function(type) {
65
+ delete(this.handlers[format(type, this.namespace)]);
66
+
67
+ if (!helpers.isUndefined(this._callbacks[type])) {
68
+ this._callbacks[type].empty();
69
+ }
70
+ };
71
+
72
+ EventHandler.prototype.fire = function(event, context, args) {
73
+ if (event.namespace && event.namespace !== this.namespace) {
74
+ return;
75
+ }
76
+
77
+ if (!helpers.isUndefined(this._callbacks[event.type])) {
78
+ this._callbacks[event.type].fireWith(context, args);
79
+ }
80
+ };
81
+
82
+ return EventHandler;
83
+ });
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Copyright 2012 Comcast
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * class Xooie.helpers
19
+ *
20
+ * A collection of helper methods used by Xooie modules.
21
+ **/
22
+
23
+ define('xooie/helpers', ['jquery'], function($){
24
+ var helpers = {};
25
+ /**
26
+ * Xooie.helpers.toAry(str) -> Array
27
+ * - str (String | Array): The string to be converted to an array, or an array.
28
+ *
29
+ * Converts a string to an array, or returns the passed argument if it is already an array. Used
30
+ * when parsing data attributes that can be either a space-delineated string or an array.
31
+ **/
32
+ helpers.toAry = function(str) {
33
+ if (typeof str === 'string') {
34
+ return str.split(/\s+/);
35
+ } else if (str instanceof Array) {
36
+ return str;
37
+ }
38
+ };
39
+
40
+ helpers.toInt = function(int) {
41
+ return parseInt(int, 10);
42
+ };
43
+
44
+ helpers.isArray = Array.isArray || function(ary) {
45
+ return Array.prototype.toString(ary) === '[object Array]';
46
+ };
47
+
48
+ helpers.isObject = function(obj) {
49
+ return Object.prototype.toString(obj) === '[object Object]';
50
+ };
51
+
52
+ helpers.isUndefined = function(obj) {
53
+ return obj === void 0;
54
+ };
55
+
56
+ helpers.isFunction = function(func) {
57
+ return typeof func === 'function';
58
+ };
59
+
60
+ return helpers;
61
+ });
@@ -0,0 +1,216 @@
1
+ define('xooie/keyboard_navigation', ['jquery', 'xooie/helpers'], function($, helpers){
2
+ var selectors, keyboardNavigation, keybindings;
3
+
4
+
5
+ keybindings = {
6
+ 37: function(event) {
7
+ moveFocus($(event.target), -1);
8
+
9
+ event.preventDefault();
10
+ },
11
+
12
+ 38: function() {
13
+
14
+ },
15
+
16
+ 39: function(event) {
17
+ moveFocus($(event.target), 1);
18
+
19
+ event.preventDefault();
20
+ },
21
+
22
+ 40: function() {
23
+
24
+ }
25
+ };
26
+
27
+ /** internal
28
+ * Xooie.Widget._moveFocus(direction)
29
+ * - direction (Integer): Determines whether or not to increment or decrement the index. Can be 1 or -1.
30
+ *
31
+ * Moves focus to either the next or previous focusable item, if available. Focus order follows the
32
+ * tab order of the page (items without tabindex or tabindex=0 will be focused before tabindex=1). Focusable
33
+ * items with a tabindex=-1 will not be focused.
34
+ **/
35
+ function moveFocus(current, direction) {
36
+ // TODO: Clean this up. It's a mess
37
+ // TODO: Write tests.
38
+ // TODO: Add detection of new contexts
39
+ // TODO: Add recollection of last focused item
40
+
41
+ var selector, selectors, tabindex, index, target;
42
+
43
+ var tabIndicies= [];
44
+
45
+ selectors = {
46
+ unindexed: ['[data-widget-type] a[href]:visible:not(:disabled):not([tabindex])',
47
+ '[data-widget-type] button:visible:not(:disabled):not([tabindex])',
48
+ '[data-widget-type] input:visible:not(:disabled):not([tabindex])',
49
+ '[data-widget-type] select:visible:not(:disabled):not([tabindex])',
50
+ '[data-widget-type] textarea:visible:not(:disabled):not([tabindex])',
51
+ '[data-widget-type] [tabindex=0]:visible:not(:disabled)'].join(','),
52
+ indexed: function(t) {
53
+ if (t > 0) {
54
+ return '[data-widget-type] [tabindex=' + t + ']:visible:not(:disabled)';
55
+ }
56
+ },
57
+ allIndexed: '[data-widget-type] [tabindex]:visible:not(:disabled)'
58
+ };
59
+
60
+ // jquery select the current item
61
+ current = $(current);
62
+
63
+ // we may not be focused on anything. If that's the case, focus on the first focusable item
64
+ if (!current.is(selectors.unindexed) && !current.is(selectors.allIndexed)) {
65
+ // get the lowest tabindex
66
+ $(selectors.allIndexed).each(function(){
67
+ var i = helpers.toInt($(this).attr('tabindex'));
68
+
69
+ if (tabIndicies.indexOf(i) === -1 && i > 0) {
70
+ tabIndicies.push(i);
71
+ }
72
+ });
73
+
74
+ if (tabIndicies.length > 0) {
75
+ tabIndicies.sort(function(a,b) { return a-b; });
76
+
77
+ target = $(selectors.indexed(tabIndicies[0])).first();
78
+ } else {
79
+ target = $(selectors.unindexed).first();
80
+ }
81
+
82
+ if (target.length > 0) {
83
+ target.focus();
84
+
85
+ return;
86
+ }
87
+ }
88
+
89
+ // get the current tabindex
90
+ tabindex = helpers.toInt(current.attr('tabindex'));
91
+
92
+ // check if tabindex is a number and not 0...
93
+ if (!tabindex) {
94
+ // if it is not, assume we're on an element that has no tab index and select other such elements
95
+ selector = selectors.unindexed;
96
+ } else {
97
+ // otherwise, select all items that are of the same tabindex
98
+ selector = selectors.indexed(tabindex);
99
+ }
100
+
101
+ // find the index of the current item
102
+ index = current.index(selector);
103
+
104
+ if (index + direction >= 0) {
105
+ // get the next/previous item
106
+ target = $(selector).eq(index + direction);
107
+
108
+ // Check to see if we have a valid target...
109
+ if (target.length > 0) {
110
+ // if it is, focus the target and return
111
+ target.focus();
112
+
113
+ return;
114
+ }
115
+ }
116
+
117
+ // if it is not, then we have several possibilities:
118
+
119
+ // If the direction is 1 and tabindex is not a number or 0, then we are at the end of the tab order. Do nothing.
120
+ if (direction === 1 && !tabindex) {
121
+ return;
122
+ // If the direction is 1 and the tabindex is a number, then we need to check for the presence of the next tabindex
123
+ } else if (direction === 1 && !isNaN(tabindex)) {
124
+ // Loop through all elements with a tab index
125
+ $(selectors.allIndexed).each(function() {
126
+ // Build a collection of all tab indicies greater than the current tab index:
127
+ var i = helpers.toInt($(this).attr('tabindex'));
128
+
129
+ if (i > tabindex && tabIndicies.indexOf(i) === -1 && i > 0) {
130
+ tabIndicies.push(i);
131
+ }
132
+ });
133
+
134
+ // If there are tab indicies that are greater than the current one...
135
+ if (tabIndicies.length > 0) {
136
+ // sort our tab indicies ascending
137
+ tabIndicies.sort(function(a, b) { return a-b; });
138
+
139
+ // we now have our new tab index
140
+ tabindex = tabIndicies[0];
141
+
142
+ // Get the first item of the new tab index
143
+ target = $(selectors.indexed(tabindex)).first();
144
+ } else {
145
+ // Otherwise, select the first unindexed item
146
+ target = $(selectors.unindexed).first();
147
+ }
148
+
149
+ } else if (direction === -1 && isNaN(tabindex)) {
150
+ // In this case, we are at the first non-indexed focusable item. We need to find the last indexed item.
151
+ // Loop through all elements with a tab index
152
+ $(selectors.allIndexed).each(function() {
153
+ var i = helpers.toInt($(this).attr('tabindex'));
154
+ // Build a collection of all tab indicies
155
+ if (tabIndicies.indexOf(i) === -1) {
156
+ tabIndicies.push(i);
157
+ }
158
+ });
159
+
160
+ if (tabIndicies.length > 0) {
161
+ // sort our tab indicies descending
162
+ tabIndicies.sort(function(a, b) { return b-a; });
163
+
164
+ // we now have our new tab index
165
+ tabindex = tabIndicies[0];
166
+
167
+ // Select the last indexed item
168
+ target = $(selectors.indexed(tabindex)).last();
169
+ }
170
+ } else if (direction === -1 && !isNaN(tabindex) && tabindex > 0) {
171
+ $(selectors.allIndexed).each(function(){
172
+ var i = helpers.toInt($(this).attr('tabindex'));
173
+
174
+ if (i < tabindex && tabIndicies.indexOf(i) === -1 && i > 0) {
175
+ tabIndicies.push(i);
176
+ }
177
+ });
178
+
179
+ if (tabIndicies.length > 0) {
180
+ // sort our tab indicies asceding
181
+ tabIndicies.sort(function(a, b) { return a-b; });
182
+
183
+ // we now have our new tab index
184
+ tabindex = tabIndicies[0];
185
+
186
+ // Select the last indexed item
187
+ target = $(selectors.indexed(tabindex)).last();
188
+ }
189
+ }
190
+
191
+ if (!helpers.isUndefined(target)) {
192
+ // assuming we have a target, focus it.
193
+ target.focus();
194
+ }
195
+
196
+ }
197
+
198
+ var instantiated;
199
+
200
+ keyboardNavigation = function(){
201
+ if (instantiated) {
202
+ return instantiated;
203
+ }
204
+
205
+ $(document).on('keyup', function(event) {
206
+ if (helpers.isFunction(keybindings[event.which])) {
207
+ keybindings[event.which](event);
208
+ }
209
+ });
210
+
211
+ instantiated = this;
212
+ };
213
+
214
+ return keyboardNavigation;
215
+
216
+ });
@@ -0,0 +1,193 @@
1
+ /**
2
+ * class Xooie.shared
3
+ *
4
+ * A module that contains functionality that is used both by [[Xooie.Widget]] and [[Xooie.Addon]]
5
+ * This module exists to abstract common functionality so that it can be maintained in one place.
6
+ * It is not intended to be used independently.
7
+ **/
8
+ define('xooie/shared', ['jquery'], function($){
9
+
10
+ /** internal
11
+ * Xooie.shared.propertyDetails(name) -> Object
12
+ * - name (String): The name of the property
13
+ *
14
+ * Generates a hash of attributes that will be used in setting and getting the property.
15
+ *
16
+ * ##### Return values
17
+ *
18
+ * - **getter** (String): The name of the internal getter method for this property.
19
+ * `_get_name`
20
+ * - **setter** (String): The name of the internal setter method for this property.
21
+ * `_set_name`
22
+ * - **processor** (String): The name of the internal processor method for this property.
23
+ * `_process_name`
24
+ * - **validator** (String): The name of the internal validator method for this property.
25
+ * `_validate_name`
26
+ * **default** (String): The name of the internally stored default value for this property.
27
+ * `_default_name`
28
+ * - **value** (String): The name of the internally stored value for this property.
29
+ * `_name`
30
+ **/
31
+ function propertyDetails (name) {
32
+ return {
33
+ getter: '_get_' + name,
34
+ setter: '_set_' + name,
35
+ processor: '_process_' + name,
36
+ validator: '_validate_' + name,
37
+ defaultValue: '_default_value_' + name,
38
+ value: '_' + name
39
+ };
40
+ }
41
+
42
+ /** internal
43
+ * Xooie.shared.propertyDispatcher(name, prototype)
44
+ * - name (String): The name of the property
45
+ * - prototype (Object): The prototype of the [[Xooie.Widget]] or [[Xooie.Addon]] for which the property is being set.
46
+ *
47
+ * Gets the [[Xooie.shared.propertyDetails]] for the property, adds the `name` to the list of [[Xooie.Widget#_definedProps]]
48
+ * (or [[Xooie.Addon#_definedProps]]). Adds a method called `name` to the prototype that allows this property to be set or
49
+ * retrieved.
50
+ **/
51
+ function propertyDispatcher (name, prototype) {
52
+ var prop = propertyDetails(name);
53
+
54
+ if (typeof prototype[name] !== 'function') {
55
+ prototype._definedProps.push(name);
56
+
57
+ prototype[name] = function(value) {
58
+ if (typeof value === 'undefined') {
59
+ return this[prop.getter]();
60
+ } else {
61
+ return this[prop.setter](value);
62
+ }
63
+ };
64
+ }
65
+ }
66
+
67
+ var shared = {
68
+ /**
69
+ * Xooie.shared.defineReadOnly(module, name[, defaultValue])
70
+ * - module (Widget | Addon): The module on which this property will be defined.
71
+ * - name (String): The name of the property to define as a read-only property.
72
+ * - defaultValue (Object): An optional default value.
73
+ *
74
+ * Defines a read-only property that can be accessed either by [[Xooie.Widget#get]]/[[Xooie.Addon#get]] or
75
+ * calling the `{{name}}` method on the instance of the module.
76
+ **/
77
+ defineReadOnly: function(module, name, defaultValue){
78
+ var prop = propertyDetails(name);
79
+
80
+ propertyDispatcher(name, module.prototype);
81
+
82
+ //The default value is reset each time this method is called;
83
+ module.prototype[prop.defaultValue] = defaultValue;
84
+
85
+ if (typeof module.prototype[prop.getter] !== 'function') {
86
+ module.prototype[prop.getter] = function() {
87
+ var value = typeof this[prop.value] !== 'undefined' ? this[prop.value] : this[prop.defaultValue];
88
+
89
+ if (typeof this[prop.processor] === 'function') {
90
+ return this[prop.processor](value);
91
+ }
92
+
93
+ return value;
94
+ };
95
+ }
96
+ },
97
+ /**
98
+ * Xooie.shared.defineWriteOnly(module, name)
99
+ * - module (Widget | Addon): The module on which this property will be defined.
100
+ * - name (String): The name of the property to define as a write-only property
101
+ *
102
+ * Defines a write-only property that can be set using [[Xooie.Widget#set]]/[[Xooie.Addon#set]] or by passing
103
+ * a value to the `{{name}}` method on the instance of the module.
104
+ **/
105
+ defineWriteOnly: function(module, name){
106
+ var prop = propertyDetails(name);
107
+
108
+ propertyDispatcher(name, module.prototype);
109
+
110
+ if (typeof module.prototype[prop.setter] !== 'function') {
111
+ module.prototype[prop.setter] = function(value){
112
+ if (typeof this[prop.validator] !== 'function' || this[prop.validator](name)) {
113
+ this[prop.value] = value;
114
+ }
115
+ };
116
+ }
117
+ },
118
+ /**
119
+ * Xooie.shared.extend(constr, _super) -> Widget | Addon
120
+ * - constr (Function): The constructor for the new [[Xooie.Widget]] or [[Xooie.Addon]] class.
121
+ * - _super (Widget | Addon): The module which is to be extended
122
+ *
123
+ * Creates a new Xooie widget/addon class that inherits all properties from the extended class.
124
+ * Constructors for the class are called in order from the top-level constructor to the
125
+ * base constructor.
126
+ **/
127
+ extend: function(constr, module){
128
+ var newModule = (function(){
129
+ return function Child() {
130
+ module.apply(this, arguments);
131
+ constr.apply(this, arguments);
132
+ this._extendCount -= 1;
133
+ };
134
+ })();
135
+
136
+
137
+ $.extend(true, newModule, module);
138
+ $.extend(true, newModule.prototype, module.prototype);
139
+
140
+ newModule.prototype._extendCount = newModule.prototype._extendCount === null ? 1 : newModule.prototype._extendCount += 1;
141
+
142
+ return newModule;
143
+ },
144
+ /**
145
+ * Xooie.shared.get(instance, name) -> object
146
+ * - instance (Widget | Addon): The instance from which the property is to be retrieved.
147
+ * - name (String): The name of the property to be retrieved.
148
+ *
149
+ * Retrieves the value of the property. Returns `undefined` if the property has not been defined.
150
+ **/
151
+ get: function(instance, name){
152
+ var prop = propertyDetails(name);
153
+
154
+ return instance[prop.getter]();
155
+ },
156
+ /**
157
+ * Xooie.shared.set(instance, name, value)
158
+ * - instance (Widget | Addon): The instance where the property is being set.
159
+ * - name (String): The name of the property to be set.
160
+ * - value: The value of the property to be set.
161
+ *
162
+ * Sets a property, so long as that property has been defined.
163
+ **/
164
+ set: function(instance, name, value){
165
+ var prop = propertyDetails(name);
166
+
167
+ if (typeof instance[prop.setter] === 'function') {
168
+ instance[prop.setter](value);
169
+ }
170
+ },
171
+
172
+ /**
173
+ * Xooie.shared.setData(instance, data)
174
+ * - instance (Widget | Addon): The instance to set data on
175
+ * - data (Object): A collection of key/value pairs
176
+ *
177
+ * Sets the properties to the values specified, as long as the property has been defined
178
+ **/
179
+ setData: function(instance, data) {
180
+ var i, prop;
181
+
182
+ for (i = 0; i < instance._definedProps.length; i++) {
183
+ prop = instance._definedProps[i];
184
+ if (typeof data[prop] !== 'undefined') {
185
+ instance.set(prop, data[prop]);
186
+ }
187
+ }
188
+ }
189
+
190
+ };
191
+
192
+ return shared;
193
+ });
@@ -0,0 +1,32 @@
1
+ define('xooie/widgets/accordion', ['jquery', 'xooie/widgets/tab'], function($, Tab){
2
+ var Accordion = Tab.extend(function() {
3
+ });
4
+
5
+ Accordion.define('namespace', 'accordion');
6
+
7
+ /** internal
8
+ * Xooie.Accordion#_process_role_tablist(tablist) -> Element
9
+ * - tablist (Element): A jQuery-selected collection of [[Xooie.Tab#tablists]]
10
+ *
11
+ * Same as [[Xooie.Tab#_process_role_tablist]] and also adds the [`aria-multiselectable="true"`](http://www.w3.org/TR/wai-aria/states_and_properties#aria-multiselectable) attribute.
12
+ **/
13
+ Accordion.prototype._process_role_tablist = function(tablist) {
14
+ Tab.prototype._process_role_tablist.apply(this, arguments);
15
+
16
+ tablist.attr('aria-multiselectable', true);
17
+
18
+ return tablist;
19
+ };
20
+
21
+ Accordion.prototype.selectTabs = function(event, selectedTab) {
22
+ var activeTabs = this.getActiveTabs();
23
+
24
+ if (activeTabs.is(selectedTab)) {
25
+ return activeTabs.not(selectedTab);
26
+ } else {
27
+ return activeTabs.add(selectedTab);
28
+ }
29
+ };
30
+
31
+ return Accordion;
32
+ });