mui-sass 0.1.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +11 -0
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +119 -0
  9. data/Rakefile +1 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +7 -0
  12. data/lib/mui-sass.rb +60 -0
  13. data/lib/mui/sass/engine.rb +13 -0
  14. data/lib/mui/sass/version.rb +5 -0
  15. data/mui-sass.gemspec +29 -0
  16. data/templates/project/manifest.rb +2 -0
  17. data/templates/project/styles.sass +1 -0
  18. data/vendor/assets/javascripts/mui.js +1593 -0
  19. data/vendor/assets/stylesheets/_mui.scss +27 -0
  20. data/vendor/assets/stylesheets/bootstrap-3.3.1/.bower.json +59 -0
  21. data/vendor/assets/stylesheets/bootstrap-3.3.1/LICENSE +21 -0
  22. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_alerts.scss +14 -0
  23. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_background-variant.scss +11 -0
  24. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_border-radius.scss +18 -0
  25. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_buttons.scss +52 -0
  26. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_center-block.scss +7 -0
  27. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_clearfix.scss +22 -0
  28. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_forms.scss +88 -0
  29. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_gradients.scss +58 -0
  30. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +81 -0
  31. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_grid.scss +122 -0
  32. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_hide-text.scss +21 -0
  33. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_image.scss +33 -0
  34. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_labels.scss +12 -0
  35. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_list-group.scss +31 -0
  36. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +10 -0
  37. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss +9 -0
  38. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_opacity.scss +8 -0
  39. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_pagination.scss +23 -0
  40. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_panels.scss +24 -0
  41. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_progress-bar.scss +10 -0
  42. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_reset-filter.scss +8 -0
  43. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_resize.scss +6 -0
  44. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +21 -0
  45. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_size.scss +10 -0
  46. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +9 -0
  47. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_table-row.scss +28 -0
  48. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +11 -0
  49. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_text-overflow.scss +8 -0
  50. data/vendor/assets/stylesheets/bootstrap-3.3.1/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +222 -0
  51. data/vendor/assets/stylesheets/mui/_appbar.scss +72 -0
  52. data/vendor/assets/stylesheets/mui/_buttons.scss +201 -0
  53. data/vendor/assets/stylesheets/mui/_colors.scss +348 -0
  54. data/vendor/assets/stylesheets/mui/_dividers.scss +25 -0
  55. data/vendor/assets/stylesheets/mui/_dropdowns.scss +90 -0
  56. data/vendor/assets/stylesheets/mui/_forms.scss +467 -0
  57. data/vendor/assets/stylesheets/mui/_grid.scss +29 -0
  58. data/vendor/assets/stylesheets/mui/_helpers.scss +284 -0
  59. data/vendor/assets/stylesheets/mui/_layout.scss +21 -0
  60. data/vendor/assets/stylesheets/mui/_mixins.scss +17 -0
  61. data/vendor/assets/stylesheets/mui/_overlay.scss +19 -0
  62. data/vendor/assets/stylesheets/mui/_panel.scss +14 -0
  63. data/vendor/assets/stylesheets/mui/_ripple.scss +55 -0
  64. data/vendor/assets/stylesheets/mui/_scaffolding.scss +110 -0
  65. data/vendor/assets/stylesheets/mui/_semantic-markup.scss +45 -0
  66. data/vendor/assets/stylesheets/mui/_tables.scss +44 -0
  67. data/vendor/assets/stylesheets/mui/_tabs.scss +75 -0
  68. data/vendor/assets/stylesheets/mui/_typography.scss +51 -0
  69. data/vendor/assets/stylesheets/mui/_variables.scss +256 -0
  70. data/vendor/assets/stylesheets/mui/mixins/_buttons.scss +58 -0
  71. data/vendor/assets/stylesheets/mui/mixins/_grid-framework.scss +61 -0
  72. data/vendor/assets/stylesheets/mui/mixins/_typography.scss +132 -0
  73. data/vendor/assets/stylesheets/mui/mixins/_util.scss +4 -0
  74. data/vendor/assets/stylesheets/mui/normalize-3.0.2.scss +427 -0
  75. metadata +173 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2fd0efddb4858bf77210c5234be75b7501a53757
