@materializecss/materialize 1.2.0 → 1.2.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.
- package/Gruntfile.js +722 -712
- package/LICENSE +21 -21
- package/README.md +91 -91
- package/dist/css/materialize.css +68 -135
- package/dist/css/materialize.min.css +12 -12
- package/dist/js/materialize.js +1112 -1112
- package/dist/js/materialize.min.js +6 -6
- package/extras/noUiSlider/nouislider.css +403 -403
- package/extras/noUiSlider/nouislider.js +2147 -2147
- package/js/anime.min.js +34 -34
- package/js/autocomplete.js +479 -479
- package/js/buttons.js +354 -354
- package/js/cards.js +40 -40
- package/js/carousel.js +732 -732
- package/js/cash.js +960 -960
- package/js/characterCounter.js +136 -136
- package/js/chips.js +486 -486
- package/js/collapsible.js +275 -275
- package/js/component.js +44 -44
- package/js/datepicker.js +983 -983
- package/js/dropdown.js +669 -669
- package/js/forms.js +285 -285
- package/js/global.js +428 -428
- package/js/materialbox.js +453 -453
- package/js/modal.js +382 -382
- package/js/parallax.js +138 -138
- package/js/pushpin.js +148 -148
- package/js/range.js +263 -263
- package/js/scrollspy.js +295 -295
- package/js/select.js +391 -391
- package/js/sidenav.js +583 -583
- package/js/slider.js +359 -359
- package/js/tabs.js +402 -402
- package/js/tapTarget.js +315 -315
- package/js/timepicker.js +712 -712
- package/js/toasts.js +325 -325
- package/js/tooltip.js +320 -320
- package/js/waves.js +614 -614
- package/package.json +87 -84
- package/sass/_style.scss +929 -929
- package/sass/components/_badges.scss +55 -55
- package/sass/components/_buttons.scss +322 -322
- package/sass/components/_cards.scss +195 -195
- package/sass/components/_carousel.scss +90 -90
- package/sass/components/_chips.scss +96 -96
- package/sass/components/_collapsible.scss +91 -91
- package/sass/components/_collection.scss +106 -106
- package/sass/components/_color-classes.scss +32 -32
- package/sass/components/_color-variables.scss +370 -370
- package/sass/components/_datepicker.scss +191 -191
- package/sass/components/_dropdown.scss +84 -84
- package/sass/components/_global.scss +646 -646
- package/sass/components/_grid.scss +158 -158
- package/sass/components/_icons-material-design.scss +5 -5
- package/sass/components/_materialbox.scss +42 -42
- package/sass/components/_modal.scss +97 -97
- package/sass/components/_navbar.scss +208 -208
- package/sass/components/_normalize.scss +447 -447
- package/sass/components/_preloader.scss +334 -334
- package/sass/components/_pulse.scss +34 -34
- package/sass/components/_sidenav.scss +214 -214
- package/sass/components/_slider.scss +91 -91
- package/sass/components/_table_of_contents.scss +33 -33
- package/sass/components/_tabs.scss +99 -99
- package/sass/components/_tapTarget.scss +103 -103
- package/sass/components/_timepicker.scss +199 -199
- package/sass/components/_toast.scss +58 -58
- package/sass/components/_tooltip.scss +32 -32
- package/sass/components/_transitions.scss +12 -12
- package/sass/components/_typography.scss +62 -62
- package/sass/components/_variables.scss +352 -352
- package/sass/components/_waves.scss +187 -187
- package/sass/components/forms/_checkboxes.scss +200 -200
- package/sass/components/forms/_file-input.scss +44 -44
- package/sass/components/forms/_forms.scss +22 -22
- package/sass/components/forms/_input-fields.scss +388 -388
- package/sass/components/forms/_radio-buttons.scss +115 -115
- package/sass/components/forms/_range.scss +161 -161
- package/sass/components/forms/_select.scss +199 -199
- package/sass/components/forms/_switches.scss +91 -91
- package/sass/ghpages-materialize.scss +7 -7
- package/sass/materialize.scss +42 -42
package/js/waves.js
CHANGED
|
@@ -1,615 +1,615 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Waves v0.7.6
|
|
3
|
-
* http://fian.my.id/Waves
|
|
4
|
-
*
|
|
5
|
-
* Copyright 2014-2018 Alfiana E. Sibuea and other contributors
|
|
6
|
-
* Released under the MIT license
|
|
7
|
-
* https://github.com/fians/Waves/blob/master/LICENSE
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
;(function(window, factory) {
|
|
11
|
-
'use strict';
|
|
12
|
-
|
|
13
|
-
// AMD. Register as an anonymous module. Wrap in function so we have access
|
|
14
|
-
// to root via `this`.
|
|
15
|
-
if (typeof define === 'function' && define.amd) {
|
|
16
|
-
define([], function() {
|
|
17
|
-
window.Waves = factory.call(window);
|
|
18
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
19
|
-
window.Waves.init();
|
|
20
|
-
}, false);
|
|
21
|
-
return window.Waves;
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Node. Does not work with strict CommonJS, but only CommonJS-like
|
|
26
|
-
// environments that support module.exports, like Node.
|
|
27
|
-
else if (typeof exports === 'object') {
|
|
28
|
-
module.exports = factory.call(window);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Browser globals.
|
|
32
|
-
else {
|
|
33
|
-
window.Waves = factory.call(window);
|
|
34
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
35
|
-
window.Waves.init();
|
|
36
|
-
}, false);
|
|
37
|
-
}
|
|
38
|
-
})(typeof global === 'object' ? global : this, function() {
|
|
39
|
-
'use strict';
|
|
40
|
-
|
|
41
|
-
var Waves = Waves || {};
|
|
42
|
-
var $$ = document.querySelectorAll.bind(document);
|
|
43
|
-
var toString = Object.prototype.toString;
|
|
44
|
-
var isTouchAvailable = 'ontouchstart' in window;
|
|
45
|
-
|
|
46
|
-
/* Feature detection */
|
|
47
|
-
var passiveIfSupported = false;
|
|
48
|
-
try {
|
|
49
|
-
window.addEventListener("test", null,
|
|
50
|
-
Object.defineProperty({}, "passive", {
|
|
51
|
-
get: function() { passiveIfSupported = { passive: false }; }
|
|
52
|
-
}
|
|
53
|
-
));
|
|
54
|
-
} catch(err) {}
|
|
55
|
-
|
|
56
|
-
// Find exact position of element
|
|
57
|
-
function isWindow(obj) {
|
|
58
|
-
return obj !== null && obj === obj.window;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function getWindow(elem) {
|
|
62
|
-
return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function isObject(value) {
|
|
66
|
-
var type = typeof value;
|
|
67
|
-
return type === 'function' || type === 'object' && !!value;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function isDOMNode(obj) {
|
|
71
|
-
return isObject(obj) && obj.nodeType > 0;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function getWavesElements(nodes) {
|
|
75
|
-
var stringRepr = toString.call(nodes);
|
|
76
|
-
|
|
77
|
-
if (stringRepr === '[object String]') {
|
|
78
|
-
return $$(nodes);
|
|
79
|
-
} else if (isObject(nodes) && /^\[object (Array|HTMLCollection|NodeList|Object)\]$/.test(stringRepr) && nodes.hasOwnProperty('length')) {
|
|
80
|
-
return nodes;
|
|
81
|
-
} else if (isDOMNode(nodes)) {
|
|
82
|
-
return [nodes];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return [];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function offset(elem) {
|
|
89
|
-
var docElem, win,
|
|
90
|
-
box = { top: 0, left: 0 },
|
|
91
|
-
doc = elem && elem.ownerDocument;
|
|
92
|
-
|
|
93
|
-
docElem = doc.documentElement;
|
|
94
|
-
|
|
95
|
-
if (typeof elem.getBoundingClientRect !== typeof undefined) {
|
|
96
|
-
box = elem.getBoundingClientRect();
|
|
97
|
-
}
|
|
98
|
-
win = getWindow(doc);
|
|
99
|
-
return {
|
|
100
|
-
top: box.top + win.pageYOffset - docElem.clientTop,
|
|
101
|
-
left: box.left + win.pageXOffset - docElem.clientLeft
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function convertStyle(styleObj) {
|
|
106
|
-
var style = '';
|
|
107
|
-
|
|
108
|
-
for (var prop in styleObj) {
|
|
109
|
-
if (styleObj.hasOwnProperty(prop)) {
|
|
110
|
-
style += (prop + ':' + styleObj[prop] + ';');
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return style;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
var Effect = {
|
|
118
|
-
|
|
119
|
-
// Effect duration
|
|
120
|
-
duration: 750,
|
|
121
|
-
|
|
122
|
-
// Effect delay (check for scroll before showing effect)
|
|
123
|
-
delay: 200,
|
|
124
|
-
|
|
125
|
-
show: function(e, element, velocity) {
|
|
126
|
-
|
|
127
|
-
// Disable right click
|
|
128
|
-
if (e.button === 2) {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
element = element || this;
|
|
133
|
-
|
|
134
|
-
// Create ripple
|
|
135
|
-
var ripple = document.createElement('div');
|
|
136
|
-
ripple.className = 'waves-ripple waves-rippling';
|
|
137
|
-
element.appendChild(ripple);
|
|
138
|
-
|
|
139
|
-
// Get click coordinate and element width
|
|
140
|
-
var pos = offset(element);
|
|
141
|
-
var relativeY = 0;
|
|
142
|
-
var relativeX = 0;
|
|
143
|
-
// Support for touch devices
|
|
144
|
-
if('touches' in e && e.touches.length) {
|
|
145
|
-
relativeY = (e.touches[0].pageY - pos.top);
|
|
146
|
-
relativeX = (e.touches[0].pageX - pos.left);
|
|
147
|
-
}
|
|
148
|
-
//Normal case
|
|
149
|
-
else {
|
|
150
|
-
relativeY = (e.pageY - pos.top);
|
|
151
|
-
relativeX = (e.pageX - pos.left);
|
|
152
|
-
}
|
|
153
|
-
// Support for synthetic events
|
|
154
|
-
relativeX = relativeX >= 0 ? relativeX : 0;
|
|
155
|
-
relativeY = relativeY >= 0 ? relativeY : 0;
|
|
156
|
-
|
|
157
|
-
var scale = 'scale(' + ((element.clientWidth / 100) * 3) + ')';
|
|
158
|
-
var translate = 'translate(0,0)';
|
|
159
|
-
|
|
160
|
-
if (velocity) {
|
|
161
|
-
translate = 'translate(' + (velocity.x) + 'px, ' + (velocity.y) + 'px)';
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Attach data to element
|
|
165
|
-
ripple.setAttribute('data-hold', Date.now());
|
|
166
|
-
ripple.setAttribute('data-x', relativeX);
|
|
167
|
-
ripple.setAttribute('data-y', relativeY);
|
|
168
|
-
ripple.setAttribute('data-scale', scale);
|
|
169
|
-
ripple.setAttribute('data-translate', translate);
|
|
170
|
-
|
|
171
|
-
// Set ripple position
|
|
172
|
-
var rippleStyle = {
|
|
173
|
-
top: relativeY + 'px',
|
|
174
|
-
left: relativeX + 'px'
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
ripple.classList.add('waves-notransition');
|
|
178
|
-
ripple.setAttribute('style', convertStyle(rippleStyle));
|
|
179
|
-
ripple.classList.remove('waves-notransition');
|
|
180
|
-
|
|
181
|
-
// Scale the ripple
|
|
182
|
-
rippleStyle['-webkit-transform'] = scale + ' ' + translate;
|
|
183
|
-
rippleStyle['-moz-transform'] = scale + ' ' + translate;
|
|
184
|
-
rippleStyle['-ms-transform'] = scale + ' ' + translate;
|
|
185
|
-
rippleStyle['-o-transform'] = scale + ' ' + translate;
|
|
186
|
-
rippleStyle.transform = scale + ' ' + translate;
|
|
187
|
-
rippleStyle.opacity = '1';
|
|
188
|
-
|
|
189
|
-
var duration = e.type === 'mousemove' ? 2500 : Effect.duration;
|
|
190
|
-
rippleStyle['-webkit-transition-duration'] = duration + 'ms';
|
|
191
|
-
rippleStyle['-moz-transition-duration'] = duration + 'ms';
|
|
192
|
-
rippleStyle['-o-transition-duration'] = duration + 'ms';
|
|
193
|
-
rippleStyle['transition-duration'] = duration + 'ms';
|
|
194
|
-
|
|
195
|
-
ripple.setAttribute('style', convertStyle(rippleStyle));
|
|
196
|
-
},
|
|
197
|
-
|
|
198
|
-
hide: function(e, element) {
|
|
199
|
-
element = element || this;
|
|
200
|
-
|
|
201
|
-
var ripples = element.getElementsByClassName('waves-rippling');
|
|
202
|
-
|
|
203
|
-
for (var i = 0, len = ripples.length; i < len; i++) {
|
|
204
|
-
removeRipple(e, element, ripples[i]);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (isTouchAvailable) {
|
|
208
|
-
element.removeEventListener('touchend', Effect.hide);
|
|
209
|
-
element.removeEventListener('touchcancel', Effect.hide);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
element.removeEventListener('mouseup', Effect.hide);
|
|
213
|
-
element.removeEventListener('mouseleave', Effect.hide);
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Collection of wrapper for HTML element that only have single tag
|
|
219
|
-
* like <input> and <img>
|
|
220
|
-
*/
|
|
221
|
-
var TagWrapper = {
|
|
222
|
-
|
|
223
|
-
// Wrap <input> tag so it can perform the effect
|
|
224
|
-
input: function(element) {
|
|
225
|
-
|
|
226
|
-
var parent = element.parentNode;
|
|
227
|
-
|
|
228
|
-
// If input already have parent just pass through
|
|
229
|
-
if (parent.tagName.toLowerCase() === 'i' && parent.classList.contains('waves-effect')) {
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// Put element class and style to the specified parent
|
|
234
|
-
var wrapper = document.createElement('i');
|
|
235
|
-
wrapper.className = element.className + ' waves-input-wrapper';
|
|
236
|
-
element.className = 'waves-button-input';
|
|
237
|
-
|
|
238
|
-
// Put element as child
|
|
239
|
-
parent.replaceChild(wrapper, element);
|
|
240
|
-
wrapper.appendChild(element);
|
|
241
|
-
|
|
242
|
-
// Apply element color and background color to wrapper
|
|
243
|
-
var elementStyle = window.getComputedStyle(element, null);
|
|
244
|
-
var color = elementStyle.color;
|
|
245
|
-
var backgroundColor = elementStyle.backgroundColor;
|
|
246
|
-
|
|
247
|
-
wrapper.setAttribute('style', 'color:' + color + ';background:' + backgroundColor);
|
|
248
|
-
element.setAttribute('style', 'background-color:rgba(0,0,0,0);');
|
|
249
|
-
|
|
250
|
-
},
|
|
251
|
-
|
|
252
|
-
// Wrap <img> tag so it can perform the effect
|
|
253
|
-
img: function(element) {
|
|
254
|
-
|
|
255
|
-
var parent = element.parentNode;
|
|
256
|
-
|
|
257
|
-
// If input already have parent just pass through
|
|
258
|
-
if (parent.tagName.toLowerCase() === 'i' && parent.classList.contains('waves-effect')) {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Put element as child
|
|
263
|
-
var wrapper = document.createElement('i');
|
|
264
|
-
parent.replaceChild(wrapper, element);
|
|
265
|
-
wrapper.appendChild(element);
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Hide the effect and remove the ripple. Must be
|
|
272
|
-
* a separate function to pass the JSLint...
|
|
273
|
-
*/
|
|
274
|
-
function removeRipple(e, el, ripple) {
|
|
275
|
-
|
|
276
|
-
// Check if the ripple still exist
|
|
277
|
-
if (!ripple) {
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
ripple.classList.remove('waves-rippling');
|
|
282
|
-
|
|
283
|
-
var relativeX = ripple.getAttribute('data-x');
|
|
284
|
-
var relativeY = ripple.getAttribute('data-y');
|
|
285
|
-
var scale = ripple.getAttribute('data-scale');
|
|
286
|
-
var translate = ripple.getAttribute('data-translate');
|
|
287
|
-
|
|
288
|
-
// Get delay beetween mousedown and mouse leave
|
|
289
|
-
var diff = Date.now() - Number(ripple.getAttribute('data-hold'));
|
|
290
|
-
var delay = 350 - diff;
|
|
291
|
-
|
|
292
|
-
if (delay < 0) {
|
|
293
|
-
delay = 0;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (e.type === 'mousemove') {
|
|
297
|
-
delay = 150;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Fade out ripple after delay
|
|
301
|
-
var duration = e.type === 'mousemove' ? 2500 : Effect.duration;
|
|
302
|
-
|
|
303
|
-
setTimeout(function() {
|
|
304
|
-
|
|
305
|
-
var style = {
|
|
306
|
-
top: relativeY + 'px',
|
|
307
|
-
left: relativeX + 'px',
|
|
308
|
-
opacity: '0',
|
|
309
|
-
|
|
310
|
-
// Duration
|
|
311
|
-
'-webkit-transition-duration': duration + 'ms',
|
|
312
|
-
'-moz-transition-duration': duration + 'ms',
|
|
313
|
-
'-o-transition-duration': duration + 'ms',
|
|
314
|
-
'transition-duration': duration + 'ms',
|
|
315
|
-
'-webkit-transform': scale + ' ' + translate,
|
|
316
|
-
'-moz-transform': scale + ' ' + translate,
|
|
317
|
-
'-ms-transform': scale + ' ' + translate,
|
|
318
|
-
'-o-transform': scale + ' ' + translate,
|
|
319
|
-
'transform': scale + ' ' + translate
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
ripple.setAttribute('style', convertStyle(style));
|
|
323
|
-
|
|
324
|
-
setTimeout(function() {
|
|
325
|
-
try {
|
|
326
|
-
el.removeChild(ripple);
|
|
327
|
-
} catch (e) {
|
|
328
|
-
return false;
|
|
329
|
-
}
|
|
330
|
-
}, duration);
|
|
331
|
-
|
|
332
|
-
}, delay);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Disable mousedown event for 500ms during and after touch
|
|
338
|
-
*/
|
|
339
|
-
var TouchHandler = {
|
|
340
|
-
|
|
341
|
-
/* uses an integer rather than bool so there's no issues with
|
|
342
|
-
* needing to clear timeouts if another touch event occurred
|
|
343
|
-
* within the 500ms. Cannot mouseup between touchstart and
|
|
344
|
-
* touchend, nor in the 500ms after touchend. */
|
|
345
|
-
touches: 0,
|
|
346
|
-
|
|
347
|
-
allowEvent: function(e) {
|
|
348
|
-
|
|
349
|
-
var allow = true;
|
|
350
|
-
|
|
351
|
-
if (/^(mousedown|mousemove)$/.test(e.type) && TouchHandler.touches) {
|
|
352
|
-
allow = false;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
return allow;
|
|
356
|
-
},
|
|
357
|
-
registerEvent: function(e) {
|
|
358
|
-
var eType = e.type;
|
|
359
|
-
|
|
360
|
-
if (eType === 'touchstart') {
|
|
361
|
-
|
|
362
|
-
TouchHandler.touches += 1; // push
|
|
363
|
-
|
|
364
|
-
} else if (/^(touchend|touchcancel)$/.test(eType)) {
|
|
365
|
-
|
|
366
|
-
setTimeout(function() {
|
|
367
|
-
if (TouchHandler.touches) {
|
|
368
|
-
TouchHandler.touches -= 1; // pop after 500ms
|
|
369
|
-
}
|
|
370
|
-
}, 500);
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Delegated click handler for .waves-effect element.
|
|
379
|
-
* returns null when .waves-effect element not in "click tree"
|
|
380
|
-
*/
|
|
381
|
-
function getWavesEffectElement(e) {
|
|
382
|
-
|
|
383
|
-
if (TouchHandler.allowEvent(e) === false) {
|
|
384
|
-
return null;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
var element = null;
|
|
388
|
-
var target = e.target || e.srcElement;
|
|
389
|
-
|
|
390
|
-
while (target.parentElement) {
|
|
391
|
-
if ( (!(target instanceof SVGElement)) && target.classList.contains('waves-effect')) {
|
|
392
|
-
element = target;
|
|
393
|
-
break;
|
|
394
|
-
}
|
|
395
|
-
target = target.parentElement;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
return element;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Bubble the click and show effect if .waves-effect elem was found
|
|
403
|
-
*/
|
|
404
|
-
function showEffect(e) {
|
|
405
|
-
|
|
406
|
-
// Disable effect if element has "disabled" property on it
|
|
407
|
-
// In some cases, the event is not triggered by the current element
|
|
408
|
-
// if (e.target.getAttribute('disabled') !== null) {
|
|
409
|
-
// return;
|
|
410
|
-
// }
|
|
411
|
-
|
|
412
|
-
var element = getWavesEffectElement(e);
|
|
413
|
-
|
|
414
|
-
if (element !== null) {
|
|
415
|
-
|
|
416
|
-
// Make it sure the element has either disabled property, disabled attribute or 'disabled' class
|
|
417
|
-
if (element.disabled || element.getAttribute('disabled') || element.classList.contains('disabled')) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
TouchHandler.registerEvent(e);
|
|
422
|
-
|
|
423
|
-
if (e.type === 'touchstart' && Effect.delay) {
|
|
424
|
-
|
|
425
|
-
var hidden = false;
|
|
426
|
-
|
|
427
|
-
var timer = setTimeout(function () {
|
|
428
|
-
timer = null;
|
|
429
|
-
Effect.show(e, element);
|
|
430
|
-
}, Effect.delay);
|
|
431
|
-
|
|
432
|
-
var hideEffect = function(hideEvent) {
|
|
433
|
-
|
|
434
|
-
// if touch hasn't moved, and effect not yet started: start effect now
|
|
435
|
-
if (timer) {
|
|
436
|
-
clearTimeout(timer);
|
|
437
|
-
timer = null;
|
|
438
|
-
Effect.show(e, element);
|
|
439
|
-
}
|
|
440
|
-
if (!hidden) {
|
|
441
|
-
hidden = true;
|
|
442
|
-
Effect.hide(hideEvent, element);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
removeListeners();
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
var touchMove = function(moveEvent) {
|
|
449
|
-
if (timer) {
|
|
450
|
-
clearTimeout(timer);
|
|
451
|
-
timer = null;
|
|
452
|
-
}
|
|
453
|
-
hideEffect(moveEvent);
|
|
454
|
-
|
|
455
|
-
removeListeners();
|
|
456
|
-
};
|
|
457
|
-
|
|
458
|
-
element.addEventListener('touchmove', touchMove, passiveIfSupported);
|
|
459
|
-
element.addEventListener('touchend', hideEffect, passiveIfSupported);
|
|
460
|
-
element.addEventListener('touchcancel', hideEffect, passiveIfSupported);
|
|
461
|
-
|
|
462
|
-
var removeListeners = function() {
|
|
463
|
-
element.removeEventListener('touchmove', touchMove);
|
|
464
|
-
element.removeEventListener('touchend', hideEffect);
|
|
465
|
-
element.removeEventListener('touchcancel', hideEffect);
|
|
466
|
-
};
|
|
467
|
-
} else {
|
|
468
|
-
|
|
469
|
-
Effect.show(e, element);
|
|
470
|
-
|
|
471
|
-
if (isTouchAvailable) {
|
|
472
|
-
element.addEventListener('touchend', Effect.hide, passiveIfSupported);
|
|
473
|
-
element.addEventListener('touchcancel', Effect.hide, passiveIfSupported);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
element.addEventListener('mouseup', Effect.hide, passiveIfSupported);
|
|
477
|
-
element.addEventListener('mouseleave', Effect.hide, passiveIfSupported);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
Waves.init = function(options) {
|
|
483
|
-
var body = document.body;
|
|
484
|
-
|
|
485
|
-
options = options || {};
|
|
486
|
-
|
|
487
|
-
if ('duration' in options) {
|
|
488
|
-
Effect.duration = options.duration;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
if ('delay' in options) {
|
|
492
|
-
Effect.delay = options.delay;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
if (isTouchAvailable) {
|
|
496
|
-
body.addEventListener('touchstart', showEffect, passiveIfSupported);
|
|
497
|
-
body.addEventListener('touchcancel', TouchHandler.registerEvent, passiveIfSupported);
|
|
498
|
-
body.addEventListener('touchend', TouchHandler.registerEvent, passiveIfSupported);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
body.addEventListener('mousedown', showEffect, passiveIfSupported);
|
|
502
|
-
};
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
/**
|
|
506
|
-
* Attach Waves to dynamically loaded inputs, or add .waves-effect and other
|
|
507
|
-
* waves classes to a set of elements. Set drag to true if the ripple mouseover
|
|
508
|
-
* or skimming effect should be applied to the elements.
|
|
509
|
-
*/
|
|
510
|
-
Waves.attach = function(elements, classes) {
|
|
511
|
-
|
|
512
|
-
elements = getWavesElements(elements);
|
|
513
|
-
|
|
514
|
-
if (toString.call(classes) === '[object Array]') {
|
|
515
|
-
classes = classes.join(' ');
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
classes = classes ? ' ' + classes : '';
|
|
519
|
-
|
|
520
|
-
var element, tagName;
|
|
521
|
-
|
|
522
|
-
for (var i = 0, len = elements.length; i < len; i++) {
|
|
523
|
-
|
|
524
|
-
element = elements[i];
|
|
525
|
-
tagName = element.tagName.toLowerCase();
|
|
526
|
-
|
|
527
|
-
if (['input', 'img'].indexOf(tagName) !== -1) {
|
|
528
|
-
TagWrapper[tagName](element);
|
|
529
|
-
element = element.parentElement;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
if (element.className.indexOf('waves-effect') === -1) {
|
|
533
|
-
element.className += ' waves-effect' + classes;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Cause a ripple to appear in an element via code.
|
|
541
|
-
*/
|
|
542
|
-
Waves.ripple = function(elements, options) {
|
|
543
|
-
elements = getWavesElements(elements);
|
|
544
|
-
var elementsLen = elements.length;
|
|
545
|
-
|
|
546
|
-
options = options || {};
|
|
547
|
-
options.wait = options.wait || 0;
|
|
548
|
-
options.position = options.position || null; // default = centre of element
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
if (elementsLen) {
|
|
552
|
-
var element, pos, off, centre = {}, i = 0;
|
|
553
|
-
var mousedown = {
|
|
554
|
-
type: 'mousedown',
|
|
555
|
-
button: 1
|
|
556
|
-
};
|
|
557
|
-
var hideRipple = function(mouseup, element) {
|
|
558
|
-
return function() {
|
|
559
|
-
Effect.hide(mouseup, element);
|
|
560
|
-
};
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
for (; i < elementsLen; i++) {
|
|
564
|
-
element = elements[i];
|
|
565
|
-
pos = options.position || {
|
|
566
|
-
x: element.clientWidth / 2,
|
|
567
|
-
y: element.clientHeight / 2
|
|
568
|
-
};
|
|
569
|
-
|
|
570
|
-
off = offset(element);
|
|
571
|
-
centre.x = off.left + pos.x;
|
|
572
|
-
centre.y = off.top + pos.y;
|
|
573
|
-
|
|
574
|
-
mousedown.pageX = centre.x;
|
|
575
|
-
mousedown.pageY = centre.y;
|
|
576
|
-
|
|
577
|
-
Effect.show(mousedown, element);
|
|
578
|
-
|
|
579
|
-
if (options.wait >= 0 && options.wait !== null) {
|
|
580
|
-
var mouseup = {
|
|
581
|
-
type: 'mouseup',
|
|
582
|
-
button: 1
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
setTimeout(hideRipple(mouseup, element), options.wait);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
/**
|
|
592
|
-
* Remove all ripples from an element.
|
|
593
|
-
*/
|
|
594
|
-
Waves.calm = function(elements) {
|
|
595
|
-
elements = getWavesElements(elements);
|
|
596
|
-
var mouseup = {
|
|
597
|
-
type: 'mouseup',
|
|
598
|
-
button: 1
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
for (var i = 0, len = elements.length; i < len; i++) {
|
|
602
|
-
Effect.hide(mouseup, elements[i]);
|
|
603
|
-
}
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
/**
|
|
607
|
-
* Deprecated API fallback
|
|
608
|
-
*/
|
|
609
|
-
Waves.displayEffect = function(options) {
|
|
610
|
-
console.error('Waves.displayEffect() has been deprecated and will be removed in future version. Please use Waves.init() to initialize Waves effect');
|
|
611
|
-
Waves.init(options);
|
|
612
|
-
};
|
|
613
|
-
|
|
614
|
-
return Waves;
|
|
1
|
+
/*!
|
|
2
|
+
* Waves v0.7.6
|
|
3
|
+
* http://fian.my.id/Waves
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2014-2018 Alfiana E. Sibuea and other contributors
|
|
6
|
+
* Released under the MIT license
|
|
7
|
+
* https://github.com/fians/Waves/blob/master/LICENSE
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
;(function(window, factory) {
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
// AMD. Register as an anonymous module. Wrap in function so we have access
|
|
14
|
+
// to root via `this`.
|
|
15
|
+
if (typeof define === 'function' && define.amd) {
|
|
16
|
+
define([], function() {
|
|
17
|
+
window.Waves = factory.call(window);
|
|
18
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
19
|
+
window.Waves.init();
|
|
20
|
+
}, false);
|
|
21
|
+
return window.Waves;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Node. Does not work with strict CommonJS, but only CommonJS-like
|
|
26
|
+
// environments that support module.exports, like Node.
|
|
27
|
+
else if (typeof exports === 'object') {
|
|
28
|
+
module.exports = factory.call(window);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Browser globals.
|
|
32
|
+
else {
|
|
33
|
+
window.Waves = factory.call(window);
|
|
34
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
35
|
+
window.Waves.init();
|
|
36
|
+
}, false);
|
|
37
|
+
}
|
|
38
|
+
})(typeof global === 'object' ? global : this, function() {
|
|
39
|
+
'use strict';
|
|
40
|
+
|
|
41
|
+
var Waves = Waves || {};
|
|
42
|
+
var $$ = document.querySelectorAll.bind(document);
|
|
43
|
+
var toString = Object.prototype.toString;
|
|
44
|
+
var isTouchAvailable = 'ontouchstart' in window;
|
|
45
|
+
|
|
46
|
+
/* Feature detection */
|
|
47
|
+
var passiveIfSupported = false;
|
|
48
|
+
try {
|
|
49
|
+
window.addEventListener("test", null,
|
|
50
|
+
Object.defineProperty({}, "passive", {
|
|
51
|
+
get: function() { passiveIfSupported = { passive: false }; }
|
|
52
|
+
}
|
|
53
|
+
));
|
|
54
|
+
} catch(err) {}
|
|
55
|
+
|
|
56
|
+
// Find exact position of element
|
|
57
|
+
function isWindow(obj) {
|
|
58
|
+
return obj !== null && obj === obj.window;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getWindow(elem) {
|
|
62
|
+
return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function isObject(value) {
|
|
66
|
+
var type = typeof value;
|
|
67
|
+
return type === 'function' || type === 'object' && !!value;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isDOMNode(obj) {
|
|
71
|
+
return isObject(obj) && obj.nodeType > 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function getWavesElements(nodes) {
|
|
75
|
+
var stringRepr = toString.call(nodes);
|
|
76
|
+
|
|
77
|
+
if (stringRepr === '[object String]') {
|
|
78
|
+
return $$(nodes);
|
|
79
|
+
} else if (isObject(nodes) && /^\[object (Array|HTMLCollection|NodeList|Object)\]$/.test(stringRepr) && nodes.hasOwnProperty('length')) {
|
|
80
|
+
return nodes;
|
|
81
|
+
} else if (isDOMNode(nodes)) {
|
|
82
|
+
return [nodes];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function offset(elem) {
|
|
89
|
+
var docElem, win,
|
|
90
|
+
box = { top: 0, left: 0 },
|
|
91
|
+
doc = elem && elem.ownerDocument;
|
|
92
|
+
|
|
93
|
+
docElem = doc.documentElement;
|
|
94
|
+
|
|
95
|
+
if (typeof elem.getBoundingClientRect !== typeof undefined) {
|
|
96
|
+
box = elem.getBoundingClientRect();
|
|
97
|
+
}
|
|
98
|
+
win = getWindow(doc);
|
|
99
|
+
return {
|
|
100
|
+
top: box.top + win.pageYOffset - docElem.clientTop,
|
|
101
|
+
left: box.left + win.pageXOffset - docElem.clientLeft
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function convertStyle(styleObj) {
|
|
106
|
+
var style = '';
|
|
107
|
+
|
|
108
|
+
for (var prop in styleObj) {
|
|
109
|
+
if (styleObj.hasOwnProperty(prop)) {
|
|
110
|
+
style += (prop + ':' + styleObj[prop] + ';');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return style;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
var Effect = {
|
|
118
|
+
|
|
119
|
+
// Effect duration
|
|
120
|
+
duration: 750,
|
|
121
|
+
|
|
122
|
+
// Effect delay (check for scroll before showing effect)
|
|
123
|
+
delay: 200,
|
|
124
|
+
|
|
125
|
+
show: function(e, element, velocity) {
|
|
126
|
+
|
|
127
|
+
// Disable right click
|
|
128
|
+
if (e.button === 2) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
element = element || this;
|
|
133
|
+
|
|
134
|
+
// Create ripple
|
|
135
|
+
var ripple = document.createElement('div');
|
|
136
|
+
ripple.className = 'waves-ripple waves-rippling';
|
|
137
|
+
element.appendChild(ripple);
|
|
138
|
+
|
|
139
|
+
// Get click coordinate and element width
|
|
140
|
+
var pos = offset(element);
|
|
141
|
+
var relativeY = 0;
|
|
142
|
+
var relativeX = 0;
|
|
143
|
+
// Support for touch devices
|
|
144
|
+
if('touches' in e && e.touches.length) {
|
|
145
|
+
relativeY = (e.touches[0].pageY - pos.top);
|
|
146
|
+
relativeX = (e.touches[0].pageX - pos.left);
|
|
147
|
+
}
|
|
148
|
+
//Normal case
|
|
149
|
+
else {
|
|
150
|
+
relativeY = (e.pageY - pos.top);
|
|
151
|
+
relativeX = (e.pageX - pos.left);
|
|
152
|
+
}
|
|
153
|
+
// Support for synthetic events
|
|
154
|
+
relativeX = relativeX >= 0 ? relativeX : 0;
|
|
155
|
+
relativeY = relativeY >= 0 ? relativeY : 0;
|
|
156
|
+
|
|
157
|
+
var scale = 'scale(' + ((element.clientWidth / 100) * 3) + ')';
|
|
158
|
+
var translate = 'translate(0,0)';
|
|
159
|
+
|
|
160
|
+
if (velocity) {
|
|
161
|
+
translate = 'translate(' + (velocity.x) + 'px, ' + (velocity.y) + 'px)';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Attach data to element
|
|
165
|
+
ripple.setAttribute('data-hold', Date.now());
|
|
166
|
+
ripple.setAttribute('data-x', relativeX);
|
|
167
|
+
ripple.setAttribute('data-y', relativeY);
|
|
168
|
+
ripple.setAttribute('data-scale', scale);
|
|
169
|
+
ripple.setAttribute('data-translate', translate);
|
|
170
|
+
|
|
171
|
+
// Set ripple position
|
|
172
|
+
var rippleStyle = {
|
|
173
|
+
top: relativeY + 'px',
|
|
174
|
+
left: relativeX + 'px'
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
ripple.classList.add('waves-notransition');
|
|
178
|
+
ripple.setAttribute('style', convertStyle(rippleStyle));
|
|
179
|
+
ripple.classList.remove('waves-notransition');
|
|
180
|
+
|
|
181
|
+
// Scale the ripple
|
|
182
|
+
rippleStyle['-webkit-transform'] = scale + ' ' + translate;
|
|
183
|
+
rippleStyle['-moz-transform'] = scale + ' ' + translate;
|
|
184
|
+
rippleStyle['-ms-transform'] = scale + ' ' + translate;
|
|
185
|
+
rippleStyle['-o-transform'] = scale + ' ' + translate;
|
|
186
|
+
rippleStyle.transform = scale + ' ' + translate;
|
|
187
|
+
rippleStyle.opacity = '1';
|
|
188
|
+
|
|
189
|
+
var duration = e.type === 'mousemove' ? 2500 : Effect.duration;
|
|
190
|
+
rippleStyle['-webkit-transition-duration'] = duration + 'ms';
|
|
191
|
+
rippleStyle['-moz-transition-duration'] = duration + 'ms';
|
|
192
|
+
rippleStyle['-o-transition-duration'] = duration + 'ms';
|
|
193
|
+
rippleStyle['transition-duration'] = duration + 'ms';
|
|
194
|
+
|
|
195
|
+
ripple.setAttribute('style', convertStyle(rippleStyle));
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
hide: function(e, element) {
|
|
199
|
+
element = element || this;
|
|
200
|
+
|
|
201
|
+
var ripples = element.getElementsByClassName('waves-rippling');
|
|
202
|
+
|
|
203
|
+
for (var i = 0, len = ripples.length; i < len; i++) {
|
|
204
|
+
removeRipple(e, element, ripples[i]);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (isTouchAvailable) {
|
|
208
|
+
element.removeEventListener('touchend', Effect.hide);
|
|
209
|
+
element.removeEventListener('touchcancel', Effect.hide);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
element.removeEventListener('mouseup', Effect.hide);
|
|
213
|
+
element.removeEventListener('mouseleave', Effect.hide);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Collection of wrapper for HTML element that only have single tag
|
|
219
|
+
* like <input> and <img>
|
|
220
|
+
*/
|
|
221
|
+
var TagWrapper = {
|
|
222
|
+
|
|
223
|
+
// Wrap <input> tag so it can perform the effect
|
|
224
|
+
input: function(element) {
|
|
225
|
+
|
|
226
|
+
var parent = element.parentNode;
|
|
227
|
+
|
|
228
|
+
// If input already have parent just pass through
|
|
229
|
+
if (parent.tagName.toLowerCase() === 'i' && parent.classList.contains('waves-effect')) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Put element class and style to the specified parent
|
|
234
|
+
var wrapper = document.createElement('i');
|
|
235
|
+
wrapper.className = element.className + ' waves-input-wrapper';
|
|
236
|
+
element.className = 'waves-button-input';
|
|
237
|
+
|
|
238
|
+
// Put element as child
|
|
239
|
+
parent.replaceChild(wrapper, element);
|
|
240
|
+
wrapper.appendChild(element);
|
|
241
|
+
|
|
242
|
+
// Apply element color and background color to wrapper
|
|
243
|
+
var elementStyle = window.getComputedStyle(element, null);
|
|
244
|
+
var color = elementStyle.color;
|
|
245
|
+
var backgroundColor = elementStyle.backgroundColor;
|
|
246
|
+
|
|
247
|
+
wrapper.setAttribute('style', 'color:' + color + ';background:' + backgroundColor);
|
|
248
|
+
element.setAttribute('style', 'background-color:rgba(0,0,0,0);');
|
|
249
|
+
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
// Wrap <img> tag so it can perform the effect
|
|
253
|
+
img: function(element) {
|
|
254
|
+
|
|
255
|
+
var parent = element.parentNode;
|
|
256
|
+
|
|
257
|
+
// If input already have parent just pass through
|
|
258
|
+
if (parent.tagName.toLowerCase() === 'i' && parent.classList.contains('waves-effect')) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Put element as child
|
|
263
|
+
var wrapper = document.createElement('i');
|
|
264
|
+
parent.replaceChild(wrapper, element);
|
|
265
|
+
wrapper.appendChild(element);
|
|
266
|
+
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Hide the effect and remove the ripple. Must be
|
|
272
|
+
* a separate function to pass the JSLint...
|
|
273
|
+
*/
|
|
274
|
+
function removeRipple(e, el, ripple) {
|
|
275
|
+
|
|
276
|
+
// Check if the ripple still exist
|
|
277
|
+
if (!ripple) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
ripple.classList.remove('waves-rippling');
|
|
282
|
+
|
|
283
|
+
var relativeX = ripple.getAttribute('data-x');
|
|
284
|
+
var relativeY = ripple.getAttribute('data-y');
|
|
285
|
+
var scale = ripple.getAttribute('data-scale');
|
|
286
|
+
var translate = ripple.getAttribute('data-translate');
|
|
287
|
+
|
|
288
|
+
// Get delay beetween mousedown and mouse leave
|
|
289
|
+
var diff = Date.now() - Number(ripple.getAttribute('data-hold'));
|
|
290
|
+
var delay = 350 - diff;
|
|
291
|
+
|
|
292
|
+
if (delay < 0) {
|
|
293
|
+
delay = 0;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (e.type === 'mousemove') {
|
|
297
|
+
delay = 150;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Fade out ripple after delay
|
|
301
|
+
var duration = e.type === 'mousemove' ? 2500 : Effect.duration;
|
|
302
|
+
|
|
303
|
+
setTimeout(function() {
|
|
304
|
+
|
|
305
|
+
var style = {
|
|
306
|
+
top: relativeY + 'px',
|
|
307
|
+
left: relativeX + 'px',
|
|
308
|
+
opacity: '0',
|
|
309
|
+
|
|
310
|
+
// Duration
|
|
311
|
+
'-webkit-transition-duration': duration + 'ms',
|
|
312
|
+
'-moz-transition-duration': duration + 'ms',
|
|
313
|
+
'-o-transition-duration': duration + 'ms',
|
|
314
|
+
'transition-duration': duration + 'ms',
|
|
315
|
+
'-webkit-transform': scale + ' ' + translate,
|
|
316
|
+
'-moz-transform': scale + ' ' + translate,
|
|
317
|
+
'-ms-transform': scale + ' ' + translate,
|
|
318
|
+
'-o-transform': scale + ' ' + translate,
|
|
319
|
+
'transform': scale + ' ' + translate
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
ripple.setAttribute('style', convertStyle(style));
|
|
323
|
+
|
|
324
|
+
setTimeout(function() {
|
|
325
|
+
try {
|
|
326
|
+
el.removeChild(ripple);
|
|
327
|
+
} catch (e) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
}, duration);
|
|
331
|
+
|
|
332
|
+
}, delay);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Disable mousedown event for 500ms during and after touch
|
|
338
|
+
*/
|
|
339
|
+
var TouchHandler = {
|
|
340
|
+
|
|
341
|
+
/* uses an integer rather than bool so there's no issues with
|
|
342
|
+
* needing to clear timeouts if another touch event occurred
|
|
343
|
+
* within the 500ms. Cannot mouseup between touchstart and
|
|
344
|
+
* touchend, nor in the 500ms after touchend. */
|
|
345
|
+
touches: 0,
|
|
346
|
+
|
|
347
|
+
allowEvent: function(e) {
|
|
348
|
+
|
|
349
|
+
var allow = true;
|
|
350
|
+
|
|
351
|
+
if (/^(mousedown|mousemove)$/.test(e.type) && TouchHandler.touches) {
|
|
352
|
+
allow = false;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return allow;
|
|
356
|
+
},
|
|
357
|
+
registerEvent: function(e) {
|
|
358
|
+
var eType = e.type;
|
|
359
|
+
|
|
360
|
+
if (eType === 'touchstart') {
|
|
361
|
+
|
|
362
|
+
TouchHandler.touches += 1; // push
|
|
363
|
+
|
|
364
|
+
} else if (/^(touchend|touchcancel)$/.test(eType)) {
|
|
365
|
+
|
|
366
|
+
setTimeout(function() {
|
|
367
|
+
if (TouchHandler.touches) {
|
|
368
|
+
TouchHandler.touches -= 1; // pop after 500ms
|
|
369
|
+
}
|
|
370
|
+
}, 500);
|
|
371
|
+
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Delegated click handler for .waves-effect element.
|
|
379
|
+
* returns null when .waves-effect element not in "click tree"
|
|
380
|
+
*/
|
|
381
|
+
function getWavesEffectElement(e) {
|
|
382
|
+
|
|
383
|
+
if (TouchHandler.allowEvent(e) === false) {
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
var element = null;
|
|
388
|
+
var target = e.target || e.srcElement;
|
|
389
|
+
|
|
390
|
+
while (target.parentElement) {
|
|
391
|
+
if ( (!(target instanceof SVGElement)) && target.classList.contains('waves-effect')) {
|
|
392
|
+
element = target;
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
target = target.parentElement;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return element;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Bubble the click and show effect if .waves-effect elem was found
|
|
403
|
+
*/
|
|
404
|
+
function showEffect(e) {
|
|
405
|
+
|
|
406
|
+
// Disable effect if element has "disabled" property on it
|
|
407
|
+
// In some cases, the event is not triggered by the current element
|
|
408
|
+
// if (e.target.getAttribute('disabled') !== null) {
|
|
409
|
+
// return;
|
|
410
|
+
// }
|
|
411
|
+
|
|
412
|
+
var element = getWavesEffectElement(e);
|
|
413
|
+
|
|
414
|
+
if (element !== null) {
|
|
415
|
+
|
|
416
|
+
// Make it sure the element has either disabled property, disabled attribute or 'disabled' class
|
|
417
|
+
if (element.disabled || element.getAttribute('disabled') || element.classList.contains('disabled')) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
TouchHandler.registerEvent(e);
|
|
422
|
+
|
|
423
|
+
if (e.type === 'touchstart' && Effect.delay) {
|
|
424
|
+
|
|
425
|
+
var hidden = false;
|
|
426
|
+
|
|
427
|
+
var timer = setTimeout(function () {
|
|
428
|
+
timer = null;
|
|
429
|
+
Effect.show(e, element);
|
|
430
|
+
}, Effect.delay);
|
|
431
|
+
|
|
432
|
+
var hideEffect = function(hideEvent) {
|
|
433
|
+
|
|
434
|
+
// if touch hasn't moved, and effect not yet started: start effect now
|
|
435
|
+
if (timer) {
|
|
436
|
+
clearTimeout(timer);
|
|
437
|
+
timer = null;
|
|
438
|
+
Effect.show(e, element);
|
|
439
|
+
}
|
|
440
|
+
if (!hidden) {
|
|
441
|
+
hidden = true;
|
|
442
|
+
Effect.hide(hideEvent, element);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
removeListeners();
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
var touchMove = function(moveEvent) {
|
|
449
|
+
if (timer) {
|
|
450
|
+
clearTimeout(timer);
|
|
451
|
+
timer = null;
|
|
452
|
+
}
|
|
453
|
+
hideEffect(moveEvent);
|
|
454
|
+
|
|
455
|
+
removeListeners();
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
element.addEventListener('touchmove', touchMove, passiveIfSupported);
|
|
459
|
+
element.addEventListener('touchend', hideEffect, passiveIfSupported);
|
|
460
|
+
element.addEventListener('touchcancel', hideEffect, passiveIfSupported);
|
|
461
|
+
|
|
462
|
+
var removeListeners = function() {
|
|
463
|
+
element.removeEventListener('touchmove', touchMove);
|
|
464
|
+
element.removeEventListener('touchend', hideEffect);
|
|
465
|
+
element.removeEventListener('touchcancel', hideEffect);
|
|
466
|
+
};
|
|
467
|
+
} else {
|
|
468
|
+
|
|
469
|
+
Effect.show(e, element);
|
|
470
|
+
|
|
471
|
+
if (isTouchAvailable) {
|
|
472
|
+
element.addEventListener('touchend', Effect.hide, passiveIfSupported);
|
|
473
|
+
element.addEventListener('touchcancel', Effect.hide, passiveIfSupported);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
element.addEventListener('mouseup', Effect.hide, passiveIfSupported);
|
|
477
|
+
element.addEventListener('mouseleave', Effect.hide, passiveIfSupported);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
Waves.init = function(options) {
|
|
483
|
+
var body = document.body;
|
|
484
|
+
|
|
485
|
+
options = options || {};
|
|
486
|
+
|
|
487
|
+
if ('duration' in options) {
|
|
488
|
+
Effect.duration = options.duration;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if ('delay' in options) {
|
|
492
|
+
Effect.delay = options.delay;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if (isTouchAvailable) {
|
|
496
|
+
body.addEventListener('touchstart', showEffect, passiveIfSupported);
|
|
497
|
+
body.addEventListener('touchcancel', TouchHandler.registerEvent, passiveIfSupported);
|
|
498
|
+
body.addEventListener('touchend', TouchHandler.registerEvent, passiveIfSupported);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
body.addEventListener('mousedown', showEffect, passiveIfSupported);
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Attach Waves to dynamically loaded inputs, or add .waves-effect and other
|
|
507
|
+
* waves classes to a set of elements. Set drag to true if the ripple mouseover
|
|
508
|
+
* or skimming effect should be applied to the elements.
|
|
509
|
+
*/
|
|
510
|
+
Waves.attach = function(elements, classes) {
|
|
511
|
+
|
|
512
|
+
elements = getWavesElements(elements);
|
|
513
|
+
|
|
514
|
+
if (toString.call(classes) === '[object Array]') {
|
|
515
|
+
classes = classes.join(' ');
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
classes = classes ? ' ' + classes : '';
|
|
519
|
+
|
|
520
|
+
var element, tagName;
|
|
521
|
+
|
|
522
|
+
for (var i = 0, len = elements.length; i < len; i++) {
|
|
523
|
+
|
|
524
|
+
element = elements[i];
|
|
525
|
+
tagName = element.tagName.toLowerCase();
|
|
526
|
+
|
|
527
|
+
if (['input', 'img'].indexOf(tagName) !== -1) {
|
|
528
|
+
TagWrapper[tagName](element);
|
|
529
|
+
element = element.parentElement;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (element.className.indexOf('waves-effect') === -1) {
|
|
533
|
+
element.className += ' waves-effect' + classes;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Cause a ripple to appear in an element via code.
|
|
541
|
+
*/
|
|
542
|
+
Waves.ripple = function(elements, options) {
|
|
543
|
+
elements = getWavesElements(elements);
|
|
544
|
+
var elementsLen = elements.length;
|
|
545
|
+
|
|
546
|
+
options = options || {};
|
|
547
|
+
options.wait = options.wait || 0;
|
|
548
|
+
options.position = options.position || null; // default = centre of element
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
if (elementsLen) {
|
|
552
|
+
var element, pos, off, centre = {}, i = 0;
|
|
553
|
+
var mousedown = {
|
|
554
|
+
type: 'mousedown',
|
|
555
|
+
button: 1
|
|
556
|
+
};
|
|
557
|
+
var hideRipple = function(mouseup, element) {
|
|
558
|
+
return function() {
|
|
559
|
+
Effect.hide(mouseup, element);
|
|
560
|
+
};
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
for (; i < elementsLen; i++) {
|
|
564
|
+
element = elements[i];
|
|
565
|
+
pos = options.position || {
|
|
566
|
+
x: element.clientWidth / 2,
|
|
567
|
+
y: element.clientHeight / 2
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
off = offset(element);
|
|
571
|
+
centre.x = off.left + pos.x;
|
|
572
|
+
centre.y = off.top + pos.y;
|
|
573
|
+
|
|
574
|
+
mousedown.pageX = centre.x;
|
|
575
|
+
mousedown.pageY = centre.y;
|
|
576
|
+
|
|
577
|
+
Effect.show(mousedown, element);
|
|
578
|
+
|
|
579
|
+
if (options.wait >= 0 && options.wait !== null) {
|
|
580
|
+
var mouseup = {
|
|
581
|
+
type: 'mouseup',
|
|
582
|
+
button: 1
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
setTimeout(hideRipple(mouseup, element), options.wait);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Remove all ripples from an element.
|
|
593
|
+
*/
|
|
594
|
+
Waves.calm = function(elements) {
|
|
595
|
+
elements = getWavesElements(elements);
|
|
596
|
+
var mouseup = {
|
|
597
|
+
type: 'mouseup',
|
|
598
|
+
button: 1
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
for (var i = 0, len = elements.length; i < len; i++) {
|
|
602
|
+
Effect.hide(mouseup, elements[i]);
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Deprecated API fallback
|
|
608
|
+
*/
|
|
609
|
+
Waves.displayEffect = function(options) {
|
|
610
|
+
console.error('Waves.displayEffect() has been deprecated and will be removed in future version. Please use Waves.init() to initialize Waves effect');
|
|
611
|
+
Waves.init(options);
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
return Waves;
|
|
615
615
|
});
|