mui-sass 0.1.19 → 0.1.20

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2fd0efddb4858bf77210c5234be75b7501a53757
4
- data.tar.gz: f5e4ad14d40016269391859ba7c43526e042a12e
3
+ metadata.gz: 640d381821e1324ed59ddc19482df5491f0e7334
4
+ data.tar.gz: 8057fb802c38951958c1787ae6d593a42d5901c0
5
5
  SHA512:
6
- metadata.gz: ebb593ac163b5dfb8d8779034a293f0cd1d8ae0e2d97c00be618c0f31a6faa026b7e92fb5e867066125a5ceafd83c54616c0413f6a8d5ea892e60f5f0a9d6ca9
7
- data.tar.gz: 3a575d3b24fabab3624382463a7774bca6871d2b9fd1c598cb7664d5727a9991a15200ccbca6e956ef29616b9675b7038eda2261454995a10eae97161ea1cd13
6
+ metadata.gz: 0fa53095c60121fd5c078364654f2d1412832ef2b15886b9ef57e9c1db66dabf74720e5d4a7751edab7b293f2a151d006b8ba4ffd97bfca039a6d36264280402
7
+ data.tar.gz: 284549e1faa915e1bddf20a128be37227e84a6c434011e2c5f6dfcfb792c604254838d8709db0fccddd4f943589d179656d3f713b11da82334aea173560105f0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.1.20 (2015-08-05)
2
+
3
+ Framework version: MUI v0.1.20
4
+
1
5
  ## 0.1.19 (2015-07-28)
2
6
 