4
+ data.tar.gz: f5e4ad14d40016269391859ba7c43526e042a12e
5
+ SHA512:
6
+ metadata.gz: ebb593ac163b5dfb8d8779034a293f0cd1d8ae0e2d97c00be618c0f31a6faa026b7e92fb5e867066125a5ceafd83c54616c0413f6a8d5ea892e60f5f0a9d6ca9
7
+ data.tar.gz: 3a575d3b24fabab3624382463a7774bca6871d2b9fd1c598cb7664d5727a9991a15200ccbca6e956ef29616b9675b7038eda2261454995a10eae97161ea1cd13
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.sass-cache/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/support/dummy_rails_app/log/
10
+ /spec/support/dummy_rails_app/tmp/
11
+ /spec/reports/
12
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.6
7
+ - 2.2.2
8
+
9
+ before_install: gem install bundler
10
+
11
+ sudo: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## 0.1.19 (2015-07-28)
2
+
3
+ - Initial release
4
+
5
+ Framework version: MUI v0.1.19
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mui-sass.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Dmitriy Tarasov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # MUI for Sass
2
+
3
+ `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
+
5
+ ## Installation
6
+
7
+ This package provides MUI framework CSS and JavaScript components. HTML Email, React, WebComponents and Design Files are not included.
8
+
9
+ ## Installation
10
+
11
+ * [Ruby on Rails](#ruby-on-rails)
12
+ * [Compass](#compass)
13
+
14
+ ### Ruby on Rails
15
+
16
+ Add this line to your Rails application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'mui-sass'
20
+ ```
21
+
22
+ And then execute `bundle` command to install.
23
+
24
+ Import `mui` in `app/assets/stylesheets/application.scss`:
25
+
26
+ ```scss
27
+ @import 'mui';
28
+ ```
29
+
30
+ Default Rails installation comes with `.css` file extension for stylesheet assests files, make sure you change it to `.scss` and remove all the `//= require` and `//= require_tree` statements from file.
31
+
32
+ Alternatively, to keep original `application.css` file, you can create `custom.scss` file in same folder and import `mui` there.
33
+
34
+ Require `mui` javascript in `app/assets/javascripts/application.js`:
35
+
36
+ ````
37
+ //= require mui
38
+ ````
39
+
40
+ ### Compass
41
+
42
+ To use Compass extension you'll need to install `mui-sass` gem:
43
+
44
+ ```
45
+ gem install mui-sass
46
+ ```
47
+
48
+ #### Existing Compass project
49
+
50
+ If you have an existing Compass project, open `config.rb` file and require `mui-sass` there:
51
+
52
+ ```ruby
53
+ require 'mui-sass'
54
+ ```
55
+
56
+ Navigate to your project's folder and run command:
57
+
58
+ ```
59
+ compass install mui -r mui-sass
60
+ ```
61
+
62
+ This will create new file `styles.scss`, that imports MUI components.
63
+
64
+ Instead of the install command provided above, you can manually import `mui`:
65
+
66
+ ```
67
+ @import 'mui';
68
+ ```
69
+
70
+ #### New Compass project
71
+
72
+ If you are creating a new Compass project and wish to include `mui-sass` run command:
73
+
74
+ ```
75
+ compass create project-name -r mui-sass --using mui
76
+ ```
77
+
78
+ This command will create a new Compass project with `styles.scss` file, which imports MUI components.
79
+
80
+ ## Usage
81
+
82
+ By default, using `@import 'mui';` and `//= require mui`, all of MUI components are imported.
83
+
84
+ You can import individual `scss` components like this:
85
+
86
+ First you need to include core components:
87
+
88
+ ```scss
89
+ @import 'mui/normalize-3.0.2';
90
+ @import 'mui/colors';
91
+ @import 'mui/variables';
92
+ @import 'mui/mixins';
93
+ ```
94
+
95
+ Then add component:
96
+ ```scss
97
+ @import 'mui/appbar';
98
+ @import 'mui/buttons';
99
+ @import 'mui/dividers';
100
+ @import 'mui/dropdowns';
101
+ @import 'mui/forms';
102
+ @import 'mui/grid';
103
+ @import 'mui/helpers';
104
+ @import 'mui/layout';
105
+ @import 'mui/overlay';
106
+ @import 'mui/panel';
107
+ @import 'mui/ripple';
108
+ @import 'mui/scaffolding';
109
+ @import 'mui/semantic-markup';
110
+ @import 'mui/tables';
111
+ @import 'mui/tabs';
112
+ @import 'mui/typography';
113
+ ```
114
+
115
+ The full set of MUI variables can be found [here](https://github.com/rubysamurai/mui-sass/blob/master/vendor/assets/stylesheets/mui/_variables.scss)
116
+
117
+ ## Contributing
118
+
119
+ Fork the project and submit a pull request.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'mui-sass'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/lib/mui-sass.rb ADDED
@@ -0,0 +1,60 @@
1
+ module Mui
2
+ module Sass
3
+ class << self
4
+ def load!
5
+ if defined?(::Compass::Frameworks)
6
+ register_compass_extension
7
+ elsif defined?(::Rails)
8
+ register_rails_engine
9
+ elsif defined?(::Sprockets)
10
+ register_sprockets
11
+ end
12
+
13
+ configure_sass
14
+ end
15
+
16
+ def gem_path
17
+ @gem_path ||= File.expand_path('..', File.dirname(__FILE__))
18
+ end
19
+
20
+ def stylesheets_path
21
+ File.join(gem_path, 'vendor/assets/stylesheets')
22
+ end
23
+
24
+ def javascripts_path
25
+ File.join(gem_path, 'vendor/assets/javascripts')
26
+ end
27
+
28
+ private
29
+
30
+ def configure_sass
31
+ require 'sass'
32
+
33
+ ::Sass.load_paths << stylesheets_path
34
+ end
35
+
36
+ def register_compass_extension
37
+ require 'mui/sass/version'
38
+
39
+ ::Compass::Frameworks.register(
40
+ 'mui',
41
+ version: Mui::Sass::VERSION,
42
+ path: gem_path,
43
+ stylesheets_directory: stylesheets_path,
44
+ templates_directory: File.join(gem_path, 'templates')
45
+ )
46
+ end
47
+
48
+ def register_rails_engine
49
+ require 'mui/sass/engine'
50
+ end
51
+
52
+ def register_sprockets
53
+ Sprockets.append_path(stylesheets_path)
54
+ Sprockets.append_path(javascripts_path)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ Mui::Sass.load!
@@ -0,0 +1,13 @@
1
+ module Mui
2
+ module Sass
3
+ module Rails
4
+ class Engine < ::Rails::Engine
5
+ initializer 'mui-sass.assets.precompile' do |app|
6
+ %w(stylesheets javascripts).each do |sub|
7
+ app.config.assets.paths << root.join('vendor/assets', sub).to_s
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Mui
2
+ module Sass
3
+ VERSION = '0.1.19'
4
+ end
5
+ end
data/mui-sass.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mui/sass/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'mui-sass'
8
+ spec.version = Mui::Sass::VERSION
9
+ spec.authors = ['Dmitriy Tarasov']
10
+ spec.email = ['info@rubysamurai.com']
11
+
12
+ spec.summary = 'MUI framework, powered by Sass and ready to use in Ruby projects'
13
+ spec.description = 'MUI framework, powered by Sass and ready to use in Ruby projects'
14
+ spec.homepage = 'https://github.com/rubysamurai/mui-sass'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.required_ruby_version = '>= 1.9.3'
23
+
24
+ spec.add_runtime_dependency 'sass', '~> 3.3'
25
+
26
+ spec.add_development_dependency 'rspec', '~> 3.3'
27
+ spec.add_development_dependency 'compass', '~> 1.0'
28
+ spec.add_development_dependency 'rails', '~> 4.0'
29
+ end
@@ -0,0 +1,2 @@
1
+ description 'MUI CSS for Sass'
2
+ stylesheet 'styles.sass'
@@ -0,0 +1 @@
1
+ @import 'mui'
@@ -0,0 +1,1593 @@
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
+ /**
1140
+ * MUI CSS/JS main module
1141
+ * @module main
1142
+ */
1143
+
1144
+ (function(win) {
1145
+ 'use strict';
1146
+
1147
+ // return if library has been loaded already
1148
+ if (win._muiLoadedJS) return;
1149
+ else win._muiLoadedJS = true;
1150
+
1151
+ // load dependencies
1152
+ var jqLite = require('./lib/jqLite.js'),
1153
+ util = require('./lib/util.js'),
1154
+ formControl = require('./forms/form-control.js'),
1155
+ select = require('./forms/select.js'),
1156
+ ripple = require('./ripple.js'),
1157
+ dropdowns = require('./dropdowns.js'),
1158
+ tabs = require('./tabs.js'),
1159
+ overlay = require('./overlay.js');
1160
+
1161
+ // expose api
1162
+ win.mui = {
1163
+ overlay: overlay,
1164
+ tabs: tabs.api
1165
+ };
1166
+
1167
+ // init libraries
1168
+ jqLite.ready(function() {
1169
+ formControl.initListeners();
1170
+ select.initListeners();
1171
+ ripple.initListeners();
1172
+ dropdowns.initListeners();
1173
+ tabs.initListeners();
1174
+ });
1175
+ })(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]);