material_design_lite-sass 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,116 @@
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 Progress 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 MaterialProgress(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
+ MaterialProgress.prototype.Constant_ = {
39
+ };
40
+
41
+ /**
42
+ * Store strings for class names defined by this component that are used in
43
+ * JavaScript. This allows us to simply change it in one place should we
44
+ * decide to modify at a later date.
45
+ * @enum {string}
46
+ * @private
47
+ */
48
+ MaterialProgress.prototype.CssClasses_ = {
49
+ INDETERMINATE_CLASS: 'mdl-progress__indeterminate'
50
+ };
51
+
52
+ MaterialProgress.prototype.setProgress = function(p) {
53
+ 'use strict';
54
+
55
+ if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) {
56
+ return;
57
+ }
58
+
59
+ this.progressbar_.style.width = p + '%';
60
+ };
61
+
62
+ MaterialProgress.prototype.setBuffer = function(p) {
63
+ 'use strict';
64
+
65
+ this.bufferbar_.style.width = p + '%';
66
+ this.auxbar_.style.width = (100 - p) + '%';
67
+ };
68
+
69
+ /**
70
+ * Initialize element.
71
+ */
72
+ MaterialProgress.prototype.init = function() {
73
+ 'use strict';
74
+
75
+ if (this.element_) {
76
+ var el = document.createElement('div');
77
+ el.className = 'progressbar bar bar1';
78
+ this.element_.appendChild(el);
79
+ this.progressbar_ = el;
80
+
81
+ el = document.createElement('div');
82
+ el.className = 'bufferbar bar bar2';
83
+ this.element_.appendChild(el);
84
+ this.bufferbar_ = el;
85
+
86
+ el = document.createElement('div');
87
+ el.className = 'auxbar bar bar3';
88
+ this.element_.appendChild(el);
89
+ this.auxbar_ = el;
90
+
91
+ this.progressbar_.style.width = '0%';
92
+ this.bufferbar_.style.width = '100%';
93
+ this.auxbar_.style.width = '0%';
94
+
95
+ this.element_.classList.add('is-upgraded');
96
+ }
97
+ };
98
+
99
+ /*
100
+ * Downgrade the component
101
+ */
102
+ MaterialProgress.prototype.mdlDowngrade_ = function() {
103
+ 'use strict';
104
+ while (this.element_.firstChild) {
105
+ this.element_.removeChild(this.element_.firstChild);
106
+ }
107
+ };
108
+
109
+ // The component registers itself. It can assume componentHandler is available
110
+ // in the global scope.
111
+ componentHandler.register({
112
+ constructor: MaterialProgress,
113
+ classAsString: 'MaterialProgress',
114
+ cssClass: 'mdl-js-progress',
115
+ widget: true
116
+ });
@@ -0,0 +1,38 @@
1
+ // Source: https://github.com/darius/requestAnimationFrame/blob/master/requestAnimationFrame.js
2
+ // Adapted from https://gist.github.com/paulirish/1579671 which derived from
3
+ // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
4
+ // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
5
+
6
+ // requestAnimationFrame polyfill by Erik Möller.
7
+ // Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon
8
+
9
+ // MIT license
10
+
11
+ (function() {
12
+ 'use strict';
13
+
14
+ if (!Date.now) {
15
+ Date.now = function() { return new Date().getTime(); };
16
+ }
17
+
18
+ var vendors = ['webkit', 'moz'];
19
+ for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
20
+ var vp = vendors[i];
21
+ window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];
22
+ window.cancelAnimationFrame = (window[vp + 'CancelAnimationFrame'] ||
23
+ window[vp + 'CancelRequestAnimationFrame']);
24
+ }
25
+
26
+ if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
27
+ var lastTime = 0;
28
+ window.requestAnimationFrame = function(callback) {
29
+ var now = Date.now();
30
+ var nextTime = Math.max(lastTime + 16, now);
31
+ return setTimeout(function() { callback(lastTime = nextTime); },
32
+ nextTime - now);
33
+ };
34
+ window.cancelAnimationFrame = clearTimeout;
35
+ }
36
+
37
+ })();
38
+
@@ -0,0 +1,257 @@
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 Radio 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 MaterialRadio(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
+ MaterialRadio.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
+ MaterialRadio.prototype.CssClasses_ = {
50
+ IS_FOCUSED: 'is-focused',
51
+ IS_DISABLED: 'is-disabled',
52
+ IS_CHECKED: 'is-checked',
53
+ IS_UPGRADED: 'is-upgraded',
54
+ JS_RADIO: 'mdl-js-radio',
55
+ RADIO_BTN: 'mdl-radio__button',
56
+ RADIO_OUTER_CIRCLE: 'mdl-radio__outer-circle',
57
+ RADIO_INNER_CIRCLE: 'mdl-radio__inner-circle',
58
+ RIPPLE_EFFECT: 'mdl-js-ripple-effect',
59
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
60
+ RIPPLE_CONTAINER: 'mdl-radio__ripple-container',
61
+ RIPPLE_CENTER: 'mdl-ripple--center',
62
+ RIPPLE: 'mdl-ripple'
63
+ };
64
+
65
+ /**
66
+ * Handle change of state.
67
+ * @param {Event} event The event that fired.
68
+ * @private
69
+ */
70
+ MaterialRadio.prototype.onChange_ = function(event) {
71
+ 'use strict';
72
+
73
+ this.updateClasses_(this.btnElement_, this.element_);
74
+
75
+ // Since other radio buttons don't get change events, we need to look for
76
+ // them to update their classes.
77
+ var radios = document.getElementsByClassName(this.CssClasses_.JS_RADIO);
78
+ for (var i = 0; i < radios.length; i++) {
79
+ var button = radios[i].querySelector('.' + this.CssClasses_.RADIO_BTN);
80
+ // Different name == different group, so no point updating those.
81
+ if (button.getAttribute('name') === this.btnElement_.getAttribute('name')) {
82
+ this.updateClasses_(button, radios[i]);
83
+ }
84
+ }
85
+ };
86
+
87
+ /**
88
+ * Handle focus.
89
+ * @param {Event} event The event that fired.
90
+ * @private
91
+ */
92
+ MaterialRadio.prototype.onFocus_ = function(event) {
93
+ 'use strict';
94
+
95
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
96
+ };
97
+
98
+ /**
99
+ * Handle lost focus.
100
+ * @param {Event} event The event that fired.
101
+ * @private
102
+ */
103
+ MaterialRadio.prototype.onBlur_ = function(event) {
104
+ 'use strict';
105
+
106
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
107
+ };
108
+
109
+ /**
110
+ * Handle mouseup.
111
+ * @param {Event} event The event that fired.
112
+ * @private
113
+ */
114
+ MaterialRadio.prototype.onMouseup_ = function(event) {
115
+ 'use strict';
116
+
117
+ this.blur_();
118
+ };
119
+
120
+ /**
121
+ * Update classes.
122
+ * @param {HTMLElement} button The button whose classes we should update.
123
+ * @param {HTMLElement} label The label whose classes we should update.
124
+ * @private
125
+ */
126
+ MaterialRadio.prototype.updateClasses_ = function(button, label) {
127
+ 'use strict';
128
+
129
+ if (button.disabled) {
130
+ label.classList.add(this.CssClasses_.IS_DISABLED);
131
+ } else {
132
+ label.classList.remove(this.CssClasses_.IS_DISABLED);
133
+ }
134
+
135
+ if (button.checked) {
136
+ label.classList.add(this.CssClasses_.IS_CHECKED);
137
+ } else {
138
+ label.classList.remove(this.CssClasses_.IS_CHECKED);
139
+ }
140
+ };
141
+
142
+ /**
143
+ * Add blur.
144
+ * @private
145
+ */
146
+ MaterialRadio.prototype.blur_ = function(event) {
147
+ 'use strict';
148
+
149
+ // TODO: figure out why there's a focus event being fired after our blur,
150
+ // so that we can avoid this hack.
151
+ window.setTimeout(function() {
152
+ this.btnElement_.blur();
153
+ }.bind(this), this.Constant_.TINY_TIMEOUT);
154
+ };
155
+
156
+ // Public methods.
157
+
158
+ /**
159
+ * Disable radio.
160
+ * @public
161
+ */
162
+ MaterialRadio.prototype.disable = function() {
163
+ 'use strict';
164
+
165
+ this.btnElement_.disabled = true;
166
+ this.updateClasses_(this.btnElement_, this.element_);
167
+ };
168
+
169
+ /**
170
+ * Enable radio.
171
+ * @public
172
+ */
173
+ MaterialRadio.prototype.enable = function() {
174
+ 'use strict';
175
+
176
+ this.btnElement_.disabled = false;
177
+ this.updateClasses_(this.btnElement_, this.element_);
178
+ };
179
+
180
+ /**
181
+ * Check radio.
182
+ * @public
183
+ */
184
+ MaterialRadio.prototype.check = function() {
185
+ 'use strict';
186
+
187
+ this.btnElement_.checked = true;
188
+ this.updateClasses_(this.btnElement_, this.element_);
189
+ };
190
+
191
+ /**
192
+ * Uncheck radio.
193
+ * @public
194
+ */
195
+ MaterialRadio.prototype.uncheck = function() {
196
+ 'use strict';
197
+
198
+ this.btnElement_.checked = false;
199
+ this.updateClasses_(this.btnElement_, this.element_);
200
+ };
201
+
202
+ /**
203
+ * Initialize element.
204
+ */
205
+ MaterialRadio.prototype.init = function() {
206
+ 'use strict';
207
+
208
+ if (this.element_) {
209
+ this.btnElement_ = this.element_.querySelector('.' +
210
+ this.CssClasses_.RADIO_BTN);
211
+
212
+ var outerCircle = document.createElement('span');
213
+ outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE);
214
+
215
+ var innerCircle = document.createElement('span');
216
+ innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE);
217
+
218
+ this.element_.appendChild(outerCircle);
219
+ this.element_.appendChild(innerCircle);
220
+
221
+ var rippleContainer;
222
+ if (this.element_.classList.contains(
223
+ this.CssClasses_.RIPPLE_EFFECT)) {
224
+ this.element_.classList.add(
225
+ this.CssClasses_.RIPPLE_IGNORE_EVENTS);
226
+ rippleContainer = document.createElement('span');
227
+ rippleContainer.classList.add(
228
+ this.CssClasses_.RIPPLE_CONTAINER);
229
+ rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT);
230
+ rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER);
231
+ rippleContainer.addEventListener('mouseup', this.onMouseup_.bind(this));
232
+
233
+ var ripple = document.createElement('span');
234
+ ripple.classList.add(this.CssClasses_.RIPPLE);
235
+
236
+ rippleContainer.appendChild(ripple);
237
+ this.element_.appendChild(rippleContainer);
238
+ }
239
+
240
+ this.btnElement_.addEventListener('change', this.onChange_.bind(this));
241
+ this.btnElement_.addEventListener('focus', this.onFocus_.bind(this));
242
+ this.btnElement_.addEventListener('blur', this.onBlur_.bind(this));
243
+ this.element_.addEventListener('mouseup', this.onMouseup_.bind(this));
244
+
245
+ this.updateClasses_(this.btnElement_, this.element_);
246
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
247
+ }
248
+ };
249
+
250
+ // The component registers itself. It can assume componentHandler is available
251
+ // in the global scope.
252
+ componentHandler.register({
253
+ constructor: MaterialRadio,
254
+ classAsString: 'MaterialRadio',
255
+ cssClass: 'mdl-js-radio',
256
+ widget: true
257
+ });
@@ -0,0 +1,244 @@
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 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) {
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
+ MaterialRipple.prototype.Constant_ = {
39
+ INITIAL_SCALE: 'scale(0.0001, 0.0001)',
40
+ INITIAL_SIZE: '1px',
41
+ INITIAL_OPACITY: '0.4',
42
+ FINAL_OPACITY: '0',
43
+ FINAL_SCALE: ''
44
+ };
45
+
46
+ /**
47
+ * Store strings for class names defined by this component that are used in
48
+ * JavaScript. This allows us to simply change it in one place should we
49
+ * decide to modify at a later date.
50
+ * @enum {string}
51
+ * @private
52
+ */
53
+ MaterialRipple.prototype.CssClasses_ = {
54
+ RIPPLE_CENTER: 'mdl-ripple--center',
55
+ RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
56
+ RIPPLE: 'mdl-ripple',
57
+ IS_ANIMATING: 'is-animating',
58
+ IS_VISIBLE: 'is-visible'
59
+ };
60
+
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';
68
+
69
+ if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) {
70
+ var rect = this.element_.getBoundingClientRect();
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);
99
+ } else {
100
+ var clientX = event.clientX ? event.clientX : event.touches[0].clientX;
101
+ var clientY = event.clientY ? event.clientY : event.touches[0].clientY;
102
+ x = Math.round(clientX - bound.left);
103
+ y = Math.round(clientY - bound.top);
104
+ }
105
+ this.setRippleXY(x, y);
106
+ this.setRippleStyles(true);
107
+ window.requestAnimationFrame(this.animFrameHandler.bind(this));
108
+ }
109
+ };
110
+
111
+ /**
112
+ * Handle mouse / finger up on element.
113
+ * @param {Event} event The event that fired.
114
+ * @private
115
+ */
116
+ MaterialRipple.prototype.upHandler_ = function(event) {
117
+ 'use strict';
118
+
119
+ // Don't fire for the artificial "mouseup" generated by a double-click.
120
+ if (event && event.detail !== 2) {
121
+ this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE);
122
+ }
123
+ };
124
+
125
+ /**
126
+ * Initialize element.
127
+ */
128
+ MaterialRipple.prototype.init = function() {
129
+ 'use strict';
130
+
131
+ if (this.element_) {
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;
147
+
148
+ this.boundDownHandler = this.downHandler_.bind(this);
149
+ this.element_.addEventListener('mousedown',
150
+ this.boundDownHandler);
151
+ this.element_.addEventListener('touchstart',
152
+ this.boundDownHandler);
153
+
154
+ this.boundUpHandler = this.upHandler_.bind(this);
155
+ this.element_.addEventListener('mouseup', this.boundUpHandler);
156
+ this.element_.addEventListener('mouseleave', this.boundUpHandler);
157
+ this.element_.addEventListener('touchend', this.boundUpHandler);
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)';
193
+ }
194
+ }
195
+
196
+ transformString = 'translate(-50%, -50%) ' + offset + scale;
197
+
198
+ this.rippleElement_.style.webkitTransform = transformString;
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);
204
+ } else {
205
+ this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING);
206
+ }
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
+ };
217
+ }
218
+ }
219
+ };
220
+
221
+ /*
222
+ * Downgrade the component
223
+ */
224
+ MaterialRipple.prototype.mdlDowngrade_ = function() {
225
+ 'use strict';
226
+ this.element_.removeEventListener('mousedown',
227
+ this.boundDownHandler);
228
+ this.element_.removeEventListener('touchstart',
229
+ this.boundDownHandler);
230
+
231
+ this.element_.removeEventListener('mouseup', this.boundUpHandler);
232
+ this.element_.removeEventListener('mouseleave', this.boundUpHandler);
233
+ this.element_.removeEventListener('touchend', this.boundUpHandler);
234
+ this.element_.removeEventListener('blur', this.boundUpHandler);
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
+ });