Downgrade functionality and components updated with downgrade methods.

master
Jonathan Garbee 2015-05-25 13:35:06 -04:00
parent c0655b660e
commit 58c2337c58
10 changed files with 290 additions and 88 deletions

View File

@ -96,17 +96,31 @@ MaterialButton.prototype.init = function() {
if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
var rippleContainer = document.createElement('span'); var rippleContainer = document.createElement('span');
rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
var ripple = document.createElement('span'); this.rippleElement_ = document.createElement('span');
ripple.classList.add(this.CssClasses_.RIPPLE); this.rippleElement_.classList.add(this.CssClasses_.RIPPLE);
rippleContainer.appendChild(ripple); rippleContainer.appendChild(this.rippleElement_);
ripple.addEventListener('mouseup', this.blurHandler.bind(this)); this.boundRippleBlurHandler = this.blurHandler.bind(this);
this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler);
this.element_.appendChild(rippleContainer); this.element_.appendChild(rippleContainer);
} }
this.element_.addEventListener('mouseup', this.blurHandler.bind(this)); this.boundButtonBlurHandler = this.blurHandler.bind(this);
this.element_.addEventListener('mouseleave', this.blurHandler.bind(this)); this.element_.addEventListener('mouseup', this.boundButtonBlurHandler);
this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler);
} }
}; };
/**
* Downgrade the element.
*/
MaterialButton.prototype.mdlDowngrade_ = function() {
'use strict';
if (this.rippleElement_) {
this.rippleElement_.removeEventListener('mouseup', this.boundRippleBlurHandler);
}
this.element_.removeEventListener('mouseup', this.boundButtonBlurHandler);
this.element_.removeEventListener('mouseleave', this.boundButtonBlurHandler);
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -211,32 +211,49 @@ MaterialCheckbox.prototype.init = function() {
this.element_.appendChild(tickContainer); this.element_.appendChild(tickContainer);
this.element_.appendChild(boxOutline); this.element_.appendChild(boxOutline);
var rippleContainer;
if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
rippleContainer = document.createElement('span'); this.rippleContainerElement_ = document.createElement('span');
rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT); this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);
rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER); this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
rippleContainer.addEventListener('mouseup', this.onMouseUp_.bind(this)); this.boundRippleMouseUp = this.onMouseUp_.bind(this);
this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
var ripple = document.createElement('span'); var ripple = document.createElement('span');
ripple.classList.add(this.CssClasses_.RIPPLE); ripple.classList.add(this.CssClasses_.RIPPLE);
rippleContainer.appendChild(ripple); this.rippleContainerElement_.appendChild(ripple);
this.element_.appendChild(rippleContainer); this.element_.appendChild(this.rippleContainerElement_);
} }
this.boundInputOnChange = this.onChange_.bind(this);
this.inputElement_.addEventListener('change', this.onChange_.bind(this)); this.boundInputOnFocus = this.onFocus_.bind(this);
this.inputElement_.addEventListener('focus', this.onFocus_.bind(this)); this.boundInputOnBlur = this.onBlur_.bind(this);
this.inputElement_.addEventListener('blur', this.onBlur_.bind(this)); this.boundElementMouseUp = this.onMouseUp_.bind(this);
this.element_.addEventListener('mouseup', this.onMouseUp_.bind(this)); this.inputElement_.addEventListener('change', this.boundInputOnChange);
this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
this.element_.addEventListener('mouseup', this.boundElementMouseUp);
this.updateClasses_(); this.updateClasses_();
this.element_.classList.add(this.CssClasses_.IS_UPGRADED); this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
} }
}; };
/*
* Downgrade the component.
*/
MaterialCheckbox.prototype.mdlDowngrade_ = function() {
'use strict';
if (this.rippleContainerElement_) {
this.rippleContainerElement_.removeEventListener('mouseup', this.boundRippleMouseUp);
}
this.inputElement_.removeEventListener('change', this.boundInputOnChange);
this.inputElement_.removeEventListener('focus', this.boundInputOnFocus);
this.inputElement_.removeEventListener('blur', this.boundInputOnBlur);
this.element_.removeEventListener('mouseup', this.boundElementMouseUp);
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -193,32 +193,50 @@ MaterialIconToggle.prototype.init = function() {
this.inputElement_ = this.inputElement_ =
this.element_.querySelector('.' + this.CssClasses_.INPUT); this.element_.querySelector('.' + this.CssClasses_.INPUT);
var rippleContainer;
if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) { if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
rippleContainer = document.createElement('span'); this.rippleContainerElement_ = document.createElement('span');
rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
rippleContainer.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT); this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT);
rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER); this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
rippleContainer.addEventListener('mouseup', this.onMouseUp_.bind(this)); this.boundRippleMouseUp = this.onMouseUp_.bind(this);
this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
var ripple = document.createElement('span'); var ripple = document.createElement('span');
ripple.classList.add(this.CssClasses_.RIPPLE); ripple.classList.add(this.CssClasses_.RIPPLE);
rippleContainer.appendChild(ripple); this.rippleContainerElement_.appendChild(ripple);
this.element_.appendChild(rippleContainer); this.element_.appendChild(this.rippleContainerElement_);
} }
this.inputElement_.addEventListener('change', this.onChange_.bind(this)); this.boundInputOnChange = this.onChange_.bind(this);
this.inputElement_.addEventListener('focus', this.onFocus_.bind(this)); this.boundInputOnFocus = this.onFocus_.bind(this);
this.inputElement_.addEventListener('blur', this.onBlur_.bind(this)); this.boundInputOnBlur = this.onBlur_.bind(this);
this.element_.addEventListener('mouseup', this.onMouseUp_.bind(this)); this.boundElementOnMouseUp = this.onMouseUp_.bind(this);
this.inputElement_.addEventListener('change', this.boundInputOnChange);
this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
this.element_.addEventListener('mouseup', this.boundElementOnMouseUp);
this.updateClasses_(); this.updateClasses_();
this.element_.classList.add('is-upgraded'); this.element_.classList.add('is-upgraded');
} }
}; };
/*
* Downgrade the component
*/
MaterialIconToggle.prototype.mdlDowngrade_ = function() {
'use strict';
if (this.rippleContainerElement_) {
this.rippleContainerElement_.removeEventListener('mouseup', this.boundRippleMouseUp);
}
this.inputElement_.removeEventListener('change', this.boundInputOnChange);
this.inputElement_.removeEventListener('focus', this.boundInputOnFocus);
this.inputElement_.removeEventListener('blur', this.boundInputOnBlur);
this.element_.removeEventListener('mouseup', this.boundElementOnMouseUp);
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -20,12 +20,14 @@
* https://github.com/jasonmayes/mdl-component-design-pattern * https://github.com/jasonmayes/mdl-component-design-pattern
* @author Jason Mayes. * @author Jason Mayes.
*/ */
/* exported componentHandler */ /* exported componentHandler */
var componentHandler = (function() { var componentHandler = (function() {
'use strict'; 'use strict';
var registeredComponents_ = []; var registeredComponents_ = [];
var createdComponents_ = []; var createdComponents_ = [];
var downgradeMethod_ = 'mdlDowngrade_';
var componentConfigProperty_ = 'mdlComponentConfigInternal_';
/** /**
* Searches registered components for a class we are interested in using. * Searches registered components for a class we are interested in using.
@ -47,7 +49,6 @@ var componentHandler = (function() {
return false; return false;
} }
/** /**
* Searches existing DOM for elements of our component type and upgrades them * Searches existing DOM for elements of our component type and upgrades them
* if they have not already been upgraded. * if they have not already been upgraded.
@ -77,7 +78,6 @@ var componentHandler = (function() {
} }
} }
/** /**
* Upgrades a specific element rather than all in the DOM. * Upgrades a specific element rather than all in the DOM.
* @param {HTMLElement} element The element we wish to upgrade. * @param {HTMLElement} element The element we wish to upgrade.
@ -98,6 +98,7 @@ var componentHandler = (function() {
if (registeredClass) { if (registeredClass) {
// new // new
var instance = new registeredClass.classConstructor(element); var instance = new registeredClass.classConstructor(element);
instance[componentConfigProperty_] = registeredClass;
createdComponents_.push(instance); createdComponents_.push(instance);
// Call any callbacks the user has registered with this component type. // Call any callbacks the user has registered with this component type.
registeredClass.callbacks.forEach(function (callback) { registeredClass.callbacks.forEach(function (callback) {
@ -107,9 +108,7 @@ var componentHandler = (function() {
// Assign per element instance for control over API // Assign per element instance for control over API
element.widget = instance; element.widget = instance;
} else { } else {
// If component creator forgot to register, try and see if throw 'Unable to find a registered component for the given class.';
// it is in global scope.
createdComponents_.push(new window[jsClass](element));
} }
var ev = document.createEvent('Events'); var ev = document.createEvent('Events');
@ -118,7 +117,6 @@ var componentHandler = (function() {
} }
} }
/** /**
* Registers a class for future use and attempts to upgrade existing DOM. * Registers a class for future use and attempts to upgrade existing DOM.
* @param {object} config An object containing: * @param {object} config An object containing:
@ -132,6 +130,19 @@ var componentHandler = (function() {
'callbacks': [] 'callbacks': []
}; };
registeredComponents_.forEach(function(item) {
if (item.cssClass === newConfig.cssClass) {
throw 'The provided cssClass has already been registered.';
}
if (item.className === newConfig.className) {
throw 'The provided className has already been registered';
}
});
if (config.constructor.prototype.hasOwnProperty(componentConfigProperty_)) {
throw 'MDL component classes must not have ' + componentConfigProperty_ + ' defined as a property.';
}
var found = findRegisteredClass_(config.classAsString, newConfig); var found = findRegisteredClass_(config.classAsString, newConfig);
if (!found) { if (!found) {
@ -139,7 +150,6 @@ var componentHandler = (function() {
} }
} }
/** /**
* Allows user to be alerted to any upgrades that are performed for a given * Allows user to be alerted to any upgrades that are performed for a given
* component type * component type
@ -155,7 +165,6 @@ var componentHandler = (function() {
} }
} }
/** /**
* Upgrades all registered components found in the current DOM. This is * Upgrades all registered components found in the current DOM. This is
* automatically called on window load. * automatically called on window load.
@ -166,6 +175,62 @@ var componentHandler = (function() {
} }
} }
/**
* Finds a created component by a given DOM node.
*
* @param node
* @returns {*}
*/
function findCreatedComponentByNodeInternal(node) {
for (var n = 0; n < createdComponents_.length; n++) {
var component = createdComponents_[n];
if (component.element_ === node) {
return component;
}
}
}
/**
* Check the component for the downgrade method.
* Execute if found.
* Remove component from createdComponents list.
*
* @param component
*/
function deconstructComponentInternal(component) {
if (component && component.__proto__[downgradeMethod_]) {
component[downgradeMethod_]();
var componentIndex = createdComponents_.indexOf(component);
createdComponents_.splice(componentIndex, 1);
var upgrades = component.element_.dataset.upgraded.split(',');
var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString);
upgrades.splice(componentPlace, 1);
component.element_.dataset.upgraded = upgrades.join(',');
var ev = document.createEvent('Events');
ev.initEvent('mdl-componentdowngraded', true, true);
component.element_.dispatchEvent(ev);
}
}
/**
* Downgrade either a given node, an array of nodes, or a NodeList.
*
* @param nodes
*/
function downgradeNodesInternal(nodes) {
var downgradeNode = function(node) {
deconstructComponentInternal(findCreatedComponentByNodeInternal(node));
};
if (nodes instanceof Array || nodes instanceof NodeList) {
for (var n = 0; n < nodes.length; n++) {
downgradeNode(nodes[n]);
}
} else if (nodes instanceof Node) {
downgradeNode(nodes);
} else {
throw 'Invalid argument provided to downgrade MDL nodes.';
}
}
// Now return the functions that should be made public with their publicly // Now return the functions that should be made public with their publicly
// facing names... // facing names...
@ -174,11 +239,11 @@ var componentHandler = (function() {
upgradeElement: upgradeElementInternal, upgradeElement: upgradeElementInternal,
upgradeAllRegistered: upgradeAllRegisteredInternal, upgradeAllRegistered: upgradeAllRegisteredInternal,
registerUpgradedCallback: registerUpgradedCallbackInternal, registerUpgradedCallback: registerUpgradedCallbackInternal,
register: registerInternal register: registerInternal,
downgradeElements: downgradeNodesInternal
}; };
})(); })();
window.addEventListener('load', function() { window.addEventListener('load', function() {
'use strict'; 'use strict';

View File

@ -142,14 +142,17 @@ MaterialRipple.prototype.init = function() {
this.rippleElement_.style.height = this.rippleSize_ + 'px'; this.rippleElement_.style.height = this.rippleSize_ + 'px';
} }
this.element_.addEventListener('mousedown', this.downHandler_.bind(this)); this.boundDownHandler = this.downHandler_.bind(this);
this.element_.addEventListener('mousedown',
this.boundDownHandler);
this.element_.addEventListener('touchstart', this.element_.addEventListener('touchstart',
this.downHandler_.bind(this)); this.boundDownHandler);
this.element_.addEventListener('mouseup', this.upHandler_.bind(this)); this.boundUpHandler = this.upHandler_.bind(this);
this.element_.addEventListener('mouseleave', this.upHandler_.bind(this)); this.element_.addEventListener('mouseup', this.boundUpHandler);
this.element_.addEventListener('touchend', this.upHandler_.bind(this)); this.element_.addEventListener('mouseleave', this.boundUpHandler);
this.element_.addEventListener('blur', this.upHandler_.bind(this)); this.element_.addEventListener('touchend', this.boundUpHandler);
this.element_.addEventListener('blur', this.boundUpHandler);
this.getFrameCount = function() { this.getFrameCount = function() {
return this.frameCount_; return this.frameCount_;
@ -212,6 +215,22 @@ MaterialRipple.prototype.init = function() {
} }
}; };
/*
* Downgrade the component
*/
MaterialRipple.prototype.mdlDowngrade_ = function() {
'use strict';
this.element_.removeEventListener('mousedown',
this.boundDownHandler);
this.element_.removeEventListener('touchstart',
this.boundDownHandler);
this.element_.removeEventListener('mouseup', this.boundUpHandler);
this.element_.removeEventListener('mouseleave', this.boundUpHandler);
this.element_.removeEventListener('touchend', this.boundUpHandler);
this.element_.removeEventListener('blur', this.boundUpHandler);
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -102,7 +102,7 @@ MaterialSlider.prototype.onContainerMouseDown_ = function(event) {
// If this click is not on the parent element (but rather some child) // If this click is not on the parent element (but rather some child)
// ignore. It may still bubble up. // ignore. It may still bubble up.
if(event.target !== this.element_.parentElement) { if (event.target !== this.element_.parentElement) {
return; return;
} }
@ -216,16 +216,31 @@ MaterialSlider.prototype.init = function() {
backgroundFlex.appendChild(this.backgroundUpper_); backgroundFlex.appendChild(this.backgroundUpper_);
} }
this.element_.addEventListener('input', this.onInput_.bind(this)); this.boundInputHandler = this.onInput_.bind(this);
this.element_.addEventListener('change', this.onChange_.bind(this)); this.boundChangeHandler = this.onChange_.bind(this);
this.element_.addEventListener('mouseup', this.onMouseUp_.bind(this)); this.boundMouseUpHandler = this.onMouseUp_.bind(this);
this.element_.parentElement.addEventListener('mousedown', this.onContainerMouseDown_.bind(this)); this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this);
this.element_.addEventListener('input', this.boundInputHandler);
this.element_.addEventListener('change', this.boundChangeHandler);
this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler);
this.updateValueStyles_(); this.updateValueStyles_();
this.element_.classList.add(this.CssClasses_.IS_UPGRADED); this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
} }
}; };
/*
* Downgrade the component
*/
MaterialSlider.prototype.mdlDowngrade_ = function() {
'use strict';
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);
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -210,35 +210,54 @@ MaterialSwitch.prototype.init = function() {
this.element_.appendChild(track); this.element_.appendChild(track);
this.element_.appendChild(thumb); this.element_.appendChild(thumb);
var rippleContainer; this.boundMouseUpHandler = this.onMouseUp_.bind(this);
if (this.element_.classList.contains( if (this.element_.classList.contains(
this.CssClasses_.RIPPLE_EFFECT)) { this.CssClasses_.RIPPLE_EFFECT)) {
this.element_.classList.add( this.element_.classList.add(
this.CssClasses_.RIPPLE_IGNORE_EVENTS); this.CssClasses_.RIPPLE_IGNORE_EVENTS);
rippleContainer = document.createElement('span'); this.rippleContainerElement_ = document.createElement('span');
rippleContainer.classList.add( this.rippleContainerElement_.classList.add(
this.CssClasses_.RIPPLE_CONTAINER); this.CssClasses_.RIPPLE_CONTAINER);
rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT); this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);
rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER); this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
rippleContainer.addEventListener('mouseup', this.onMouseUp_.bind(this)); this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler);
var ripple = document.createElement('span'); var ripple = document.createElement('span');
ripple.classList.add(this.CssClasses_.RIPPLE); ripple.classList.add(this.CssClasses_.RIPPLE);
rippleContainer.appendChild(ripple); this.rippleContainerElement_.appendChild(ripple);
this.element_.appendChild(rippleContainer); this.element_.appendChild(this.rippleContainerElement_);
} }
this.inputElement_.addEventListener('change', this.onChange_.bind(this)); this.boundChangeHandler = this.onChange_.bind(this);
this.inputElement_.addEventListener('focus', this.onFocus_.bind(this)); this.boundFocusHandler = this.onFocus_.bind(this);
this.inputElement_.addEventListener('blur', this.onBlur_.bind(this)); this.boundBlurHandler = this.onBlur_.bind(this);
this.element_.addEventListener('mouseup', this.onMouseUp_.bind(this));
this.inputElement_.addEventListener('change', this.boundChangeHandler);
this.inputElement_.addEventListener('focus', this.boundFocusHandler);
this.inputElement_.addEventListener('blur', this.boundBlurHandler);
this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
this.updateClasses_(); this.updateClasses_();
this.element_.classList.add('is-upgraded'); this.element_.classList.add('is-upgraded');
} }
}; };
/*
* Downgrade the component.
*/
MaterialSwitch.prototype.mdlDowngrade_ = function() {
'use strict';
if (this.rippleContainerElement_) {
this.rippleContainerElement_.removeEventListener('mouseup', this.boundMouseUpHandler);
}
this.inputElement_.removeEventListener('change', this.boundChangeHandler);
this.inputElement_.removeEventListener('focus', this.boundFocusHandler);
this.inputElement_.removeEventListener('blur', this.boundBlurHandler);
this.element_.removeEventListener('mouseup', this.boundMouseUpHandler);
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -115,6 +115,15 @@ MaterialTabs.prototype.init = function() {
} }
}; };
/*
* Downgrade the component
*/
MaterialTabs.prototype.mdlDowngrade = function() {
for (var i = 0; i < this.tabs_.length; i++) {
this.tabs_[i].removeEventListener('click', MaterialTab.onClick_);
}
};
function MaterialTab(tab, ctx) { function MaterialTab(tab, ctx) {
'use strict'; 'use strict';
@ -128,20 +137,21 @@ function MaterialTab(tab, ctx) {
rippleContainer.appendChild(ripple); rippleContainer.appendChild(ripple);
tab.appendChild(rippleContainer); tab.appendChild(rippleContainer);
} }
tab.addEventListener('click', this.onClick_);
tab.addEventListener('click', function(e) {
e.preventDefault();
var href = tab.href.split('#')[1];
var panel = ctx.element_.querySelector('#' + href);
ctx.resetTabState_();
ctx.resetPanelState_();
tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
});
} }
} }
MaterialTab.prototype.onClick_ = function(e) {
'use strict';
e.preventDefault();
var href = tab.href.split('#')[1];
var panel = ctx.element_.querySelector('#' + href);
ctx.resetTabState_();
ctx.resetPanelState_();
tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -179,14 +179,18 @@ MaterialTextfield.prototype.init = function() {
} }
} }
this.input_.addEventListener('input', this.updateClasses_.bind(this)); this.boundUpdateClassesHandler = this.updateClasses_.bind(this);
this.input_.addEventListener('focus', this.onFocus_.bind(this)); this.boundFocusHandler = this.onFocus_.bind(this);
this.input_.addEventListener('blur', this.onBlur_.bind(this)); this.boundBlurHandler = this.onBlur_.bind(this);
this.input_.addEventListener('input', this.boundUpdateClassesHandler);
this.input_.addEventListener('focus', this.boundFocusHandler);
this.input_.addEventListener('blur', this.boundBlurHandler);
if (this.maxRows !== this.Constant_.NO_MAX_ROWS) { if (this.maxRows !== this.Constant_.NO_MAX_ROWS) {
// TODO: This should handle pasting multi line text. // TODO: This should handle pasting multi line text.
// Currently doesn't. // Currently doesn't.
this.input_.addEventListener('keydown', this.onKeyDown_.bind(this)); this.boundKeyDownHandler = this.onKeyDown_.bind(this);
this.input_.addEventListener('keydown', this.boundKeyDownHandler);
} }
this.updateClasses_(); this.updateClasses_();
@ -195,6 +199,19 @@ MaterialTextfield.prototype.init = function() {
} }
}; };
/*
* Downgrade the component
*/
MaterialTextfield.prototype.mdlDowngrade_ = function() {
'use strict';
this.input_.removeEventListener('input', this.boundUpdateClassesHandler);
this.input_.removeEventListener('focus', this.boundFocusHandler);
this.input_.removeEventListener('blur', this.boundBlurHandler);
if (this.boundKeyDownHandler) {
this.input_.removeEventListener('keydown', this.boundKeyDownHandler);
}
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -49,7 +49,6 @@ MaterialTooltip.prototype.CssClasses_ = {
IS_ACTIVE: 'is-active' IS_ACTIVE: 'is-active'
}; };
/** /**
* Handle mouseenter for tooltip. * Handle mouseenter for tooltip.
* @param {Event} event The event that fired. * @param {Event} event The event that fired.
@ -66,7 +65,6 @@ MaterialTooltip.prototype.handleMouseEnter_ = function(event) {
this.element_.classList.add(this.CssClasses_.IS_ACTIVE); this.element_.classList.add(this.CssClasses_.IS_ACTIVE);
}; };
/** /**
* Handle mouseleave for tooltip. * Handle mouseleave for tooltip.
* @param {Event} event The event that fired. * @param {Event} event The event that fired.
@ -79,7 +77,6 @@ MaterialTooltip.prototype.handleMouseLeave_ = function(event) {
this.element_.classList.remove(this.CssClasses_.IS_ACTIVE); this.element_.classList.remove(this.CssClasses_.IS_ACTIVE);
}; };
/** /**
* Initialize element. * Initialize element.
*/ */
@ -88,20 +85,31 @@ MaterialTooltip.prototype.init = function() {
if (this.element_) { if (this.element_) {
var forElId = this.element_.getAttribute('for'); var forElId = this.element_.getAttribute('for');
var forEl = null;
if (forElId) { if (forElId) {
forEl = document.getElementById(forElId); this.forElement_ = document.getElementById(forElId);
} }
if (forEl) { if (this.forElement_) {
forEl.addEventListener('mouseenter', this.handleMouseEnter_.bind(this), this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this);
this.boundMouseLeaveHandler = this.handleMouseLeave_.bind(this);
this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler,
false); false);
forEl.addEventListener('mouseleave', this.handleMouseLeave_.bind(this)); this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveHandler);
} }
} }
}; };
/*
* Downgrade the component
*/
MaterialTooltip.prototype.mdlDowngrade_ = function() {
'use strict';
if (this.forElement_) {
this.forElement_.removeEventListener('mouseenter', this.boundMouseEnterHandler, false);
this.forElement_.removeEventListener('mouseleave', this.boundMouseLeaveHandler);
}
};
// The component registers itself. It can assume componentHandler is available // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.