xooie 0.0.17.pre → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +6 -0
- data/vendor/assets/javascripts/xooie/carousel.js +5 -5
- data/vendor/assets/javascripts/xooie/event_handler.js +83 -0
- data/vendor/assets/javascripts/xooie/helpers.js +61 -0
- data/vendor/assets/javascripts/xooie/keyboard_navigation.js +216 -0
- data/vendor/assets/javascripts/xooie/shared.js +193 -0
- data/vendor/assets/javascripts/xooie/widgets/accordion.js +32 -0
- data/vendor/assets/javascripts/xooie/widgets/base.js +628 -0
- data/vendor/assets/javascripts/xooie/widgets/carousel.js +769 -0
- data/vendor/assets/javascripts/xooie/widgets/dialog.js +132 -0
- data/vendor/assets/javascripts/xooie/widgets/dropdown.js +283 -0
- data/vendor/assets/javascripts/xooie/widgets/tab.js +355 -0
- data/vendor/assets/javascripts/xooie/xooie.js +282 -0
- metadata +33 -10
@@ -0,0 +1,355 @@
|
|
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.Tab < Xooie.Widget
|
19
|
+
*
|
20
|
+
* A widget that associates containers of information with "tabs". The pattern is
|
21
|
+
* designed to mimic the real-world concept of a filing cabinet, where content is
|
22
|
+
* stored in folders with protruding tabs that label said content.
|
23
|
+
*
|
24
|
+
* The Tab widget should be used as a way to organize how content is displayed
|
25
|
+
* visually. Content is hidden until the associated tab is activated.
|
26
|
+
**/
|
27
|
+
define('xooie/widgets/tab', ['jquery', 'xooie/helpers', 'xooie/widgets/base', 'xooie/event_handler'], function($, helpers, Base, EventHandler) {
|
28
|
+
|
29
|
+
function setSelection(widget, selectedTabs) {
|
30
|
+
var activeTabs = widget.getActiveTabs();
|
31
|
+
|
32
|
+
activeTabs.not(selectedTabs).each(function() {
|
33
|
+
widget.deactivateTab($(this));
|
34
|
+
});
|
35
|
+
|
36
|
+
selectedTabs.not(activeTabs).each(function() {
|
37
|
+
widget.activateTab($(this));
|
38
|
+
});
|
39
|
+
}
|
40
|
+
/**
|
41
|
+
* Xooie.Tab@xooie-tab-active(event)
|
42
|
+
* - event (Event): A jQuery event object
|
43
|
+
*
|
44
|
+
* An event that is fired when a tab is activated. Triggers on the `root` element of the widget.
|
45
|
+
*
|
46
|
+
* ##### Event Properties
|
47
|
+
* - **tabId** (String): The id of the tab that was activated.
|
48
|
+
**/
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Xooie.Tab@xooie-tab-inactive(event)
|
52
|
+
* - event (Event): A jQuery event object
|
53
|
+
*
|
54
|
+
* An event that is fired when a tab is deactivated. Triggers on the `root` element of the widget.
|
55
|
+
*
|
56
|
+
* ##### Event Properties
|
57
|
+
* - **tabId** (String): The id of the tab that was deactivated.
|
58
|
+
**/
|
59
|
+
|
60
|
+
/**
|
61
|
+
* new Xooie.Tab(element[, addons])
|
62
|
+
* - element (Element | String): A jQuery-selected element or string selector for the root element of this widget
|
63
|
+
* - addons (Array): An optional collection of [[Xooie.Addon]] classes to be instantiated with this widget
|
64
|
+
*
|
65
|
+
* Instantiates a new Tab instance. See [[Xooie.Widget]] for more functionality.
|
66
|
+
**/
|
67
|
+
var Tab = Base.extend(function(){
|
68
|
+
var self = this;
|
69
|
+
|
70
|
+
this._tabEvents = new EventHandler(this.namespace());
|
71
|
+
|
72
|
+
this._tabEvents.add({
|
73
|
+
keyup: function(event){
|
74
|
+
if ([13,32].indexOf(event.which) !== -1){
|
75
|
+
setSelection(self, self.selectTabs(event, $(this)));
|
76
|
+
|
77
|
+
event.preventDefault();
|
78
|
+
}
|
79
|
+
},
|
80
|
+
|
81
|
+
mouseup: function(event){
|
82
|
+
setSelection(self, self.selectTabs(event, $(this)));
|
83
|
+
},
|
84
|
+
|
85
|
+
click: function(event){
|
86
|
+
event.preventDefault();
|
87
|
+
}
|
88
|
+
});
|
89
|
+
|
90
|
+
// TODO: Test and document this. Also, create a property for data-activate
|
91
|
+
this.root().on(this.initEvent(), function(){
|
92
|
+
self.activateTab(self.tabs().filter('[data-activate="true"]'));
|
93
|
+
});
|
94
|
+
|
95
|
+
});
|
96
|
+
|
97
|
+
/** internal
|
98
|
+
* Xooie.Tab#_namespace -> String
|
99
|
+
*
|
100
|
+
* See [[Xooie.Widget#_namespace]].
|
101
|
+
* Default: `tab`.
|
102
|
+
**/
|
103
|
+
/**
|
104
|
+
* Xooie.Tab#namespace([value]) -> String
|
105
|
+
* - value: an optional value to be set.
|
106
|
+
*
|
107
|
+
* See [[Xooie.Widget#namespace]]
|
108
|
+
**/
|
109
|
+
Tab.define('namespace', 'tab');
|
110
|
+
|
111
|
+
/** internal
|
112
|
+
* Xooie.Tab#_tabSelector -> String
|
113
|
+
*
|
114
|
+
* An alternative selector for a [[Xooie.Tab#tabs]]. This allows developers to specify a tab control that may not
|
115
|
+
* be a child of the tab widget.
|
116
|
+
**/
|
117
|
+
/**
|
118
|
+
* Xooie.Tab#tabSelector([value]) -> String
|
119
|
+
* - value: an optional value to be set.
|
120
|
+
*
|
121
|
+
* The method for setting or getting [[Xooie.Tab#_tabSelector]]. Returns the current value of
|
122
|
+
* [[Xooie.Tab#_tabSelector]] if no value is passed or sets the value.
|
123
|
+
**/
|
124
|
+
Tab.define('tabSelector');
|
125
|
+
|
126
|
+
/** internal
|
127
|
+
* Xooie.Tab#_activeClass -> String
|
128
|
+
*
|
129
|
+
* A class string that is applied to active [[Xooie.Tab#tabs]] and [[Xooie.Tab#tabpanels]].
|
130
|
+
* Default: `is-tab-active`.
|
131
|
+
**/
|
132
|
+
/**
|
133
|
+
* Xooie.Tab#activeClass([value]) -> String
|
134
|
+
* - value: an optional value to be set.
|
135
|
+
*
|
136
|
+
* The method for setting or getting [[Xooie.Tab#_activeClass]]. Returns the current value of
|
137
|
+
* [[Xooie.Tab#_activeClass]] if no value is passed or sets the value.
|
138
|
+
**/
|
139
|
+
Tab.defineReadOnly('activeClass', 'is-tab-active');
|
140
|
+
|
141
|
+
/**
|
142
|
+
* Xooie.Tab#tabpanels() -> Elements
|
143
|
+
*
|
144
|
+
* Tabpanels are elements that contain the content that is shown or hidden when the corresponding
|
145
|
+
* [[Xooie.Tab#tabs]] is activated.
|
146
|
+
* This role maps to the ARIA [tab role](http://www.w3.org/TR/wai-aria/roles#tab)
|
147
|
+
**/
|
148
|
+
Tab.defineRole('tabpanel');
|
149
|
+
|
150
|
+
/**
|
151
|
+
* Xooie.Tab#tabs() -> Elements
|
152
|
+
*
|
153
|
+
* Tabs are elements that, when activated, also activate the corresponding [[Xooie.Tab#tabpanels]].
|
154
|
+
* This role maps to the ARIA [tabpanel role](http://www.w3.org/TR/wai-aria/roles#tabpanel).
|
155
|
+
**/
|
156
|
+
Tab.defineRole('tab');
|
157
|
+
|
158
|
+
/**
|
159
|
+
* Xooie.Tab#tablists() -> Elements
|
160
|
+
*
|
161
|
+
* A tablist is an element that contains all the [[Xooie.Tab#tabs]]. If any tabs are not decendants of
|
162
|
+
* the tablist, ownership of the tab is indicated using the `aria-owns` attribute.
|
163
|
+
* There should only be one tablist per tab widget.
|
164
|
+
* This role maps to the ARIA [tablist role](http://www.w3.org/TR/wai-aria/roles#tablist)
|
165
|
+
**/
|
166
|
+
Tab.defineRole('tablist');
|
167
|
+
|
168
|
+
/**
|
169
|
+
* Xooie.Tab#activateTab(tab)
|
170
|
+
* - tab (Element): One of the [[Xooie.Tab#tabs]] associated with this widget.
|
171
|
+
*
|
172
|
+
* Activates the [[Xooie.Tab#tabs]] by adding the [[Xooie.Tab#activeClass]] class and setting the `aria-expanded` property to 'true'.
|
173
|
+
* The method also activates the [[Xooie.Tab#tabpanels]] that is indicated by the tab's `aria-controls` attribute,
|
174
|
+
* adding the [[Xooie.Tab#activeClass]] class and setting `aria-expanded` to 'true'.
|
175
|
+
**/
|
176
|
+
Tab.prototype.activateTab = function(tab) {
|
177
|
+
tab.addClass(this.activeClass())
|
178
|
+
.attr('aria-selected', true);
|
179
|
+
|
180
|
+
$('#' + tab.attr('aria-controls')).addClass(this.activeClass())
|
181
|
+
.attr('aria-expanded', true)
|
182
|
+
.focus();
|
183
|
+
|
184
|
+
var e = $.Event('xooie-tab-active');
|
185
|
+
|
186
|
+
e.tabId = tab.attr('id');
|
187
|
+
|
188
|
+
this.root().trigger(e);
|
189
|
+
};
|
190
|
+
|
191
|
+
/**
|
192
|
+
* Xooie.Tab#deactivateTab(tab)
|
193
|
+
* - tab (Element): One of the [[Xooie.Tab#tabs]] associated with this widget.
|
194
|
+
*
|
195
|
+
* Deactivates the [[Xooie.Tab#tabs]] by removing the [[Xooie.Tab#activeClass]] class and setting the `aria-expanded` property to 'false'.
|
196
|
+
* The method also deactivates the [[Xooie.Tab#tabpanels]] that is indicated by the tab's `aria-controls` attribute,
|
197
|
+
* removing the [[Xooie.Tab#activeClass]] class and setting `aria-expanded` to 'false'.
|
198
|
+
**/
|
199
|
+
Tab.prototype.deactivateTab = function(tab) {
|
200
|
+
tab.removeClass(this.activeClass())
|
201
|
+
.attr('aria-selected', false);
|
202
|
+
|
203
|
+
$('#' + tab.attr('aria-controls')).removeClass(this.activeClass())
|
204
|
+
.attr('aria-expanded', false);
|
205
|
+
|
206
|
+
var e = $.Event('xooie-tab-inactive');
|
207
|
+
|
208
|
+
e.tabId = tab.attr('id');
|
209
|
+
|
210
|
+
this.root().trigger(e);
|
211
|
+
};
|
212
|
+
|
213
|
+
/**
|
214
|
+
* Xooie.Tab#selectTabs(event, selectedTab)
|
215
|
+
* - event (Event): Browser event that triggered selectTabs call
|
216
|
+
* - selectedTab (Element): Tab that was selected by a mouse or keyboard event
|
217
|
+
*
|
218
|
+
* Only called by mouse/keyboard event handlers to generate the list of
|
219
|
+
* currently active tabs. Should return a jQuery collection of tabs that are
|
220
|
+
* to be active. Any tabs which are currently active and not in the
|
221
|
+
* collection will be deactivated, and likewise any tabs not currently active
|
222
|
+
* and in the collection will be activated.
|
223
|
+
*
|
224
|
+
* Override this method to alter the behavior of the Tab widget.
|
225
|
+
**/
|
226
|
+
Tab.prototype.selectTabs = function(event, selectedTab) {
|
227
|
+
return selectedTab;
|
228
|
+
};
|
229
|
+
|
230
|
+
/**
|
231
|
+
* Xooie.Tab#getActiveTabs() -> Elements
|
232
|
+
*
|
233
|
+
* Returns a jQuery-selected collection of all [[Xooie.Tab#tabs]] that currently have the
|
234
|
+
* [[Xooie.Tab#activeClass]] class.
|
235
|
+
**/
|
236
|
+
Tab.prototype.getActiveTabs = function() {
|
237
|
+
return this.tabs().filter('.' + this.activeClass());
|
238
|
+
};
|
239
|
+
|
240
|
+
/** internal
|
241
|
+
* Xooie.Tab#_process_role_tab(tabs) -> Element
|
242
|
+
* - tabs (Element): A jQuery-selected collection of [[Xooie.Tab#tabs]]
|
243
|
+
*
|
244
|
+
* This method processes the elements that have been designated as [[Xooie.Tab#tabs]] with
|
245
|
+
* the `data-x-role="tab"` attribute. Tabs are given the [`role="tab"`](http://www.w3.org/TR/wai-aria/roles#tab) and [`aria-selected="false"`](http://www.w3.org/TR/wai-aria/states_and_properties#aria-selected)
|
246
|
+
* [ARIA](http://www.w3.org/TR/wai-aria/) attributes.
|
247
|
+
**/
|
248
|
+
Tab.prototype._process_role_tab = function(tabs){
|
249
|
+
var tabpanels = this.tabpanels(),
|
250
|
+
tab, panelId,
|
251
|
+
self = this;
|
252
|
+
|
253
|
+
tabs.attr('role', 'tab')
|
254
|
+
.attr('aria-selected', false);
|
255
|
+
|
256
|
+
tabs.each(function(index) {
|
257
|
+
tab = $(this);
|
258
|
+
panelId = tabpanels.eq(index).attr('id');
|
259
|
+
|
260
|
+
$(this).attr('aria-controls', panelId);
|
261
|
+
|
262
|
+
if ($(this).is('a')) {
|
263
|
+
$(this).attr('href', '#' + panelId);
|
264
|
+
}
|
265
|
+
|
266
|
+
});
|
267
|
+
|
268
|
+
tabs.on(this._tabEvents.handlers);
|
269
|
+
|
270
|
+
return tabs;
|
271
|
+
};
|
272
|
+
|
273
|
+
/** internal
|
274
|
+
* Xooie.Tab#_get_role_tab() -> Element
|
275
|
+
*
|
276
|
+
* Internal method used to retrieve the [[Xooie.Tab#tabs]] for this widget. If [[Xooie.Tab#tabSelector]] has been
|
277
|
+
* defined then its value will be used to select from the DOM. Otherwise, tabs will be selected from decendants of
|
278
|
+
* the root using the `[data-x-role="tab"]` selector.
|
279
|
+
**/
|
280
|
+
Tab.prototype._get_role_tab = function(){
|
281
|
+
if (!helpers.isUndefined(this.tabSelector())) {
|
282
|
+
return $(this.tabSelector());
|
283
|
+
} else {
|
284
|
+
return this.root().find('[data-x-role="tab"]');
|
285
|
+
}
|
286
|
+
};
|
287
|
+
|
288
|
+
/** internal
|
289
|
+
* Xooie.Tab#_render_role_tab() -> Elements
|
290
|
+
*
|
291
|
+
* TODO: Create this method to keep parity with the existing tab functionality
|
292
|
+
**/
|
293
|
+
Tab.prototype._render_role_tab = function(){
|
294
|
+
|
295
|
+
};
|
296
|
+
|
297
|
+
/** internal
|
298
|
+
* Xooie.Tab#_process_role_tablist(tablist) -> Element
|
299
|
+
* - tablist (Element): A jQuery-selected collection of [[Xooie.Tab#tablists]]
|
300
|
+
*
|
301
|
+
* This method processes the elements that have been designated as [[Xooie.Tab#tablists]] with
|
302
|
+
* the `data-x-role="tablist"` attribute. The tablist is given the [`role="tablist"`](http://www.w3.org/TR/wai-aria/roles#tablist)
|
303
|
+
* [ARIA](http://www.w3.org/TR/wai-aria/) attributes. If any [[Xooie.Tab#tabs]] are not decendants of the tab list, the ids of those
|
304
|
+
* tabs are added to the [`aria-owns`](http://www.w3.org/TR/wai-aria/states_and_properties#aria-owns) attribute.
|
305
|
+
**/
|
306
|
+
Tab.prototype._process_role_tablist = function(tablist) {
|
307
|
+
var tabs = this.tabs();
|
308
|
+
|
309
|
+
tablist.attr('role', 'tablist');
|
310
|
+
|
311
|
+
tabs.each(function(index) {
|
312
|
+
var owns, id;
|
313
|
+
if (tablist.has(this).length === 0) {
|
314
|
+
owns = tablist.attr('aria-owns') || '';
|
315
|
+
|
316
|
+
owns = owns.split(' ');
|
317
|
+
|
318
|
+
id = $(this).attr('id');
|
319
|
+
|
320
|
+
if (owns.indexOf(id) === -1) {
|
321
|
+
owns.push(id);
|
322
|
+
}
|
323
|
+
|
324
|
+
tablist.attr('aria-owns', owns.join(' '));
|
325
|
+
}
|
326
|
+
});
|
327
|
+
|
328
|
+
return tablist;
|
329
|
+
};
|
330
|
+
/** internal
|
331
|
+
* Xooie.Tab#_render_role_tablist() -> Element
|
332
|
+
*
|
333
|
+
* TODO: Add this method to render the tablist if it is not included.
|
334
|
+
**/
|
335
|
+
Tab.prototype._render_role_tablist = function(){
|
336
|
+
return $('<ul data-x-role="tablist"></ul>');
|
337
|
+
};
|
338
|
+
|
339
|
+
/** internal
|
340
|
+
* Xooie.Tab#_process_role_tabpanel(tabpanels) -> Element
|
341
|
+
* - tabpanels (Element): A jQuery-selected collection of [[Xooie.Tab#tabpanels]]
|
342
|
+
*
|
343
|
+
* This method processes the elements that have been designated as [[Xooie.Tab#tabpanels]] with
|
344
|
+
* the `data-x-role="tabpanel"` attribute. Tabs are given the [`role="tabpanel"`](http://www.w3.org/TR/wai-aria/roles#tab) and [`aria-expanded="false"`](http://www.w3.org/TR/wai-aria/states_and_properties#aria-selected)
|
345
|
+
* [ARIA](http://www.w3.org/TR/wai-aria/) attributes.
|
346
|
+
**/
|
347
|
+
Tab.prototype._process_role_tabpanel = function(tabpanels) {
|
348
|
+
tabpanels.attr('role', 'tabpanel')
|
349
|
+
.attr('aria-expanded', false);
|
350
|
+
|
351
|
+
return tabpanels;
|
352
|
+
};
|
353
|
+
|
354
|
+
return Tab;
|
355
|
+
});
|
@@ -0,0 +1,282 @@
|
|
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
|
+
var $X, Xooie;
|
18
|
+
|
19
|
+
/** alias of: $X
|
20
|
+
* Xooie
|
21
|
+
*
|
22
|
+
* Xooie is a JavaScript UI widget library.
|
23
|
+
**/
|
24
|
+
|
25
|
+
/**
|
26
|
+
* $X(element)
|
27
|
+
* - element (Element | String): A jQuery collection or string representing the DOM element to be
|
28
|
+
* instantiated as a Xooie widget.
|
29
|
+
*
|
30
|
+
* Traverses the DOM, starting from the element passed to the method, and instantiates a Xooie
|
31
|
+
* widget for every element that has a data-widget-type attribute.
|
32
|
+
**/
|
33
|
+
|
34
|
+
$X = Xooie = (function(static_config) {
|
35
|
+
var config = {
|
36
|
+
widgets: {},
|
37
|
+
addons: {}
|
38
|
+
},
|
39
|
+
obj = function() {
|
40
|
+
return false;
|
41
|
+
},
|
42
|
+
gcTimer = null;
|
43
|
+
|
44
|
+
function copyObj(dst, src) {
|
45
|
+
var name;
|
46
|
+
|
47
|
+
for (name in src) {
|
48
|
+
if (src.hasOwnProperty(name)) {
|
49
|
+
dst[name] = src[name];
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
function gcCallback() {
|
55
|
+
if (typeof Xooie.cleanup !== 'undefined') {
|
56
|
+
Xooie.cleanup();
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
/**
|
61
|
+
* $X.config(options)
|
62
|
+
* - options (Object): An object that describes the configuration options for Xooie.
|
63
|
+
*
|
64
|
+
* Defines the url strings for Xooie modules that will be used to require said modules.
|
65
|
+
*
|
66
|
+
* ##### Options
|
67
|
+
*
|
68
|
+
* - **root** (String): The location of all Xooie files.
|
69
|
+
* Default: `xooie`.
|
70
|
+
* - **widgets** (Object): Defines the location of widgets. By default, Xooie will look for widgets in the
|
71
|
+
* '/widgets' directory, relative to the `{root}`.
|
72
|
+
* - **addons** (Object): Defines the location of addons. By default, Xooie will look for addons in the
|
73
|
+
* '/addons' directory, relative to the `{root}`.
|
74
|
+
* - **cleanupInterval** (Integer): Defines the interval at which Xooie checks for instantiated widgets that are
|
75
|
+
* no longer active in the DOM. A value of '0' means no cleanup occurs.
|
76
|
+
* Default: `0`.
|
77
|
+
**/
|
78
|
+
|
79
|
+
obj.config = function(options) {
|
80
|
+
var name;
|
81
|
+
|
82
|
+
for (name in options) {
|
83
|
+
if (options.hasOwnProperty(name)) {
|
84
|
+
if (name === 'widgets' || name == 'addons') {
|
85
|
+
copyObj(config[name], options[name]);
|
86
|
+
} else {
|
87
|
+
config[name] = options[name];
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
if (typeof options.cleanupInterval !== 'undefined') {
|
93
|
+
gcTimer = clearInterval(gcTimer);
|
94
|
+
|
95
|
+
if (config.cleanupInterval > 0) {
|
96
|
+
gcTimer = setInterval(gcCallback, config.cleanupInterval);
|
97
|
+
}
|
98
|
+
}
|
99
|
+
};
|
100
|
+
|
101
|
+
/** internal
|
102
|
+
* $X._mapName(name, type) -> String
|
103
|
+
* - name (String): The name of the module, as determeined by the `data-widget-type` or `data-addons` properties.
|
104
|
+
* - type (String): The type of module. Can be either `'widget'` or `'addon'`
|
105
|
+
*
|
106
|
+
* Maps the name of the widget or addon to the correct url string where the module file is located.
|
107
|
+
**/
|
108
|
+
|
109
|
+
obj._mapName = function(name, type) {
|
110
|
+
if (typeof config[type][name] === 'undefined') {
|
111
|
+
return [config.root, '/', type, '/', name].join('');
|
112
|
+
} else {
|
113
|
+
return config[type][name];
|
114
|
+
}
|
115
|
+
};
|
116
|
+
|
117
|
+
obj.config({
|
118
|
+
root: 'xooie',
|
119
|
+
cleanupInterval: 0
|
120
|
+
});
|
121
|
+
|
122
|
+
if (static_config) {
|
123
|
+
obj.config(static_config);
|
124
|
+
}
|
125
|
+
|
126
|
+
return obj;
|
127
|
+
}(Xooie));
|
128
|
+
|
129
|
+
define('xooie/xooie', ['jquery', 'xooie/helpers', 'xooie/stylesheet'], function($, helpers, Stylesheet){
|
130
|
+
var config = Xooie.config,
|
131
|
+
_mapName = Xooie._mapName,
|
132
|
+
widgetSelector = '[data-widget-type]';
|
133
|
+
widgetDataAttr = 'widgetType';
|
134
|
+
addonDataAttr = 'addons';
|
135
|
+
|
136
|
+
$X = Xooie = function(element){
|
137
|
+
var nodes, moduleNames, moduleUrls,
|
138
|
+
node, url,
|
139
|
+
i, j;
|
140
|
+
|
141
|
+
element = $(element);
|
142
|
+
|
143
|
+
// Find all elements labeled as widgets:
|
144
|
+
nodes = element.find(widgetSelector);
|
145
|
+
|
146
|
+
// If the element is also tagged, add it to the collection:
|
147
|
+
if (element.is(widgetSelector)){
|
148
|
+
nodes = nodes.add(element);
|
149
|
+
}
|
150
|
+
|
151
|
+
// This array will be the list of unique modules to load:
|
152
|
+
moduleUrls = [];
|
153
|
+
|
154
|
+
// Iterate through each item in the collection:
|
155
|
+
for(i = 0; i < nodes.length; i+=1) {
|
156
|
+
node = $(nodes[i]);
|
157
|
+
|
158
|
+
// Add all of the widget types to the list of modules we need:
|
159
|
+
moduleNames = helpers.toAry(node.data(widgetDataAttr));
|
160
|
+
|
161
|
+
// For each widget we check to see if the url is already in our
|
162
|
+
// list of urls to require:
|
163
|
+
for (j = 0; j < moduleNames.length; j+=1) {
|
164
|
+
url = $X._mapName(moduleNames[j], 'widgets');
|
165
|
+
|
166
|
+
if (moduleUrls.indexOf(url) === -1) {
|
167
|
+
moduleUrls.push(url);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
// Do the same with each addon name:
|
172
|
+
moduleNames = helpers.toAry(node.data(addonDataAttr)) || [];
|
173
|
+
|
174
|
+
for (j = 0; j < moduleNames.length; j+=1) {
|
175
|
+
url = $X._mapName(moduleNames[j], 'addons');
|
176
|
+
|
177
|
+
if (moduleUrls.indexOf(url) === -1) {
|
178
|
+
moduleUrls.push(url);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
// Now that we have a list of urls to load, let's load them:
|
184
|
+
require(moduleUrls, function(){
|
185
|
+
var widgets, addons, node,
|
186
|
+
addonMods, widgetMod, argIndex,
|
187
|
+
i, j, k;
|
188
|
+
|
189
|
+
// We need to iterate through our collection of nodes again:
|
190
|
+
for (i = 0; i < nodes.length; i+=1) {
|
191
|
+
node = $(nodes[i]);
|
192
|
+
|
193
|
+
// This time, we're keeping track of our addons and widges separately:
|
194
|
+
widgets = helpers.toAry(node.data(widgetDataAttr));
|
195
|
+
addons = helpers.toAry(node.data(addonDataAttr)) || [];
|
196
|
+
|
197
|
+
// Iterate through each widget type:
|
198
|
+
for (j = 0; j < widgets.length; j+=1) {
|
199
|
+
|
200
|
+
// Get the index of this module from the moduleUrls:
|
201
|
+
argIndex = moduleUrls.indexOf($X._mapName(widgets[j], 'widgets'));
|
202
|
+
|
203
|
+
//Get the widget that we'll be instantiating:
|
204
|
+
widgetMod = arguments[argIndex];
|
205
|
+
|
206
|
+
addonMods = [];
|
207
|
+
|
208
|
+
// Now get each addon that we'll instantiate with the widget:
|
209
|
+
for (k = 0; k < addons.length; k+=1) {
|
210
|
+
// Get the index of the addon module from moduleUrls:
|
211
|
+
argIndex = moduleUrls.indexOf($X._mapName(addons[k], 'addons'));
|
212
|
+
|
213
|
+
addonMods.push(arguments[argIndex]);
|
214
|
+
}
|
215
|
+
|
216
|
+
// Instantiate the new instance using the argIndex to find the right module:
|
217
|
+
new widgetMod(node, addonMods);
|
218
|
+
}
|
219
|
+
}
|
220
|
+
});
|
221
|
+
};
|
222
|
+
|
223
|
+
Xooie.config = config;
|
224
|
+
Xooie._mapName = _mapName;
|
225
|
+
|
226
|
+
/** internal, read-only
|
227
|
+
* $X._stylesheet -> Object
|
228
|
+
*
|
229
|
+
* An instance of the [[Stylesheet]] class used to manipluate a dynamically created Xooie stylesheet
|
230
|
+
**/
|
231
|
+
Xooie._stylesheet = new Stylesheet('Xooie');
|
232
|
+
|
233
|
+
/** internal
|
234
|
+
* $X._styleRules -> Object
|
235
|
+
*
|
236
|
+
* A cache of css rules defined by the [[Xooie.Widget.createStyleRule]] method.
|
237
|
+
**/
|
238
|
+
Xooie._styleRules = {};
|
239
|
+
|
240
|
+
/** internal
|
241
|
+
* $X._instanceCache -> Array
|
242
|
+
*
|
243
|
+
* A collection of currently instantiated widgets.
|
244
|
+
**/
|
245
|
+
Xooie._instanceCache = [];
|
246
|
+
|
247
|
+
/** internal
|
248
|
+
* $X._instanceIndex -> Integer
|
249
|
+
*
|
250
|
+
* Tracks the next available instance index in the cache. This value also serves as the id of the
|
251
|
+
* next instantiated widget.
|
252
|
+
**/
|
253
|
+
Xooie._instanceIndex = 0;
|
254
|
+
|
255
|
+
/**
|
256
|
+
* $X.cleanup()
|
257
|
+
*
|
258
|
+
* Checks all instantiated widgets to ensure that the root element is still in the DOM. If the
|
259
|
+
* root element is no longer in the DOM, the module is garbage collected.
|
260
|
+
**/
|
261
|
+
|
262
|
+
Xooie.cleanup = function() {
|
263
|
+
var i, instance;
|
264
|
+
|
265
|
+
for (i = 0; i < $X._instanceCache.length; i++) {
|
266
|
+
instance = $X._instanceCache[i];
|
267
|
+
|
268
|
+
if (instance.root() && instance.root().parents('body').length === 0) {
|
269
|
+
instance.cleanup();
|
270
|
+
delete $X._instanceCache[i];
|
271
|
+
}
|
272
|
+
}
|
273
|
+
};
|
274
|
+
|
275
|
+
return Xooie;
|
276
|
+
});
|
277
|
+
|
278
|
+
require(['jquery', 'xooie/xooie'], function($, $X){
|
279
|
+
$(document).ready(function() {
|
280
|
+
$X($(this));
|
281
|
+
});
|
282
|
+
});
|