Project import generated by Copybara.
GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/node_modules/material-design-lite/src/ripple/_ripple.scss b/node_modules/material-design-lite/src/ripple/_ripple.scss
new file mode 100644
index 0000000..cbf86eb
--- /dev/null
+++ b/node_modules/material-design-lite/src/ripple/_ripple.scss
@@ -0,0 +1,42 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import "../variables";
+
+.mdl-ripple {
+ background : $ripple-bg-color;
+ border-radius : 50%;
+ height : 50px;
+ left : 0;
+ opacity : 0;
+ pointer-events : none;
+ position : absolute;
+ top : 0;
+ transform : translate(-50%, -50%);
+ width : 50px;
+ overflow : hidden;
+
+ &.is-animating {
+ transition: transform 0.3s $animation-curve-linear-out-slow-in,
+ width 0.3s $animation-curve-linear-out-slow-in,
+ height 0.3s $animation-curve-linear-out-slow-in,
+ opacity 0.6s $animation-curve-linear-out-slow-in;
+ }
+
+ &.is-visible {
+ opacity: 0.3;
+ }
+}
diff --git a/node_modules/material-design-lite/src/ripple/ripple.js b/node_modules/material-design-lite/src/ripple/ripple.js
new file mode 100644
index 0000000..eaf30f4
--- /dev/null
+++ b/node_modules/material-design-lite/src/ripple/ripple.js
@@ -0,0 +1,260 @@
+/**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+(function() {
+ 'use strict';
+
+ /**
+ * Class constructor for Ripple MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialRipple = function MaterialRipple(element) {
+ this.element_ = element;
+
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialRipple'] = MaterialRipple;
+
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialRipple.prototype.Constant_ = {
+ INITIAL_SCALE: 'scale(0.0001, 0.0001)',
+ INITIAL_SIZE: '1px',
+ INITIAL_OPACITY: '0.4',
+ FINAL_OPACITY: '0',
+ FINAL_SCALE: ''
+ };
+
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialRipple.prototype.CssClasses_ = {
+ RIPPLE_CENTER: 'mdl-ripple--center',
+ RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+ RIPPLE: 'mdl-ripple',
+ IS_ANIMATING: 'is-animating',
+ IS_VISIBLE: 'is-visible'
+ };
+
+ /**
+ * Handle mouse / finger down on element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialRipple.prototype.downHandler_ = function(event) {
+ if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) {
+ var rect = this.element_.getBoundingClientRect();
+ this.boundHeight = rect.height;
+ this.boundWidth = rect.width;
+ this.rippleSize_ = Math.sqrt(rect.width * rect.width +
+ rect.height * rect.height) * 2 + 2;
+ this.rippleElement_.style.width = this.rippleSize_ + 'px';
+ this.rippleElement_.style.height = this.rippleSize_ + 'px';
+ }
+
+ this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE);
+
+ if (event.type === 'mousedown' && this.ignoringMouseDown_) {
+ this.ignoringMouseDown_ = false;
+ } else {
+ if (event.type === 'touchstart') {
+ this.ignoringMouseDown_ = true;
+ }
+ var frameCount = this.getFrameCount();
+ if (frameCount > 0) {
+ return;
+ }
+ this.setFrameCount(1);
+ var bound = event.currentTarget.getBoundingClientRect();
+ var x;
+ var y;
+ // Check if we are handling a keyboard click.
+ if (event.clientX === 0 && event.clientY === 0) {
+ x = Math.round(bound.width / 2);
+ y = Math.round(bound.height / 2);
+ } else {
+ var clientX = event.clientX !== undefined ? event.clientX : event.touches[0].clientX;
+ var clientY = event.clientY !== undefined ? event.clientY : event.touches[0].clientY;
+ x = Math.round(clientX - bound.left);
+ y = Math.round(clientY - bound.top);
+ }
+ this.setRippleXY(x, y);
+ this.setRippleStyles(true);
+ window.requestAnimationFrame(this.animFrameHandler.bind(this));
+ }
+ };
+
+ /**
+ * Handle mouse / finger up on element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialRipple.prototype.upHandler_ = function(event) {
+ // Don't fire for the artificial "mouseup" generated by a double-click.
+ if (event && event.detail !== 2) {
+ // Allow a repaint to occur before removing this class, so the animation
+ // shows for tap events, which seem to trigger a mouseup too soon after
+ // mousedown.
+ window.setTimeout(function() {
+ this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE);
+ }.bind(this), 0);
+ }
+ };
+
+ /**
+ * Initialize element.
+ */
+ MaterialRipple.prototype.init = function() {
+ if (this.element_) {
+ var recentering =
+ this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);
+ if (!this.element_.classList.contains(
+ this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) {
+ this.rippleElement_ = this.element_.querySelector('.' +
+ this.CssClasses_.RIPPLE);
+ this.frameCount_ = 0;
+ this.rippleSize_ = 0;
+ this.x_ = 0;
+ this.y_ = 0;
+
+ // Touch start produces a compat mouse down event, which would cause a
+ // second ripples. To avoid that, we use this property to ignore the first
+ // mouse down after a touch start.
+ this.ignoringMouseDown_ = false;
+
+ this.boundDownHandler = this.downHandler_.bind(this);
+ this.element_.addEventListener('mousedown',
+ this.boundDownHandler);
+ this.element_.addEventListener('touchstart',
+ this.boundDownHandler);
+
+ this.boundUpHandler = this.upHandler_.bind(this);
+ this.element_.addEventListener('mouseup', this.boundUpHandler);
+ this.element_.addEventListener('mouseleave', this.boundUpHandler);
+ this.element_.addEventListener('touchend', this.boundUpHandler);
+ this.element_.addEventListener('blur', this.boundUpHandler);
+
+ /**
+ * Getter for frameCount_.
+ * @return {number} the frame count.
+ */
+ this.getFrameCount = function() {
+ return this.frameCount_;
+ };
+
+ /**
+ * Setter for frameCount_.
+ * @param {number} fC the frame count.
+ */
+ this.setFrameCount = function(fC) {
+ this.frameCount_ = fC;
+ };
+
+ /**
+ * Getter for rippleElement_.
+ * @return {Element} the ripple element.
+ */
+ this.getRippleElement = function() {
+ return this.rippleElement_;
+ };
+
+ /**
+ * Sets the ripple X and Y coordinates.
+ * @param {number} newX the new X coordinate
+ * @param {number} newY the new Y coordinate
+ */
+ this.setRippleXY = function(newX, newY) {
+ this.x_ = newX;
+ this.y_ = newY;
+ };
+
+ /**
+ * Sets the ripple styles.
+ * @param {boolean} start whether or not this is the start frame.
+ */
+ this.setRippleStyles = function(start) {
+ if (this.rippleElement_ !== null) {
+ var transformString;
+ var scale;
+ var size;
+ var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';
+
+ if (start) {
+ scale = this.Constant_.INITIAL_SCALE;
+ size = this.Constant_.INITIAL_SIZE;
+ } else {
+ scale = this.Constant_.FINAL_SCALE;
+ size = this.rippleSize_ + 'px';
+ if (recentering) {
+ offset = 'translate(' + this.boundWidth / 2 + 'px, ' +
+ this.boundHeight / 2 + 'px)';
+ }
+ }
+
+ transformString = 'translate(-50%, -50%) ' + offset + scale;
+
+ this.rippleElement_.style.webkitTransform = transformString;
+ this.rippleElement_.style.msTransform = transformString;
+ this.rippleElement_.style.transform = transformString;
+
+ if (start) {
+ this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING);
+ } else {
+ this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING);
+ }
+ }
+ };
+
+ /**
+ * Handles an animation frame.
+ */
+ this.animFrameHandler = function() {
+ if (this.frameCount_-- > 0) {
+ window.requestAnimationFrame(this.animFrameHandler.bind(this));
+ } else {
+ this.setRippleStyles(false);
+ }
+ };
+ }
+ }
+ };
+
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialRipple,
+ classAsString: 'MaterialRipple',
+ cssClass: 'mdl-js-ripple-effect',
+ widget: false
+ });
+})();