mui-sass 0.1.21 → 0.1.21.1

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