mirror of
https://github.com/google/material-design-lite.git
synced 2024-09-20 16:57:31 +03:00
Fixed test case 'should upgrade a single component to an element by using its CSS classes' to reveal a bug in the current upgradeElement
caused by dataUpgraded
not being correctly updated. Added test case 'should upgrade a single component to an element' to reveal a bug in the current upgradeElement
caused by unreliably checking of upgraded class.
Added `getUpgradedListOfElement_(element)` for getting a list of names of the upgraded classes. Made `isElementUpgraded_(element, jsClass)` more reliable. In `upgradeElementInternal(element, optJsClass)`: * Added argument verification. * Improved class search efficiency when jsClass is omitted. * Made `dataUpgraded` update correctly. (Closes #1115)
This commit is contained in:
parent
62ff493131
commit
384315ca64
@ -50,6 +50,18 @@ var componentHandler = (function() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the classNames of the upgraded classes on the element.
|
||||
* @param {HTMLElement} element The element to fetch data from.
|
||||
* @return {[string]}
|
||||
* @private
|
||||
*/
|
||||
function getUpgradedListOfElement_(element) {
|
||||
var dataUpgraded = element.getAttribute('data-upgraded');
|
||||
// Use `['']` as default value to conform the `,name,name...` style.
|
||||
return dataUpgraded === null ? [''] : dataUpgraded.split(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given element has already been upgraded for the given
|
||||
* class.
|
||||
@ -59,8 +71,8 @@ var componentHandler = (function() {
|
||||
* @private
|
||||
*/
|
||||
function isElementUpgraded_(element, jsClass) {
|
||||
var dataUpgraded = element.getAttribute('data-upgraded');
|
||||
return dataUpgraded && dataUpgraded.indexOf(jsClass) !== -1;
|
||||
var upgradedList = getUpgradedListOfElement_(element);
|
||||
return upgradedList.indexOf(jsClass) !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,36 +111,40 @@ var componentHandler = (function() {
|
||||
* the element to.
|
||||
*/
|
||||
function upgradeElementInternal(element, optJsClass) {
|
||||
// Only upgrade elements that have not already been upgraded.
|
||||
var dataUpgraded = element.getAttribute('data-upgraded');
|
||||
|
||||
var registeredClasses = [];
|
||||
// Verify argument type.
|
||||
if (!(typeof element === 'object' && element instanceof Element)) {
|
||||
throw new Error('Invalid argument provided to upgrade MDL element.');
|
||||
}
|
||||
var upgradedList = getUpgradedListOfElement_(element);
|
||||
var classesToUpgrade = [];
|
||||
// If jsClass is not provided scan the registered components to find the
|
||||
// ones matching the element's CSS classList.
|
||||
if (!optJsClass) {
|
||||
registeredClasses = registeredComponents_.filter(function(component) {
|
||||
return element.classList.contains(component.cssClass) &&
|
||||
!isElementUpgraded_(element, component.className);
|
||||
var classList = element.classList;
|
||||
registeredComponents_.forEach(function (component) {
|
||||
// Match CSS & Not to be upgraded & Not upgraded.
|
||||
if (classList.contains(component.cssClass) &&
|
||||
classesToUpgrade.indexOf(component) === -1 &&
|
||||
!isElementUpgraded_(element, component.className)) {
|
||||
classesToUpgrade.push(component);
|
||||
}
|
||||
});
|
||||
} else if (!isElementUpgraded_(element, optJsClass)) {
|
||||
registeredClasses.push(findRegisteredClass_(optJsClass));
|
||||
classesToUpgrade.push(findRegisteredClass_(optJsClass));
|
||||
}
|
||||
|
||||
// Upgrade the element for each classes.
|
||||
for (var i = 0, l = registeredClasses.length; i < l; i++) {
|
||||
var registeredClass = registeredClasses[i];
|
||||
for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) {
|
||||
registeredClass = classesToUpgrade[i];
|
||||
if (registeredClass) {
|
||||
// Mark element as upgraded.
|
||||
if (dataUpgraded === null) {
|
||||
dataUpgraded = '';
|
||||
}
|
||||
element.setAttribute('data-upgraded', dataUpgraded + ',' +
|
||||
registeredClass.className);
|
||||
upgradedList.push(registeredClass.className);
|
||||
element.setAttribute('data-upgraded', upgradedList.join(','));
|
||||
var instance = new registeredClass.classConstructor(element);
|
||||
instance[componentConfigProperty_] = registeredClass;
|
||||
createdComponents_.push(instance);
|
||||
// Call any callbacks the user has registered with this component type.
|
||||
for (var j = 0, len = registeredClass.callbacks.length; j < len; j++) {
|
||||
for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) {
|
||||
registeredClass.callbacks[j](element);
|
||||
}
|
||||
|
||||
|
@ -97,9 +97,9 @@ describe('componentHandler', function() {
|
||||
|
||||
it('should upgrade a single component to an element by using its CSS classes', function() {
|
||||
var el = document.createElement('button');
|
||||
el.className = 'mdl-button mdl-js-button';
|
||||
el.className = 'mdl-js-button mdl-js-ripple-effect';
|
||||
componentHandler.upgradeElement(el);
|
||||
expect($(el)).to.have.data('upgraded', ',MaterialButton');
|
||||
expect($(el)).to.have.data('upgraded', ',MaterialButton,MaterialRipple');
|
||||
});
|
||||
|
||||
it('should upgrade the entire DOM available', function() {
|
||||
@ -116,6 +116,14 @@ describe('componentHandler', function() {
|
||||
document.body.removeChild(buttonTwo);
|
||||
});
|
||||
|
||||
it('should upgrade a single component to an element', function() {
|
||||
var el = document.createElement('button');
|
||||
el.setAttribute('data-upgraded', ',MaterialButtonPostfix');
|
||||
el.className = 'mdl-js-button';
|
||||
componentHandler.upgradeElement(el);
|
||||
expect($(el)).to.have.data('upgraded', ',MaterialButtonPostfix,MaterialButton');
|
||||
});
|
||||
|
||||
it('should upgrade all elements and their children within an HTMLCollection', function() {
|
||||
var container = createNestedElementsForComponentHandlerTest();
|
||||
var buttons = document.querySelectorAll('.mdl-js-button');
|
||||
|
Loading…
Reference in New Issue
Block a user