material_design_lite-sass 1.0.2.1 → 1.0.3
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/material_design_lite/sass/version.rb +1 -1
- data/vendor/assets/javascripts/material.js +2562 -2993
- data/vendor/assets/javascripts/material/button.js +114 -112
- data/vendor/assets/javascripts/material/checkbox.js +255 -260
- data/vendor/assets/javascripts/material/data-table.js +140 -124
- data/vendor/assets/javascripts/material/icon-toggle.js +239 -243
- data/vendor/assets/javascripts/material/layout.js +392 -388
- data/vendor/assets/javascripts/material/mdlComponentHandler.js +68 -27
- data/vendor/assets/javascripts/material/menu.js +430 -414
- data/vendor/assets/javascripts/material/progress.js +110 -97
- data/vendor/assets/javascripts/material/radio.js +244 -247
- data/vendor/assets/javascripts/material/ripple.js +220 -211
- data/vendor/assets/javascripts/material/slider.js +228 -228
- data/vendor/assets/javascripts/material/spinner.js +122 -119
- data/vendor/assets/javascripts/material/switch.js +246 -250
- data/vendor/assets/javascripts/material/tabs.js +129 -127
- data/vendor/assets/javascripts/material/textfield.js +221 -222
- data/vendor/assets/javascripts/material/tooltip.js +126 -122
- data/vendor/assets/stylesheets/material/_badge.scss +1 -1
- data/vendor/assets/stylesheets/material/_button.scss +15 -8
- data/vendor/assets/stylesheets/material/_card.scss +1 -1
- data/vendor/assets/stylesheets/material/_checkbox.scss +1 -1
- data/vendor/assets/stylesheets/material/_data-table.scss +5 -3
- data/vendor/assets/stylesheets/material/_functions.scss +16 -0
- data/vendor/assets/stylesheets/material/_grid.scss +11 -20
- data/vendor/assets/stylesheets/material/_layout.scss +7 -5
- data/vendor/assets/stylesheets/material/_menu.scss +4 -1
- data/vendor/assets/stylesheets/material/_radio.scss +1 -1
- data/vendor/assets/stylesheets/material/_slider.scss +1 -0
- data/vendor/assets/stylesheets/material/_switch.scss +1 -1
- data/vendor/assets/stylesheets/material/_tabs.scss +1 -1
- data/vendor/assets/stylesheets/material/_textfield.scss +15 -5
- data/vendor/assets/stylesheets/material/_tooltip.scss +2 -2
- data/vendor/assets/stylesheets/material/_variables.scss +18 -43
- data/vendor/assets/stylesheets/material/resets/_h5bp.scss +28 -21
- metadata +1 -1
@@ -15,230 +15,239 @@
|
|
15
15
|
* limitations under the License.
|
16
16
|
*/
|
17
17
|
|
18
|
-
|
19
|
-
* Class constructor for Ripple 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 MaterialRipple(element) {
|
18
|
+
(function() {
|
25
19
|
'use strict';
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
21
|
+
/**
|
22
|
+
* Class constructor for Ripple MDL component.
|
23
|
+
* Implements MDL component design pattern defined at:
|
24
|
+
* https://github.com/jasonmayes/mdl-component-design-pattern
|
25
|
+
*
|
26
|
+
* @param {HTMLElement} element The element that will be upgraded.
|
27
|
+
*/
|
28
|
+
var MaterialRipple = function MaterialRipple(element) {
|
29
|
+
this.element_ = element;
|
30
|
+
|
31
|
+
// Initialize instance.
|
32
|
+
this.init();
|
33
|
+
};
|
34
|
+
window.MaterialRipple = MaterialRipple;
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Store constants in one place so they can be updated easily.
|
38
|
+
*
|
39
|
+
* @enum {String | Number}
|
40
|
+
* @private
|
41
|
+
*/
|
42
|
+
MaterialRipple.prototype.Constant_ = {
|
43
|
+
INITIAL_SCALE: 'scale(0.0001, 0.0001)',
|
44
|
+
INITIAL_SIZE: '1px',
|
45
|
+
INITIAL_OPACITY: '0.4',
|
46
|
+
FINAL_OPACITY: '0',
|
47
|
+
FINAL_SCALE: ''
|
48
|
+
};
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Store strings for class names defined by this component that are used in
|
52
|
+
* JavaScript. This allows us to simply change it in one place should we
|
53
|
+
* decide to modify at a later date.
|
54
|
+
*
|
55
|
+
* @enum {String}
|
56
|
+
* @private
|
57
|
+
*/
|
58
|
+
MaterialRipple.prototype.CssClasses_ = {
|
59
|
+
RIPPLE_CENTER: 'mdl-ripple--center',
|
60
|
+
RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
|
61
|
+
RIPPLE: 'mdl-ripple',
|
62
|
+
IS_ANIMATING: 'is-animating',
|
63
|
+
IS_VISIBLE: 'is-visible'
|
64
|
+
};
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Handle mouse / finger down on element.
|
68
|
+
*
|
69
|
+
* @param {Event} event The event that fired.
|
70
|
+
* @private
|
71
|
+
*/
|
72
|
+
MaterialRipple.prototype.downHandler_ = function(event) {
|
73
|
+
if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) {
|
74
|
+
var rect = this.element_.getBoundingClientRect();
|
75
|
+
this.boundHeight = rect.height;
|
76
|
+
this.boundWidth = rect.width;
|
77
|
+
this.rippleSize_ = Math.sqrt(rect.width * rect.width +
|
78
|
+
rect.height * rect.height) * 2 + 2;
|
79
|
+
this.rippleElement_.style.width = this.rippleSize_ + 'px';
|
80
|
+
this.rippleElement_.style.height = this.rippleSize_ + 'px';
|
81
|
+
}
|
60
82
|
|
61
|
-
|
62
|
-
* Handle mouse / finger down on element.
|
63
|
-
* @param {Event} event The event that fired.
|
64
|
-
* @private
|
65
|
-
*/
|
66
|
-
MaterialRipple.prototype.downHandler_ = function(event) {
|
67
|
-
'use strict';
|
83
|
+
this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE);
|
68
84
|
|
69
|
-
|
70
|
-
|
71
|
-
this.boundHeight = rect.height;
|
72
|
-
this.boundWidth = rect.width;
|
73
|
-
this.rippleSize_ = Math.sqrt(rect.width * rect.width +
|
74
|
-
rect.height * rect.height) * 2 + 2;
|
75
|
-
this.rippleElement_.style.width = this.rippleSize_ + 'px';
|
76
|
-
this.rippleElement_.style.height = this.rippleSize_ + 'px';
|
77
|
-
}
|
78
|
-
|
79
|
-
this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE);
|
80
|
-
|
81
|
-
if (event.type === 'mousedown' && this.ignoringMouseDown_) {
|
82
|
-
this.ignoringMouseDown_ = false;
|
83
|
-
} else {
|
84
|
-
if (event.type === 'touchstart') {
|
85
|
-
this.ignoringMouseDown_ = true;
|
86
|
-
}
|
87
|
-
var frameCount = this.getFrameCount();
|
88
|
-
if (frameCount > 0) {
|
89
|
-
return;
|
90
|
-
}
|
91
|
-
this.setFrameCount(1);
|
92
|
-
var bound = event.currentTarget.getBoundingClientRect();
|
93
|
-
var x;
|
94
|
-
var y;
|
95
|
-
// Check if we are handling a keyboard click.
|
96
|
-
if (event.clientX === 0 && event.clientY === 0) {
|
97
|
-
x = Math.round(bound.width / 2);
|
98
|
-
y = Math.round(bound.height / 2);
|
85
|
+
if (event.type === 'mousedown' && this.ignoringMouseDown_) {
|
86
|
+
this.ignoringMouseDown_ = false;
|
99
87
|
} else {
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
88
|
+
if (event.type === 'touchstart') {
|
89
|
+
this.ignoringMouseDown_ = true;
|
90
|
+
}
|
91
|
+
var frameCount = this.getFrameCount();
|
92
|
+
if (frameCount > 0) {
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
this.setFrameCount(1);
|
96
|
+
var bound = event.currentTarget.getBoundingClientRect();
|
97
|
+
var x;
|
98
|
+
var y;
|
99
|
+
// Check if we are handling a keyboard click.
|
100
|
+
if (event.clientX === 0 && event.clientY === 0) {
|
101
|
+
x = Math.round(bound.width / 2);
|
102
|
+
y = Math.round(bound.height / 2);
|
103
|
+
} else {
|
104
|
+
var clientX = event.clientX ? event.clientX : event.touches[0].clientX;
|
105
|
+
var clientY = event.clientY ? event.clientY : event.touches[0].clientY;
|
106
|
+
x = Math.round(clientX - bound.left);
|
107
|
+
y = Math.round(clientY - bound.top);
|
108
|
+
}
|
109
|
+
this.setRippleXY(x, y);
|
110
|
+
this.setRippleStyles(true);
|
111
|
+
window.requestAnimationFrame(this.animFrameHandler.bind(this));
|
104
112
|
}
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
};
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
113
|
+
};
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Handle mouse / finger up on element.
|
117
|
+
*
|
118
|
+
* @param {Event} event The event that fired.
|
119
|
+
* @private
|
120
|
+
*/
|
121
|
+
MaterialRipple.prototype.upHandler_ = function(event) {
|
122
|
+
// Don't fire for the artificial "mouseup" generated by a double-click.
|
123
|
+
if (event && event.detail !== 2) {
|
124
|
+
this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE);
|
125
|
+
}
|
126
|
+
// Allow a repaint to occur before removing this class, so the animation
|
127
|
+
// shows for tap events, which seem to trigger a mouseup too soon after
|
128
|
+
// mousedown.
|
129
|
+
window.setTimeout(function() {
|
130
|
+
this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE);
|
131
|
+
}.bind(this), 0);
|
132
|
+
};
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Initialize element.
|
136
|
+
*/
|
137
|
+
MaterialRipple.prototype.init = function() {
|
138
|
+
if (this.element_) {
|
139
|
+
var recentering =
|
140
|
+
this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);
|
141
|
+
if (!this.element_.classList.contains(
|
142
|
+
this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) {
|
143
|
+
this.rippleElement_ = this.element_.querySelector('.' +
|
144
|
+
this.CssClasses_.RIPPLE);
|
145
|
+
this.frameCount_ = 0;
|
146
|
+
this.rippleSize_ = 0;
|
147
|
+
this.x_ = 0;
|
148
|
+
this.y_ = 0;
|
149
|
+
|
150
|
+
// Touch start produces a compat mouse down event, which would cause a
|
151
|
+
// second ripples. To avoid that, we use this property to ignore the first
|
152
|
+
// mouse down after a touch start.
|
153
|
+
this.ignoringMouseDown_ = false;
|
154
|
+
|
155
|
+
this.boundDownHandler = this.downHandler_.bind(this);
|
156
|
+
this.element_.addEventListener('mousedown',
|
157
|
+
this.boundDownHandler);
|
158
|
+
this.element_.addEventListener('touchstart',
|
159
|
+
this.boundDownHandler);
|
160
|
+
|
161
|
+
this.boundUpHandler = this.upHandler_.bind(this);
|
162
|
+
this.element_.addEventListener('mouseup', this.boundUpHandler);
|
163
|
+
this.element_.addEventListener('mouseleave', this.boundUpHandler);
|
164
|
+
this.element_.addEventListener('touchend', this.boundUpHandler);
|
165
|
+
this.element_.addEventListener('blur', this.boundUpHandler);
|
166
|
+
|
167
|
+
this.getFrameCount = function() {
|
168
|
+
return this.frameCount_;
|
169
|
+
};
|
170
|
+
|
171
|
+
this.setFrameCount = function(fC) {
|
172
|
+
this.frameCount_ = fC;
|
173
|
+
};
|
174
|
+
|
175
|
+
this.getRippleElement = function() {
|
176
|
+
return this.rippleElement_;
|
177
|
+
};
|
178
|
+
|
179
|
+
this.setRippleXY = function(newX, newY) {
|
180
|
+
this.x_ = newX;
|
181
|
+
this.y_ = newY;
|
182
|
+
};
|
183
|
+
|
184
|
+
this.setRippleStyles = function(start) {
|
185
|
+
if (this.rippleElement_ !== null) {
|
186
|
+
var transformString;
|
187
|
+
var scale;
|
188
|
+
var size;
|
189
|
+
var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';
|
190
|
+
|
191
|
+
if (start) {
|
192
|
+
scale = this.Constant_.INITIAL_SCALE;
|
193
|
+
size = this.Constant_.INITIAL_SIZE;
|
194
|
+
} else {
|
195
|
+
scale = this.Constant_.FINAL_SCALE;
|
196
|
+
size = this.rippleSize_ + 'px';
|
197
|
+
if (recentering) {
|
198
|
+
offset = 'translate(' + this.boundWidth / 2 + 'px, ' +
|
199
|
+
this.boundHeight / 2 + 'px)';
|
200
|
+
}
|
201
|
+
}
|
130
202
|
|
131
|
-
|
132
|
-
var recentering =
|
133
|
-
this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);
|
134
|
-
if (!this.element_.classList.contains(
|
135
|
-
this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) {
|
136
|
-
this.rippleElement_ = this.element_.querySelector('.' +
|
137
|
-
this.CssClasses_.RIPPLE);
|
138
|
-
this.frameCount_ = 0;
|
139
|
-
this.rippleSize_ = 0;
|
140
|
-
this.x_ = 0;
|
141
|
-
this.y_ = 0;
|
142
|
-
|
143
|
-
// Touch start produces a compat mouse down event, which would cause a
|
144
|
-
// second ripples. To avoid that, we use this property to ignore the first
|
145
|
-
// mouse down after a touch start.
|
146
|
-
this.ignoringMouseDown_ = false;
|
203
|
+
transformString = 'translate(-50%, -50%) ' + offset + scale;
|
147
204
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
this.element_.addEventListener('touchstart',
|
152
|
-
this.boundDownHandler);
|
205
|
+
this.rippleElement_.style.webkitTransform = transformString;
|
206
|
+
this.rippleElement_.style.msTransform = transformString;
|
207
|
+
this.rippleElement_.style.transform = transformString;
|
153
208
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
this.element_.addEventListener('blur', this.boundUpHandler);
|
159
|
-
|
160
|
-
this.getFrameCount = function() {
|
161
|
-
return this.frameCount_;
|
162
|
-
};
|
163
|
-
|
164
|
-
this.setFrameCount = function(fC) {
|
165
|
-
this.frameCount_ = fC;
|
166
|
-
};
|
167
|
-
|
168
|
-
this.getRippleElement = function() {
|
169
|
-
return this.rippleElement_;
|
170
|
-
};
|
171
|
-
|
172
|
-
this.setRippleXY = function(newX, newY) {
|
173
|
-
this.x_ = newX;
|
174
|
-
this.y_ = newY;
|
175
|
-
};
|
176
|
-
|
177
|
-
this.setRippleStyles = function(start) {
|
178
|
-
if (this.rippleElement_ !== null) {
|
179
|
-
var transformString;
|
180
|
-
var scale;
|
181
|
-
var size;
|
182
|
-
var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';
|
183
|
-
|
184
|
-
if (start) {
|
185
|
-
scale = this.Constant_.INITIAL_SCALE;
|
186
|
-
size = this.Constant_.INITIAL_SIZE;
|
187
|
-
} else {
|
188
|
-
scale = this.Constant_.FINAL_SCALE;
|
189
|
-
size = this.rippleSize_ + 'px';
|
190
|
-
if (recentering) {
|
191
|
-
offset = 'translate(' + this.boundWidth / 2 + 'px, ' +
|
192
|
-
this.boundHeight / 2 + 'px)';
|
209
|
+
if (start) {
|
210
|
+
this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING);
|
211
|
+
} else {
|
212
|
+
this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING);
|
193
213
|
}
|
194
214
|
}
|
215
|
+
};
|
195
216
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
this.rippleElement_.style.msTransform = transformString;
|
200
|
-
this.rippleElement_.style.transform = transformString;
|
201
|
-
|
202
|
-
if (start) {
|
203
|
-
this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING);
|
217
|
+
this.animFrameHandler = function() {
|
218
|
+
if (this.frameCount_-- > 0) {
|
219
|
+
window.requestAnimationFrame(this.animFrameHandler.bind(this));
|
204
220
|
} else {
|
205
|
-
this.
|
221
|
+
this.setRippleStyles(false);
|
206
222
|
}
|
207
|
-
}
|
208
|
-
}
|
209
|
-
|
210
|
-
this.animFrameHandler = function() {
|
211
|
-
if (this.frameCount_-- > 0) {
|
212
|
-
window.requestAnimationFrame(this.animFrameHandler.bind(this));
|
213
|
-
} else {
|
214
|
-
this.setRippleStyles(false);
|
215
|
-
}
|
216
|
-
};
|
223
|
+
};
|
224
|
+
}
|
217
225
|
}
|
218
|
-
}
|
219
|
-
|
226
|
+
};
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Downgrade the component
|
230
|
+
*
|
231
|
+
* @private
|
232
|
+
*/
|
233
|
+
MaterialRipple.prototype.mdlDowngrade_ = function() {
|
234
|
+
this.element_.removeEventListener('mousedown',
|
235
|
+
this.boundDownHandler);
|
236
|
+
this.element_.removeEventListener('touchstart',
|
237
|
+
this.boundDownHandler);
|
220
238
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
};
|
236
|
-
|
237
|
-
// The component registers itself. It can assume componentHandler is available
|
238
|
-
// in the global scope.
|
239
|
-
componentHandler.register({
|
240
|
-
constructor: MaterialRipple,
|
241
|
-
classAsString: 'MaterialRipple',
|
242
|
-
cssClass: 'mdl-js-ripple-effect',
|
243
|
-
widget: false
|
244
|
-
});
|
239
|
+
this.element_.removeEventListener('mouseup', this.boundUpHandler);
|
240
|
+
this.element_.removeEventListener('mouseleave', this.boundUpHandler);
|
241
|
+
this.element_.removeEventListener('touchend', this.boundUpHandler);
|
242
|
+
this.element_.removeEventListener('blur', this.boundUpHandler);
|
243
|
+
};
|
244
|
+
|
245
|
+
// The component registers itself. It can assume componentHandler is available
|
246
|
+
// in the global scope.
|
247
|
+
componentHandler.register({
|
248
|
+
constructor: MaterialRipple,
|
249
|
+
classAsString: 'MaterialRipple',
|
250
|
+
cssClass: 'mdl-js-ripple-effect',
|
251
|
+
widget: false
|
252
|
+
});
|
253
|
+
})();
|
@@ -15,238 +15,238 @@
|
|
15
15
|
* limitations under the License.
|
16
16
|
*/
|
17
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) {
|
18
|
+
(function() {
|
25
19
|
'use strict';
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
}
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
/**
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
}
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
};
|
70
|
-
|
71
|
-
/**
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
MaterialSlider.prototype.
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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';
|
21
|
+
/**
|
22
|
+
* Class constructor for Slider MDL component.
|
23
|
+
* Implements MDL component design pattern defined at:
|
24
|
+
* https://github.com/jasonmayes/mdl-component-design-pattern
|
25
|
+
*
|
26
|
+
* @param {HTMLElement} element The element that will be upgraded.
|
27
|
+
*/
|
28
|
+
var MaterialSlider = function MaterialSlider(element) {
|
29
|
+
this.element_ = element;
|
30
|
+
// Browser feature detection.
|
31
|
+
this.isIE_ = window.navigator.msPointerEnabled;
|
32
|
+
// Initialize instance.
|
33
|
+
this.init();
|
34
|
+
};
|
35
|
+
window.MaterialSlider = MaterialSlider;
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Store constants in one place so they can be updated easily.
|
39
|
+
*
|
40
|
+
* @enum {String | Number}
|
41
|
+
* @private
|
42
|
+
*/
|
43
|
+
MaterialSlider.prototype.Constant_ = {
|
44
|
+
// None for now.
|
45
|
+
};
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Store strings for class names defined by this component that are used in
|
49
|
+
* JavaScript. This allows us to simply change it in one place should we
|
50
|
+
* decide to modify at a later date.
|
51
|
+
*
|
52
|
+
* @enum {String}
|
53
|
+
* @private
|
54
|
+
*/
|
55
|
+
MaterialSlider.prototype.CssClasses_ = {
|
56
|
+
IE_CONTAINER: 'mdl-slider__ie-container',
|
57
|
+
SLIDER_CONTAINER: 'mdl-slider__container',
|
58
|
+
BACKGROUND_FLEX: 'mdl-slider__background-flex',
|
59
|
+
BACKGROUND_LOWER: 'mdl-slider__background-lower',
|
60
|
+
BACKGROUND_UPPER: 'mdl-slider__background-upper',
|
61
|
+
IS_LOWEST_VALUE: 'is-lowest-value',
|
62
|
+
IS_UPGRADED: 'is-upgraded'
|
63
|
+
};
|
64
|
+
|
65
|
+
/**
|
66
|
+
* Handle input on element.
|
67
|
+
*
|
68
|
+
* @param {Event} event The event that fired.
|
69
|
+
* @private
|
70
|
+
*/
|
71
|
+
MaterialSlider.prototype.onInput_ = function(event) {
|
72
|
+
this.updateValueStyles_();
|
73
|
+
};
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Handle change on element.
|
77
|
+
*
|
78
|
+
* @param {Event} event The event that fired.
|
79
|
+
* @private
|
80
|
+
*/
|
81
|
+
MaterialSlider.prototype.onChange_ = function(event) {
|
82
|
+
this.updateValueStyles_();
|
83
|
+
};
|
84
|
+
|
85
|
+
/**
|
86
|
+
* Handle mouseup on element.
|
87
|
+
*
|
88
|
+
* @param {Event} event The event that fired.
|
89
|
+
* @private
|
90
|
+
*/
|
91
|
+
MaterialSlider.prototype.onMouseUp_ = function(event) {
|
92
|
+
event.target.blur();
|
93
|
+
};
|
94
|
+
|
95
|
+
/**
|
96
|
+
* Handle mousedown on container element.
|
97
|
+
* This handler is purpose is to not require the use to click
|
98
|
+
* exactly on the 2px slider element, as FireFox seems to be very
|
99
|
+
* strict about this.
|
100
|
+
*
|
101
|
+
* @param {Event} event The event that fired.
|
102
|
+
* @private
|
103
|
+
*/
|
104
|
+
MaterialSlider.prototype.onContainerMouseDown_ = function(event) {
|
105
|
+
// If this click is not on the parent element (but rather some child)
|
106
|
+
// ignore. It may still bubble up.
|
107
|
+
if (event.target !== this.element_.parentElement) {
|
108
|
+
return;
|
109
|
+
}
|
189
110
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
this.element_.
|
198
|
-
|
199
|
-
|
111
|
+
// Discard the original event and create a new event that
|
112
|
+
// is on the slider element.
|
113
|
+
event.preventDefault();
|
114
|
+
var newEvent = new MouseEvent('mousedown', {
|
115
|
+
target: event.target,
|
116
|
+
buttons: event.buttons,
|
117
|
+
clientX: event.clientX,
|
118
|
+
clientY: this.element_.getBoundingClientRect().y
|
119
|
+
});
|
120
|
+
this.element_.dispatchEvent(newEvent);
|
121
|
+
};
|
122
|
+
|
123
|
+
/**
|
124
|
+
* Handle updating of values.
|
125
|
+
*
|
126
|
+
* @param {Event} event The event that fired.
|
127
|
+
* @private
|
128
|
+
*/
|
129
|
+
MaterialSlider.prototype.updateValueStyles_ = function(event) {
|
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);
|
200
136
|
} else {
|
201
|
-
|
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_);
|
137
|
+
this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE);
|
218
138
|
}
|
219
139
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
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
|
+
*
|
153
|
+
* @public
|
154
|
+
*/
|
155
|
+
MaterialSlider.prototype.disable = function() {
|
156
|
+
this.element_.disabled = true;
|
157
|
+
};
|
158
|
+
|
159
|
+
/**
|
160
|
+
* Enable slider.
|
161
|
+
*
|
162
|
+
* @public
|
163
|
+
*/
|
164
|
+
MaterialSlider.prototype.enable = function() {
|
165
|
+
|
166
|
+
this.element_.disabled = false;
|
167
|
+
};
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Update slider value.
|
171
|
+
*
|
172
|
+
* @param {Number} value The value to which to set the control (optional).
|
173
|
+
* @public
|
174
|
+
*/
|
175
|
+
MaterialSlider.prototype.change = function(value) {
|
176
|
+
|
177
|
+
if (typeof value !== 'undefined') {
|
178
|
+
this.element_.value = value;
|
179
|
+
}
|
229
180
|
this.updateValueStyles_();
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
181
|
+
};
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Initialize element.
|
185
|
+
*/
|
186
|
+
MaterialSlider.prototype.init = function() {
|
187
|
+
|
188
|
+
if (this.element_) {
|
189
|
+
if (this.isIE_) {
|
190
|
+
// Since we need to specify a very large height in IE due to
|
191
|
+
// implementation limitations, we add a parent here that trims it down to
|
192
|
+
// a reasonable size.
|
193
|
+
var containerIE = document.createElement('div');
|
194
|
+
containerIE.classList.add(this.CssClasses_.IE_CONTAINER);
|
195
|
+
this.element_.parentElement.insertBefore(containerIE, this.element_);
|
196
|
+
this.element_.parentElement.removeChild(this.element_);
|
197
|
+
containerIE.appendChild(this.element_);
|
198
|
+
} else {
|
199
|
+
// For non-IE browsers, we need a div structure that sits behind the
|
200
|
+
// slider and allows us to style the left and right sides of it with
|
201
|
+
// different colors.
|
202
|
+
var container = document.createElement('div');
|
203
|
+
container.classList.add(this.CssClasses_.SLIDER_CONTAINER);
|
204
|
+
this.element_.parentElement.insertBefore(container, this.element_);
|
205
|
+
this.element_.parentElement.removeChild(this.element_);
|
206
|
+
container.appendChild(this.element_);
|
207
|
+
var backgroundFlex = document.createElement('div');
|
208
|
+
backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX);
|
209
|
+
container.appendChild(backgroundFlex);
|
210
|
+
this.backgroundLower_ = document.createElement('div');
|
211
|
+
this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER);
|
212
|
+
backgroundFlex.appendChild(this.backgroundLower_);
|
213
|
+
this.backgroundUpper_ = document.createElement('div');
|
214
|
+
this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER);
|
215
|
+
backgroundFlex.appendChild(this.backgroundUpper_);
|
216
|
+
}
|
217
|
+
|
218
|
+
this.boundInputHandler = this.onInput_.bind(this);
|
219
|
+
this.boundChangeHandler = this.onChange_.bind(this);
|
220
|
+
this.boundMouseUpHandler = this.onMouseUp_.bind(this);
|
221
|
+
this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this);
|
222
|
+
this.element_.addEventListener('input', this.boundInputHandler);
|
223
|
+
this.element_.addEventListener('change', this.boundChangeHandler);
|
224
|
+
this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
|
225
|
+
this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler);
|
226
|
+
|
227
|
+
this.updateValueStyles_();
|
228
|
+
this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
|
229
|
+
}
|
230
|
+
};
|
231
|
+
|
232
|
+
/**
|
233
|
+
* Downgrade the component
|
234
|
+
*
|
235
|
+
* @private
|
236
|
+
*/
|
237
|
+
MaterialSlider.prototype.mdlDowngrade_ = function() {
|
238
|
+
this.element_.removeEventListener('input', this.boundInputHandler);
|
239
|
+
this.element_.removeEventListener('change', this.boundChangeHandler);
|
240
|
+
this.element_.removeEventListener('mouseup', this.boundMouseUpHandler);
|
241
|
+
this.element_.parentElement.removeEventListener('mousedown', this.boundContainerMouseDownHandler);
|
242
|
+
};
|
243
|
+
|
244
|
+
// The component registers itself. It can assume componentHandler is available
|
245
|
+
// in the global scope.
|
246
|
+
componentHandler.register({
|
247
|
+
constructor: MaterialSlider,
|
248
|
+
classAsString: 'MaterialSlider',
|
249
|
+
cssClass: 'mdl-js-slider',
|
250
|
+
widget: true
|
251
|
+
});
|
252
|
+
})();
|