mirror of
				https://github.com/mdbootstrap/mdb-ui-kit.git
				synced 2025-11-04 09:57:36 +03:00 
			
		
		
		
	Ripples.js rewritten with jQuery + added JS maps
This commit is contained in:
		
							parent
							
								
									ad6365bd0d
								
							
						
					
					
						commit
						fc0fed6eab
					
				
							
								
								
									
										11
									
								
								Gruntfile.js
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Gruntfile.js
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -52,10 +52,13 @@ module.exports = function(grunt) {
 | 
			
		|||
        },
 | 
			
		||||
 | 
			
		||||
        uglify: {
 | 
			
		||||
            options: {
 | 
			
		||||
              sourceMap: true
 | 
			
		||||
            },
 | 
			
		||||
            minifyjs: {
 | 
			
		||||
                files: {
 | 
			
		||||
                    "dist/js/material.min.js": "scripts/material.js",
 | 
			
		||||
                    "dist/js/ripples.min.js": "scripts/ripples.js"
 | 
			
		||||
                    "dist/js/material.min.js": "dist/js/material.js",
 | 
			
		||||
                    "dist/js/ripples.min.js": "dist/js/ripples.js"
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
| 
						 | 
				
			
			@ -164,9 +167,9 @@ module.exports = function(grunt) {
 | 
			
		|||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    grunt.registerTask("default", ["less", "autoprefixer", "cssmin", "uglify", "copy"]);
 | 
			
		||||
    grunt.registerTask("default", ["less", "autoprefixer", "cssmin", "copy", "uglify"]);
 | 
			
		||||
 | 
			
		||||
    grunt.registerTask("scss", ["sass", "autoprefixer", "cssmin", "uglify", "copy"]);
 | 
			
		||||
    grunt.registerTask("scss", ["sass", "autoprefixer", "cssmin", "copy", "uglify"]);
 | 
			
		||||
 | 
			
		||||
    grunt.registerTask("build", function(target) {
 | 
			
		||||
        var buildType = "default";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								dist/css/ripples.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								dist/css/ripples.css
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -19,22 +19,16 @@
 | 
			
		|||
  margin-top: -10px;
 | 
			
		||||
  border-radius: 100%;
 | 
			
		||||
  background-color: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  -webkit-transform: scale(1);
 | 
			
		||||
      -ms-transform: scale(1);
 | 
			
		||||
          transform: scale(1);
 | 
			
		||||
  -webkit-transform-origin: 50%;
 | 
			
		||||
      -ms-transform-origin: 50%;
 | 
			
		||||
          transform-origin: 50%;
 | 
			
		||||
  transform: scale(1);
 | 
			
		||||
  transform-origin: 50%;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
  pointer-events: none;
 | 
			
		||||
}
 | 
			
		||||
.ripple.ripple-on {
 | 
			
		||||
  -webkit-transition: opacity 0.15s ease-in 0s, -webkit-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
 | 
			
		||||
          transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
  transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
 | 
			
		||||
  opacity: 0.2;
 | 
			
		||||
}
 | 
			
		||||
.ripple.ripple-out {
 | 
			
		||||
  -webkit-transition: opacity 0.1s linear 0s !important;
 | 
			
		||||
          transition: opacity 0.1s linear 0s !important;
 | 
			
		||||
  transition: opacity 0.1s linear 0s !important;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								dist/css/ripples.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/css/ripples.min.css
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
.withripple{position:relative}.ripple-wrapper{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;overflow:hidden;border-radius:inherit}.ripple{position:absolute;width:20px;height:20px;margin-left:-10px;margin-top:-10px;border-radius:100%;background-color:rgba(0,0,0,.05);-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);-webkit-transform-origin:50%;-ms-transform-origin:50%;transform-origin:50%;opacity:0;pointer-events:none}.ripple.ripple-on{-webkit-transition:opacity .15s ease-in 0s,-webkit-transform .5s cubic-bezier(0.4,0,.2,1) .1s;transition:opacity .15s ease-in 0s,transform .5s cubic-bezier(0.4,0,.2,1) .1s;opacity:1}.ripple.ripple-out{-webkit-transition:opacity .1s linear 0s!important;transition:opacity .1s linear 0s!important;opacity:0}
 | 
			
		||||
.withripple{position:relative}.ripple-wrapper{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;overflow:hidden;border-radius:inherit}.ripple{position:absolute;width:20px;height:20px;margin-left:-10px;margin-top:-10px;border-radius:100%;background-color:rgba(0,0,0,.05);-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);-webkit-transform-origin:50%;-ms-transform-origin:50%;transform-origin:50%;opacity:0;pointer-events:none}.ripple.ripple-on{-webkit-transition:opacity .15s ease-in 0s,-webkit-transform .5s cubic-bezier(0.4,0,.2,1) .1s;transition:opacity .15s ease-in 0s,transform .5s cubic-bezier(0.4,0,.2,1) .1s;opacity:.2}.ripple.ripple-out{-webkit-transition:opacity .1s linear 0s!important;transition:opacity .1s linear 0s!important;opacity:0}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										311
									
								
								dist/js/material.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										311
									
								
								dist/js/material.js
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,159 +1,170 @@
 | 
			
		|||
/* globals jQuery, ripples */
 | 
			
		||||
/* globals jQuery */
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
    // Selector to select only not already processed elements
 | 
			
		||||
    $.expr[":"].notmdproc = function(obj){
 | 
			
		||||
        if ($(obj).data("mdproc")) {
 | 
			
		||||
            return false;
 | 
			
		||||
        } else {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    function _isChar(evt) {
 | 
			
		||||
        if (typeof evt.which == "undefined") {
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (typeof evt.which == "number" && evt.which > 0) {
 | 
			
		||||
            return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
  // Selector to select only not already processed elements
 | 
			
		||||
  $.expr[":"].notmdproc = function(obj){
 | 
			
		||||
    if ($(obj).data("mdproc")) {
 | 
			
		||||
      return false;
 | 
			
		||||
    } else {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    $.material =  {
 | 
			
		||||
        "options": {
 | 
			
		||||
            "withRipples": [
 | 
			
		||||
                ".btn:not(.btn-link)",
 | 
			
		||||
                ".card-image",
 | 
			
		||||
                ".navbar a:not(.withoutripple)",
 | 
			
		||||
                ".dropdown-menu a",
 | 
			
		||||
                ".nav-tabs a:not(.withoutripple)",
 | 
			
		||||
                ".withripple"
 | 
			
		||||
            ].join(","),
 | 
			
		||||
            "inputElements": "input.form-control, textarea.form-control, select.form-control",
 | 
			
		||||
            "checkboxElements": ".checkbox > label > input[type=checkbox]",
 | 
			
		||||
            "radioElements": ".radio > label > input[type=radio]"
 | 
			
		||||
        },
 | 
			
		||||
        "checkbox": function(selector) {
 | 
			
		||||
            // Add fake-checkbox to material checkboxes
 | 
			
		||||
            $((selector) ? selector : this.options.checkboxElements)
 | 
			
		||||
            .filter(":notmdproc")
 | 
			
		||||
            .data("mdproc", true)
 | 
			
		||||
            .after("<span class=ripple></span><span class=check></span>");
 | 
			
		||||
        },
 | 
			
		||||
        "radio": function(selector) {
 | 
			
		||||
            // Add fake-radio to material radios
 | 
			
		||||
            $((selector) ? selector : this.options.radioElements)
 | 
			
		||||
            .filter(":notmdproc")
 | 
			
		||||
            .data("mdproc", true)
 | 
			
		||||
            .after("<span class=circle></span><span class=check></span>");
 | 
			
		||||
        },
 | 
			
		||||
        "input": function(selector) {
 | 
			
		||||
            $((selector) ? selector : this.options.inputElements)
 | 
			
		||||
            .filter(":notmdproc")
 | 
			
		||||
            .data("mdproc", true)
 | 
			
		||||
            .each( function() {
 | 
			
		||||
                var $this = $(this);
 | 
			
		||||
                $this.wrap("<div class=form-control-wrapper></div>");
 | 
			
		||||
                $this.after("<span class=material-input></span>");
 | 
			
		||||
                if ($this.hasClass("floating-label")) {
 | 
			
		||||
                    var placeholder = $this.attr("placeholder");
 | 
			
		||||
                    $this.attr("placeholder", null).removeClass("floating-label");
 | 
			
		||||
                    $this.after("<div class=floating-label>" + placeholder + "</div>");
 | 
			
		||||
                }
 | 
			
		||||
                if ($this.val() === null || $this.val() == "undefined" || $this.val() === "") {
 | 
			
		||||
                    $this.addClass("empty");
 | 
			
		||||
                }
 | 
			
		||||
                if ($this.parent().next().is("[type=file]")) {
 | 
			
		||||
                    $this.parent().addClass("fileinput");
 | 
			
		||||
                    var $input = $this.parent().next().detach();
 | 
			
		||||
                    $this.after($input);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
  function _isChar(evt) {
 | 
			
		||||
    if (typeof evt.which == "undefined") {
 | 
			
		||||
      return true;
 | 
			
		||||
    } else if (typeof evt.which == "number" && evt.which > 0) {
 | 
			
		||||
      return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
            $(document)
 | 
			
		||||
            .on("change", ".checkbox input", function() { $(this).blur(); })
 | 
			
		||||
            .on("keydown paste", ".form-control", function(e) {
 | 
			
		||||
                if(_isChar(e)) {
 | 
			
		||||
                    $(this).removeClass("empty");
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .on("keyup change", ".form-control", function() {
 | 
			
		||||
                var $this = $(this);
 | 
			
		||||
                if($this.val() === "") {
 | 
			
		||||
                    $this.addClass("empty");
 | 
			
		||||
                } else {
 | 
			
		||||
                    $this.removeClass("empty");
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .on("focus", ".form-control-wrapper.fileinput", function() {
 | 
			
		||||
                $(this).find("input").addClass("focus");
 | 
			
		||||
            })
 | 
			
		||||
            .on("blur", ".form-control-wrapper.fileinput", function() {
 | 
			
		||||
                $(this).find("input").removeClass("focus");
 | 
			
		||||
            })
 | 
			
		||||
            .on("change", ".form-control-wrapper.fileinput [type=file]", function() {
 | 
			
		||||
                var value = "";
 | 
			
		||||
                $.each($(this)[0].files, function(i, file) {
 | 
			
		||||
                    console.log(file);
 | 
			
		||||
                    value += file.name + ", ";
 | 
			
		||||
                });
 | 
			
		||||
                value = value.substring(0, value.length - 2);
 | 
			
		||||
                if (value) {
 | 
			
		||||
                    $(this).prev().removeClass("empty");
 | 
			
		||||
                } else {
 | 
			
		||||
                    $(this).prev().addClass("empty");
 | 
			
		||||
                }
 | 
			
		||||
                $(this).prev().val(value);
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        "ripples": function(selector) {
 | 
			
		||||
            ripples.init((selector) ? selector : this.options.withRipples);
 | 
			
		||||
        },
 | 
			
		||||
        "init": function() {
 | 
			
		||||
            this.ripples();
 | 
			
		||||
            this.input();
 | 
			
		||||
            this.checkbox();
 | 
			
		||||
            this.radio();
 | 
			
		||||
  $.material =  {
 | 
			
		||||
    "options": {
 | 
			
		||||
      "withRipples": [
 | 
			
		||||
        ".btn:not(.btn-link)",
 | 
			
		||||
        ".card-image",
 | 
			
		||||
        ".navbar a:not(.withoutripple)",
 | 
			
		||||
        ".dropdown-menu a",
 | 
			
		||||
        ".nav-tabs a:not(.withoutripple)",
 | 
			
		||||
        ".withripple"
 | 
			
		||||
      ].join(","),
 | 
			
		||||
      "inputElements": "input.form-control, textarea.form-control, select.form-control",
 | 
			
		||||
      "checkboxElements": ".checkbox > label > input[type=checkbox]",
 | 
			
		||||
      "radioElements": ".radio > label > input[type=radio]"
 | 
			
		||||
    },
 | 
			
		||||
    "checkbox": function(selector) {
 | 
			
		||||
      // Add fake-checkbox to material checkboxes
 | 
			
		||||
      $((selector) ? selector : this.options.checkboxElements)
 | 
			
		||||
      .filter(":notmdproc")
 | 
			
		||||
      .data("mdproc", true)
 | 
			
		||||
      .after("<span class=ripple></span><span class=check></span>");
 | 
			
		||||
    },
 | 
			
		||||
    "radio": function(selector) {
 | 
			
		||||
      // Add fake-radio to material radios
 | 
			
		||||
      $((selector) ? selector : this.options.radioElements)
 | 
			
		||||
      .filter(":notmdproc")
 | 
			
		||||
      .data("mdproc", true)
 | 
			
		||||
      .after("<span class=circle></span><span class=check></span>");
 | 
			
		||||
    },
 | 
			
		||||
    "input": function(selector) {
 | 
			
		||||
      $((selector) ? selector : this.options.inputElements)
 | 
			
		||||
      .filter(":notmdproc")
 | 
			
		||||
      .data("mdproc", true)
 | 
			
		||||
      .each( function() {
 | 
			
		||||
        var $this = $(this);
 | 
			
		||||
        $this.wrap("<div class=form-control-wrapper></div>");
 | 
			
		||||
        $this.after("<span class=material-input></span>");
 | 
			
		||||
 | 
			
		||||
            if (document.arrive) {
 | 
			
		||||
                document.arrive("input, textarea, select", function() {
 | 
			
		||||
                    $.material.init();
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Detect autofill
 | 
			
		||||
            (function() {
 | 
			
		||||
                // This part of code will detect autofill when the page is loading (username and password inputs for example)
 | 
			
		||||
                var loading = setInterval(function() {
 | 
			
		||||
                    $("input").each(function() {
 | 
			
		||||
                        if ($(this).val() !== $(this).attr("value")) {
 | 
			
		||||
                            $(this).trigger("change");
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }, 100);
 | 
			
		||||
                // After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
 | 
			
		||||
                setTimeout(function() {
 | 
			
		||||
                    clearInterval(loading);
 | 
			
		||||
                }, 10000);
 | 
			
		||||
                // Now we just listen on inputs of the focused form (because user can select from the autofill dropdown only when the input has focus)
 | 
			
		||||
                var focused;
 | 
			
		||||
                $(document)
 | 
			
		||||
                .on("focus", "input", function() {
 | 
			
		||||
                    var $inputs = $(this).parents("form").find("input");
 | 
			
		||||
                    focused = setInterval(function() {
 | 
			
		||||
                        $inputs.each(function() {
 | 
			
		||||
                            if ($(this).val() !== $(this).attr("value")) {
 | 
			
		||||
                                $(this).trigger("change");
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                    }, 100);
 | 
			
		||||
                })
 | 
			
		||||
                .on("blur", "input", function() {
 | 
			
		||||
                    clearInterval(focused);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            })();
 | 
			
		||||
        // Add floating label if required
 | 
			
		||||
        if ($this.hasClass("floating-label")) {
 | 
			
		||||
          var placeholder = $this.attr("placeholder");
 | 
			
		||||
          $this.attr("placeholder", null).removeClass("floating-label");
 | 
			
		||||
          $this.after("<div class=floating-label>" + placeholder + "</div>");
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
        // Add hint label if required
 | 
			
		||||
        if ($this.attr("data-hint")) {
 | 
			
		||||
          $this.after("<div class=hint>" + $this.attr("data-hint") + "</div>");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set as empty if is empty (damn I must improve this...)
 | 
			
		||||
        if ($this.val() === null || $this.val() == "undefined" || $this.val() === "") {
 | 
			
		||||
          $this.addClass("empty");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Support for file input
 | 
			
		||||
        if ($this.parent().next().is("[type=file]")) {
 | 
			
		||||
          $this.parent().addClass("fileinput");
 | 
			
		||||
          var $input = $this.parent().next().detach();
 | 
			
		||||
          $this.after($input);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      $(document)
 | 
			
		||||
      .on("change", ".checkbox input[type=checkbox]", function() { $(this).blur(); })
 | 
			
		||||
      .on("keydown paste", ".form-control", function(e) {
 | 
			
		||||
        if(_isChar(e)) {
 | 
			
		||||
          $(this).removeClass("empty");
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .on("keyup change", ".form-control", function() {
 | 
			
		||||
        var $this = $(this);
 | 
			
		||||
        if($this.val() === "") {
 | 
			
		||||
          $this.addClass("empty");
 | 
			
		||||
        } else {
 | 
			
		||||
          $this.removeClass("empty");
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .on("focus", ".form-control-wrapper.fileinput", function() {
 | 
			
		||||
        $(this).find("input").addClass("focus");
 | 
			
		||||
      })
 | 
			
		||||
      .on("blur", ".form-control-wrapper.fileinput", function() {
 | 
			
		||||
        $(this).find("input").removeClass("focus");
 | 
			
		||||
      })
 | 
			
		||||
      .on("change", ".form-control-wrapper.fileinput [type=file]", function() {
 | 
			
		||||
        var value = "";
 | 
			
		||||
        $.each($(this)[0].files, function(i, file) {
 | 
			
		||||
          console.log(file);
 | 
			
		||||
          value += file.name + ", ";
 | 
			
		||||
        });
 | 
			
		||||
        value = value.substring(0, value.length - 2);
 | 
			
		||||
        if (value) {
 | 
			
		||||
          $(this).prev().removeClass("empty");
 | 
			
		||||
        } else {
 | 
			
		||||
          $(this).prev().addClass("empty");
 | 
			
		||||
        }
 | 
			
		||||
        $(this).prev().val(value);
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
    "ripples": function(selector) {
 | 
			
		||||
      $.ripples({"target": (selector) ? selector : this.options.withRipples});
 | 
			
		||||
    },
 | 
			
		||||
    "init": function() {
 | 
			
		||||
      this.ripples();
 | 
			
		||||
      this.input();
 | 
			
		||||
      this.checkbox();
 | 
			
		||||
      this.radio();
 | 
			
		||||
 | 
			
		||||
      if (document.arrive) {
 | 
			
		||||
        document.arrive("input, textarea, select", function() {
 | 
			
		||||
          $.material.init();
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Detect autofill
 | 
			
		||||
      (function() {
 | 
			
		||||
        // This part of code will detect autofill when the page is loading (username and password inputs for example)
 | 
			
		||||
        var loading = setInterval(function() {
 | 
			
		||||
          $("input[type!=checkbox]").each(function() {
 | 
			
		||||
            if ($(this).val() && $(this).val() !== $(this).attr("value")) {
 | 
			
		||||
              $(this).trigger("change");
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        }, 100);
 | 
			
		||||
        // After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
 | 
			
		||||
        setTimeout(function() {
 | 
			
		||||
          clearInterval(loading);
 | 
			
		||||
        }, 10000);
 | 
			
		||||
        // Now we just listen on inputs of the focused form (because user can select from the autofill dropdown only when the input has focus)
 | 
			
		||||
        var focused;
 | 
			
		||||
        $(document)
 | 
			
		||||
        .on("focus", "input", function() {
 | 
			
		||||
          var $inputs = $(this).parents("form").find("input");
 | 
			
		||||
          focused = setInterval(function() {
 | 
			
		||||
            $inputs.each(function() {
 | 
			
		||||
              if ($(this).val() !== $(this).attr("value")) {
 | 
			
		||||
                $(this).trigger("change");
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
          }, 100);
 | 
			
		||||
        })
 | 
			
		||||
        .on("blur", "input", function() {
 | 
			
		||||
          clearInterval(focused);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
      })();
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								dist/js/material.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								dist/js/material.min.js
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1 +1,2 @@
 | 
			
		|||
!function(a){function b(a){return"undefined"==typeof a.which?!0:"number"==typeof a.which&&a.which>0?!a.ctrlKey&&!a.metaKey&&!a.altKey&&8!=a.which:!1}a.expr[":"].notmdproc=function(b){return a(b).data("mdproc")?!1:!0},a.material={options:{withRipples:[".btn:not(.btn-link)",".card-image",".navbar a:not(.withoutripple)",".dropdown-menu a",".nav-tabs a:not(.withoutripple)",".withripple"].join(","),inputElements:"input.form-control, textarea.form-control, select.form-control",checkboxElements:".checkbox > label > input[type=checkbox]",radioElements:".radio > label > input[type=radio]"},checkbox:function(b){a(b?b:this.options.checkboxElements).filter(":notmdproc").data("mdproc",!0).after("<span class=ripple></span><span class=check></span>")},radio:function(b){a(b?b:this.options.radioElements).filter(":notmdproc").data("mdproc",!0).after("<span class=circle></span><span class=check></span>")},input:function(c){a(c?c:this.options.inputElements).filter(":notmdproc").data("mdproc",!0).each(function(){var b=a(this);if(b.wrap("<div class=form-control-wrapper></div>"),b.after("<span class=material-input></span>"),b.hasClass("floating-label")){var c=b.attr("placeholder");b.attr("placeholder",null).removeClass("floating-label"),b.after("<div class=floating-label>"+c+"</div>")}if(b.attr("data-hint")&&b.after("<div class=hint>"+b.attr("data-hint")+"</div>"),(null===b.val()||"undefined"==b.val()||""===b.val())&&b.addClass("empty"),b.parent().next().is("[type=file]")){b.parent().addClass("fileinput");var d=b.parent().next().detach();b.after(d)}}),a(document).on("change",".checkbox input[type=checkbox]",function(){a(this).blur()}).on("keydown paste",".form-control",function(c){b(c)&&a(this).removeClass("empty")}).on("keyup change",".form-control",function(){var b=a(this);""===b.val()?b.addClass("empty"):b.removeClass("empty")}).on("focus",".form-control-wrapper.fileinput",function(){a(this).find("input").addClass("focus")}).on("blur",".form-control-wrapper.fileinput",function(){a(this).find("input").removeClass("focus")}).on("change",".form-control-wrapper.fileinput [type=file]",function(){var b="";a.each(a(this)[0].files,function(a,c){console.log(c),b+=c.name+", "}),b=b.substring(0,b.length-2),b?a(this).prev().removeClass("empty"):a(this).prev().addClass("empty"),a(this).prev().val(b)})},ripples:function(a){ripples.init(a?a:this.options.withRipples)},init:function(){this.ripples(),this.input(),this.checkbox(),this.radio(),document.arrive&&document.arrive("input, textarea, select",function(){a.material.init()}),function(){var b=setInterval(function(){a("input[type!=checkbox]").each(function(){a(this).val()&&a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100);setTimeout(function(){clearInterval(b)},1e4);var c;a(document).on("focus","input",function(){var b=a(this).parents("form").find("input");c=setInterval(function(){b.each(function(){a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100)}).on("blur","input",function(){clearInterval(c)})}()}}}(jQuery);
 | 
			
		||||
!function(a){function b(a){return"undefined"==typeof a.which?!0:"number"==typeof a.which&&a.which>0?!a.ctrlKey&&!a.metaKey&&!a.altKey&&8!=a.which:!1}a.expr[":"].notmdproc=function(b){return a(b).data("mdproc")?!1:!0},a.material={options:{withRipples:[".btn:not(.btn-link)",".card-image",".navbar a:not(.withoutripple)",".dropdown-menu a",".nav-tabs a:not(.withoutripple)",".withripple"].join(","),inputElements:"input.form-control, textarea.form-control, select.form-control",checkboxElements:".checkbox > label > input[type=checkbox]",radioElements:".radio > label > input[type=radio]"},checkbox:function(b){a(b?b:this.options.checkboxElements).filter(":notmdproc").data("mdproc",!0).after("<span class=ripple></span><span class=check></span>")},radio:function(b){a(b?b:this.options.radioElements).filter(":notmdproc").data("mdproc",!0).after("<span class=circle></span><span class=check></span>")},input:function(c){a(c?c:this.options.inputElements).filter(":notmdproc").data("mdproc",!0).each(function(){var b=a(this);if(b.wrap("<div class=form-control-wrapper></div>"),b.after("<span class=material-input></span>"),b.hasClass("floating-label")){var c=b.attr("placeholder");b.attr("placeholder",null).removeClass("floating-label"),b.after("<div class=floating-label>"+c+"</div>")}if(b.attr("data-hint")&&b.after("<div class=hint>"+b.attr("data-hint")+"</div>"),(null===b.val()||"undefined"==b.val()||""===b.val())&&b.addClass("empty"),b.parent().next().is("[type=file]")){b.parent().addClass("fileinput");var d=b.parent().next().detach();b.after(d)}}),a(document).on("change",".checkbox input[type=checkbox]",function(){a(this).blur()}).on("keydown paste",".form-control",function(c){b(c)&&a(this).removeClass("empty")}).on("keyup change",".form-control",function(){var b=a(this);""===b.val()?b.addClass("empty"):b.removeClass("empty")}).on("focus",".form-control-wrapper.fileinput",function(){a(this).find("input").addClass("focus")}).on("blur",".form-control-wrapper.fileinput",function(){a(this).find("input").removeClass("focus")}).on("change",".form-control-wrapper.fileinput [type=file]",function(){var b="";a.each(a(this)[0].files,function(a,c){console.log(c),b+=c.name+", "}),b=b.substring(0,b.length-2),b?a(this).prev().removeClass("empty"):a(this).prev().addClass("empty"),a(this).prev().val(b)})},ripples:function(b){a.ripples({target:b?b:this.options.withRipples})},init:function(){this.ripples(),this.input(),this.checkbox(),this.radio(),document.arrive&&document.arrive("input, textarea, select",function(){a.material.init()}),function(){var b=setInterval(function(){a("input[type!=checkbox]").each(function(){a(this).val()&&a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100);setTimeout(function(){clearInterval(b)},1e4);var c;a(document).on("focus","input",function(){var b=a(this).parents("form").find("input");c=setInterval(function(){b.each(function(){a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100)}).on("blur","input",function(){clearInterval(c)})}()}}}(jQuery);
 | 
			
		||||
//# sourceMappingURL=material.min.js.map
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								dist/js/material.min.js.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/js/material.min.js.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
{"version":3,"file":"material.min.js","sources":["material.js"],"names":["$","_isChar","evt","which","ctrlKey","metaKey","altKey","expr","notmdproc","obj","data","material","options","withRipples","join","inputElements","checkboxElements","radioElements","checkbox","selector","this","filter","after","radio","input","each","$this","wrap","hasClass","placeholder","attr","removeClass","val","addClass","parent","next","is","$input","detach","document","on","blur","e","find","value","files","i","file","console","log","name","substring","length","prev","ripples","target","init","arrive","loading","setInterval","trigger","setTimeout","clearInterval","focused","$inputs","parents","jQuery"],"mappings":"CAEA,SAAUA,GAUR,QAASC,GAAQC,GACf,MAAwB,mBAAbA,GAAIC,OACN,EACsB,gBAAbD,GAAIC,OAAqBD,EAAIC,MAAQ,GAC7CD,EAAIE,UAAYF,EAAIG,UAAYH,EAAII,QAAuB,GAAbJ,EAAIC,OAErD,EAdTH,EAAEO,KAAK,KAAKC,UAAY,SAASC,GAC/B,MAAIT,GAAES,GAAKC,KAAK,WACP,GAEA,GAaXV,EAAEW,UACAC,SACEC,aACE,sBACA,cACA,gCACA,mBACA,kCACA,eACAC,KAAK,KACPC,cAAiB,iEACjBC,iBAAoB,2CACpBC,cAAiB,sCAEnBC,SAAY,SAASC,GAEnBnB,EAAE,EAAamB,EAAWC,KAAKR,QAAQI,kBACtCK,OAAO,cACPX,KAAK,UAAU,GACfY,MAAM,wDAETC,MAAS,SAASJ,GAEhBnB,EAAE,EAAamB,EAAWC,KAAKR,QAAQK,eACtCI,OAAO,cACPX,KAAK,UAAU,GACfY,MAAM,wDAETE,MAAS,SAASL,GAChBnB,EAAE,EAAamB,EAAWC,KAAKR,QAAQG,eACtCM,OAAO,cACPX,KAAK,UAAU,GACfe,KAAM,WACL,GAAIC,GAAQ1B,EAAEoB,KAKd,IAJAM,EAAMC,KAAK,0CACXD,EAAMJ,MAAM,sCAGRI,EAAME,SAAS,kBAAmB,CACpC,GAAIC,GAAcH,EAAMI,KAAK,cAC7BJ,GAAMI,KAAK,cAAe,MAAMC,YAAY,kBAC5CL,EAAMJ,MAAM,6BAA+BO,EAAc,UAc3D,GAVIH,EAAMI,KAAK,cACbJ,EAAMJ,MAAM,mBAAqBI,EAAMI,KAAK,aAAe,WAIzC,OAAhBJ,EAAMM,OAAiC,aAAfN,EAAMM,OAAwC,KAAhBN,EAAMM,QAC9DN,EAAMO,SAAS,SAIbP,EAAMQ,SAASC,OAAOC,GAAG,eAAgB,CAC3CV,EAAMQ,SAASD,SAAS,YACxB,IAAII,GAASX,EAAMQ,SAASC,OAAOG,QACnCZ,GAAMJ,MAAMe,MAIhBrC,EAAEuC,UACDC,GAAG,SAAU,iCAAkC,WAAaxC,EAAEoB,MAAMqB,SACpED,GAAG,gBAAiB,gBAAiB,SAASE,GAC1CzC,EAAQyC,IACT1C,EAAEoB,MAAMW,YAAY,WAGvBS,GAAG,eAAgB,gBAAiB,WACnC,GAAId,GAAQ1B,EAAEoB,KACK,MAAhBM,EAAMM,MACPN,EAAMO,SAAS,SAEfP,EAAMK,YAAY,WAGrBS,GAAG,QAAS,kCAAmC,WAC9CxC,EAAEoB,MAAMuB,KAAK,SAASV,SAAS,WAEhCO,GAAG,OAAQ,kCAAmC,WAC7CxC,EAAEoB,MAAMuB,KAAK,SAASZ,YAAY,WAEnCS,GAAG,SAAU,8CAA+C,WAC3D,GAAII,GAAQ,EACZ5C,GAAEyB,KAAKzB,EAAEoB,MAAM,GAAGyB,MAAO,SAASC,EAAGC,GACnCC,QAAQC,IAAIF,GACZH,GAASG,EAAKG,KAAO,OAEvBN,EAAQA,EAAMO,UAAU,EAAGP,EAAMQ,OAAS,GACtCR,EACF5C,EAAEoB,MAAMiC,OAAOtB,YAAY,SAE3B/B,EAAEoB,MAAMiC,OAAOpB,SAAS,SAE1BjC,EAAEoB,MAAMiC,OAAOrB,IAAIY,MAGvBU,QAAW,SAASnC,GAClBnB,EAAEsD,SAASC,OAAU,EAAapC,EAAWC,KAAKR,QAAQC,eAE5D2C,KAAQ,WACNpC,KAAKkC,UACLlC,KAAKI,QACLJ,KAAKF,WACLE,KAAKG,QAEDgB,SAASkB,QACXlB,SAASkB,OAAO,0BAA2B,WACzCzD,EAAEW,SAAS6C,SAKf,WAEE,GAAIE,GAAUC,YAAY,WACxB3D,EAAE,yBAAyByB,KAAK,WAC1BzB,EAAEoB,MAAMY,OAAShC,EAAEoB,MAAMY,QAAUhC,EAAEoB,MAAMU,KAAK,UAClD9B,EAAEoB,MAAMwC,QAAQ,aAGnB,IAEHC,YAAW,WACTC,cAAcJ,IACb,IAEH,IAAIK,EACJ/D,GAAEuC,UACDC,GAAG,QAAS,QAAS,WACpB,GAAIwB,GAAUhE,EAAEoB,MAAM6C,QAAQ,QAAQtB,KAAK,QAC3CoB,GAAUJ,YAAY,WACpBK,EAAQvC,KAAK,WACPzB,EAAEoB,MAAMY,QAAUhC,EAAEoB,MAAMU,KAAK,UACjC9B,EAAEoB,MAAMwC,QAAQ,aAGnB,OAEJpB,GAAG,OAAQ,QAAS,WACnBsB,cAAcC,WAOrBG"}
 | 
			
		||||
							
								
								
									
										274
									
								
								dist/js/ripples.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										274
									
								
								dist/js/ripples.js
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,189 +1,105 @@
 | 
			
		|||
/* Copyright 2014+, Federico Zivolo, LICENSE at https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md */
 | 
			
		||||
/* globals CustomEvent */
 | 
			
		||||
window.ripples = {
 | 
			
		||||
    done: false,
 | 
			
		||||
    init : function(withRipple) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
/* globals jQuery */
 | 
			
		||||
 | 
			
		||||
        if (this.done) {
 | 
			
		||||
            return console.log("Ripples.js was already initialzied.");
 | 
			
		||||
        }
 | 
			
		||||
(function($) {
 | 
			
		||||
  $.ripples = function(options) {
 | 
			
		||||
 | 
			
		||||
        this.done = true;
 | 
			
		||||
    // Default options
 | 
			
		||||
    var defaultOptions = {
 | 
			
		||||
      "target": ".btn:not(.btn-link), .card-image, .navbar a:not(.withoutripple), .nav-tabs a:not(.withoutripple), .withripple"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Cross browser matches function
 | 
			
		||||
        function matchesSelector(domElement, selector) {
 | 
			
		||||
            var matches = domElement.matches ||
 | 
			
		||||
                domElement.matchesSelector ||
 | 
			
		||||
                domElement.webkitMatchesSelector ||
 | 
			
		||||
                domElement.mozMatchesSelector ||
 | 
			
		||||
                domElement.msMatchesSelector ||
 | 
			
		||||
                domElement.oMatchesSelector;
 | 
			
		||||
            return matches.call(domElement, selector);
 | 
			
		||||
        }
 | 
			
		||||
    // Fade out the ripple and then destroy it
 | 
			
		||||
    function rippleOut(ripple) {
 | 
			
		||||
 | 
			
		||||
        // animations time
 | 
			
		||||
        var rippleOutTime = 100,
 | 
			
		||||
            rippleStartTime = 500;
 | 
			
		||||
      // Unbind events from ripple
 | 
			
		||||
      ripple.off();
 | 
			
		||||
 | 
			
		||||
        // Helper to bind events on dynamically created elements
 | 
			
		||||
        var bind = function(events, selector, callback) {
 | 
			
		||||
            if (typeof events === "string") {
 | 
			
		||||
                events = [events];
 | 
			
		||||
            }
 | 
			
		||||
            events.forEach(function(event) {
 | 
			
		||||
                document.addEventListener(event, function(e) {
 | 
			
		||||
                    var target = (typeof e.detail !== "number") ? e.detail : e.target;
 | 
			
		||||
      // Start the out animation
 | 
			
		||||
      ripple.addClass("ripple-out");
 | 
			
		||||
 | 
			
		||||
                    if (matchesSelector(target, selector)) {
 | 
			
		||||
                        callback(e, target);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var rippleStart = function(e, target, callback) {
 | 
			
		||||
 | 
			
		||||
            // Init variables
 | 
			
		||||
            var $rippleWrapper      = target,
 | 
			
		||||
                $el                 = $rippleWrapper.parentNode,
 | 
			
		||||
                $ripple             = document.createElement("div"),
 | 
			
		||||
                elPos               = $el.getBoundingClientRect(),
 | 
			
		||||
                // Mouse pos in most cases
 | 
			
		||||
                mousePos            = {x: e.clientX - elPos.left, y: ((window.ontouchstart) ? e.clientY - window.scrollY: e.clientY) - elPos.top},
 | 
			
		||||
                scale               = "scale(" + Math.round($rippleWrapper.offsetWidth / 5) + ")",
 | 
			
		||||
                rippleEnd           = new CustomEvent("rippleEnd", {detail: $ripple}),
 | 
			
		||||
                _rippleOpacity      = 0.3,
 | 
			
		||||
                refreshElementStyle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // If multitouch is detected or some other black magic suff is happening...
 | 
			
		||||
            if (e.touches) {
 | 
			
		||||
                mousePos  = {x: e.touches[0].clientX - elPos.left, y:  e.touches[0].clientY - elPos.top};
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $ripplecache = $ripple;
 | 
			
		||||
 | 
			
		||||
            // Set ripple class
 | 
			
		||||
            $ripple.className = "ripple";
 | 
			
		||||
 | 
			
		||||
            // Move ripple to the mouse position
 | 
			
		||||
            $ripple.setAttribute("style", "left:" + mousePos.x + "px; top:" + mousePos.y + "px;");
 | 
			
		||||
 | 
			
		||||
            // Get the clicked target's text color, this will be applied to the ripple as background-color.
 | 
			
		||||
            var targetColor = window.getComputedStyle($el).color;
 | 
			
		||||
 | 
			
		||||
            // Convert the rgb color to an rgba color with opacity set to __rippleOpacity__
 | 
			
		||||
            if ( targetColor.indexOf("rgba") >= 0 ) {
 | 
			
		||||
                var alphaPosition = targetColor.lastIndexOf(",") + 1;
 | 
			
		||||
                targetColor = targetColor.substring(0, alphaPosition) + _rippleOpacity + ")";
 | 
			
		||||
            } else {
 | 
			
		||||
                targetColor = targetColor.replace("rgb", "rgba").replace(")", ", " + _rippleOpacity + ")");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Insert new ripple into ripple wrapper
 | 
			
		||||
            $rippleWrapper.appendChild($ripple);
 | 
			
		||||
 | 
			
		||||
            // Make sure the ripple has the class applied (ugly hack but it works)
 | 
			
		||||
            refreshElementStyle = window.getComputedStyle($ripple).opacity;
 | 
			
		||||
 | 
			
		||||
            // Let other funtions know that this element is animating
 | 
			
		||||
            $ripple.dataset.animating = 1;
 | 
			
		||||
 | 
			
		||||
            // Set scale value, background-color and opacity to ripple and animate it
 | 
			
		||||
            $ripple.className = "ripple ripple-on";
 | 
			
		||||
 | 
			
		||||
            // Prepare the style of the ripple
 | 
			
		||||
            var rippleStyle = [
 | 
			
		||||
                $ripple.getAttribute("style"),
 | 
			
		||||
                "background-color: " + targetColor,
 | 
			
		||||
                "-ms-transform: " + scale,
 | 
			
		||||
                "-moz-transform:" + scale,
 | 
			
		||||
                "-webkit-transform:" + scale,
 | 
			
		||||
                "transform: " + scale
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            // Apply the style
 | 
			
		||||
            $ripple.setAttribute("style", rippleStyle.join(";"));
 | 
			
		||||
 | 
			
		||||
            // This function is called when the animation is finished
 | 
			
		||||
            setTimeout(function() {
 | 
			
		||||
 | 
			
		||||
                // Let know to other functions that this element has finished the animation
 | 
			
		||||
                $ripple.dataset.animating = 0;
 | 
			
		||||
                document.dispatchEvent(rippleEnd);
 | 
			
		||||
                if (callback) {
 | 
			
		||||
                    callback();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }, rippleStartTime);
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var rippleOut = function($ripple) {
 | 
			
		||||
            // Clear previous animation
 | 
			
		||||
            $ripple.className = "ripple ripple-on ripple-out";
 | 
			
		||||
 | 
			
		||||
            // Let ripple fade out (with CSS)
 | 
			
		||||
            setTimeout(function() {
 | 
			
		||||
                $ripple.remove();
 | 
			
		||||
            }, rippleOutTime);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Helper, need to know if mouse is up or down
 | 
			
		||||
        var mouseDown = false;
 | 
			
		||||
        bind(["mousedown", "touchstart"], "*", function() {
 | 
			
		||||
            mouseDown = true;
 | 
			
		||||
        });
 | 
			
		||||
        bind(["mouseup", "touchend", "mouseout"], "*", function() {
 | 
			
		||||
            mouseDown = false;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Append ripple wrapper if not exists already
 | 
			
		||||
        var rippleInit = function(e, target) {
 | 
			
		||||
            if (target.getElementsByClassName("ripple-wrapper").length === 0) {
 | 
			
		||||
                target.className += " withripple";
 | 
			
		||||
                var $rippleWrapper = document.createElement("div");
 | 
			
		||||
                $rippleWrapper.className = "ripple-wrapper";
 | 
			
		||||
                target.appendChild($rippleWrapper);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var $ripplecache;
 | 
			
		||||
 | 
			
		||||
        // Events handler
 | 
			
		||||
        // init RippleJS and start ripple effect on mousedown
 | 
			
		||||
        bind(["mouseover"], withRipple, rippleInit);
 | 
			
		||||
 | 
			
		||||
        // Init if the device is touch screen
 | 
			
		||||
        bind(["touchstart"], withRipple, rippleInit);
 | 
			
		||||
 | 
			
		||||
        // start ripple effect on mousedown
 | 
			
		||||
        bind(["mousedown", "touchstart"], ".ripple-wrapper", function(e, $ripple) {
 | 
			
		||||
            // Start ripple only on left or middle mouse click and touch click
 | 
			
		||||
            if (e.which === 0 || e.which === 1 || e.which === 2) {
 | 
			
		||||
                rippleStart(e, $ripple);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // if animation ends and user is not holding mouse then destroy the ripple
 | 
			
		||||
        bind("rippleEnd", ".ripple-wrapper .ripple", function(e, $ripple) {
 | 
			
		||||
 | 
			
		||||
            var $ripples = $ripple.parentNode.getElementsByClassName("ripple");
 | 
			
		||||
 | 
			
		||||
            if (!mouseDown || ( $ripples[0] == $ripple && $ripples.length > 1)) {
 | 
			
		||||
                rippleOut($ripple);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Destroy ripple when mouse is not holded anymore if the ripple still exists
 | 
			
		||||
        bind(["mouseup", "touchend", "mouseout"], ".ripple-wrapper", function() {
 | 
			
		||||
            var $ripple = $ripplecache;
 | 
			
		||||
            if ($ripple && $ripple.dataset.animating != 1) {
 | 
			
		||||
                rippleOut($ripple);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
      // This function is called when the transition "out" ends
 | 
			
		||||
      ripple.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){
 | 
			
		||||
        ripple.remove();
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    // Apply custom options
 | 
			
		||||
    options = $.extend(defaultOptions, options);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    $(document)
 | 
			
		||||
    .on("mousedown", options.target, function(e) {
 | 
			
		||||
      // If the ripple wrapper does not exists, create it
 | 
			
		||||
      if (!$(this).find(".ripple-wrapper").length) {
 | 
			
		||||
        $(this).append("<div class=ripple-wrapper></div>");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var wrapper = $(this).find(".ripple-wrapper");
 | 
			
		||||
 | 
			
		||||
      // Get the mouse position relative to the ripple wrapper
 | 
			
		||||
      var wrapperOffset = wrapper.offset();
 | 
			
		||||
      var relX = e.pageX - wrapperOffset.left;
 | 
			
		||||
      var relY = e.pageY - wrapperOffset.top;
 | 
			
		||||
 | 
			
		||||
      // Meet the new ripple
 | 
			
		||||
      var ripple = $("<div></div>");
 | 
			
		||||
 | 
			
		||||
      // Add to it the ripple class
 | 
			
		||||
      ripple.addClass("ripple");
 | 
			
		||||
 | 
			
		||||
      // Position it in the right place
 | 
			
		||||
      ripple.css({"left": relX, "top": relY});
 | 
			
		||||
 | 
			
		||||
      // Set the background color of the ripple
 | 
			
		||||
      ripple.css({"background-color": window.getComputedStyle($(this)[0]).color});
 | 
			
		||||
 | 
			
		||||
      // Spawn it
 | 
			
		||||
      wrapper.append(ripple);
 | 
			
		||||
 | 
			
		||||
      // Make sure the ripple has the styles applied (ugly hack but it works)
 | 
			
		||||
      (function() { return window.getComputedStyle(ripple[0]).opacity; })();
 | 
			
		||||
 | 
			
		||||
      // Set the new size
 | 
			
		||||
      var size = (Math.max($(this).outerWidth(), $(this).outerHeight()) / ripple.outerWidth()) * 2.5;
 | 
			
		||||
 | 
			
		||||
      ripple.css({
 | 
			
		||||
        "-ms-transform": "scale(" + size + ")",
 | 
			
		||||
        "-moz-transform": "scale(" + size + ")",
 | 
			
		||||
        "-webkit-transform": "scale(" + size + ")",
 | 
			
		||||
        "transform": "scale(" + size + ")"
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // Start the transition
 | 
			
		||||
      ripple.addClass("ripple-on");
 | 
			
		||||
      ripple.data("animating", "on");
 | 
			
		||||
      ripple.data("mousedown", "on");
 | 
			
		||||
 | 
			
		||||
      // This function is called when the transition "on" ends
 | 
			
		||||
      setTimeout(function() {
 | 
			
		||||
        ripple.data("animating", "off");
 | 
			
		||||
        if (ripple.data("mousedown") == "off") {
 | 
			
		||||
          rippleOut(ripple);
 | 
			
		||||
        }
 | 
			
		||||
      }, 500);
 | 
			
		||||
 | 
			
		||||
      // On mouseup or on mouseleave, set the mousedown flag to "off" and try to destroy the ripple
 | 
			
		||||
      wrapper.on("mouseup mouseleave", function() {
 | 
			
		||||
        ripple.data("mousedown", "off");
 | 
			
		||||
        // If the transition "on" is finished then we can destroy the ripple with transition "out"
 | 
			
		||||
        if (ripple.data("animating") == "off") {
 | 
			
		||||
          rippleOut(ripple);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  $.fn.ripples = function() {
 | 
			
		||||
    $.ripples({"target": $(this)});
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								dist/js/ripples.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								dist/js/ripples.min.js
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1 +1,2 @@
 | 
			
		|||
window.ripples={done:!1,init:function(a){"use strict";function b(a,b){var c=a.matches||a.matchesSelector||a.webkitMatchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector;return c.call(a,b)}if(this.done)return console.log("Ripples.js was already initialzied.");this.done=!0;var c=100,d=500,e=function(a,c,d){"string"==typeof a&&(a=[a]),a.forEach(function(a){document.addEventListener(a,function(a){var e="number"!=typeof a.detail?a.detail:a.target;b(e,c)&&d(a,e)})})},f=function(a,b,c){var e,f=b,g=f.parentNode,h=document.createElement("div"),j=g.getBoundingClientRect(),k={x:a.clientX-j.left,y:(window.ontouchstart?a.clientY-window.scrollY:a.clientY)-j.top},l="scale("+Math.round(f.offsetWidth/5)+")",m=new CustomEvent("rippleEnd",{detail:h}),n=.3;a.touches&&(k={x:a.touches[0].clientX-j.left,y:a.touches[0].clientY-j.top}),i=h,h.className="ripple",h.setAttribute("style","left:"+k.x+"px; top:"+k.y+"px;");var o=window.getComputedStyle(g).color;if(o.indexOf("rgba")>=0){var p=o.lastIndexOf(",")+1;o=o.substring(0,p)+n+")"}else o=o.replace("rgb","rgba").replace(")",", "+n+")");f.appendChild(h),e=window.getComputedStyle(h).opacity,h.dataset.animating=1,h.className="ripple ripple-on";var q=[h.getAttribute("style"),"background-color: "+o,"-ms-transform: "+l,"-moz-transform:"+l,"-webkit-transform:"+l,"transform: "+l];h.setAttribute("style",q.join(";")),setTimeout(function(){h.dataset.animating=0,document.dispatchEvent(m),c&&c()},d)},g=function(a){a.className="ripple ripple-on ripple-out",setTimeout(function(){a.remove()},c)},h=!1;e(["mousedown","touchstart"],"*",function(){h=!0}),e(["mouseup","touchend","mouseout"],"*",function(){h=!1});var i,j=function(a,b){if(0===b.getElementsByClassName("ripple-wrapper").length){b.className+=" withripple";var c=document.createElement("div");c.className="ripple-wrapper",b.appendChild(c)}};e(["mouseover"],a,j),e(["touchstart"],a,j),e(["mousedown","touchstart"],".ripple-wrapper",function(a,b){(0===a.which||1===a.which||2===a.which)&&f(a,b)}),e("rippleEnd",".ripple-wrapper .ripple",function(a,b){var c=b.parentNode.getElementsByClassName("ripple");(!h||c[0]==b&&c.length>1)&&g(b)}),e(["mouseup","touchend","mouseout"],".ripple-wrapper",function(){var a=i;a&&1!=a.dataset.animating&&g(a)})}};
 | 
			
		||||
!function(a){a.ripples=function(b){function c(a){a.off(),a.addClass("ripple-out"),a.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd",function(){a.remove()})}var d={target:".btn:not(.btn-link), .card-image, .navbar a:not(.withoutripple), .nav-tabs a:not(.withoutripple), .withripple"};b=a.extend(d,b),a(document).on("mousedown",b.target,function(b){a(this).find(".ripple-wrapper").length||a(this).append("<div class=ripple-wrapper></div>");var d=a(this).find(".ripple-wrapper"),e=d.offset(),f=b.pageX-e.left,g=b.pageY-e.top,h=a("<div></div>");h.addClass("ripple"),h.css({left:f,top:g}),h.css({"background-color":window.getComputedStyle(a(this)[0]).color}),d.append(h),function(){return window.getComputedStyle(h[0]).opacity}();var i=Math.max(a(this).outerWidth(),a(this).outerHeight())/h.outerWidth()*2.5;h.css({"-ms-transform":"scale("+i+")","-moz-transform":"scale("+i+")","-webkit-transform":"scale("+i+")",transform:"scale("+i+")"}),h.addClass("ripple-on"),h.data("animating","on"),h.data("mousedown","on"),setTimeout(function(){h.data("animating","off"),"off"==h.data("mousedown")&&c(h)},500),d.on("mouseup mouseleave",function(){h.data("mousedown","off"),"off"==h.data("animating")&&c(h)})})},a.fn.ripples=function(){a.ripples({target:a(this)})}}(jQuery);
 | 
			
		||||
//# sourceMappingURL=ripples.min.js.map
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								dist/js/ripples.min.js.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/js/ripples.min.js.map
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
{"version":3,"file":"ripples.min.js","sources":["ripples.js"],"names":["$","ripples","options","rippleOut","ripple","off","addClass","on","remove","defaultOptions","target","extend","document","e","this","find","length","append","wrapper","wrapperOffset","offset","relX","pageX","left","relY","pageY","top","css","background-color","window","getComputedStyle","color","opacity","size","Math","max","outerWidth","outerHeight","-ms-transform","-moz-transform","-webkit-transform","transform","data","setTimeout","fn","jQuery"],"mappings":"CAGA,SAAUA,GACRA,EAAEC,QAAU,SAASC,GASnB,QAASC,GAAUC,GAGjBA,EAAOC,MAGPD,EAAOE,SAAS,cAGhBF,EAAOG,GAAG,mEAAoE,WAC5EH,EAAOI,WAhBX,GAAIC,IACFC,OAAU,gHAqBZR,GAAUF,EAAEW,OAAOF,EAAgBP,GAGnCF,EAAEY,UACDL,GAAG,YAAaL,EAAQQ,OAAQ,SAASG,GAEnCb,EAAEc,MAAMC,KAAK,mBAAmBC,QACnChB,EAAEc,MAAMG,OAAO,mCAGjB,IAAIC,GAAUlB,EAAEc,MAAMC,KAAK,mBAGvBI,EAAgBD,EAAQE,SACxBC,EAAOR,EAAES,MAAQH,EAAcI,KAC/BC,EAAOX,EAAEY,MAAQN,EAAcO,IAG/BtB,EAASJ,EAAE,cAGfI,GAAOE,SAAS,UAGhBF,EAAOuB,KAAKJ,KAAQF,EAAMK,IAAOF,IAGjCpB,EAAOuB,KAAKC,mBAAoBC,OAAOC,iBAAiB9B,EAAEc,MAAM,IAAIiB,QAGpEb,EAAQD,OAAOb,GAGf,WAAc,MAAOyB,QAAOC,iBAAiB1B,EAAO,IAAI4B,UAGxD,IAAIC,GAAQC,KAAKC,IAAInC,EAAEc,MAAMsB,aAAcpC,EAAEc,MAAMuB,eAAiBjC,EAAOgC,aAAgB,GAE3FhC,GAAOuB,KACLW,gBAAiB,SAAWL,EAAO,IACnCM,iBAAkB,SAAWN,EAAO,IACpCO,oBAAqB,SAAWP,EAAO,IACvCQ,UAAa,SAAWR,EAAO,MAIjC7B,EAAOE,SAAS,aAChBF,EAAOsC,KAAK,YAAa,MACzBtC,EAAOsC,KAAK,YAAa,MAGzBC,WAAW,WACTvC,EAAOsC,KAAK,YAAa,OACO,OAA5BtC,EAAOsC,KAAK,cACdvC,EAAUC,IAEX,KAGHc,EAAQX,GAAG,qBAAsB,WAC/BH,EAAOsC,KAAK,YAAa,OAEO,OAA5BtC,EAAOsC,KAAK,cACdvC,EAAUC,QAQlBJ,EAAE4C,GAAG3C,QAAU,WACbD,EAAEC,SAASS,OAAUV,EAAEc,UAGxB+B"}
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +26,7 @@
 | 
			
		|||
}
 | 
			
		||||
.ripple.ripple-on {
 | 
			
		||||
    transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    opacity: 0.2;
 | 
			
		||||
}
 | 
			
		||||
.ripple.ripple-out {
 | 
			
		||||
    transition: opacity 0.1s linear 0s !important;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,170 +1,170 @@
 | 
			
		|||
/* globals jQuery, ripples */
 | 
			
		||||
/* globals jQuery */
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
    // Selector to select only not already processed elements
 | 
			
		||||
    $.expr[":"].notmdproc = function(obj){
 | 
			
		||||
        if ($(obj).data("mdproc")) {
 | 
			
		||||
            return false;
 | 
			
		||||
        } else {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    function _isChar(evt) {
 | 
			
		||||
        if (typeof evt.which == "undefined") {
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (typeof evt.which == "number" && evt.which > 0) {
 | 
			
		||||
            return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
  // Selector to select only not already processed elements
 | 
			
		||||
  $.expr[":"].notmdproc = function(obj){
 | 
			
		||||
    if ($(obj).data("mdproc")) {
 | 
			
		||||
      return false;
 | 
			
		||||
    } else {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    $.material =  {
 | 
			
		||||
        "options": {
 | 
			
		||||
            "withRipples": [
 | 
			
		||||
                ".btn:not(.btn-link)",
 | 
			
		||||
                ".card-image",
 | 
			
		||||
                ".navbar a:not(.withoutripple)",
 | 
			
		||||
                ".dropdown-menu a",
 | 
			
		||||
                ".nav-tabs a:not(.withoutripple)",
 | 
			
		||||
                ".withripple"
 | 
			
		||||
            ].join(","),
 | 
			
		||||
            "inputElements": "input.form-control, textarea.form-control, select.form-control",
 | 
			
		||||
            "checkboxElements": ".checkbox > label > input[type=checkbox]",
 | 
			
		||||
            "radioElements": ".radio > label > input[type=radio]"
 | 
			
		||||
        },
 | 
			
		||||
        "checkbox": function(selector) {
 | 
			
		||||
            // Add fake-checkbox to material checkboxes
 | 
			
		||||
            $((selector) ? selector : this.options.checkboxElements)
 | 
			
		||||
            .filter(":notmdproc")
 | 
			
		||||
            .data("mdproc", true)
 | 
			
		||||
            .after("<span class=ripple></span><span class=check></span>");
 | 
			
		||||
        },
 | 
			
		||||
        "radio": function(selector) {
 | 
			
		||||
            // Add fake-radio to material radios
 | 
			
		||||
            $((selector) ? selector : this.options.radioElements)
 | 
			
		||||
            .filter(":notmdproc")
 | 
			
		||||
            .data("mdproc", true)
 | 
			
		||||
            .after("<span class=circle></span><span class=check></span>");
 | 
			
		||||
        },
 | 
			
		||||
        "input": function(selector) {
 | 
			
		||||
            $((selector) ? selector : this.options.inputElements)
 | 
			
		||||
            .filter(":notmdproc")
 | 
			
		||||
            .data("mdproc", true)
 | 
			
		||||
            .each( function() {
 | 
			
		||||
                var $this = $(this);
 | 
			
		||||
                $this.wrap("<div class=form-control-wrapper></div>");
 | 
			
		||||
                $this.after("<span class=material-input></span>");
 | 
			
		||||
  function _isChar(evt) {
 | 
			
		||||
    if (typeof evt.which == "undefined") {
 | 
			
		||||
      return true;
 | 
			
		||||
    } else if (typeof evt.which == "number" && evt.which > 0) {
 | 
			
		||||
      return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
                // Add floating label if required
 | 
			
		||||
                if ($this.hasClass("floating-label")) {
 | 
			
		||||
                    var placeholder = $this.attr("placeholder");
 | 
			
		||||
                    $this.attr("placeholder", null).removeClass("floating-label");
 | 
			
		||||
                    $this.after("<div class=floating-label>" + placeholder + "</div>");
 | 
			
		||||
                }
 | 
			
		||||
  $.material =  {
 | 
			
		||||
    "options": {
 | 
			
		||||
      "withRipples": [
 | 
			
		||||
        ".btn:not(.btn-link)",
 | 
			
		||||
        ".card-image",
 | 
			
		||||
        ".navbar a:not(.withoutripple)",
 | 
			
		||||
        ".dropdown-menu a",
 | 
			
		||||
        ".nav-tabs a:not(.withoutripple)",
 | 
			
		||||
        ".withripple"
 | 
			
		||||
      ].join(","),
 | 
			
		||||
      "inputElements": "input.form-control, textarea.form-control, select.form-control",
 | 
			
		||||
      "checkboxElements": ".checkbox > label > input[type=checkbox]",
 | 
			
		||||
      "radioElements": ".radio > label > input[type=radio]"
 | 
			
		||||
    },
 | 
			
		||||
    "checkbox": function(selector) {
 | 
			
		||||
      // Add fake-checkbox to material checkboxes
 | 
			
		||||
      $((selector) ? selector : this.options.checkboxElements)
 | 
			
		||||
      .filter(":notmdproc")
 | 
			
		||||
      .data("mdproc", true)
 | 
			
		||||
      .after("<span class=ripple></span><span class=check></span>");
 | 
			
		||||
    },
 | 
			
		||||
    "radio": function(selector) {
 | 
			
		||||
      // Add fake-radio to material radios
 | 
			
		||||
      $((selector) ? selector : this.options.radioElements)
 | 
			
		||||
      .filter(":notmdproc")
 | 
			
		||||
      .data("mdproc", true)
 | 
			
		||||
      .after("<span class=circle></span><span class=check></span>");
 | 
			
		||||
    },
 | 
			
		||||
    "input": function(selector) {
 | 
			
		||||
      $((selector) ? selector : this.options.inputElements)
 | 
			
		||||
      .filter(":notmdproc")
 | 
			
		||||
      .data("mdproc", true)
 | 
			
		||||
      .each( function() {
 | 
			
		||||
        var $this = $(this);
 | 
			
		||||
        $this.wrap("<div class=form-control-wrapper></div>");
 | 
			
		||||
        $this.after("<span class=material-input></span>");
 | 
			
		||||
 | 
			
		||||
                // Add hint label if required
 | 
			
		||||
                if ($this.attr("data-hint")) {
 | 
			
		||||
                    $this.after("<div class=hint>" + $this.attr("data-hint") + "</div>");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Set as empty if is empty (damn I must improve this...)
 | 
			
		||||
                if ($this.val() === null || $this.val() == "undefined" || $this.val() === "") {
 | 
			
		||||
                    $this.addClass("empty");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Support for file input
 | 
			
		||||
                if ($this.parent().next().is("[type=file]")) {
 | 
			
		||||
                    $this.parent().addClass("fileinput");
 | 
			
		||||
                    var $input = $this.parent().next().detach();
 | 
			
		||||
                    $this.after($input);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            $(document)
 | 
			
		||||
            .on("change", ".checkbox input[type=checkbox]", function() { $(this).blur(); })
 | 
			
		||||
            .on("keydown paste", ".form-control", function(e) {
 | 
			
		||||
                if(_isChar(e)) {
 | 
			
		||||
                    $(this).removeClass("empty");
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .on("keyup change", ".form-control", function() {
 | 
			
		||||
                var $this = $(this);
 | 
			
		||||
                if($this.val() === "") {
 | 
			
		||||
                    $this.addClass("empty");
 | 
			
		||||
                } else {
 | 
			
		||||
                    $this.removeClass("empty");
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .on("focus", ".form-control-wrapper.fileinput", function() {
 | 
			
		||||
                $(this).find("input").addClass("focus");
 | 
			
		||||
            })
 | 
			
		||||
            .on("blur", ".form-control-wrapper.fileinput", function() {
 | 
			
		||||
                $(this).find("input").removeClass("focus");
 | 
			
		||||
            })
 | 
			
		||||
            .on("change", ".form-control-wrapper.fileinput [type=file]", function() {
 | 
			
		||||
                var value = "";
 | 
			
		||||
                $.each($(this)[0].files, function(i, file) {
 | 
			
		||||
                    console.log(file);
 | 
			
		||||
                    value += file.name + ", ";
 | 
			
		||||
                });
 | 
			
		||||
                value = value.substring(0, value.length - 2);
 | 
			
		||||
                if (value) {
 | 
			
		||||
                    $(this).prev().removeClass("empty");
 | 
			
		||||
                } else {
 | 
			
		||||
                    $(this).prev().addClass("empty");
 | 
			
		||||
                }
 | 
			
		||||
                $(this).prev().val(value);
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        "ripples": function(selector) {
 | 
			
		||||
            ripples.init((selector) ? selector : this.options.withRipples);
 | 
			
		||||
        },
 | 
			
		||||
        "init": function() {
 | 
			
		||||
            this.ripples();
 | 
			
		||||
            this.input();
 | 
			
		||||
            this.checkbox();
 | 
			
		||||
            this.radio();
 | 
			
		||||
 | 
			
		||||
            if (document.arrive) {
 | 
			
		||||
                document.arrive("input, textarea, select", function() {
 | 
			
		||||
                    $.material.init();
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Detect autofill
 | 
			
		||||
            (function() {
 | 
			
		||||
                // This part of code will detect autofill when the page is loading (username and password inputs for example)
 | 
			
		||||
                var loading = setInterval(function() {
 | 
			
		||||
                    $("input[type!=checkbox]").each(function() {
 | 
			
		||||
                        if ($(this).val() && $(this).val() !== $(this).attr("value")) {
 | 
			
		||||
                            $(this).trigger("change");
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }, 100);
 | 
			
		||||
                // After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
 | 
			
		||||
                setTimeout(function() {
 | 
			
		||||
                    clearInterval(loading);
 | 
			
		||||
                }, 10000);
 | 
			
		||||
                // Now we just listen on inputs of the focused form (because user can select from the autofill dropdown only when the input has focus)
 | 
			
		||||
                var focused;
 | 
			
		||||
                $(document)
 | 
			
		||||
                .on("focus", "input", function() {
 | 
			
		||||
                    var $inputs = $(this).parents("form").find("input");
 | 
			
		||||
                    focused = setInterval(function() {
 | 
			
		||||
                        $inputs.each(function() {
 | 
			
		||||
                            if ($(this).val() !== $(this).attr("value")) {
 | 
			
		||||
                                $(this).trigger("change");
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                    }, 100);
 | 
			
		||||
                })
 | 
			
		||||
                .on("blur", "input", function() {
 | 
			
		||||
                    clearInterval(focused);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            })();
 | 
			
		||||
        // Add floating label if required
 | 
			
		||||
        if ($this.hasClass("floating-label")) {
 | 
			
		||||
          var placeholder = $this.attr("placeholder");
 | 
			
		||||
          $this.attr("placeholder", null).removeClass("floating-label");
 | 
			
		||||
          $this.after("<div class=floating-label>" + placeholder + "</div>");
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
        // Add hint label if required
 | 
			
		||||
        if ($this.attr("data-hint")) {
 | 
			
		||||
          $this.after("<div class=hint>" + $this.attr("data-hint") + "</div>");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set as empty if is empty (damn I must improve this...)
 | 
			
		||||
        if ($this.val() === null || $this.val() == "undefined" || $this.val() === "") {
 | 
			
		||||
          $this.addClass("empty");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Support for file input
 | 
			
		||||
        if ($this.parent().next().is("[type=file]")) {
 | 
			
		||||
          $this.parent().addClass("fileinput");
 | 
			
		||||
          var $input = $this.parent().next().detach();
 | 
			
		||||
          $this.after($input);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      $(document)
 | 
			
		||||
      .on("change", ".checkbox input[type=checkbox]", function() { $(this).blur(); })
 | 
			
		||||
      .on("keydown paste", ".form-control", function(e) {
 | 
			
		||||
        if(_isChar(e)) {
 | 
			
		||||
          $(this).removeClass("empty");
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .on("keyup change", ".form-control", function() {
 | 
			
		||||
        var $this = $(this);
 | 
			
		||||
        if($this.val() === "") {
 | 
			
		||||
          $this.addClass("empty");
 | 
			
		||||
        } else {
 | 
			
		||||
          $this.removeClass("empty");
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .on("focus", ".form-control-wrapper.fileinput", function() {
 | 
			
		||||
        $(this).find("input").addClass("focus");
 | 
			
		||||
      })
 | 
			
		||||
      .on("blur", ".form-control-wrapper.fileinput", function() {
 | 
			
		||||
        $(this).find("input").removeClass("focus");
 | 
			
		||||
      })
 | 
			
		||||
      .on("change", ".form-control-wrapper.fileinput [type=file]", function() {
 | 
			
		||||
        var value = "";
 | 
			
		||||
        $.each($(this)[0].files, function(i, file) {
 | 
			
		||||
          console.log(file);
 | 
			
		||||
          value += file.name + ", ";
 | 
			
		||||
        });
 | 
			
		||||
        value = value.substring(0, value.length - 2);
 | 
			
		||||
        if (value) {
 | 
			
		||||
          $(this).prev().removeClass("empty");
 | 
			
		||||
        } else {
 | 
			
		||||
          $(this).prev().addClass("empty");
 | 
			
		||||
        }
 | 
			
		||||
        $(this).prev().val(value);
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
    "ripples": function(selector) {
 | 
			
		||||
      $.ripples({"target": (selector) ? selector : this.options.withRipples});
 | 
			
		||||
    },
 | 
			
		||||
    "init": function() {
 | 
			
		||||
      this.ripples();
 | 
			
		||||
      this.input();
 | 
			
		||||
      this.checkbox();
 | 
			
		||||
      this.radio();
 | 
			
		||||
 | 
			
		||||
      if (document.arrive) {
 | 
			
		||||
        document.arrive("input, textarea, select", function() {
 | 
			
		||||
          $.material.init();
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Detect autofill
 | 
			
		||||
      (function() {
 | 
			
		||||
        // This part of code will detect autofill when the page is loading (username and password inputs for example)
 | 
			
		||||
        var loading = setInterval(function() {
 | 
			
		||||
          $("input[type!=checkbox]").each(function() {
 | 
			
		||||
            if ($(this).val() && $(this).val() !== $(this).attr("value")) {
 | 
			
		||||
              $(this).trigger("change");
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        }, 100);
 | 
			
		||||
        // After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
 | 
			
		||||
        setTimeout(function() {
 | 
			
		||||
          clearInterval(loading);
 | 
			
		||||
        }, 10000);
 | 
			
		||||
        // Now we just listen on inputs of the focused form (because user can select from the autofill dropdown only when the input has focus)
 | 
			
		||||
        var focused;
 | 
			
		||||
        $(document)
 | 
			
		||||
        .on("focus", "input", function() {
 | 
			
		||||
          var $inputs = $(this).parents("form").find("input");
 | 
			
		||||
          focused = setInterval(function() {
 | 
			
		||||
            $inputs.each(function() {
 | 
			
		||||
              if ($(this).val() !== $(this).attr("value")) {
 | 
			
		||||
                $(this).trigger("change");
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
          }, 100);
 | 
			
		||||
        })
 | 
			
		||||
        .on("blur", "input", function() {
 | 
			
		||||
          clearInterval(focused);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
      })();
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,189 +1,105 @@
 | 
			
		|||
/* Copyright 2014+, Federico Zivolo, LICENSE at https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md */
 | 
			
		||||
/* globals CustomEvent */
 | 
			
		||||
window.ripples = {
 | 
			
		||||
    done: false,
 | 
			
		||||
    init : function(withRipple) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
/* globals jQuery */
 | 
			
		||||
 | 
			
		||||
        if (this.done) {
 | 
			
		||||
            return console.log("Ripples.js was already initialzied.");
 | 
			
		||||
        }
 | 
			
		||||
(function($) {
 | 
			
		||||
  $.ripples = function(options) {
 | 
			
		||||
 | 
			
		||||
        this.done = true;
 | 
			
		||||
    // Default options
 | 
			
		||||
    var defaultOptions = {
 | 
			
		||||
      "target": ".btn:not(.btn-link), .card-image, .navbar a:not(.withoutripple), .nav-tabs a:not(.withoutripple), .withripple"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Cross browser matches function
 | 
			
		||||
        function matchesSelector(domElement, selector) {
 | 
			
		||||
            var matches = domElement.matches ||
 | 
			
		||||
                domElement.matchesSelector ||
 | 
			
		||||
                domElement.webkitMatchesSelector ||
 | 
			
		||||
                domElement.mozMatchesSelector ||
 | 
			
		||||
                domElement.msMatchesSelector ||
 | 
			
		||||
                domElement.oMatchesSelector;
 | 
			
		||||
            return matches.call(domElement, selector);
 | 
			
		||||
        }
 | 
			
		||||
    // Fade out the ripple and then destroy it
 | 
			
		||||
    function rippleOut(ripple) {
 | 
			
		||||
 | 
			
		||||
        // animations time
 | 
			
		||||
        var rippleOutTime = 100,
 | 
			
		||||
            rippleStartTime = 500;
 | 
			
		||||
      // Unbind events from ripple
 | 
			
		||||
      ripple.off();
 | 
			
		||||
 | 
			
		||||
        // Helper to bind events on dynamically created elements
 | 
			
		||||
        var bind = function(events, selector, callback) {
 | 
			
		||||
            if (typeof events === "string") {
 | 
			
		||||
                events = [events];
 | 
			
		||||
            }
 | 
			
		||||
            events.forEach(function(event) {
 | 
			
		||||
                document.addEventListener(event, function(e) {
 | 
			
		||||
                    var target = (typeof e.detail !== "number") ? e.detail : e.target;
 | 
			
		||||
      // Start the out animation
 | 
			
		||||
      ripple.addClass("ripple-out");
 | 
			
		||||
 | 
			
		||||
                    if (matchesSelector(target, selector)) {
 | 
			
		||||
                        callback(e, target);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var rippleStart = function(e, target, callback) {
 | 
			
		||||
 | 
			
		||||
            // Init variables
 | 
			
		||||
            var $rippleWrapper      = target,
 | 
			
		||||
                $el                 = $rippleWrapper.parentNode,
 | 
			
		||||
                $ripple             = document.createElement("div"),
 | 
			
		||||
                elPos               = $el.getBoundingClientRect(),
 | 
			
		||||
                // Mouse pos in most cases
 | 
			
		||||
                mousePos            = {x: e.clientX - elPos.left, y: ((window.ontouchstart) ? e.clientY - window.scrollY: e.clientY) - elPos.top},
 | 
			
		||||
                scale               = "scale(" + Math.round($rippleWrapper.offsetWidth / 5) + ")",
 | 
			
		||||
                rippleEnd           = new CustomEvent("rippleEnd", {detail: $ripple}),
 | 
			
		||||
                _rippleOpacity      = 0.3,
 | 
			
		||||
                refreshElementStyle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // If multitouch is detected or some other black magic suff is happening...
 | 
			
		||||
            if (e.touches) {
 | 
			
		||||
                mousePos  = {x: e.touches[0].clientX - elPos.left, y:  e.touches[0].clientY - elPos.top};
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $ripplecache = $ripple;
 | 
			
		||||
 | 
			
		||||
            // Set ripple class
 | 
			
		||||
            $ripple.className = "ripple";
 | 
			
		||||
 | 
			
		||||
            // Move ripple to the mouse position
 | 
			
		||||
            $ripple.setAttribute("style", "left:" + mousePos.x + "px; top:" + mousePos.y + "px;");
 | 
			
		||||
 | 
			
		||||
            // Get the clicked target's text color, this will be applied to the ripple as background-color.
 | 
			
		||||
            var targetColor = window.getComputedStyle($el).color;
 | 
			
		||||
 | 
			
		||||
            // Convert the rgb color to an rgba color with opacity set to __rippleOpacity__
 | 
			
		||||
            if ( targetColor.indexOf("rgba") >= 0 ) {
 | 
			
		||||
                var alphaPosition = targetColor.lastIndexOf(",") + 1;
 | 
			
		||||
                targetColor = targetColor.substring(0, alphaPosition) + _rippleOpacity + ")";
 | 
			
		||||
            } else {
 | 
			
		||||
                targetColor = targetColor.replace("rgb", "rgba").replace(")", ", " + _rippleOpacity + ")");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Insert new ripple into ripple wrapper
 | 
			
		||||
            $rippleWrapper.appendChild($ripple);
 | 
			
		||||
 | 
			
		||||
            // Make sure the ripple has the class applied (ugly hack but it works)
 | 
			
		||||
            refreshElementStyle = window.getComputedStyle($ripple).opacity;
 | 
			
		||||
 | 
			
		||||
            // Let other funtions know that this element is animating
 | 
			
		||||
            $ripple.dataset.animating = 1;
 | 
			
		||||
 | 
			
		||||
            // Set scale value, background-color and opacity to ripple and animate it
 | 
			
		||||
            $ripple.className = "ripple ripple-on";
 | 
			
		||||
 | 
			
		||||
            // Prepare the style of the ripple
 | 
			
		||||
            var rippleStyle = [
 | 
			
		||||
                $ripple.getAttribute("style"),
 | 
			
		||||
                "background-color: " + targetColor,
 | 
			
		||||
                "-ms-transform: " + scale,
 | 
			
		||||
                "-moz-transform:" + scale,
 | 
			
		||||
                "-webkit-transform:" + scale,
 | 
			
		||||
                "transform: " + scale
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            // Apply the style
 | 
			
		||||
            $ripple.setAttribute("style", rippleStyle.join(";"));
 | 
			
		||||
 | 
			
		||||
            // This function is called when the animation is finished
 | 
			
		||||
            setTimeout(function() {
 | 
			
		||||
 | 
			
		||||
                // Let know to other functions that this element has finished the animation
 | 
			
		||||
                $ripple.dataset.animating = 0;
 | 
			
		||||
                document.dispatchEvent(rippleEnd);
 | 
			
		||||
                if (callback) {
 | 
			
		||||
                    callback();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }, rippleStartTime);
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var rippleOut = function($ripple) {
 | 
			
		||||
            // Clear previous animation
 | 
			
		||||
            $ripple.className = "ripple ripple-on ripple-out";
 | 
			
		||||
 | 
			
		||||
            // Let ripple fade out (with CSS)
 | 
			
		||||
            setTimeout(function() {
 | 
			
		||||
                $ripple.remove();
 | 
			
		||||
            }, rippleOutTime);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Helper, need to know if mouse is up or down
 | 
			
		||||
        var mouseDown = false;
 | 
			
		||||
        bind(["mousedown", "touchstart"], "*", function() {
 | 
			
		||||
            mouseDown = true;
 | 
			
		||||
        });
 | 
			
		||||
        bind(["mouseup", "touchend", "mouseout"], "*", function() {
 | 
			
		||||
            mouseDown = false;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Append ripple wrapper if not exists already
 | 
			
		||||
        var rippleInit = function(e, target) {
 | 
			
		||||
            if (target.getElementsByClassName("ripple-wrapper").length === 0) {
 | 
			
		||||
                target.className += " withripple";
 | 
			
		||||
                var $rippleWrapper = document.createElement("div");
 | 
			
		||||
                $rippleWrapper.className = "ripple-wrapper";
 | 
			
		||||
                target.appendChild($rippleWrapper);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var $ripplecache;
 | 
			
		||||
 | 
			
		||||
        // Events handler
 | 
			
		||||
        // init RippleJS and start ripple effect on mousedown
 | 
			
		||||
        bind(["mouseover"], withRipple, rippleInit);
 | 
			
		||||
 | 
			
		||||
        // Init if the device is touch screen
 | 
			
		||||
        bind(["touchstart"], withRipple, rippleInit);
 | 
			
		||||
 | 
			
		||||
        // start ripple effect on mousedown
 | 
			
		||||
        bind(["mousedown", "touchstart"], ".ripple-wrapper", function(e, $ripple) {
 | 
			
		||||
            // Start ripple only on left or middle mouse click and touch click
 | 
			
		||||
            if (e.which === 0 || e.which === 1 || e.which === 2) {
 | 
			
		||||
                rippleStart(e, $ripple);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // if animation ends and user is not holding mouse then destroy the ripple
 | 
			
		||||
        bind("rippleEnd", ".ripple-wrapper .ripple", function(e, $ripple) {
 | 
			
		||||
 | 
			
		||||
            var $ripples = $ripple.parentNode.getElementsByClassName("ripple");
 | 
			
		||||
 | 
			
		||||
            if (!mouseDown || ( $ripples[0] == $ripple && $ripples.length > 1)) {
 | 
			
		||||
                rippleOut($ripple);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Destroy ripple when mouse is not holded anymore if the ripple still exists
 | 
			
		||||
        bind(["mouseup", "touchend", "mouseout"], ".ripple-wrapper", function() {
 | 
			
		||||
            var $ripple = $ripplecache;
 | 
			
		||||
            if ($ripple && $ripple.dataset.animating != 1) {
 | 
			
		||||
                rippleOut($ripple);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
      // This function is called when the transition "out" ends
 | 
			
		||||
      ripple.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){
 | 
			
		||||
        ripple.remove();
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    // Apply custom options
 | 
			
		||||
    options = $.extend(defaultOptions, options);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    $(document)
 | 
			
		||||
    .on("mousedown", options.target, function(e) {
 | 
			
		||||
      // If the ripple wrapper does not exists, create it
 | 
			
		||||
      if (!$(this).find(".ripple-wrapper").length) {
 | 
			
		||||
        $(this).append("<div class=ripple-wrapper></div>");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var wrapper = $(this).find(".ripple-wrapper");
 | 
			
		||||
 | 
			
		||||
      // Get the mouse position relative to the ripple wrapper
 | 
			
		||||
      var wrapperOffset = wrapper.offset();
 | 
			
		||||
      var relX = e.pageX - wrapperOffset.left;
 | 
			
		||||
      var relY = e.pageY - wrapperOffset.top;
 | 
			
		||||
 | 
			
		||||
      // Meet the new ripple
 | 
			
		||||
      var ripple = $("<div></div>");
 | 
			
		||||
 | 
			
		||||
      // Add to it the ripple class
 | 
			
		||||
      ripple.addClass("ripple");
 | 
			
		||||
 | 
			
		||||
      // Position it in the right place
 | 
			
		||||
      ripple.css({"left": relX, "top": relY});
 | 
			
		||||
 | 
			
		||||
      // Set the background color of the ripple
 | 
			
		||||
      ripple.css({"background-color": window.getComputedStyle($(this)[0]).color});
 | 
			
		||||
 | 
			
		||||
      // Spawn it
 | 
			
		||||
      wrapper.append(ripple);
 | 
			
		||||
 | 
			
		||||
      // Make sure the ripple has the styles applied (ugly hack but it works)
 | 
			
		||||
      (function() { return window.getComputedStyle(ripple[0]).opacity; })();
 | 
			
		||||
 | 
			
		||||
      // Set the new size
 | 
			
		||||
      var size = (Math.max($(this).outerWidth(), $(this).outerHeight()) / ripple.outerWidth()) * 2.5;
 | 
			
		||||
 | 
			
		||||
      ripple.css({
 | 
			
		||||
        "-ms-transform": "scale(" + size + ")",
 | 
			
		||||
        "-moz-transform": "scale(" + size + ")",
 | 
			
		||||
        "-webkit-transform": "scale(" + size + ")",
 | 
			
		||||
        "transform": "scale(" + size + ")"
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // Start the transition
 | 
			
		||||
      ripple.addClass("ripple-on");
 | 
			
		||||
      ripple.data("animating", "on");
 | 
			
		||||
      ripple.data("mousedown", "on");
 | 
			
		||||
 | 
			
		||||
      // This function is called when the transition "on" ends
 | 
			
		||||
      setTimeout(function() {
 | 
			
		||||
        ripple.data("animating", "off");
 | 
			
		||||
        if (ripple.data("mousedown") == "off") {
 | 
			
		||||
          rippleOut(ripple);
 | 
			
		||||
        }
 | 
			
		||||
      }, 500);
 | 
			
		||||
 | 
			
		||||
      // On mouseup or on mouseleave, set the mousedown flag to "off" and try to destroy the ripple
 | 
			
		||||
      wrapper.on("mouseup mouseleave", function() {
 | 
			
		||||
        ripple.data("mousedown", "off");
 | 
			
		||||
        // If the transition "on" is finished then we can destroy the ripple with transition "out"
 | 
			
		||||
        if (ripple.data("animating") == "off") {
 | 
			
		||||
          rippleOut(ripple);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  $.fn.ripples = function() {
 | 
			
		||||
    $.ripples({"target": $(this)});
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user