material_design_lite-sass 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -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 +108 -0
  9. data/Rakefile +4 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +7 -0
  12. data/lib/material_design_lite-sass.rb +46 -0
  13. data/lib/material_design_lite/sass/engine.rb +13 -0
  14. data/lib/material_design_lite/sass/version.rb +5 -0
  15. data/material_design_lite-sass.gemspec +28 -0
  16. data/vendor/assets/javascripts/material.js +3919 -0
  17. data/vendor/assets/javascripts/material/button.js +132 -0
  18. data/vendor/assets/javascripts/material/checkbox.js +265 -0
  19. data/vendor/assets/javascripts/material/data-table.js +149 -0
  20. data/vendor/assets/javascripts/material/icon-toggle.js +248 -0
  21. data/vendor/assets/javascripts/material/layout.js +434 -0
  22. data/vendor/assets/javascripts/material/mdlComponentHandler.js +346 -0
  23. data/vendor/assets/javascripts/material/menu.js +468 -0
  24. data/vendor/assets/javascripts/material/progress.js +116 -0
  25. data/vendor/assets/javascripts/material/rAF.js +38 -0
  26. data/vendor/assets/javascripts/material/radio.js +257 -0
  27. data/vendor/assets/javascripts/material/ripple.js +244 -0
  28. data/vendor/assets/javascripts/material/slider.js +252 -0
  29. data/vendor/assets/javascripts/material/spinner.js +140 -0
  30. data/vendor/assets/javascripts/material/switch.js +269 -0
  31. data/vendor/assets/javascripts/material/tabs.js +152 -0
  32. data/vendor/assets/javascripts/material/textfield.js +247 -0
  33. data/vendor/assets/javascripts/material/tooltip.js +146 -0
  34. data/vendor/assets/stylesheets/_material.scss +50 -0
  35. data/vendor/assets/stylesheets/material/_animation.scss +34 -0
  36. data/vendor/assets/stylesheets/material/_badge.scss +66 -0
  37. data/vendor/assets/stylesheets/material/_button.scss +298 -0
  38. data/vendor/assets/stylesheets/material/_card.scss +111 -0
  39. data/vendor/assets/stylesheets/material/_checkbox.scss +175 -0
  40. data/vendor/assets/stylesheets/material/_color-definitions.scss +599 -0
  41. data/vendor/assets/stylesheets/material/_data-table.scss +105 -0
  42. data/vendor/assets/stylesheets/material/_functions.scss +3 -0
  43. data/vendor/assets/stylesheets/material/_grid.scss +180 -0
  44. data/vendor/assets/stylesheets/material/_icon-toggle.scss +121 -0
  45. data/vendor/assets/stylesheets/material/_layout.scss +580 -0
  46. data/vendor/assets/stylesheets/material/_mega_footer.scss +309 -0
  47. data/vendor/assets/stylesheets/material/_menu.scss +193 -0
  48. data/vendor/assets/stylesheets/material/_mini_footer.scss +88 -0
  49. data/vendor/assets/stylesheets/material/_mixins.scss +268 -0
  50. data/vendor/assets/stylesheets/material/_palette.scss +2303 -0
  51. data/vendor/assets/stylesheets/material/_progress.scss +115 -0
  52. data/vendor/assets/stylesheets/material/_radio.scss +155 -0
  53. data/vendor/assets/stylesheets/material/_resets.scss +55 -0
  54. data/vendor/assets/stylesheets/material/_ripple.scss +42 -0
  55. data/vendor/assets/stylesheets/material/_shadow.scss +42 -0
  56. data/vendor/assets/stylesheets/material/_slider.scss +396 -0
  57. data/vendor/assets/stylesheets/material/_spinner.scss +248 -0
  58. data/vendor/assets/stylesheets/material/_switch.scss +199 -0
  59. data/vendor/assets/stylesheets/material/_tabs.scss +115 -0
  60. data/vendor/assets/stylesheets/material/_textfield.scss +190 -0
  61. data/vendor/assets/stylesheets/material/_tooltip.scss +66 -0
  62. data/vendor/assets/stylesheets/material/_typography.scss +297 -0
  63. data/vendor/assets/stylesheets/material/_variables.scss +572 -0
  64. data/vendor/assets/stylesheets/material/resets/_h5bp.scss +284 -0
  65. data/vendor/assets/stylesheets/material/resets/_mobile.scss +25 -0
  66. metadata +151 -0
