mui-sass 0.1.19 → 0.1.20

Sign up to get free protection for your applications and to get access to all the features.
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]);