@materializecss/materialize 1.1.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.
Files changed (83) hide show
  1. package/Gruntfile.js +38 -24
  2. package/LICENSE +21 -21
  3. package/README.md +91 -97
  4. package/dist/css/materialize.css +8608 -8631
  5. package/dist/css/materialize.min.css +12 -12
  6. package/dist/js/materialize.js +12816 -12669
  7. package/dist/js/materialize.min.js +6 -6
  8. package/extras/noUiSlider/nouislider.css +404 -406
  9. package/extras/noUiSlider/nouislider.js +2147 -2147
  10. package/extras/noUiSlider/nouislider.min.js +0 -0
  11. package/js/anime.min.js +34 -34
  12. package/js/autocomplete.js +479 -479
  13. package/js/buttons.js +354 -354
  14. package/js/cards.js +40 -40
  15. package/js/carousel.js +732 -732
  16. package/js/cash.js +960 -960
  17. package/js/characterCounter.js +136 -136
  18. package/js/chips.js +486 -486
  19. package/js/collapsible.js +275 -275
  20. package/js/component.js +44 -44
  21. package/js/datepicker.js +983 -983
  22. package/js/dropdown.js +669 -669
  23. package/js/forms.js +285 -275
  24. package/js/global.js +428 -424
  25. package/js/materialbox.js +453 -453
  26. package/js/modal.js +382 -382
  27. package/js/parallax.js +138 -138
  28. package/js/pushpin.js +148 -148
  29. package/js/range.js +263 -263
  30. package/js/scrollspy.js +295 -295
  31. package/js/select.js +391 -310
  32. package/js/sidenav.js +583 -583
  33. package/js/slider.js +359 -359
  34. package/js/tabs.js +402 -402
  35. package/js/tapTarget.js +315 -315
  36. package/js/timepicker.js +712 -648
  37. package/js/toasts.js +325 -322
  38. package/js/tooltip.js +320 -320
  39. package/js/waves.js +614 -614
  40. package/package.json +87 -82
  41. package/sass/_style.scss +929 -929
  42. package/sass/components/_badges.scss +55 -55
  43. package/sass/components/_buttons.scss +322 -322
  44. package/sass/components/_cards.scss +195 -195
  45. package/sass/components/_carousel.scss +90 -90
  46. package/sass/components/_chips.scss +96 -96
  47. package/sass/components/_collapsible.scss +91 -91
  48. package/sass/components/_collection.scss +106 -106
  49. package/sass/components/_color-classes.scss +32 -32
  50. package/sass/components/_color-variables.scss +370 -370
  51. package/sass/components/_datepicker.scss +191 -191
  52. package/sass/components/_dropdown.scss +84 -84
  53. package/sass/components/_global.scss +646 -642
  54. package/sass/components/_grid.scss +158 -158
  55. package/sass/components/_icons-material-design.scss +5 -5
  56. package/sass/components/_materialbox.scss +42 -42
  57. package/sass/components/_modal.scss +97 -97
  58. package/sass/components/_navbar.scss +208 -208
  59. package/sass/components/_normalize.scss +447 -447
  60. package/sass/components/_preloader.scss +334 -334
  61. package/sass/components/_pulse.scss +34 -34
  62. package/sass/components/_sidenav.scss +214 -214
  63. package/sass/components/_slider.scss +91 -91
  64. package/sass/components/_table_of_contents.scss +33 -33
  65. package/sass/components/_tabs.scss +99 -99
  66. package/sass/components/_tapTarget.scss +103 -103
  67. package/sass/components/_timepicker.scss +199 -183
  68. package/sass/components/_toast.scss +58 -58
  69. package/sass/components/_tooltip.scss +32 -32
  70. package/sass/components/_transitions.scss +12 -12
  71. package/sass/components/_typography.scss +62 -62
  72. package/sass/components/_variables.scss +352 -352
  73. package/sass/components/_waves.scss +187 -187
  74. package/sass/components/forms/_checkboxes.scss +200 -200
  75. package/sass/components/forms/_file-input.scss +44 -44
  76. package/sass/components/forms/_forms.scss +22 -22
  77. package/sass/components/forms/_input-fields.scss +388 -379
  78. package/sass/components/forms/_radio-buttons.scss +115 -115
  79. package/sass/components/forms/_range.scss +161 -161
  80. package/sass/components/forms/_select.scss +199 -199
  81. package/sass/components/forms/_switches.scss +91 -91
  82. package/sass/ghpages-materialize.scss +7 -7
  83. 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
  });