@@ -0,0 +1,252 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2015 Google Inc. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Class constructor for Slider MDL component.
20
+ * Implements MDL component design pattern defined at:
21
+ * https://github.com/jasonmayes/mdl-component-design-pattern
22
+ * @param {HTMLElement} element The element that will be upgraded.
23
+ */
24
+ function MaterialSlider(element) {
25
+ 'use strict';
26
+
27
+ this.element_ = element;
28
+ // Browser feature detection.
29
+ this.isIE_ = window.navigator.msPointerEnabled;
30
+ // Initialize instance.
31
+ this.init();
32
+ }
33
+
34
+ /**
35
+ * Store constants in one place so they can be updated easily.
36
+ * @enum {string | number}
37
+ * @private
38
+ */
39
+ MaterialSlider.prototype.Constant_ = {
40
+ // None for now.
41
+ };
42
+
43
+ /**
44
+ * Store strings for class names defined by this component that are used in
45
+ * JavaScript. This allows us to simply change it in one place should we
46
+ * decide to modify at a later date.
47
+ * @enum {string}
48
+ * @private
49
+ */
50
+ MaterialSlider.prototype.CssClasses_ = {
51
+ IE_CONTAINER: 'mdl-slider__ie-container',
52
+ SLIDER_CONTAINER: 'mdl-slider__container',
53
+ BACKGROUND_FLEX: 'mdl-slider__background-flex',
54
+ BACKGROUND_LOWER: 'mdl-slider__background-lower',
55
+ BACKGROUND_UPPER: 'mdl-slider__background-upper',
56
+ IS_LOWEST_VALUE: 'is-lowest-value',
57
+ IS_UPGRADED: 'is-upgraded'
58
+ };
59
+
60
+ /**
61
+ * Handle input on element.
62
+ * @param {Event} event The event that fired.
63
+ * @private
64
+ */
65
+ MaterialSlider.prototype.onInput_ = function(event) {
66
+ 'use strict';
67
+
68
+ this.updateValueStyles_();
69
+ };
70
+
71
+ /**
72
+ * Handle change on element.
73
+ * @param {Event} event The event that fired.
74
+ * @private
75
+ */
76
+ MaterialSlider.prototype.onChange_ = function(event) {
77
+ 'use strict';
78
+
79
+ this.updateValueStyles_();
80
+ };
81
+
82
+ /**
83
+ * Handle mouseup on element.
84
+ * @param {Event} event The event that fired.
85
+ * @private
86
+ */
87
+ MaterialSlider.prototype.onMouseUp_ = function(event) {
88
+ 'use strict';
89
+
90
+ event.target.blur();
91
+ };
92
+
93
+ /**
94
+ * Handle mousedown on container element.
95
+ * This handler is purpose is to not require the use to click
96
+ * exactly on the 2px slider element, as FireFox seems to be very
97
+ * strict about this.
98
+ * @param {Event} event The event that fired.
99
+ * @private
100
+ */
101
+ MaterialSlider.prototype.onContainerMouseDown_ = function(event) {
102
+ 'use strict';
103
+
104
+ // If this click is not on the parent element (but rather some child)
105
+ // ignore. It may still bubble up.
106
+ if (event.target !== this.element_.parentElement) {
107
+ return;
108
+ }
109
+
110
+ // Discard the original event and create a new event that
111
+ // is on the slider element.
112
+ event.preventDefault();
113
+ var newEvent = new MouseEvent('mousedown', {
114
+ target: event.target,
115
+ buttons: event.buttons,
116
+ clientX: event.clientX,
117
+ clientY: this.element_.getBoundingClientRect().y
118
+ });
119
+ this.element_.dispatchEvent(newEvent);
120
+ };
121
+
122
+ /**
123
+ * Handle updating of values.
124
+ * @param {Event} event The event that fired.
125
+ * @private
126
+ */
127
+ MaterialSlider.prototype.updateValueStyles_ = function(event) {
128
+ 'use strict';
129
+
130
+ // Calculate and apply percentages to div structure behind slider.
131
+ var fraction = (this.element_.value - this.element_.min) /
132
+ (this.element_.max - this.element_.min);
133
+
134
+ if (fraction === 0) {
135
+ this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE);
136
+ } else {
137
+ this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE);
138
+ }
139
+
140
+ if (!this.isIE_) {
141
+ this.backgroundLower_.style.flex = fraction;
142
+ this.backgroundLower_.style.webkitFlex = fraction;
143
+ this.backgroundUpper_.style.flex = 1 - fraction;
144
+ this.backgroundUpper_.style.webkitFlex = 1 - fraction;
145
+ }
146
+ };
147
+
148
+ // Public methods.
149
+
150
+ /**
151
+ * Disable slider.
152
+ * @public
153
+ */
154
+ MaterialSlider.prototype.disable = function() {
155
+ 'use strict';
156
+
157
+ this.element_.disabled = true;
158
+ };
159
+
160
+ /**
161
+ * Enable slider.
162
+ * @public
163
+ */
164
+ MaterialSlider.prototype.enable = function() {
165
+ 'use strict';
166
+
167
+ this.element_.disabled = false;
168
+ };
169
+
170
+ /**
171
+ * Update slider value.
172
+ * @param {Number} value The value to which to set the control (optional).
173
+ * @public
174
+ */
175
+ MaterialSlider.prototype.change = function(value) {
176
+ 'use strict';
177
+
178
+ if (value) {
179
+ this.element_.value = value;
180
+ }
181
+ this.updateValueStyles_();
182
+ };
183
+
184
+ /**
185
+ * Initialize element.
186
+ */
187
+ MaterialSlider.prototype.init = function() {
188
+ 'use strict';
189
+
190
+ if (this.element_) {
191
+ if (this.isIE_) {
192
+ // Since we need to specify a very large height in IE due to
193
+ // implementation limitations, we add a parent here that trims it down to
194
+ // a reasonable size.
195
+ var containerIE = document.createElement('div');
196
+ containerIE.classList.add(this.CssClasses_.IE_CONTAINER);
197
+ this.element_.parentElement.insertBefore(containerIE, this.element_);
198
+ this.element_.parentElement.removeChild(this.element_);
199
+ containerIE.appendChild(this.element_);
200
+ } else {
201
+ // For non-IE browsers, we need a div structure that sits behind the
202
+ // slider and allows us to style the left and right sides of it with
203
+ // different colors.
204
+ var container = document.createElement('div');
205
+ container.classList.add(this.CssClasses_.SLIDER_CONTAINER);
206
+ this.element_.parentElement.insertBefore(container, this.element_);
207
+ this.element_.parentElement.removeChild(this.element_);
208
+ container.appendChild(this.element_);
209
+ var backgroundFlex = document.createElement('div');
210
+ backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX);
211
+ container.appendChild(backgroundFlex);
212
+ this.backgroundLower_ = document.createElement('div');
213
+ this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER);
214
+ backgroundFlex.appendChild(this.backgroundLower_);
215
+ this.backgroundUpper_ = document.createElement('div');
216
+ this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER);
217
+ backgroundFlex.appendChild(this.backgroundUpper_);
218
+ }
219
+
220
+ this.boundInputHandler = this.onInput_.bind(this);
221
+ this.boundChangeHandler = this.onChange_.bind(this);
222
+ this.boundMouseUpHandler = this.onMouseUp_.bind(this);
223
+ this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this);
224
+ this.element_.addEventListener('input', this.boundInputHandler);
225
+ this.element_.addEventListener('change', this.boundChangeHandler);
226
+ this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
227
+ this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler);
228
+
229
+ this.updateValueStyles_();
230
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
231
+ }
232
+ };
233
+
234
+ /*
235
+ * Downgrade the component
236
+ */
237
+ MaterialSlider.prototype.mdlDowngrade_ = function() {
238
+ 'use strict';
239
+ this.element_.removeEventListener('input', this.boundInputHandler);
240
+ this.element_.removeEventListener('change', this.boundChangeHandler);
241
+ this.element_.removeEventListener('mouseup', this.boundMouseUpHandler);
242
+ this.element_.parentElement.removeEventListener('mousedown', this.boundContainerMouseDownHandler);
243
+ };
244
+
245
+ // The component registers itself. It can assume componentHandler is available
246
+ // in the global scope.
247
+ componentHandler.register({
248
+ constructor: MaterialSlider,
249
+ classAsString: 'MaterialSlider',
250
+ cssClass: 'mdl-js-slider',
251
+ widget: true
252
+ });
@@ -0,0 +1,140 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2015 Google Inc. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Class constructor for Spinner MDL component.
20
+ * Implements MDL component design pattern defined at:
21
+ * https://github.com/jasonmayes/mdl-component-design-pattern
22
+ * @param {HTMLElement} element The element that will be upgraded.
23
+ * @constructor
24
+ */
25
+ function MaterialSpinner(element) {
26
+ 'use strict';
27
+
28
+ this.element_ = element;
29
+
30
+ // Initialize instance.
31
+ this.init();
32
+ }
33
+
34
+ /**
35
+ * Store constants in one place so they can be updated easily.
36
+ * @enum {string | number}
37
+ * @private
38
+ */
39
+ MaterialSpinner.prototype.Constant_ = {
40
+ MDL_SPINNER_LAYER_COUNT: 4
41
+ };
42
+
43
+ /**
44
+ * Store strings for class names defined by this component that are used in
45
+ * JavaScript. This allows us to simply change it in one place should we
46
+ * decide to modify at a later date.
47
+ * @enum {string}
48
+ * @private
49
+ */
50
+ MaterialSpinner.prototype.CssClasses_ = {
51
+ MDL_SPINNER_LAYER: 'mdl-spinner__layer',
52
+ MDL_SPINNER_CIRCLE_CLIPPER: 'mdl-spinner__circle-clipper',
53
+ MDL_SPINNER_CIRCLE: 'mdl-spinner__circle',
54
+ MDL_SPINNER_GAP_PATCH: 'mdl-spinner__gap-patch',
55
+ MDL_SPINNER_LEFT: 'mdl-spinner__left',
56
+ MDL_SPINNER_RIGHT: 'mdl-spinner__right'
57
+ };
58
+
59
+ /**
60
+ * Auxiliary method to create a spinner layer.
61
+ */
62
+ MaterialSpinner.prototype.createLayer = function(index) {
63
+ 'use strict';
64
+
65
+ var layer = document.createElement('div');
66
+ layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER);
67
+ layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER + '-' + index);
68
+
69
+ var leftClipper = document.createElement('div');
70
+ leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);
71
+ leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);
72
+
73
+ var gapPatch = document.createElement('div');
74
+ gapPatch.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);
75
+
76
+ var rightClipper = document.createElement('div');
77
+ rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);
78
+ rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);
79
+
80
+ var circleOwners = [leftClipper, gapPatch, rightClipper];
81
+
82
+ for (var i = 0; i < circleOwners.length; i++) {
83
+ var circle = document.createElement('div');
84
+ circle.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE);
85
+ circleOwners[i].appendChild(circle);
86
+ }
87
+
88
+ layer.appendChild(leftClipper);
89
+ layer.appendChild(gapPatch);
90
+ layer.appendChild(rightClipper);
91
+
92
+ this.element_.appendChild(layer);
93
+ };
94
+
95
+ /**
96
+ * Stops the spinner animation.
97
+ * Public method for users who need to stop the spinner for any reason.
98
+ * @public
99
+ */
100
+ MaterialSpinner.prototype.stop = function() {
101
+ 'use strict';
102
+
103
+ this.element_.classList.remove('is-active');
104
+ };
105
+
106
+ /**
107
+ * Starts the spinner animation.
108
+ * Public method for users who need to manually start the spinner for any reason
109
+ * (instead of just adding the 'is-active' class to their markup).
110
+ * @public
111
+ */
112
+ MaterialSpinner.prototype.start = function() {
113
+ 'use strict';
114
+
115
+ this.element_.classList.add('is-active');
116
+ };
117
+
118
+ /**
119
+ * Initialize element.
120
+ */
121
+ MaterialSpinner.prototype.init = function() {
122
+ 'use strict';
123
+
124
+ if (this.element_) {
125
+ for (var i = 1; i <= this.Constant_.MDL_SPINNER_LAYER_COUNT; i++) {
126
+ this.createLayer(i);
127
+ }
128
+
129
+ this.element_.classList.add('is-upgraded');
130
+ }
131
+ };
132
+
133
+ // The component registers itself. It can assume componentHandler is available
134
+ // in the global scope.
135
+ componentHandler.register({
136
+ constructor: MaterialSpinner,
137
+ classAsString: 'MaterialSpinner',
138
+ cssClass: 'mdl-js-spinner',
139
+ widget: true
140
+ });
@@ -0,0 +1,269 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2015 Google Inc. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Class constructor for Checkbox MDL component.
20
+ * Implements MDL component design pattern defined at:
21
+ * https://github.com/jasonmayes/mdl-component-design-pattern
22
+ * @param {HTMLElement} element The element that will be upgraded.
23
+ */
24
+ function MaterialSwitch(element) {
25
+ 'use strict';
26
+
27
+ this.element_ = element;
28
+
29
+ // Initialize instance.
30
+ this.init();
31
+ }
32
+
33
+ /**
34
+ * Store constants in one place so they can be updated easily.
35
+ * @enum {string | number}
36
+ * @private
37
+ */
38
+ MaterialSwitch.prototype.Constant_ = {
39
+ TINY_TIMEOUT: 0.001
40
+ };
41
+
42
+ /**
43
+ * Store strings for class names defined by this component that are used in
44
+ * JavaScript. This allows us to simply change it in one place should we
45
+ * decide to modify at a later date.
46
+ * @enum {string}
47
+ * @private
48
+ */
49
+ MaterialSwitch.prototype.CssClasses_ = {
50
+ INPUT: 'mdl-switch__input',
51
+ TRACK: 'mdl-switch__track',
52
+ THUMB: 'mdl-switch__thumb',
53
+ FOCUS_HELPER: 'mdl-switch__focus-helper',
54
+ RIPPLE_EFFECT: 'mdl-js-ripple-effect',
55
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
56
+ RIPPLE_CONTAINER: 'mdl-switch__ripple-container',
57
+ RIPPLE_CENTER: 'mdl-ripple--center',
58
+ RIPPLE: 'mdl-ripple',
59
+ IS_FOCUSED: 'is-focused',
60
+ IS_DISABLED: 'is-disabled',
61
+ IS_CHECKED: 'is-checked'
62
+ };
63
+
64
+ /**
65
+ * Handle change of state.
66
+ * @param {Event} event The event that fired.
67
+ * @private
68
+ */
69
+ MaterialSwitch.prototype.onChange_ = function(event) {
70
+ 'use strict';
71
+
72
+ this.updateClasses_();
73
+ };
74
+
75
+ /**
76
+ * Handle focus of element.
77
+ * @param {Event} event The event that fired.
78
+ * @private
79
+ */
80
+ MaterialSwitch.prototype.onFocus_ = function(event) {
81
+ 'use strict';
82
+
83
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
84
+ };
85
+
86
+ /**
87
+ * Handle lost focus of element.
88
+ * @param {Event} event The event that fired.
89
+ * @private
90
+ */
91
+ MaterialSwitch.prototype.onBlur_ = function(event) {
92
+ 'use strict';
93
+
94
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
95
+ };
96
+
97
+ /**
98
+ * Handle mouseup.
99
+ * @param {Event} event The event that fired.
100
+ * @private
101
+ */
102
+ MaterialSwitch.prototype.onMouseUp_ = function(event) {
103
+ 'use strict';
104
+
105
+ this.blur_();
106
+ };
107
+
108
+ /**
109
+ * Handle class updates.
110
+ * @param {HTMLElement} button The button whose classes we should update.
111
+ * @param {HTMLElement} label The label whose classes we should update.
112
+ * @private
113
+ */
114
+ MaterialSwitch.prototype.updateClasses_ = function() {
115
+ 'use strict';
116
+
117
+ if (this.inputElement_.disabled) {
118
+ this.element_.classList.add(this.CssClasses_.IS_DISABLED);
119
+ } else {
120
+ this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
121
+ }
122
+
123
+ if (this.inputElement_.checked) {
124
+ this.element_.classList.add(this.CssClasses_.IS_CHECKED);
125
+ } else {
126
+ this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
127
+ }
128
+ };
129
+
130
+ /**
131
+ * Add blur.
132
+ * @private
133
+ */
134
+ MaterialSwitch.prototype.blur_ = function(event) {
135
+ 'use strict';
136
+
137
+ // TODO: figure out why there's a focus event being fired after our blur,
138
+ // so that we can avoid this hack.
139
+ window.setTimeout(function() {
140
+ this.inputElement_.blur();
141
+ }.bind(this), this.Constant_.TINY_TIMEOUT);
142
+ };
143
+
144
+ // Public methods.
145
+
146
+ /**
147
+ * Disable switch.
148
+ * @public
149
+ */
150
+ MaterialSwitch.prototype.disable = function() {
151
+ 'use strict';
152
+
153
+ this.inputElement_.disabled = true;
154
+ this.updateClasses_();
155
+ };
156
+
157
+ /**
158
+ * Enable switch.
159
+ * @public
160
+ */
161
+ MaterialSwitch.prototype.enable = function() {
162
+ 'use strict';
163
+
164
+ this.inputElement_.disabled = false;
165
+ this.updateClasses_();
166
+ };
167
+
168
+ /**
169
+ * Activate switch.
170
+ * @public
171
+ */
172
+ MaterialSwitch.prototype.on = function() {
173
+ 'use strict';
174
+
175
+ this.inputElement_.checked = true;
176
+ this.updateClasses_();
177
+ };
178
+
179
+ /**
180
+ * Deactivate switch.
181
+ * @public
182
+ */
183
+ MaterialSwitch.prototype.off = function() {
184
+ 'use strict';
185
+
186
+ this.inputElement_.checked = false;
187
+ this.updateClasses_();
188
+ };
189
+
190
+ /**
191
+ * Initialize element.
192
+ */
193
+ MaterialSwitch.prototype.init = function() {
194
+ 'use strict';
195
+
196
+ if (this.element_) {
197
+ this.inputElement_ = this.element_.querySelector('.' +
198
+ this.CssClasses_.INPUT);
199
+
200
+ var track = document.createElement('div');
201
+ track.classList.add(this.CssClasses_.TRACK);
202
+
203
+ var thumb = document.createElement('div');
204
+ thumb.classList.add(this.CssClasses_.THUMB);
205
+
206
+ var focusHelper = document.createElement('span');
207
+ focusHelper.classList.add(this.CssClasses_.FOCUS_HELPER);
208
+
209
+ thumb.appendChild(focusHelper);
210
+
211
+ this.element_.appendChild(track);
212
+ this.element_.appendChild(thumb);
213
+
214
+ this.boundMouseUpHandler = this.onMouseUp_.bind(this);
215
+
216
+ if (this.element_.classList.contains(
217
+ this.CssClasses_.RIPPLE_EFFECT)) {
218
+ this.element_.classList.add(
219
+ this.CssClasses_.RIPPLE_IGNORE_EVENTS);
220
+ this.rippleContainerElement_ = document.createElement('span');
221
+ this.rippleContainerElement_.classList.add(
222
+ this.CssClasses_.RIPPLE_CONTAINER);
223
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);
224
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
225
+ this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler);
226
+
227
+ var ripple = document.createElement('span');
228
+ ripple.classList.add(this.CssClasses_.RIPPLE);
229
+
230
+ this.rippleContainerElement_.appendChild(ripple);
231
+ this.element_.appendChild(this.rippleContainerElement_);
232
+ }
233
+
234
+ this.boundChangeHandler = this.onChange_.bind(this);
235
+ this.boundFocusHandler = this.onFocus_.bind(this);
236
+ this.boundBlurHandler = this.onBlur_.bind(this);
237
+
238
+ this.inputElement_.addEventListener('change', this.boundChangeHandler);
239
+ this.inputElement_.addEventListener('focus', this.boundFocusHandler);
240
+ this.inputElement_.addEventListener('blur', this.boundBlurHandler);
241
+ this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
242
+
243
+ this.updateClasses_();
244
+ this.element_.classList.add('is-upgraded');
245
+ }
246
+ };
247
+
248
+ /*
249
+ * Downgrade the component.
250
+ */
251
+ MaterialSwitch.prototype.mdlDowngrade_ = function() {
252
+ 'use strict';
253
+ if (this.rippleContainerElement_) {
254
+ this.rippleContainerElement_.removeEventListener('mouseup', this.boundMouseUpHandler);
255
+ }
256
+ this.inputElement_.removeEventListener('change', this.boundChangeHandler);
257
+ this.inputElement_.removeEventListener('focus', this.boundFocusHandler);
258
+ this.inputElement_.removeEventListener('blur', this.boundBlurHandler);
259
+ this.element_.removeEventListener('mouseup', this.boundMouseUpHandler);
260
+ };
261
+
262
+ // The component registers itself. It can assume componentHandler is available
263
+ // in the global scope.
264
+ componentHandler.register({
265
+ constructor: MaterialSwitch,
266
+ classAsString: 'MaterialSwitch',
267
+ cssClass: 'mdl-js-switch',
268
+ widget: true
269
+ });