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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +108 -0
- data/Rakefile +4 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/material_design_lite-sass.rb +46 -0
- data/lib/material_design_lite/sass/engine.rb +13 -0
- data/lib/material_design_lite/sass/version.rb +5 -0
- data/material_design_lite-sass.gemspec +28 -0
- data/vendor/assets/javascripts/material.js +3919 -0
- data/vendor/assets/javascripts/material/button.js +132 -0
- data/vendor/assets/javascripts/material/checkbox.js +265 -0
- data/vendor/assets/javascripts/material/data-table.js +149 -0
- data/vendor/assets/javascripts/material/icon-toggle.js +248 -0
- data/vendor/assets/javascripts/material/layout.js +434 -0
- data/vendor/assets/javascripts/material/mdlComponentHandler.js +346 -0
- data/vendor/assets/javascripts/material/menu.js +468 -0
- data/vendor/assets/javascripts/material/progress.js +116 -0
- data/vendor/assets/javascripts/material/rAF.js +38 -0
- data/vendor/assets/javascripts/material/radio.js +257 -0
- data/vendor/assets/javascripts/material/ripple.js +244 -0
- data/vendor/assets/javascripts/material/slider.js +252 -0
- data/vendor/assets/javascripts/material/spinner.js +140 -0
- data/vendor/assets/javascripts/material/switch.js +269 -0
- data/vendor/assets/javascripts/material/tabs.js +152 -0
- data/vendor/assets/javascripts/material/textfield.js +247 -0
- data/vendor/assets/javascripts/material/tooltip.js +146 -0
- data/vendor/assets/stylesheets/_material.scss +50 -0
- data/vendor/assets/stylesheets/material/_animation.scss +34 -0
- data/vendor/assets/stylesheets/material/_badge.scss +66 -0
- data/vendor/assets/stylesheets/material/_button.scss +298 -0
- data/vendor/assets/stylesheets/material/_card.scss +111 -0
- data/vendor/assets/stylesheets/material/_checkbox.scss +175 -0
- data/vendor/assets/stylesheets/material/_color-definitions.scss +599 -0
- data/vendor/assets/stylesheets/material/_data-table.scss +105 -0
- data/vendor/assets/stylesheets/material/_functions.scss +3 -0
- data/vendor/assets/stylesheets/material/_grid.scss +180 -0
- data/vendor/assets/stylesheets/material/_icon-toggle.scss +121 -0
- data/vendor/assets/stylesheets/material/_layout.scss +580 -0
- data/vendor/assets/stylesheets/material/_mega_footer.scss +309 -0
- data/vendor/assets/stylesheets/material/_menu.scss +193 -0
- data/vendor/assets/stylesheets/material/_mini_footer.scss +88 -0
- data/vendor/assets/stylesheets/material/_mixins.scss +268 -0
- data/vendor/assets/stylesheets/material/_palette.scss +2303 -0
- data/vendor/assets/stylesheets/material/_progress.scss +115 -0
- data/vendor/assets/stylesheets/material/_radio.scss +155 -0
- data/vendor/assets/stylesheets/material/_resets.scss +55 -0
- data/vendor/assets/stylesheets/material/_ripple.scss +42 -0
- data/vendor/assets/stylesheets/material/_shadow.scss +42 -0
- data/vendor/assets/stylesheets/material/_slider.scss +396 -0
- data/vendor/assets/stylesheets/material/_spinner.scss +248 -0
- data/vendor/assets/stylesheets/material/_switch.scss +199 -0
- data/vendor/assets/stylesheets/material/_tabs.scss +115 -0
- data/vendor/assets/stylesheets/material/_textfield.scss +190 -0
- data/vendor/assets/stylesheets/material/_tooltip.scss +66 -0
- data/vendor/assets/stylesheets/material/_typography.scss +297 -0
- data/vendor/assets/stylesheets/material/_variables.scss +572 -0
- data/vendor/assets/stylesheets/material/resets/_h5bp.scss +284 -0
- data/vendor/assets/stylesheets/material/resets/_mobile.scss +25 -0
- 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
|
+
});
|