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.
@@ -5,8 +5,10 @@
5
5
  * This module exists to abstract common functionality so that it can be maintained in one place.
6
6
  * It is not intended to be used independently.
7
7
  **/
8
- define('xooie/shared', ['jquery'], function($){
8
+ define('xooie/shared', ['jquery', 'xooie/helpers'], function ($, helpers) {
9
+ 'use strict';
9
10
 
11
+ var shared;
10
12
  /** internal
11
13
  * Xooie.shared.propertyDetails(name) -> Object
12
14
  * - name (String): The name of the property
@@ -28,7 +30,7 @@ define('xooie/shared', ['jquery'], function($){
28
30
  * - **value** (String): The name of the internally stored value for this property.
29
31
  * `_name`
30
32
  **/
31
- function propertyDetails (name) {
33
+ function propertyDetails(name) {
32
34
  return {
33
35
  getter: '_get_' + name,
34
36
  setter: '_set_' + name,
@@ -48,23 +50,22 @@ define('xooie/shared', ['jquery'], function($){
48
50
  * (or [[Xooie.Addon#_definedProps]]). Adds a method called `name` to the prototype that allows this property to be set or
49
51
  * retrieved.
50
52
  **/
51
- function propertyDispatcher (name, prototype) {
53
+ function propertyDispatcher(name, prototype) {
52
54
  var prop = propertyDetails(name);
53
55
 
54
- if (typeof prototype[name] !== 'function') {
56
+ if (!helpers.isFunction(prototype[name])) {
55
57
  prototype._definedProps.push(name);
56
58
 
57
- prototype[name] = function(value) {
58
- if (typeof value === 'undefined') {
59
+ prototype[name] = function (value) {
60
+ if (helpers.isUndefined(value)) {
59
61
  return this[prop.getter]();
60
- } else {
61
- return this[prop.setter](value);
62
62
  }
63
+ return this[prop.setter](value);
63
64
  };
64
65
  }
65
66
  }
66
67
 
67
- var shared = {
68
+ shared = {
68
69
  /**
69
70
  * Xooie.shared.defineReadOnly(module, name[, defaultValue])
70
71
  * - module (Widget | Addon): The module on which this property will be defined.
@@ -74,7 +75,7 @@ define('xooie/shared', ['jquery'], function($){
74
75
  * Defines a read-only property that can be accessed either by [[Xooie.Widget#get]]/[[Xooie.Addon#get]] or
75
76
  * calling the `{{name}}` method on the instance of the module.
76
77
  **/
77
- defineReadOnly: function(module, name, defaultValue){
78
+ defineReadOnly: function (module, name, defaultValue) {
78
79
  var prop = propertyDetails(name);
79
80
 
80
81
  propertyDispatcher(name, module.prototype);
@@ -82,11 +83,11 @@ define('xooie/shared', ['jquery'], function($){
82
83
  //The default value is reset each time this method is called;
83
84
  module.prototype[prop.defaultValue] = defaultValue;
84
85
 
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];
86
+ if (!helpers.isFunction(module.prototype[prop.getter])) {
87
+ module.prototype[prop.getter] = function () {
88
+ var value = helpers.isUndefined(this[prop.value]) ? this[prop.defaultValue] : this[prop.value];
88
89
 
89
- if (typeof this[prop.processor] === 'function') {
90
+ if (helpers.isFunction(this[prop.processor])) {
90
91
  return this[prop.processor](value);
91
92
  }
92
93
 
@@ -102,42 +103,69 @@ define('xooie/shared', ['jquery'], function($){
102
103
  * Defines a write-only property that can be set using [[Xooie.Widget#set]]/[[Xooie.Addon#set]] or by passing
103
104
  * a value to the `{{name}}` method on the instance of the module.
104
105
  **/
105
- defineWriteOnly: function(module, name){
106
+ defineWriteOnly: function (module, name) {
106
107
  var prop = propertyDetails(name);
107
108
 
108
109
  propertyDispatcher(name, module.prototype);
109
110
 
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)) {
111
+ if (!helpers.isFunction(module.prototype[prop.setter])) {
112
+ module.prototype[prop.setter] = function (value) {
113
+ if (!helpers.isFunction(this[prop.validator]) || this[prop.validator](name)) {
113
114
  this[prop.value] = value;
114
115
  }
115
116
  };
116
117
  }
117
118
  },
118
119
  /**
119
- * Xooie.shared.extend(constr, _super) -> Widget | Addon
120
+ * Xooie.shared.create(constr, post_constr, _super) -> Widget | Addon
120
121
  * - 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
+ * - post_constr (Function): The optional constructor method to run after all constructors have run.
123
+ * - _super (Widget | Addon): The optional module which is to be extended
122
124
  *
123
125
  * Creates a new Xooie widget/addon class that inherits all properties from the extended class.
124
126
  * Constructors for the class are called in order from the top-level constructor to the
125
- * base constructor.
127
+ * base constructor followed by the post constructors from the base to top-level post constructor.
126
128
  **/
127
- extend: function(constr, module){
128
- var newModule = (function(){
129
+
130
+ create: function (constr, post_constr, _super) {
131
+ var newModule = (function () {
129
132
  return function Child() {
130
- module.apply(this, arguments);
131
- constr.apply(this, arguments);
132
- this._extendCount -= 1;
133
+ var i, result;
134
+
135
+ for (i = 0; i < Child._constructors.length; i += 1) {
136
+ result = Child._constructors[i].apply(this, arguments);
137
+
138
+ if (!helpers.isUndefined(result)) {
139
+ return result;
140
+ }
141
+ }
142
+
143
+ for (i = 0; i < Child._postConstructors.length; i += 1) {
144
+ Child._postConstructors[i].apply(this, arguments);
145
+ }
133
146
  };
134
- })();
135
-
147
+ }());
148
+
149
+ if (!helpers.isUndefined(_super)) {
150
+ $.extend(true, newModule, _super);
151
+ $.extend(true, newModule.prototype, _super.prototype);
152
+ }
153
+
154
+ if (helpers.isUndefined(newModule._constructors)) {
155
+ newModule._constructors = [];
156
+ }
136
157
 
137
- $.extend(true, newModule, module);
138
- $.extend(true, newModule.prototype, module.prototype);
158
+ if (constr) {
159
+ newModule._constructors.push(constr);
160
+ }
139
161
 
140
- newModule.prototype._extendCount = newModule.prototype._extendCount === null ? 1 : newModule.prototype._extendCount += 1;
162
+ if (helpers.isUndefined(newModule._postConstructors)) {
163
+ newModule._postConstructors = [];
164
+ }
165
+
166
+ if (post_constr) {
167
+ newModule._postConstructors.unshift(post_constr);
168
+ }
141
169
 
142
170
  return newModule;
143
171
  },
@@ -148,7 +176,7 @@ define('xooie/shared', ['jquery'], function($){
148
176
  *
149
177
  * Retrieves the value of the property. Returns `undefined` if the property has not been defined.
150
178
  **/
151
- get: function(instance, name){
179
+ get: function (instance, name) {
152
180
  var prop = propertyDetails(name);
153
181
 
154
182
  return instance[prop.getter]();
@@ -161,10 +189,10 @@ define('xooie/shared', ['jquery'], function($){
161
189
  *
162
190
  * Sets a property, so long as that property has been defined.
163
191
  **/
164
- set: function(instance, name, value){
192
+ set: function (instance, name, value) {
165
193
  var prop = propertyDetails(name);
166
194
 
167
- if (typeof instance[prop.setter] === 'function') {
195
+ if (helpers.isFunction(instance[prop.setter])) {
168
196
  instance[prop.setter](value);
169
197
  }
170
198
  },
@@ -176,12 +204,12 @@ define('xooie/shared', ['jquery'], function($){
176
204
  *
177
205
  * Sets the properties to the values specified, as long as the property has been defined
178
206
  **/
179
- setData: function(instance, data) {
207
+ setData: function (instance, data) {
180
208
  var i, prop;
181
209
 
182
- for (i = 0; i < instance._definedProps.length; i++) {
210
+ for (i = 0; i < instance._definedProps.length; i += 1) {
183
211
  prop = instance._definedProps[i];
184
- if (typeof data[prop] !== 'undefined') {
212
+ if (!helpers.isUndefined(data[prop])) {
185
213
  instance.set(prop, data[prop]);
186
214
  }
187
215
  }
@@ -14,120 +14,125 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- define('xooie/stylesheet', ['jquery', 'xooie/helpers'], function($, helpers) {
18
-
17
+ define('xooie/stylesheet', ['jquery', 'xooie/helpers'], function ($, helpers) {
18
+ 'use strict';
19
19
 
20
- function nameCheck (index, name) {
21
- return document.styleSheets[index].ownerNode.getAttribute('id') === name;
20
+ function nameCheck(index, name) {
21
+ var s = document.styleSheets[index];
22
+
23
+ if (!helpers.isUndefined(s.ownerNode)) {
24
+ return s.ownerNode.getAttribute('id') === name;
22
25
  }
26
+ return s.id === name;
27
+ }
23
28
 
24
- var Stylesheet = function(name){
25
- var title;
29
+ var Stylesheet = function (name) {
30
+ //check to see if a stylesheet already exists with this name
31
+ this.element = $('style[id=' + name + ']');
26
32
 
27
- //check to see if a stylesheet already exists with this name
28
- this.element = $('style[id=' + name + ']');
33
+ if (this.element.length <= 0) {
34
+ //if it does, use it, else create a new one
35
+ this.element = $(['<style id="' + name + '">',
36
+ '/* This is a dynamically generated stylesheet: ' + name + ' */',
37
+ '</style>'].join(''));
29
38
 
30
- if (this.element.length <= 0) {
31
- //if it does, use it, else create a new one
32
- this.element = $(['<style id="' + name + '">',
33
- '/* This is a dynamically generated stylesheet: ' + name + ' */',
34
- '</style>'].join(''));
39
+ this.element.appendTo($('head'));
40
+ }
35
41
 
36
- this.element.appendTo($('head'));
37
- }
42
+ this._name = name;
43
+ };
38
44
 
39
- this._name = name;
40
- };
45
+ Stylesheet.prototype.get = function () {
46
+ return document.styleSheets[this.getIndex()];
47
+ };
41
48
 
42
- Stylesheet.prototype.get = function(){
43
- return document.styleSheets[this.getIndex()];
44
- };
49
+ Stylesheet.prototype.getRule = function (ruleName) {
50
+ var i, rules;
45
51
 
46
- Stylesheet.prototype.getRule = function(ruleName){
47
- ruleName = ruleName.toLowerCase();
52
+ ruleName = ruleName.toLowerCase();
48
53
 
49
- var i, rules;
54
+ //Check if this uses the IE format (styleSheet.rules) or the Mozilla/Webkit format
55
+ rules = this.get().cssRules || this.get().rules;
50
56
 
51
- //Check if this uses the IE format (styleSheet.rules) or the Mozilla/Webkit format
52
- rules = this.get().cssRules || this.get().rules;
57
+ for (i = 0; i < rules.length; i += 1) {
58
+ if (rules[i].selectorText.toLowerCase() === ruleName) {
59
+ return rules[i];
60
+ }
61
+ }
53
62
 
54
- for (i = 0; i < rules.length; i += 1){
55
- if (rules[i].selectorText.toLowerCase() === ruleName) {
56
- return rules[i];
57
- }
58
- }
63
+ return false;
64
+ };
59
65
 
60
- return false;
61
- };
62
-
63
- Stylesheet.prototype.addRule = function(ruleName, properties){
64
- var rule = this.getRule(ruleName), index, prop, propString = '';
65
-
66
- if (!rule){
67
- for (prop in properties) {
68
- propString += prop + ': ' + properties[prop] + ';';
69
- }
70
-
71
- if (this.get().insertRule) {
72
- //This is the W3C-preferred method
73
- index = this.get().cssRules.length;
74
- this.get().insertRule(ruleName + ' {' + propString + '}', index);
75
- rule = this.get().cssRules[index];
76
- } else {
77
- //support for IE < 9
78
- index = this.get().rules.length;
79
- this.get().addRule(ruleName, propString, index);
80
- rule = this.get().rules[index];
81
- }
82
- }
66
+ Stylesheet.prototype.addRule = function (ruleName, properties) {
67
+ var rule = this.getRule(ruleName), index, prop, propString = '';
83
68
 
84
- return rule;
85
- };
69
+ if (!rule) {
70
+ for (prop in properties) {
71
+ if (properties.hasOwnProperty(prop)) {
72
+ propString += prop + ': ' + properties[prop] + ';';
73
+ }
74
+ }
75
+
76
+ if (this.get().insertRule) {
77
+ //This is the W3C-preferred method
78
+ index = this.get().cssRules.length;
79
+ this.get().insertRule(ruleName + ' {' + propString + '}', index);
80
+ rule = this.get().cssRules[index];
81
+ } else {
82
+ //support for IE < 9
83
+ index = this.get().rules.length;
84
+ this.get().addRule(ruleName, propString, index);
85
+ rule = this.get().rules[index];
86
+ }
87
+ }
86
88
 
87
- Stylesheet.prototype.deleteRule = function(ruleName){
88
- ruleName = ruleName.toLowerCase();
89
+ return rule;
90
+ };
89
91
 
90
- var i, rules;
92
+ Stylesheet.prototype.deleteRule = function (ruleName) {
93
+ var i, rules;
91
94
 
92
- //Check if this uses the IE format (styleSheet.rules) or the Mozilla/Webkit format
93
- rules = this.get().cssRules || this.get().rules;
95
+ ruleName = ruleName.toLowerCase();
94
96
 
95
- for (i = 0; i < rules.length; i += 1){
96
- if (rules[i].selectorText.toLowerCase() === ruleName) {
97
- if (this.get().deleteRule) {
98
- //this is the W3C-preferred method
99
- this.get().deleteRule(i);
100
- } else {
101
- //support for IE < 9
102
- this.get().removeRule(i);
103
- }
97
+ //Check if this uses the IE format (styleSheet.rules) or the Mozilla/Webkit format
98
+ rules = this.get().cssRules || this.get().rules;
104
99
 
105
- return true;
106
- }
100
+ for (i = 0; i < rules.length; i += 1) {
101
+ if (rules[i].selectorText.toLowerCase() === ruleName) {
102
+ if (this.get().deleteRule) {
103
+ //this is the W3C-preferred method
104
+ this.get().deleteRule(i);
105
+ } else {
106
+ //support for IE < 9
107
+ this.get().removeRule(i);
107
108
  }
108
109
 
109
- return false;
110
- };
110
+ return true;
111
+ }
112
+ }
111
113
 
112
- Stylesheet.prototype.getIndex = function() {
113
- var i;
114
+ return false;
115
+ };
114
116
 
115
- if (helpers.isUndefined(document.styleSheets)) {
116
- return;
117
- }
117
+ Stylesheet.prototype.getIndex = function () {
118
+ var i;
118
119
 
119
- if (!helpers.isUndefined(this._index) && nameCheck(this._index, this._name)) {
120
- return this._index;
121
- } else {
122
- for (i = 0; i < document.styleSheets.length; i += 1){
123
- if (nameCheck(i, this._name)) {
124
- this._index = i;
125
- return i;
126
- }
127
- }
128
- }
129
- };
120
+ if (helpers.isUndefined(document.styleSheets)) {
121
+ return;
122
+ }
123
+
124
+ if (!helpers.isUndefined(this._index) && nameCheck(this._index, this._name)) {
125
+ return this._index;
126
+ }
127
+
128
+ for (i = 0; i < document.styleSheets.length; i += 1) {
129
+ if (nameCheck(i, this._name)) {
130
+ this._index = i;
131
+ return i;
132
+ }
133
+ }
134
+ };
130
135
 
131
- return Stylesheet;
136
+ return Stylesheet;
132
137
 
133
138
  });
@@ -0,0 +1,125 @@
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/tab', ['jquery', 'xooie/base'], function($, Base) {
18
+
19
+ var Tab = Base('tab', function() {
20
+ var self = this;
21
+
22
+ this.createTabs();
23
+ });
24
+
25
+ Tab.setDefaultOptions({
26
+ panelSelector: '[data-role="tab-panel"]',
27
+ stripSelector: '[data-role="tab-strip"]',
28
+ controlSelector: '[data-role="tab-selector"]',
29
+ controlButtonSelector: '[data-tab-control]',
30
+ tabTemplateSelector: '[data-role="tab-template"]',
31
+
32
+ activeTabClass: 'is-tab-active'
33
+ });
34
+
35
+ $.extend(Tab.prototype, {
36
+ switchToTab: function(index, key) {
37
+ if (index !== this._currentTab && index >= 0 && index < this.getPanel().length) {
38
+ var e = $.Event('tabChange');
39
+ e.fromTab = this._currentTab;
40
+ e.toTab = index;
41
+ e.which = key;
42
+
43
+ this.getPanel(this._currentTab).removeClass(this.options.activeTabClass);
44
+ this.getTab(this._currentTab).removeClass(this.options.activeTabClass);
45
+
46
+ this.getPanel(index).addClass(this.options.activeTabClass);
47
+ this.getTab(index).addClass(this.options.activeTabClass);
48
+
49
+ this._currentTab = index;
50
+
51
+ this.root.trigger(e);
52
+ }
53
+ },
54
+
55
+ getPanel: function(index) {
56
+ var panels = this.root.find(this.options.panelSelector);
57
+
58
+ if (typeof index === 'undefined') {
59
+ return panels;
60
+ } else {
61
+ return panels.eq(index);
62
+ }
63
+ },
64
+
65
+ getTab: function(index) {
66
+ var tabs = this.root.find(this.options.controlSelector);
67
+ if (typeof index === 'undefined') {
68
+ return tabs;
69
+ } else {
70
+ return tabs.eq(index);
71
+ }
72
+ },
73
+
74
+ createTabs: function() {
75
+ var tabStrip = this.root.find(this.options.stripSelector),
76
+ template = this.root.find(this.options.tabTemplateSelector),
77
+ panels = this.getPanel(),
78
+ i, element, control,
79
+ activeTab = 0, handler, self = this;
80
+
81
+ if (template.length === 0){
82
+ return;
83
+ }
84
+
85
+ this.getTab().remove();
86
+
87
+ handler = function(event) {
88
+ var keys = [13,32];
89
+
90
+ if ([1,13,32].indexOf(event.which) !== -1){
91
+ self.switchToTab($(this).data('tab-index'), event.which);
92
+ }
93
+ };
94
+
95
+ for (i = 0; i < panels.length; i++) {
96
+ if(tabStrip.length > 0 && template.length > 0) {
97
+ element = this.render(template, {
98
+ panel_label: panels.eq(i).attr('data-tab-label'),
99
+ panel_index: i,
100
+ panel_has_next: (i < panels.length - 1)
101
+ });
102
+
103
+ if (element.is(this.options.controlButtonSelector)) {
104
+ control = element;
105
+ } else {
106
+ control = element.find(this.options.controlButtonSelector);
107
+ }
108
+
109
+ control.data('tab-index', i)
110
+ .on('mouseup keyup', handler);
111
+
112
+ tabStrip.append(element);
113
+ }
114
+
115
+ if (panels.eq(i).hasClass(this.options.activeTabClass)) {
116
+ activeTab = i;
117
+ }
118
+ }
119
+
120
+ this.switchToTab(activeTab);
121
+ }
122
+ });
123
+
124
+ return Tab;
125
+ });
@@ -1,6 +1,7 @@
1
- define('xooie/widgets/accordion', ['jquery', 'xooie/widgets/tab'], function($, Tab){
2
- var Accordion = Tab.extend(function() {
3
- });
1
+ define('xooie/widgets/accordion', ['xooie/widgets/tab'], function (Tab) {
2
+ 'use strict';
3
+
4
+ var Accordion = Tab.extend();
4
5
 
5
6
  Accordion.define('namespace', 'accordion');
6
7
 
@@ -10,7 +11,7 @@ define('xooie/widgets/accordion', ['jquery', 'xooie/widgets/tab'], function($, T
10
11
  *
11
12
  * 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
  **/
13
- Accordion.prototype._process_role_tablist = function(tablist) {
14
+ Accordion.prototype._process_role_tablist = function (tablist) {
14
15
  Tab.prototype._process_role_tablist.apply(this, arguments);
15
16
 
16
17
  tablist.attr('aria-multiselectable', true);
@@ -18,14 +19,13 @@ define('xooie/widgets/accordion', ['jquery', 'xooie/widgets/tab'], function($, T
18
19
  return tablist;
19
20
  };
20
21
 
21
- Accordion.prototype.selectTabs = function(event, selectedTab) {
22
+ Accordion.prototype.selectTabs = function (selectedTab) {
22
23
  var activeTabs = this.getActiveTabs();
23
24
 
24
25
  if (activeTabs.is(selectedTab)) {
25
26
  return activeTabs.not(selectedTab);
26
- } else {
27
- return activeTabs.add(selectedTab);
28
27
  }
28
+ return activeTabs.add(selectedTab);
29
29
  };
30
30
 
31
31
  return Accordion;