3
7
  - Initial release
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # MUI for Sass
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/mui-sass.svg)](http://badge.fury.io/rb/mui-sass)
4
+ [![Build Status](https://travis-ci.org/rubysamurai/mui-sass.svg?branch=master)](https://travis-ci.org/rubysamurai/mui-sass)
5
+
3
6
  `mui-sass` is a Sass-powered version of [MUI framework](https://www.muicss.com/) for your Ruby applications. It works with Ruby on Rails, Compass, Sprockets, etc.
4
7
 
5
8
  ## Installation
data/Rakefile CHANGED
@@ -1 +1,4 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ task default: :spec
4
+ RSpec::Core::RakeTask.new
@@ -1,5 +1,5 @@
1
1
  module Mui
2
2
  module Sass
3
- VERSION = '0.1.19'
3
+ VERSION = '0.1.20'
4
4
  end
5
5
  end
@@ -1,1141 +1,3 @@
1
- (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
- /**
3
- * MUI config module
4
- * @module config
5
- */
6
-
7
- /** Define module API */
8
- module.exports = {
9
- /** Use debug mode */
10
- debug: true
11
- };
12
-
13
- },{}],2:[function(require,module,exports){
14
- /**
15
- * MUI CSS/JS dropdown module
16
- * @module dropdowns
17
- */
18
-
19
- 'use strict';
20
-
21
-
22
- var jqLite = require('./lib/jqLite.js'),
23
- util = require('./lib/util.js'),
24
- attrKey = 'data-mui-toggle',
25
- attrSelector = '[data-mui-toggle="dropdown"]',
26
- openClass = 'mui-open',
27
- menuClass = 'mui-dropdown-menu';
28
-
29
-
30
- /**
31
- * Initialize toggle element.
32
- * @param {Element} toggleEl - The toggle element.
33
- */
34
- function initialize(toggleEl) {
35
- // check flag
36
- if (toggleEl._muiDropdown === true) return;
37
- else toggleEl._muiDropdown = true;
38
-
39
- // attach click handler
40
- jqLite.on(toggleEl, 'click', clickHandler);
41
- }
42
-
43
-
44
- /**
45
- * Handle click events on dropdown toggle element.
46
- * @param {Event} ev - The DOM event
47
- */
48
- function clickHandler(ev) {
49
- // only left clicks
50
- if (ev.button !== 0) return;
51
-
52
- var toggleEl = this;
53
-
54
- // exit if toggle button is disabled
55
- if (toggleEl.getAttribute('disabled') !== null) return;
56
-
57
- // prevent form submission
58
- ev.preventDefault();
59
- ev.stopPropagation();
60
-
61
- // toggle dropdown
62
- toggleDropdown(toggleEl);
63
- }
64
-
65
-
66
- /**
67
- * Toggle the dropdown.
68
- * @param {Element} toggleEl - The dropdown toggle element.
69
- */
70
- function toggleDropdown(toggleEl) {
71
- var wrapperEl = toggleEl.parentNode,
72
- menuEl = toggleEl.nextElementSibling,
73
- doc = wrapperEl.ownerDocument;
74
-
75
- // exit if no menu element
76
- if (!menuEl || !jqLite.hasClass(menuEl, menuClass)) {
77
- return util.raiseError('Dropdown menu element not found');
78
- }
79
-
80
- // method to close dropdown
81
- function closeDropdownFn() {
82
- jqLite.removeClass(menuEl, openClass);
83
-
84
- // remove event handlers
85
- jqLite.off(doc, 'click', closeDropdownFn);
86
- }
87
-
88
- // method to open dropdown
89
- function openDropdownFn() {
90
- // position menu element below toggle button
91
- var wrapperRect = wrapperEl.getBoundingClientRect(),
92
- toggleRect = toggleEl.getBoundingClientRect();
93
-
94
- var top = toggleRect.top - wrapperRect.top + toggleRect.height;
95
- jqLite.css(menuEl, 'top', top + 'px');
96
-
97
- // add open class to wrapper
98
- jqLite.addClass(menuEl, openClass);
99
-
100
- // close dropdown when user clicks outside of menu
101
- jqLite.on(doc, 'click', closeDropdownFn);
102
- }
103
-
104
- // toggle dropdown
105
- if (jqLite.hasClass(menuEl, openClass)) closeDropdownFn();
106
- else openDropdownFn();
107
- }
108
-
109
-
110
- /** Define module API */
111
- module.exports = {
112
- /** Initialize module listeners */
113
- initListeners: function() {
114
- var doc = document;
115
-
116
- // markup elements available when method is called
117
- var elList = doc.querySelectorAll(attrSelector);
118
- for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
119
-
120
- // listen for new elements
121
- util.onNodeInserted(function(el) {
122
- if (el.getAttribute(attrKey) === 'dropdown') initialize(el);
123
- });
124
- }
125
- };
126
-
127
- },{"./lib/jqLite.js":5,"./lib/util.js":6}],3:[function(require,module,exports){
128
- /**
129
- * MUI CSS/JS form-control module
130
- * @module forms/form-control
131
- */
132
-
133
- 'use strict';
134
-
135
-
136
- var jqLite = require('../lib/jqLite.js'),
137
- util = require('../lib/util.js'),
138
- cssSelector = '.mui-form-control',
139
- emptyClass = 'mui-empty',
140
- notEmptyClass = 'mui-not-empty',
141
- dirtyClass = 'mui-dirty',
142
- formControlClass = 'mui-form-control',
143
- floatingLabelClass = 'mui-form-floating-label';
144
-
145
-
146
- /**
147
- * Initialize input element.
148
- * @param {Element} inputEl - The input element.
149
- */
150
- function initialize(inputEl) {
151
- // check flag
152
- if (inputEl._muiFormControl === true) return;
153
- else inputEl._muiFormControl = true;
154
-
155
- if (inputEl.value.length) jqLite.addClass(inputEl, notEmptyClass);
156
- else jqLite.addClass(inputEl, emptyClass);
157
-
158
- jqLite.on(inputEl, 'input', inputHandler);
159
-
160
- // add dirty class on focus
161
- jqLite.on(inputEl, 'focus', function(){jqLite.addClass(this, dirtyClass);});
162
- }
163
-
164
-
165
- /**
166
- * Handle input events.
167
- */
168
- function inputHandler() {
169
- var inputEl = this;
170
-
171
- if (inputEl.value.length) {
172
- jqLite.removeClass(inputEl, emptyClass);
173
- jqLite.addClass(inputEl, notEmptyClass);
174
- } else {
175
- jqLite.removeClass(inputEl, notEmptyClass);
176
- jqLite.addClass(inputEl, emptyClass)
177
- }
178
-
179
- jqLite.addClass(inputEl, dirtyClass);
180
- }
181
-
182
-
183
- /** Define module API */
184
- module.exports = {
185
- /** Initialize input elements */
186
- initialize: initialize,
187
-
188
- /** Initialize module listeners */
189
- initListeners: function() {
190
- var doc = document;
191
-
192
- // markup elements available when method is called
193
- var elList = doc.querySelectorAll(cssSelector);
194
- for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
195
-
196
- // listen for new elements
197
- util.onNodeInserted(function(el) {
198
- if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') initialize(el);
199
- });
200
-
201
- // add transition css for floating labels
202
- setTimeout(function() {
203
- var css = '.' + floatingLabelClass + '{' + [
204
- '-webkit-transition',
205
- '-moz-transition',
206
- '-o-transition',
207
- 'transition',
208
- ''
209
- ].join(':all .15s ease-out;') + '}';
210
-
211
- util.loadStyle(css);
212
- }, 150);
213
-
214
- // pointer-events shim for floating labels
215
- if (util.supportsPointerEvents() === false) {
216
- jqLite.on(document, 'click', function(ev) {
217
- var targetEl = ev.target;
218
-
219
- if (targetEl.tagName === 'LABEL' &&
220
- jqLite.hasClass(targetEl, floatingLabelClass)) {
221
- var inputEl = targetEl.previousElementSibling;
222
- if (jqLite.hasClass(inputEl, formControlClass)) inputEl.focus();
223
- }
224
- });
225
- }
226
- }
227
- };
228
-
229
- },{"../lib/jqLite.js":5,"../lib/util.js":6}],4:[function(require,module,exports){
230
- /**
231
- * MUI CSS/JS select module
232
- * @module forms/select
233
- */
234
-
235
- 'use strict';
236
-
237
-
238
- var jqLite = require('../lib/jqLite.js'),
239
- util = require('../lib/util.js'),
240
- wrapperClass = 'mui-select',
241
- cssSelector = '.mui-select > select',
242
- menuClass = 'mui-select-menu',
243
- optionHeight = 42, // from CSS
244
- menuPadding = 8; // from CSS
245
-
246
-
247
- /**
248
- * Initialize select element.
249
- * @param {Element} selectEl - The select element.
250
- */
251
- function initialize(selectEl) {
252
- // check flag
253
- if (selectEl._muiSelect === true) return;
254
- else selectEl._muiSelect = true;
255
-
256
- // initialize element
257
- new Select(selectEl);
258
- }
259
-
260
-
261
- /**
262
- * Creates a new Select object
263
- * @class
264
- */
265
- function Select(selectEl) {
266
- // instance variables
267
- this.selectEl = selectEl;
268
- this.wrapperEl = selectEl.parentNode;
269
- this.useDefault = false;
270
-
271
- // attach event handlers
272
- jqLite.on(selectEl, 'touchstart', util.callback(this, 'touchstartHandler'));
273
- jqLite.on(selectEl, 'mousedown', util.callback(this, 'mousedownHandler'));
274
- jqLite.on(selectEl, 'focus', util.callback(this, 'focusHandler'));
275
- jqLite.on(selectEl, 'click', util.callback(this, 'clickHandler'));
276
-
277
- // make wrapper focusable and fix firefox bug
278
- this.wrapperEl.tabIndex = -1;
279
- var callbackFn = util.callback(this, 'wrapperFocusHandler');
280
- jqLite.on(this.wrapperEl, 'focus', callbackFn);
281
- }
282
-
283
-
284
- /**
285
- * Use default on touch devices.
286
- */
287
- Select.prototype.touchstartHandler = function() {
288
- // set flag
289
- this.useDefault = true;
290
- }
291
-
292
-
293
- /**
294
- * Disable default dropdown on mousedown.
295
- * @param {Event} ev - The DOM event
296
- */
297
- Select.prototype.mousedownHandler = function(ev) {
298
- if (ev.button !== 0 || this.useDefault === true) return;
299
- ev.preventDefault();
300
- }
301
-
302
-
303
- /**
304
- * Handle focus event on select element.
305
- * @param {Event} ev - The DOM event
306
- */
307
- Select.prototype.focusHandler = function(ev) {
308
- // check flag
309
- if (this.useDefault === true) return;
310
-
311
- var selectEl = this.selectEl,
312
- wrapperEl = this.wrapperEl,
313
- origIndex = selectEl.tabIndex,
314
- keydownFn = util.callback(this, 'keydownHandler');
315
-
316
- // attach keydown handler
317
- jqLite.on(document, 'keydown', keydownFn);
318
-
319
- // disable tabfocus once
320
- selectEl.tabIndex = -1;
321
- jqLite.one(wrapperEl, 'blur', function() {
322
- selectEl.tabIndex = origIndex;
323
- jqLite.off(document, 'keydown', keydownFn);
324
- });
325
-
326
- // defer focus to parent
327
- wrapperEl.focus();
328
- }
329
-
330
-
331
- /**
332
- * Handle keydown events on document
333
- **/
334
- Select.prototype.keydownHandler = function(ev) {
335
- // spacebar, down, up
336
- if (ev.keyCode === 32 || ev.keyCode === 38 || ev.keyCode === 40) {
337
- // prevent window scroll
338
- ev.preventDefault();
339
-
340
- if (this.selectEl.disabled !== true) this.renderMenu();
341
- }
342
- }
343
-
344
-
345
- /**
346
- * Handle focus event on wrapper element.
347
- */
348
- Select.prototype.wrapperFocusHandler = function() {
349
- // firefox bugfix
350
- if (this.selectEl.disabled) return this.wrapperEl.blur();
351
- }
352
-
353
-
354
- /**
355
- * Handle click events on select element.
356
- * @param {Event} ev - The DOM event
357
- */
358
- Select.prototype.clickHandler = function(ev) {
359
- // only left clicks
360
- if (ev.button !== 0) return;
361
- this.renderMenu();
362
- }
363
-
364
-
365
- /**
366
- * Render options dropdown.
367
- */
368
- Select.prototype.renderMenu = function() {
369
- // check and reset flag
370
- if (this.useDefault === true) return this.useDefault = false;
371
-
372
- new Menu(this.selectEl);
373
- }
374
-
375
-
376
- /**
377
- * Creates a new Menu
378
- * @class
379
- */
380
- function Menu(selectEl) {
381
- // instance variables
382
- this.origIndex = null;
383
- this.currentIndex = null;
384
- this.selectEl = selectEl;
385
- this.menuEl = this._createMenuEl(selectEl);
386
- this.clickCallbackFn = util.callback(this, 'clickHandler');
387
- this.keydownCallbackFn = util.callback(this, 'keydownHandler');
388
- this.destroyCallbackFn = util.callback(this, 'destroy');
389
-
390
- // add to DOM
391
- selectEl.parentNode.appendChild(this.menuEl);
392
-
393
- // blur active element
394
- setTimeout(function() {
395
- // ie10 bugfix
396
- if (document.activeElement.nodeName.toLowerCase() !== "body") {
397
- document.activeElement.blur();
398
- }
399
- }, 0);
400
-
401
- // attach event handlers
402
- jqLite.on(this.menuEl, 'click', this.clickCallbackFn);
403
- jqLite.on(document, 'keydown', this.keydownCallbackFn);
404
- jqLite.on(window, 'resize', this.destroyCallbackFn);
405
-
406
- // attach event handler after current event loop exits
407
- var fn = this.destroyCallbackFn;
408
- setTimeout(function() {jqLite.on(document, 'click', fn);}, 0);
409
- }
410
-
411
-
412
- /**
413
- * Create menu element
414
- * @param {Element} selectEl - The select element
415
- */
416
- Menu.prototype._createMenuEl = function(selectEl) {
417
- var optionEl, itemEl, i, minTop, maxTop, top;
418
-
419
- var menuEl = document.createElement('div'),
420
- optionList = selectEl.children,
421
- m = optionList.length,
422
- selectedPos = 0,
423
- idealTop = 13;
424
-
425
-
426
- // create element
427
- menuEl.className = menuClass;
428
-
429
- // add options
430
- for (i=0; i < m; i++) {
431
- optionEl = optionList[i];
432
-
433
- itemEl = document.createElement('div');
434
- itemEl.textContent = optionEl.textContent;
435
- itemEl._muiPos = i;
436
-
437
- if (optionEl.selected) selectedPos = i;
438
-
439
- menuEl.appendChild(itemEl);
440
- }
441
-
442
- // add selected attribute
443
- menuEl.children[selectedPos].setAttribute('selected', true);
444
-
445
- // save indices
446
- this.origIndex = selectedPos;
447
- this.currentIndex = selectedPos;
448
-
449
- var viewHeight = document.documentElement.clientHeight;
450
-
451
- // set height (use viewport as maximum height)
452
- var height = m * optionHeight + 2 * menuPadding;
453
- height = Math.min(height, viewHeight);
454
- jqLite.css(menuEl, 'height', height + 'px');
455
-
456
- // ideal position
457
- idealTop += selectedPos * optionHeight;
458
- idealTop = -1 * idealTop;
459
-
460
- // minimum position
461
- minTop = -1 * selectEl.getBoundingClientRect().top;
462
-
463
- // maximium position
464
- maxTop = (viewHeight - height) + minTop;
465
-
466
- // prevent overflow-y
467
- top = Math.max(idealTop, minTop);
468
- top = Math.min(top, maxTop);
469
-
470
- jqLite.css(menuEl, 'top', top + 'px');
471
-
472
- return menuEl;
473
- }
474
-
475
-
476
- /**
477
- * Handle keydown events on document element.
478
- * @param {Event} ev - The DOM event
479
- */
480
- Menu.prototype.keydownHandler = function(ev) {
481
- var keyCode = ev.keyCode;
482
-
483
- // tab
484
- if (keyCode === 9) return this.destroy();
485
-
486
- // escape | up | down | enter
487
- if (keyCode === 27 || keyCode === 40 || keyCode === 38 || keyCode === 13) {
488
- ev.preventDefault();
489
- }
490
-
491
- if (keyCode === 27) {
492
- this.destroy();
493
- } else if (keyCode === 40) {
494
- this.increment();
495
- } else if (keyCode === 38) {
496
- this.decrement();
497
- } else if (keyCode === 13) {
498
- this.selectCurrent();
499
- this.destroy();
500
- }
501
- }
502
-
503
-
504
- /**
505
- * Handle click events on menu element.
506
- * @param {Event} ev - The DOM event
507
- */
508
- Menu.prototype.clickHandler = function(ev) {
509
- // don't allow events to bubble
510
- ev.stopPropagation();
511
-
512
- var pos = ev.target._muiPos;
513
-
514
- // ignore clicks on non-items
515
- if (pos === undefined) return;
516
-
517
- // select option
518
- this.currentIndex = pos;
519
- this.selectCurrent();
520
-
521
- // destroy menu
522
- this.destroy();
523
- }
524
-
525
-
526
- /**
527
- * Increment selected item
528
- */
529
- Menu.prototype.increment = function() {
530
- if (this.currentIndex === this.menuEl.children.length - 1) return;
531
-
532
- this.menuEl.children[this.currentIndex].removeAttribute('selected');
533
- this.currentIndex += 1;
534
- this.menuEl.children[this.currentIndex].setAttribute('selected', true);
535
- }
536
-
537
-
538
- /**
539
- * Decrement selected item
540
- */
541
- Menu.prototype.decrement = function() {
542
- if (this.currentIndex === 0) return;
543
-
544
- this.menuEl.children[this.currentIndex].removeAttribute('selected');
545
- this.currentIndex -= 1;
546
- this.menuEl.children[this.currentIndex].setAttribute('selected', true);
547
- }
548
-
549
-
550
- /**
551
- * Select current item
552
- */
553
- Menu.prototype.selectCurrent = function() {
554
- if (this.currentIndex !== this.origIndex) {
555
- this.selectEl.children[this.origIndex].selected = false;
556
- this.selectEl.children[this.currentIndex].selected = true;
557
-
558
- // trigger change event
559
- util.dispatchEvent(this.selectEl, 'change');
560
- }
561
- }
562
-
563
-
564
- /**
565
- * Destroy menu and detach event handlers
566
- */
567
- Menu.prototype.destroy = function() {
568
- // remove element and focus element
569
- this.menuEl.parentNode.removeChild(this.menuEl);
570
- this.selectEl.focus();
571
-
572
- // remove event handlers
573
- jqLite.off(this.menuEl, 'click', this.clickCallbackFn);
574
- jqLite.off(document, 'keydown', this.keydownCallbackFn);
575
- jqLite.off(document, 'click', this.destroyCallbackFn);
576
- jqLite.off(window, 'resize', this.destroyCallbackFn);
577
- }
578
-
579
-
580
- /** Define module API */
581
- module.exports = {
582
- /** Initialize module listeners */
583
- initListeners: function() {
584
- var doc = document;
585
-
586
- // markup elements available when method is called
587
- var elList = doc.querySelectorAll(cssSelector);
588
- for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
589
-
590
- // listen for new elements
591
- util.onNodeInserted(function(el) {
592
- if (el.tagName === 'SELECT' &&
593
- jqLite.hasClass(el.parentNode, wrapperClass)) {
594
- initialize(el);
595
- }
596
- });
597
- }
598
- };
599
-
600
- },{"../lib/jqLite.js":5,"../lib/util.js":6}],5:[function(require,module,exports){
601
- /**
602
- * MUI CSS/JS jqLite module
603
- * @module lib/jqLite
604
- */
605
-
606
- 'use strict';
607
-
608
-
609
- /**
610
- * Add a class to an element.
611
- * @param {Element} element - The DOM element.
612
- * @param {string} cssClasses - Space separated list of class names.
613
- */
614
- function jqLiteAddClass(element, cssClasses) {
615
- if (!cssClasses || !element.setAttribute) return;
616
-
617
- var existingClasses = _getExistingClasses(element),
618
- splitClasses = cssClasses.split(' '),
619
- cssClass;
620
-
621
- for (var i=0; i < splitClasses.length; i++) {
622
- cssClass = splitClasses[i].trim();
623
- if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
624
- existingClasses += cssClass + ' ';
625
- }
626
- }
627
-
628
- element.setAttribute('class', existingClasses.trim());
629
- }
630
-
631
-
632
- /**
633
- * Get or set CSS properties.
634
- * @param {Element} element - The DOM element.
635
- * @param {string} [name] - The property name.
636
- * @param {string} [value] - The property value.
637
- */
638
- function jqLiteCss(element, name, value) {
639
- // Return full style object
640
- if (name === undefined) {
641
- return getComputedStyle(element);
642
- }
643
-
644
- var nameType = jqLiteType(name);
645
-
646
- // Set multiple values
647
- if (nameType === 'object') {
648
- for (var key in name) element.style[_camelCase(key)] = name[key];
649
- return;
650
- }
651
-
652
- // Set a single value
653
- if (nameType === 'string' && value !== undefined) {
654
- element.style[_camelCase(name)] = value;
655
- }
656
-
657
- var styleObj = getComputedStyle(element),
658
- isArray = (jqLiteType(name) === 'array');
659
-
660
- // Read single value
661
- if (!isArray) return _getCurrCssProp(element, name, styleObj);
662
-
663
- // Read multiple values
664
- var outObj = {},
665
- key;
666
-
667
- for (var i=0; i < name.length; i++) {
668
- key = name[i];
669
- outObj[key] = _getCurrCssProp(element, key, styleObj);
670
- }
671
-
672
- return outObj;
673
- }
674
-
675
-
676
- /**
677
- * Check if element has class.
678
- * @param {Element} element - The DOM element.
679
- * @param {string} cls - The class name string.
680
- */
681
- function jqLiteHasClass(element, cls) {
682
- if (!cls || !element.getAttribute) return false;
683
- return (_getExistingClasses(element).indexOf(' ' + cls + ' ') > -1);
684
- }
685
-
686
-
687
- /**
688
- * Return the type of a variable.
689
- * @param {} somevar - The JavaScript variable.
690
- */
691
- function jqLiteType(somevar) {
692
- // handle undefined
693
- if (somevar === undefined) return 'undefined';
694
-
695
- // handle others (of type [object <Type>])
696
- var typeStr = Object.prototype.toString.call(somevar);
697
- if (typeStr.indexOf('[object ') === 0) {
698
- return typeStr.slice(8, -1).toLowerCase();
699
- } else {
700
- throw "Could not understand type: " + typeStr;
701
- }
702
- }
703
-
704
-
705
- /**
706
- * Attach an event handler to a DOM element
707
- * @param {Element} element - The DOM element.
708
- * @param {string} type - The event type name.
709
- * @param {Function} callback - The callback function.
710
- * @param {Boolean} useCapture - Use capture flag.
711
- */
712
- function jqLiteOn(element, type, callback, useCapture) {
713
- useCapture = (useCapture === undefined) ? false : useCapture;
714
-
715
- // add to DOM
716
- element.addEventListener(type, callback, useCapture);
717
-
718
- // add to cache
719
- var cache = element._muiEventCache = element._muiEventCache || {};
720
- cache[type] = cache[type] || [];
721
- cache[type].push([callback, useCapture]);
722
- }
723
-
724
-
725
- /**
726
- * Remove an event handler from a DOM element
727
- * @param {Element} element - The DOM element.
728
- * @param {string} type - The event type name.
729
- * @param {Function} callback - The callback function.
730
- * @param {Boolean} useCapture - Use capture flag.
731
- */
732
- function jqLiteOff(element, type, callback, useCapture) {
733
- useCapture = (useCapture === undefined) ? false : useCapture;
734
-
735
- // remove from cache
736
- var cache = element._muiEventCache = element._muiEventCache || {},
737
- argsList = cache[type] || [],
738
- args,
739
- i;
740
-
741
- i = argsList.length;
742
- while (i--) {
743
- args = argsList[i];
744
-
745
- // remove all events if callback is undefined
746
- if (callback === undefined ||
747
- (args[0] === callback && args[1] === useCapture)) {
748
-
749
- // remove from cache
750
- argsList.splice(i, 1);
751
-
752
- // remove from DOM
753
- element.removeEventListener(type, args[0], args[1]);
754
- }
755
- }
756
- }
757
-
758
-
759
- /**
760
- * Attach an event hander which will only execute once
761
- * @param {Element} element - The DOM element.
762
- * @param {string} type - The event type name.
763
- * @param {Function} callback - The callback function.
764
- * @param {Boolean} useCapture - Use capture flag.
765
- */
766
- function jqLiteOne(element, type, callback, useCapture) {
767
- jqLiteOn(element, type, function onFn(ev) {
768
- // execute callback
769
- if (callback) callback.apply(this, arguments);
770
-
771
- // remove wrapper
772
- jqLiteOff(element, type, onFn);
773
- }, useCapture);
774
- }
775
-
776
-
777
- /**
778
- * Return object representing top/left offset and element height/width.
779
- * @param {Element} element - The DOM element.
780
- */
781
- function jqLiteOffset(element) {
782
- var win = window,
783
- docEl = document.documentElement,
784
- rect = element.getBoundingClientRect(),
785
- viewLeft,
786
- viewTop;
787
-
788
- viewLeft = (win.pageXOffset || docEl.scrollLeft) - (docEl.clientLeft || 0);
789
- viewTop = (win.pageYOffset || docEl.scrollTop) - (docEl.clientTop || 0);
790
-
791
- return {
792
- top: rect.top + viewTop,
793
- left: rect.left + viewLeft,
794
- height: rect.height,
795
- width: rect.width
796
- };
797
- }
798
-
799
-
800
- /**
801
- * Attach a callback to the DOM ready event listener
802
- * @param {Function} fn - The callback function.
803
- */
804
- function jqLiteReady(fn) {
805
- var done = false,
806
- top = true,
807
- doc = document,
808
- win = doc.defaultView,
809
- root = doc.documentElement,
810
- add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
811
- rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
812
- pre = doc.addEventListener ? '' : 'on';
813
-
814
- var init = function(e) {
815
- if (e.type == 'readystatechange' && doc.readyState != 'complete') {
816
- return;
817
- }
818
-
819
- (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
820
- if (!done && (done = true)) fn.call(win, e.type || e);
821
- };
822
-
823
- var poll = function() {
824
- try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }
825
- init('poll');
826
- };
827
-
828
- if (doc.readyState == 'complete') {
829
- fn.call(win, 'lazy');
830
- } else {
831
- if (doc.createEventObject && root.doScroll) {
832
- try { top = !win.frameElement; } catch(e) { }
833
- if (top) poll();
834
- }
835
- doc[add](pre + 'DOMContentLoaded', init, false);
836
- doc[add](pre + 'readystatechange', init, false);
837
- win[add](pre + 'load', init, false);
838
- }
839
- }
840
-
841
-
842
- /**
843
- * Remove classes from a DOM element
844
- * @param {Element} element - The DOM element.
845
- * @param {string} cssClasses - Space separated list of class names.
846
- */
847
- function jqLiteRemoveClass(element, cssClasses) {
848
- if (!cssClasses || !element.setAttribute) return;
849
-
850
- var existingClasses = _getExistingClasses(element),
851
- splitClasses = cssClasses.split(' '),
852
- cssClass;
853
-
854
- for (var i=0; i < splitClasses.length; i++) {
855
- cssClass = splitClasses[i].trim();
856
- while (existingClasses.indexOf(' ' + cssClass + ' ') >= 0) {
857
- existingClasses = existingClasses.replace(' ' + cssClass + ' ', ' ');
858
- }
859
- }
860
-
861
- element.setAttribute('class', existingClasses.trim());
862
- }
863
-
864
-
865
- // ------------------------------
866
- // Utilities
867
- // ------------------------------
868
- var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g,
869
- MOZ_HACK_REGEXP = /^moz([A-Z])/,
870
- ESCAPE_REGEXP = /([.*+?^=!:${}()|\[\]\/\\])/g,
871
- BOOLEAN_ATTRS;
872
-
873
-
874
- BOOLEAN_ATTRS = {
875
- multiple: true,
876
- selected: true,
877
- checked: true,
878
- disabled: true,
879
- readonly: true,
880
- required: true,
881
- open: true
882
- }
883
-
884
-
885
- function _getExistingClasses(element) {
886
- var classes = (element.getAttribute('class') || '').replace(/[\n\t]/g, '');
887
- return ' ' + classes + ' ';
888
- }
889
-
890
-
891
- function _camelCase(name) {
892
- return name.
893
- replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
894
- return offset ? letter.toUpperCase() : letter;
895
- }).
896
- replace(MOZ_HACK_REGEXP, 'Moz$1');
897
- }
898
-
899
-
900
- function _escapeRegExp(string) {
901
- return string.replace(ESCAPE_REGEXP, "\\$1");
902
- }
903
-
904
-
905
- function _getCurrCssProp(elem, name, computed) {
906
- var ret;
907
-
908
- // try computed style
909
- ret = computed.getPropertyValue(name);
910
-
911
- // try style attribute (if element is not attached to document)
912
- if (ret === '' && !elem.ownerDocument) ret = elem.style[_camelCase(name)];
913
-
914
- return ret;
915
- }
916
-
917
-
918
- /**
919
- * Module API
920
- */
921
- module.exports = {
922
- /** Add classes */
923
- addClass: jqLiteAddClass,
924
-
925
- /** Get or set CSS properties */
926
- css: jqLiteCss,
927
-
928
- /** Check for class */
929
- hasClass: jqLiteHasClass,
930
-
931
- /** Remove event handlers */
932
- off: jqLiteOff,
933
-
934
- /** Return offset values */
935
- offset: jqLiteOffset,
936
-
937
- /** Add event handlers */
938
- on: jqLiteOn,
939
-
940
- /** Add an execute-once event handler */
941
- one: jqLiteOne,
942
-
943
- /** DOM ready event handler */
944
- ready: jqLiteReady,
945
-
946
- /** Remove classes */
947
- removeClass: jqLiteRemoveClass,
948
-
949
- /** Check JavaScript variable instance type */
950
- type: jqLiteType
951
- };
952
-
953
- },{}],6:[function(require,module,exports){
954
- /**
955
- * MUI CSS/JS utilities module
956
- * @module lib/util
957
- */
958
-
959
- 'use strict';
960
-
961
-
962
- var config = require('../config.js'),
963
- jqLite = require('./jqLite.js'),
964
- win = window,
965
- doc = window.document,
966
- nodeInsertedCallbacks = [],
967
- head,
968
- _supportsPointerEvents;
969
-
970
-
971
- head = doc.head || doc.getElementsByTagName('head')[0] || doc.documentElement;
972
-
973
-
974
- /**
975
- * Logging function
976
- */
977
- function logFn() {
978
- if (config.debug && typeof win.console !== "undefined") {
979
- try {
980
- win.console.log.apply(win.console, arguments);
981
- } catch (a) {
982
- var e = Array.prototype.slice.call(arguments);
983
- win.console.log(e.join("\n"));
984
- }
985
- }
986
- }
987
-
988
-
989
- /**
990
- * Load CSS text in new stylesheet
991
- * @param {string} cssText - The css text.
992
- */
993
- function loadStyleFn(cssText) {
994
- if (doc.createStyleSheet) {
995
- doc.createStyleSheet().cssText = cssText;
996
- } else {
997
- var e = doc.createElement('style');
998
- e.type = 'text/css';
999
-
1000
- if (e.styleSheet) e.styleSheet.cssText = cssText;
1001
- else e.appendChild(doc.createTextNode(cssText));
1002
-
1003
- // add to document
1004
- head.insertBefore(e, head.firstChild);
1005
- }
1006
- }
1007
-
1008
-
1009
- /**
1010
- * Raise an error
1011
- * @param {string} msg - The error message.
1012
- */
1013
- function raiseErrorFn(msg) {
1014
- throw "MUI Error: " + msg;
1015
- }
1016
-
1017
-
1018
- /**
1019
- * Register callbacks on muiNodeInserted event
1020
- * @param {function} callbackFn - The callback function.
1021
- */
1022
- function onNodeInsertedFn(callbackFn) {
1023
- nodeInsertedCallbacks.push(callbackFn);
1024
-
1025
- // initalize listeners
1026
- if (nodeInsertedCallbacks._initialized === undefined) {
1027
- jqLite.on(doc, 'animationstart', animationHandlerFn);
1028
- jqLite.on(doc, 'mozAnimationStart', animationHandlerFn);
1029
- jqLite.on(doc, 'webkitAnimationStart', animationHandlerFn);
1030
-
1031
- nodeInsertedCallbacks._initialized = true;
1032
- }
1033
- }
1034
-
1035
-
1036
- /**
1037
- * Execute muiNodeInserted callbacks
1038
- * @param {Event} ev - The DOM event.
1039
- */
1040
- function animationHandlerFn(ev) {
1041
- // check animation name
1042
- if (ev.animationName !== 'mui-node-inserted') return;
1043
-
1044
- var el = ev.target;
1045
-
1046
- // iterate through callbacks
1047
- for (var i=nodeInsertedCallbacks.length - 1; i >= 0; i--) {
1048
- nodeInsertedCallbacks[i](el);
1049
- }
1050
- }
1051
-
1052
-
1053
- /**
1054
- * Convert Classname object, with class as key and true/false as value, to an
1055
- * class string.
1056
- * @param {Object} classes The classes
1057
- * @return {String} class string
1058
- */
1059
- function classNamesFn(classes) {
1060
- var cs = '';
1061
- for (var i in classes) {
1062
- cs += (classes[i]) ? i + ' ' : '';
1063
- }
1064
- return cs.trim();
1065
- }
1066
-
1067
-
1068
- /**
1069
- * Check if client supports pointer events.
1070
- */
1071
- function supportsPointerEventsFn() {
1072
- // check cache
1073
- if (_supportsPointerEvents !== undefined) return _supportsPointerEvents;
1074
-
1075
- var element = document.createElement('x');
1076
- element.style.cssText = 'pointer-events:auto';
1077
- _supportsPointerEvents = (element.style.pointerEvents === 'auto');
1078
- return _supportsPointerEvents;
1079
- }
1080
-
1081
-
1082
- /**
1083
- * Create callback closure.
1084
- * @param {Object} instance - The object instance.
1085
- * @param {String} funcName - The name of the callback function.
1086
- */
1087
- function callbackFn(instance, funcName) {
1088
- return function() {instance[funcName].apply(instance, arguments);};
1089
- }
1090
-
1091
-
1092
- /**
1093
- * Dispatch event.
1094
- * @param {Element} element - The DOM element.
1095
- * @param {String} eventType - The event type.
1096
- * @param {Boolean} bubbles=true - If true, event bubbles.
1097
- * @param {Boolean} cancelable=true = If true, event is cancelable
1098
- */
1099
- function dispatchEventFn(element, eventType, bubbles, cancelable) {
1100
- var ev = document.createEvent('HTMLEvents'),
1101
- bubbles = (bubbles !== undefined) ? bubbles : true,
1102
- cancelable = (cancelable !== undefined) ? cancelable : true;
1103
-
1104
- ev.initEvent(eventType, bubbles, cancelable);
1105
- element.dispatchEvent(ev);
1106
- }
1107
-
1108
-
1109
- /**
1110
- * Define the module API
1111
- */
1112
- module.exports = {
1113
- /** Create callback closures */
1114
- callback: callbackFn,
1115
-
1116
- /** Classnames object to string */
1117
- classNames: classNamesFn,
1118
-
1119
- /** Dispatch event */
1120
- dispatchEvent: dispatchEventFn,
1121
-
1122
- /** Log messages to the console when debug is turned on */
1123
- log: logFn,
1124
-
1125
- /** Load CSS text as new stylesheet */
1126
- loadStyle: loadStyleFn,
1127
-
1128
- /** Register muiNodeInserted handler */
1129
- onNodeInserted: onNodeInsertedFn,
1130
-
1131
- /** Raise MUI error */
1132
- raiseError: raiseErrorFn,
1133
-
1134
- /** Support Pointer Events check */
1135
- supportsPointerEvents: supportsPointerEventsFn
1136
- };
1137
-
1138
- },{"../config.js":1,"./jqLite.js":5}],7:[function(require,module,exports){
1139
1
  /**
1140
2
  * MUI CSS/JS main module
1141
3
  * @module main
@@ -1173,421 +35,3 @@ module.exports = {
1173
35
  tabs.initListeners();
1174
36
  });
1175
37
  })(window);
1176
-
1177
- },{"./dropdowns.js":2,"./forms/form-control.js":3,"./forms/select.js":4,"./lib/jqLite.js":5,"./lib/util.js":6,"./overlay.js":8,"./ripple.js":9,"./tabs.js":10}],8:[function(require,module,exports){
1178
- /**
1179
- * MUI CSS/JS overlay module
1180
- * @module overlay
1181
- */
1182
-
1183
- 'use strict';
1184
-
1185
-
1186
- var util = require('./lib/util.js'),
1187
- jqLite = require('./lib/jqLite.js'),
1188
- bodyClass = 'mui-overlay-on',
1189
- overlayId = 'mui-overlay',
1190
- iosRegex = /(iPad|iPhone|iPod)/g;
1191
-
1192
-
1193
- /**
1194
- * Turn overlay on/off.
1195
- * @param {string} action - Turn overlay "on"/"off".
1196
- * @param {object} [options]
1197
- * @config {boolean} [keyboard] - If true, close when escape key is pressed.
1198
- * @config {boolean} [static] - If false, close when backdrop is clicked.
1199
- * @config {Function} [onclose] - Callback function to execute on close
1200
- * @param {Element} [childElement] - Child element to add to overlay.
1201
- */
1202
- function overlayFn(action) {
1203
- var overlayEl;
1204
-
1205
- if (action === 'on') {
1206
- // extract arguments
1207
- var arg, options, childElement;
1208
-
1209
- // pull options and childElement from arguments
1210
- for (var i=arguments.length - 1; i > 0; i--) {
1211
- arg = arguments[i];
1212
-
1213
- if (jqLite.type(arg) === 'object') options = arg;
1214
- if (arg instanceof Element && arg.nodeType === 1) childElement = arg;
1215
- }
1216
-
1217
- // option defaults
1218
- options = options || {};
1219
- if (options.keyboard === undefined) options.keyboard = true;
1220
- if (options.static === undefined) options.static = false;
1221
-
1222
- // execute method
1223
- overlayEl = overlayOn(options, childElement);
1224
-
1225
- } else if (action === 'off') {
1226
- overlayEl = overlayOff();
1227
-
1228
- } else {
1229
- // raise error
1230
- util.raiseError("Expecting 'on' or 'off'");
1231
- }
1232
-
1233
- return overlayEl;
1234
- }
1235
-
1236
-
1237
- /**
1238
- * Turn on overlay.
1239
- * @param {object} options - Overlay options.
1240
- * @param {Element} childElement - The child element.
1241
- */
1242
- function overlayOn(options, childElement) {
1243
- var bodyEl = document.body,
1244
- overlayEl = document.getElementById(overlayId);
1245
-
1246
- // add overlay
1247
- jqLite.addClass(bodyEl, bodyClass);
1248
-
1249
- if (!overlayEl) {
1250
- // create overlayEl
1251
- overlayEl = document.createElement('div');
1252
- overlayEl.setAttribute('id', overlayId);
1253
-
1254
- // add child element
1255
- if (childElement) overlayEl.appendChild(childElement);
1256
-
1257
- bodyEl.appendChild(overlayEl);
1258
-
1259
- } else {
1260
- // remove existing children
1261
- while (overlayEl.firstChild) overlayEl.removeChild(overlayEl.firstChild);
1262
-
1263
- // add child element
1264
- if (childElement) overlayEl.appendChild(childElement);
1265
- }
1266
-
1267
- // iOS bugfix
1268
- if (iosRegex.test(navigator.userAgent)) {
1269
- jqLite.css(overlayEl, 'cursor', 'pointer');
1270
- }
1271
-
1272
- // handle options
1273
- if (options.keyboard) addKeyupHandler();
1274
- else removeKeyupHandler();
1275
-
1276
- if (options.static) removeClickHandler(overlayEl);
1277
- else addClickHandler(overlayEl);
1278
-
1279
- // attach options
1280
- overlayEl.muiOptions = options;
1281
-
1282
- return overlayEl;
1283
- }
1284
-
1285
-
1286
- /**
1287
- * Turn off overlay.
1288
- */
1289
- function overlayOff() {
1290
- var overlayEl = document.getElementById(overlayId),
1291
- callbackFn;
1292
-
1293
- if (overlayEl) {
1294
- // remove children
1295
- while (overlayEl.firstChild) overlayEl.removeChild(overlayEl.firstChild);
1296
-
1297
- // remove overlay element
1298
- overlayEl.parentNode.removeChild(overlayEl);
1299
-
1300
- // callback reference
1301
- callbackFn = overlayEl.muiOptions.onclose;
1302
- }
1303
-
1304
- jqLite.removeClass(document.body, bodyClass);
1305
-
1306
- // remove option handlers
1307
- removeKeyupHandler();
1308
- removeClickHandler(overlayEl);
1309
-
1310
- // execute callback
1311
- if (callbackFn) callbackFn();
1312
-
1313
- return overlayEl;
1314
- }
1315
-
1316
-
1317
- /**
1318
- * Add keyup handler.
1319
- */
1320
- function addKeyupHandler() {
1321
- jqLite.on(document, 'keyup', onKeyup);
1322
- }
1323
-
1324
-
1325
- /**
1326
- * Remove keyup handler.
1327
- */
1328
- function removeKeyupHandler() {
1329
- jqLite.off(document, 'keyup', onKeyup);
1330
- }
1331
-
1332
-
1333
- /**
1334
- * Teardown overlay when escape key is pressed.
1335
- */
1336
- function onKeyup(ev) {
1337
- if (ev.keyCode === 27) overlayOff();
1338
- }
1339
-
1340
-
1341
- /**
1342
- * Add click handler.
1343
- */
1344
- function addClickHandler(overlayEl) {
1345
- jqLite.on(overlayEl, 'click', onClick);
1346
- }
1347
-
1348
-
1349
- /**
1350
- * Remove click handler.
1351
- */
1352
- function removeClickHandler(overlayEl) {
1353
- jqLite.off(overlayEl, 'click', onClick);
1354
- }
1355
-
1356
-
1357
- /**
1358
- * Teardown overlay when backdrop is clicked.
1359
- */
1360
- function onClick(ev) {
1361
- if (ev.target.id === overlayId) overlayOff();
1362
- }
1363
-
1364
-
1365
- /** Define module API */
1366
- module.exports = overlayFn;
1367
-
1368
- },{"./lib/jqLite.js":5,"./lib/util.js":6}],9:[function(require,module,exports){
1369
- /**
1370
- * MUI CSS/JS ripple module
1371
- * @module ripple
1372
- */
1373
-
1374
- 'use strict';
1375
-
1376
-
1377
- var jqLite = require('./lib/jqLite.js'),
1378
- util = require('./lib/util.js'),
1379
- btnClass = 'mui-btn',
1380
- btnFlatClass = 'mui-btn-flat',
1381
- btnFloatingClass = 'mui-btn-floating',
1382
- rippleClass = 'mui-ripple-effect',
1383
- animationName = 'mui-btn-inserted';
1384
-
1385
-
1386
- /**
1387
- * Add ripple effects to button element.
1388
- * @param {Element} buttonEl - The button element.
1389
- */
1390
- function initialize(buttonEl) {
1391
- // check flag
1392
- if (buttonEl._muiRipple === true) return;
1393
- else buttonEl._muiRipple = true;
1394
-
1395
- // exit if element is INPUT (doesn't support absolute positioned children)
1396
- if (buttonEl.tagName === 'INPUT') return;
1397
-
1398
- // attach event handler
1399
- jqLite.on(buttonEl, 'touchstart', eventHandler);
1400
- jqLite.on(buttonEl, 'mousedown', eventHandler);
1401
- }
1402
-
1403
-
1404
- /**
1405
- * Event handler
1406
- * @param {Event} ev - The DOM event
1407
- */
1408
- function eventHandler(ev) {
1409
- // only left clicks
1410
- if (ev.button !== 0) return;
1411
-
1412
- var buttonEl = this;
1413
-
1414
- // exit if button is disabled
1415
- if (buttonEl.disabled === true) return;
1416
-
1417
- // de-dupe touchstart and mousedown with 100msec flag
1418
- if (buttonEl.touchFlag === true) {
1419
- return;
1420
- } else {
1421
- buttonEl.touchFlag = true;
1422
- setTimeout(function() {
1423
- buttonEl.touchFlag = false;
1424
- }, 100);
1425
- }
1426
-
1427
- var rippleEl = document.createElement('div');
1428
- rippleEl.className = rippleClass;
1429
-
1430
- var offset = jqLite.offset(buttonEl),
1431
- xPos = ev.pageX - offset.left,
1432
- yPos = ev.pageY - offset.top,
1433
- diameter,
1434
- radius;
1435
-
1436
- // get height
1437
- if (jqLite.hasClass(buttonEl, btnFloatingClass)) {
1438
- diameter = offset.height / 2;
1439
- } else {
1440
- diameter = offset.height;
1441
- }
1442
-
1443
- radius = diameter / 2;
1444
-
1445
- jqLite.css(rippleEl, {
1446
- height: diameter + 'px',
1447
- width: diameter + 'px',
1448
- top: yPos - radius + 'px',
1449
- left: xPos - radius + 'px'
1450
- });
1451
-
1452
- buttonEl.appendChild(rippleEl);
1453
-
1454
- window.setTimeout(function() {
1455
- buttonEl.removeChild(rippleEl);
1456
- }, 2000);
1457
- }
1458
-
1459
-
1460
- /** Define module API */
1461
- module.exports = {
1462
- /** Initialize module listeners */
1463
- initListeners: function() {
1464
- var doc = document;
1465
-
1466
- // markup elements available when method is called
1467
- var elList = doc.getElementsByClassName(btnClass);
1468
- for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
1469
-
1470
- // listen for new elements
1471
- util.onNodeInserted(function(el) {
1472
- if (jqLite.hasClass(el, btnClass)) initialize(el);
1473
- });
1474
- }
1475
- };
1476
-
1477
- },{"./lib/jqLite.js":5,"./lib/util.js":6}],10:[function(require,module,exports){
1478
- /**
1479
- * MUI CSS/JS tabs module
1480
- * @module tabs
1481
- */
1482
-
1483
- 'use strict';
1484
-
1485
-
1486
- var jqLite = require('./lib/jqLite.js'),
1487
- util = require('./lib/util.js'),
1488
- attrKey = 'data-mui-toggle',
1489
- attrSelector = '[' + attrKey + '="tab"]',
1490
- controlsAttrKey = 'data-mui-controls',
1491
- activeClass = 'mui-active';
1492
-
1493
-
1494
- /**
1495
- * Initialize the toggle element
1496
- * @param {Element} toggleEl - The toggle element.
1497
- */
1498
- function initialize(toggleEl) {
1499
- // check flag
1500
- if (toggleEl._muiTabs === true) return;
1501
- else toggleEl._muiTabs = true;
1502
-
1503
- // attach click handler
1504
- jqLite.on(toggleEl, 'click', clickHandler);
1505
- }
1506
-
1507
-
1508
- /**
1509
- * Handle clicks on the toggle element.
1510
- * @param {Event} ev - The DOM event.
1511
- */
1512
- function clickHandler(ev) {
1513
- // only left clicks
1514
- if (ev.button !== 0) return;
1515
-
1516
- var toggleEl = this;
1517
-
1518
- // exit if toggle element is disabled
1519
- if (toggleEl.getAttribute('disabled') !== null) return;
1520
-
1521
- // let event bubble before toggling tab
1522
- setTimeout(function() {
1523
- if (!ev.defaultPrevented) activateTab(toggleEl);
1524
- }, 0);
1525
- }
1526
-
1527
-
1528
- /**
1529
- * Activate the tab controlled by the toggle element.
1530
- * @param {Element} toggleEl - The toggle element.
1531
- */
1532
- function activateTab(toggleEl) {
1533
- var tabEl = toggleEl.parentNode,
1534
- paneId = toggleEl.getAttribute(controlsAttrKey),
1535
- paneEl = document.getElementById(paneId),
1536
- tabs,
1537
- panes,
1538
- el,
1539
- i;
1540
-
1541
- // raise error if pane doesn't exist
1542
- if (!paneEl) util.raiseError('Tab pane "' + paneId + '" not found');
1543
-
1544
- // de-activate tab siblings
1545
- tabs = tabEl.parentNode.children;
1546
- for (i=tabs.length - 1; i >= 0; i--) {
1547
- el = tabs[i];
1548
- if (el !== tabEl) jqLite.removeClass(el, activeClass);
1549
- }
1550
-
1551
- // de-activate pane siblings
1552
- panes = paneEl.parentNode.children;
1553
- for (i=panes.length - 1; i >= 0; i--) {
1554
- el = panes[i];
1555
- if (el !== paneEl) jqLite.removeClass(el, activeClass);
1556
- }
1557
-
1558
- // activate tab and pane
1559
- jqLite.addClass(tabEl, activeClass);
1560
- jqLite.addClass(paneEl, activeClass);
1561
- }
1562
-
1563
-
1564
- /** Define module API */
1565
- module.exports = {
1566
- /** Initialize module listeners */
1567
- initListeners: function() {
1568
- // markup elements available when method is called
1569
- var elList = document.querySelectorAll(attrSelector);
1570
- for (var i=elList.length - 1; i >= 0; i--) initialize(elList[i]);
1571
-
1572
- // TODO: listen for new elements
1573
- util.onNodeInserted(function(el) {
1574
- if (el.getAttribute(attrKey) === 'tab') initialize(el);
1575
- });
1576
- },
1577
-
1578
- /** External API */
1579
- api: {
1580
- activate: function(paneId) {
1581
- var cssSelector = '[' + controlsAttrKey + '=' + paneId + ']',
1582
- toggleEl = document.querySelectorAll(cssSelector);
1583
-
1584
- if (!toggleEl.length) {
1585
- util.raiseError('Tab control for pane "' + paneId + '" not found');
1586
- }
1587
-
1588
- activateTab(toggleEl[0]);
1589
- }
1590
- }
1591
- };
1592
-
1593
- },{"./lib/jqLite.js":5,"./lib/util.js":6}]},{},[7]);