vendor/assets/javascripts/material.js in material_design_lite-rails-1.0.5 vs vendor/assets/javascripts/material.js in material_design_lite-rails-1.0.6

- old
+ new

@@ -92,11 +92,11 @@ var registeredComponents_ = []; /** @type {!Array<componentHandler.Component>} */ var createdComponents_ = []; - var downgradeMethod_ = 'mdlDowngrade_'; + var downgradeMethod_ = 'mdlDowngrade'; var componentConfigProperty_ = 'mdlComponentConfigInternal_'; /** * Searches registered components for a class we are interested in using. * Optionally replaces a match with passed object if specified. @@ -652,10 +652,17 @@ this.rippleElement_.removeEventListener('mouseup', this.boundRippleBlurHandler); } this.element_.removeEventListener('mouseup', this.boundButtonBlurHandler); this.element_.removeEventListener('mouseleave', this.boundButtonBlurHandler); }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialButton.prototype.mdlDowngrade = MaterialButton.prototype.mdlDowngrade_; +MaterialButton.prototype['mdlDowngrade'] = MaterialButton.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialButton, classAsString: 'MaterialButton', @@ -898,10 +905,17 @@ this.inputElement_.removeEventListener('change', this.boundInputOnChange); this.inputElement_.removeEventListener('focus', this.boundInputOnFocus); this.inputElement_.removeEventListener('blur', this.boundInputOnBlur); this.element_.removeEventListener('mouseup', this.boundElementMouseUp); }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialCheckbox.prototype.mdlDowngrade = MaterialCheckbox.prototype.mdlDowngrade_; +MaterialCheckbox.prototype['mdlDowngrade'] = MaterialCheckbox.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialCheckbox, classAsString: 'MaterialCheckbox', @@ -1131,10 +1145,17 @@ this.inputElement_.removeEventListener('change', this.boundInputOnChange); this.inputElement_.removeEventListener('focus', this.boundInputOnFocus); this.inputElement_.removeEventListener('blur', this.boundInputOnBlur); this.element_.removeEventListener('mouseup', this.boundElementOnMouseUp); }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialIconToggle.prototype.mdlDowngrade = MaterialIconToggle.prototype.mdlDowngrade_; +MaterialIconToggle.prototype['mdlDowngrade'] = MaterialIconToggle.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialIconToggle, classAsString: 'MaterialIconToggle', @@ -1254,19 +1275,19 @@ forEl.addEventListener('click', this.handleForClick_.bind(this)); forEl.addEventListener('keydown', this.handleForKeyboardEvent_.bind(this)); } } var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); - this.boundItemKeydown = this.handleItemKeyboardEvent_.bind(this); - this.boundItemClick = this.handleItemClick_.bind(this); + this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this); + this.boundItemClick_ = this.handleItemClick_.bind(this); for (var i = 0; i < items.length; i++) { // Add a listener to each menu item. - items[i].addEventListener('click', this.boundItemClick); + items[i].addEventListener('click', this.boundItemClick_); // Add a tab index to each menu item. items[i].tabIndex = '-1'; // Add a keyboard listener to each menu item. - items[i].addEventListener('keydown', this.boundItemKeydown); + items[i].addEventListener('keydown', this.boundItemKeydown_); } // Add ripple classes to each item, if the user has enabled ripples. if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); for (i = 0; i < items.length; i++) { @@ -1397,11 +1418,11 @@ * * @param {Event} evt The event that fired. * @private */ MaterialMenu.prototype.handleItemClick_ = function (evt) { - if (evt.target.getAttribute('disabled') !== null) { + if (evt.target.hasAttribute('disabled')) { evt.stopPropagation(); } else { // Wait some time before closing menu, so the user can see the ripple. this.closing_ = true; window.setTimeout(function (evt) { @@ -1495,11 +1516,13 @@ var callback = function (e) { // Check to see if the document is processing the same event that // displayed the menu in the first place. If so, do nothing. // Also check to see if the menu is in the process of closing itself, and // do nothing in that case. - if (e !== evt && !this.closing_) { + // Also check if the clicked element is a menu item + // if so, do nothing. + if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) { document.removeEventListener('click', callback); this.hide(); } }.bind(this); document.addEventListener('click', callback); @@ -1517,12 +1540,13 @@ // Remove all transition delays; menu items fade out concurrently. for (var i = 0; i < items.length; i++) { items[i].style.transitionDelay = null; } // Measure the inner element. - var height = this.element_.getBoundingClientRect().height; - var width = this.element_.getBoundingClientRect().width; + var rect = this.element_.getBoundingClientRect(); + var height = rect.height; + var width = rect.width; // Turn on animation, and apply the final clip. Also make invisible. // This triggers the transitions. this.element_.classList.add(this.CssClasses_.IS_ANIMATING); this.applyClip_(height, width); this.container_.classList.remove(this.CssClasses_.IS_VISIBLE); @@ -1550,14 +1574,21 @@ * @private */ MaterialMenu.prototype.mdlDowngrade_ = function () { var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); for (var i = 0; i < items.length; i++) { - items[i].removeEventListener('click', this.boundItemClick); - items[i].removeEventListener('keydown', this.boundItemKeydown); + items[i].removeEventListener('click', this.boundItemClick_); + items[i].removeEventListener('keydown', this.boundItemKeydown_); } }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialMenu.prototype.mdlDowngrade = MaterialMenu.prototype.mdlDowngrade_; +MaterialMenu.prototype['mdlDowngrade'] = MaterialMenu.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialMenu, classAsString: 'MaterialMenu', @@ -1665,10 +1696,17 @@ MaterialProgress.prototype.mdlDowngrade_ = function () { while (this.element_.firstChild) { this.element_.removeChild(this.element_.firstChild); } }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialProgress.prototype.mdlDowngrade = MaterialProgress.prototype.mdlDowngrade_; +MaterialProgress.prototype['mdlDowngrade'] = MaterialProgress.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialProgress, classAsString: 'MaterialProgress', @@ -1872,10 +1910,14 @@ * Initialize element. */ MaterialRadio.prototype.init = function () { if (this.element_) { this.btnElement_ = this.element_.querySelector('.' + this.CssClasses_.RADIO_BTN); + this.boundChangeHandler_ = this.onChange_.bind(this); + this.boundFocusHandler_ = this.onChange_.bind(this); + this.boundBlurHandler_ = this.onBlur_.bind(this); + this.boundMouseUpHandler_ = this.onMouseup_.bind(this); var outerCircle = document.createElement('span'); outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE); var innerCircle = document.createElement('span'); innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE); this.element_.appendChild(outerCircle); @@ -1885,24 +1927,47 @@ this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); rippleContainer = document.createElement('span'); rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT); rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER); - rippleContainer.addEventListener('mouseup', this.onMouseup_.bind(this)); + rippleContainer.addEventListener('mouseup', this.boundMouseUpHandler_); var ripple = document.createElement('span'); ripple.classList.add(this.CssClasses_.RIPPLE); rippleContainer.appendChild(ripple); this.element_.appendChild(rippleContainer); } - this.btnElement_.addEventListener('change', this.onChange_.bind(this)); - this.btnElement_.addEventListener('focus', this.onFocus_.bind(this)); - this.btnElement_.addEventListener('blur', this.onBlur_.bind(this)); - this.element_.addEventListener('mouseup', this.onMouseup_.bind(this)); + this.btnElement_.addEventListener('change', this.boundChangeHandler_); + this.btnElement_.addEventListener('focus', this.boundFocusHandler_); + this.btnElement_.addEventListener('blur', this.boundBlurHandler_); + this.element_.addEventListener('mouseup', this.boundMouseUpHandler_); this.updateClasses_(); this.element_.classList.add(this.CssClasses_.IS_UPGRADED); } }; +/** + * Downgrade the element. + * + * @private + */ +MaterialRadio.prototype.mdlDowngrade_ = function () { + var rippleContainer = this.element_.querySelector('.' + this.CssClasses_.RIPPLE_CONTAINER); + this.btnElement_.removeEventListener('change', this.boundChangeHandler_); + this.btnElement_.removeEventListener('focus', this.boundFocusHandler_); + this.btnElement_.removeEventListener('blur', this.boundBlurHandler_); + this.element_.removeEventListener('mouseup', this.boundMouseUpHandler_); + if (rippleContainer) { + rippleContainer.removeEventListener('mouseup', this.boundMouseUpHandler_); + this.element_.removeChild(rippleContainer); + } +}; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialRadio.prototype.mdlDowngrade = MaterialRadio.prototype.mdlDowngrade_; +MaterialRadio.prototype['mdlDowngrade'] = MaterialRadio.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialRadio, classAsString: 'MaterialRadio', @@ -2125,10 +2190,17 @@ this.element_.removeEventListener('input', this.boundInputHandler); this.element_.removeEventListener('change', this.boundChangeHandler); this.element_.removeEventListener('mouseup', this.boundMouseUpHandler); this.element_.parentElement.removeEventListener('mousedown', this.boundContainerMouseDownHandler); }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialSlider.prototype.mdlDowngrade = MaterialSlider.prototype.mdlDowngrade_; +MaterialSlider.prototype['mdlDowngrade'] = MaterialSlider.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialSlider, classAsString: 'MaterialSlider', @@ -2496,10 +2568,17 @@ this.inputElement_.removeEventListener('change', this.boundChangeHandler); this.inputElement_.removeEventListener('focus', this.boundFocusHandler); this.inputElement_.removeEventListener('blur', this.boundBlurHandler); this.element_.removeEventListener('mouseup', this.boundMouseUpHandler); }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialSwitch.prototype.mdlDowngrade = MaterialSwitch.prototype.mdlDowngrade_; +MaterialSwitch.prototype['mdlDowngrade'] = MaterialSwitch.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialSwitch, classAsString: 'MaterialSwitch', @@ -2762,14 +2841,16 @@ * Check the validity state and update field accordingly. * * @public */ MaterialTextfield.prototype.checkValidity = function () { - if (this.input_.validity.valid) { - this.element_.classList.remove(this.CssClasses_.IS_INVALID); - } else { - this.element_.classList.add(this.CssClasses_.IS_INVALID); + if (this.input_.validity) { + if (this.input_.validity.valid) { + this.element_.classList.remove(this.CssClasses_.IS_INVALID); + } else { + this.element_.classList.add(this.CssClasses_.IS_INVALID); + } } }; MaterialTextfield.prototype['checkValidity'] = MaterialTextfield.prototype.checkValidity; /** * Check the dirty state and update field accordingly. @@ -2809,15 +2890,11 @@ * * @param {string} value The value to which to set the control (optional). * @public */ MaterialTextfield.prototype.change = function (value) { - if (value) { - this.input_.value = value; - } else { - this.input_.value = ''; - } + this.input_.value = value || ''; this.updateClasses_(); }; MaterialTextfield.prototype['change'] = MaterialTextfield.prototype.change; /** * Initialize element. @@ -2843,12 +2920,16 @@ // TODO: This should handle pasting multi line text. // Currently doesn't. this.boundKeyDownHandler = this.onKeyDown_.bind(this); this.input_.addEventListener('keydown', this.boundKeyDownHandler); } + var invalid = this.element_.classList.contains(this.CssClasses_.IS_INVALID); this.updateClasses_(); this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + if (invalid) { + this.element_.classList.add(this.CssClasses_.IS_INVALID); + } } } }; /** * Downgrade the component @@ -2861,10 +2942,17 @@ this.input_.removeEventListener('blur', this.boundBlurHandler); if (this.boundKeyDownHandler) { this.input_.removeEventListener('keydown', this.boundKeyDownHandler); } }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialTextfield.prototype.mdlDowngrade = MaterialTextfield.prototype.mdlDowngrade_; +MaterialTextfield.prototype['mdlDowngrade'] = MaterialTextfield.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialTextfield, classAsString: 'MaterialTextfield', @@ -2961,11 +3049,11 @@ if (forElId) { this.forElement_ = document.getElementById(forElId); } if (this.forElement_) { // Tabindex needs to be set for `blur` events to be emitted - if (!this.forElement_.getAttribute('tabindex')) { + if (!this.forElement_.hasAttribute('tabindex')) { this.forElement_.setAttribute('tabindex', '0'); } this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this); this.boundMouseLeaveHandler = this.handleMouseLeave_.bind(this); this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false); @@ -2987,10 +3075,17 @@ this.forElement_.removeEventListener('click', this.boundMouseEnterHandler, false); this.forElement_.removeEventListener('touchstart', this.boundMouseEnterHandler, false); this.forElement_.removeEventListener('mouseleave', this.boundMouseLeaveHandler); } }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialTooltip.prototype.mdlDowngrade = MaterialTooltip.prototype.mdlDowngrade_; +MaterialTooltip.prototype['mdlDowngrade'] = MaterialTooltip.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialTooltip, classAsString: 'MaterialTooltip', @@ -3125,20 +3220,22 @@ } else { this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN); // Collapse drawer (if any) when moving to a large screen size. if (this.drawer_) { this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN); + this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN); } } }; /** * Handles toggling of the drawer. * * @private */ MaterialLayout.prototype.drawerToggleHandler_ = function () { this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN); + this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN); }; /** * Handles (un)setting the `is-animating` class * * @private @@ -3186,11 +3283,12 @@ container.classList.add(this.CssClasses_.CONTAINER); this.element_.parentElement.insertBefore(container, this.element_); this.element_.parentElement.removeChild(this.element_); container.appendChild(this.element_); var directChildren = this.element_.childNodes; - for (var c = 0; c < directChildren.length; c++) { + var numChildren = directChildren.length; + for (var c = 0; c < numChildren; c++) { var child = directChildren[c]; if (child.classList && child.classList.contains(this.CssClasses_.HEADER)) { this.header_ = child; } if (child.classList && child.classList.contains(this.CssClasses_.DRAWER)) { @@ -3202,15 +3300,10 @@ } if (this.header_) { this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR); } var mode = this.Mode_.STANDARD; - // Keep an eye on screen size, and add/remove auxiliary class for styling - // of small screens. - this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH); - this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)); - this.screenSizeHandler_(); if (this.header_) { if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) { mode = this.Mode_.SEAMED; } else if (this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)) { mode = this.Mode_.WATERFALL; @@ -3236,21 +3329,14 @@ // the header. this.content_.addEventListener('scroll', this.contentScrollHandler_.bind(this)); this.contentScrollHandler_(); } } - /** - * Prevents an event from triggering the default behaviour. - * @param {Event} ev the event to eat. - */ - var eatEvent = function (ev) { - ev.preventDefault(); - }; // Add drawer toggling button to our layout, if we have an openable drawer. if (this.drawer_) { var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN); - if (typeof drawerButton === 'undefined' || drawerButton === null) { + if (!drawerButton) { drawerButton = document.createElement('div'); drawerButton.classList.add(this.CssClasses_.DRAWER_BTN); var drawerButtonIcon = document.createElement('i'); drawerButtonIcon.classList.add(this.CssClasses_.ICON); drawerButtonIcon.textContent = this.Constant_.MENU_ICON; @@ -3266,11 +3352,10 @@ drawerButton.addEventListener('click', this.drawerToggleHandler_.bind(this)); // Add a class if the layout has a drawer, for altering the left padding. // Adds the HAS_DRAWER to the elements since this.header_ may or may // not be present. this.element_.classList.add(this.CssClasses_.HAS_DRAWER); - this.drawer_.addEventListener('mousewheel', eatEvent); // If we have a fixed header, add the button to the header rather than // the layout. if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) { this.header_.insertBefore(drawerButton, this.header_.firstChild); } else { @@ -3278,12 +3363,17 @@ } var obfuscator = document.createElement('div'); obfuscator.classList.add(this.CssClasses_.OBFUSCATOR); this.element_.appendChild(obfuscator); obfuscator.addEventListener('click', this.drawerToggleHandler_.bind(this)); - obfuscator.addEventListener('mousewheel', eatEvent); + this.obfuscator_ = obfuscator; } + // Keep an eye on screen size, and add/remove auxiliary class for styling + // of small screens. + this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH); + this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)); + this.screenSizeHandler_(); // Initialize tabs, if any. if (this.header_ && this.tabBar_) { this.element_.classList.add(this.CssClasses_.HAS_TABS); var tabContainer = document.createElement('div'); tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER); @@ -3349,30 +3439,28 @@ * @param {!Array<HTMLElement>} tabs Array with HTML elements for all tabs. * @param {!Array<HTMLElement>} panels Array with HTML elements for all panels. * @param {MaterialLayout} layout The MaterialLayout object that owns the tab. */ function MaterialLayoutTab(tab, tabs, panels, layout) { - if (tab) { - if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) { - var rippleContainer = document.createElement('span'); - rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER); - rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT); - var ripple = document.createElement('span'); - ripple.classList.add(layout.CssClasses_.RIPPLE); - rippleContainer.appendChild(ripple); - tab.appendChild(rippleContainer); - } - tab.addEventListener('click', function (e) { - e.preventDefault(); - var href = tab.href.split('#')[1]; - var panel = layout.content_.querySelector('#' + href); - layout.resetTabState_(tabs); - layout.resetPanelState_(panels); - tab.classList.add(layout.CssClasses_.IS_ACTIVE); - panel.classList.add(layout.CssClasses_.IS_ACTIVE); - }); + if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) { + var rippleContainer = document.createElement('span'); + rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER); + rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT); + var ripple = document.createElement('span'); + ripple.classList.add(layout.CssClasses_.RIPPLE); + rippleContainer.appendChild(ripple); + tab.appendChild(rippleContainer); } + tab.addEventListener('click', function (e) { + e.preventDefault(); + var href = tab.href.split('#')[1]; + var panel = layout.content_.querySelector('#' + href); + layout.resetTabState_(tabs); + layout.resetPanelState_(panels); + tab.classList.add(layout.CssClasses_.IS_ACTIVE); + panel.classList.add(layout.CssClasses_.IS_ACTIVE); + }); } // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialLayout, @@ -3425,10 +3513,11 @@ * @private */ MaterialDataTable.prototype.CssClasses_ = { DATA_TABLE: 'mdl-data-table', SELECTABLE: 'mdl-data-table--selectable', + SELECT_ELEMENT: 'mdl-data-table__select', IS_SELECTED: 'is-selected', IS_UPGRADED: 'is-upgraded' }; /** * Generates and returns a function that toggles the selection state of a @@ -3477,22 +3566,21 @@ * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes. * @private */ MaterialDataTable.prototype.createCheckbox_ = function (row, opt_rows) { var label = document.createElement('label'); - label.classList.add('mdl-checkbox'); - label.classList.add('mdl-js-checkbox'); - label.classList.add('mdl-js-ripple-effect'); - label.classList.add('mdl-data-table__select'); + var labelClasses = [ + 'mdl-checkbox', + 'mdl-js-checkbox', + 'mdl-js-ripple-effect', + this.CssClasses_.SELECT_ELEMENT + ]; + label.className = labelClasses.join(' '); var checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.classList.add('mdl-checkbox__input'); - if (row) { - checkbox.addEventListener('change', this.selectRow_(checkbox, row)); - } else if (opt_rows) { - checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows)); - } + checkbox.addEventListener('change', this.selectRow_(checkbox, row, opt_rows)); label.appendChild(checkbox); componentHandler.upgradeElement(label, 'MaterialCheckbox'); return label; }; /** @@ -3757,9 +3845,16 @@ this.element_.removeEventListener('mouseup', this.boundUpHandler); this.element_.removeEventListener('mouseleave', this.boundUpHandler); this.element_.removeEventListener('touchend', this.boundUpHandler); this.element_.removeEventListener('blur', this.boundUpHandler); }; +/** + * Public alias for the downgrade method. + * + * @public + */ +MaterialRipple.prototype.mdlDowngrade = MaterialRipple.prototype.mdlDowngrade_; +MaterialRipple.prototype['mdlDowngrade'] = MaterialRipple.prototype.mdlDowngrade; // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ constructor: MaterialRipple, classAsString: 'MaterialRipple',