diff --git a/src/jqLite.js b/src/jqLite.js index 0629619e5e35..a0da2de1e629 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -381,15 +381,33 @@ function jqLiteHasClass(element, selector) { indexOf(" " + selector + " ") > -1); } -function jqLiteRemoveClass(element, cssClasses) { - if (cssClasses && element.setAttribute) { - forEach(cssClasses.split(' '), function(cssClass) { - element.setAttribute('class', trim( - (" " + (element.getAttribute('class') || '') + " ") - .replace(/[\n\t]/g, " ") - .replace(" " + trim(cssClass) + " ", " ")) - ); - }); +function jqLiteRemoveClass(element, cssClassesOrFunc) { + if (element.setAttribute) { + + //if selector is passed + if (cssClassesOrFunc) { + //if cssClassesOrFunc is a function + if (isFunction(cssClassesOrFunc)) { + /* + * takes index of element in the set, and a list of the elements class names + * index of element in set will always be 0 + * returns one or more space-separated class names to be removed + */ + cssClassesOrFunc = cssClassesOrFunc.call(element, 0, element.className); + } + //remove classes + forEach(cssClassesOrFunc.split(' '), function(cssClass) { + element.setAttribute('class', trim( + (" " + (element.getAttribute('class') || '') + " ") + .replace(/[\n\t]/g, " ") + .replace(" " + trim(cssClass) + " ", " ")) + ); + }); + + } else { + // if no class names are specified in the parameter, all classes will be removed + element.setAttribute('class', ''); + } } } @@ -934,15 +952,32 @@ forEach({ addClass: jqLiteAddClass, removeClass: jqLiteRemoveClass, - toggleClass: function(element, selector, condition) { - if (selector) { - forEach(selector.split(' '), function(className) { + toggleClass: function(element, selectorOrFunc, condition) { + + //if selector passed toggle classes + if (selectorOrFunc) { + + //if selector is a function + if (isFunction(selectorOrFunc)) { + /* + * takes index of element in the set, and a list of the elements class names + * index of element in set will always be 0 + * returns one or more space-separated class names to be toggled + */ + selectorOrFunc = selectorOrFunc.call(element, 0, element.className, condition); + } + //toggle values + forEach(selectorOrFunc.split(' '), function(className) { var classCondition = condition; if (isUndefined(classCondition)) { classCondition = !jqLiteHasClass(element, className); } (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className); }); + + // if no selector is passed all class names on the element will be toggled. + } else { + jqLiteRemoveClass(element); } }, diff --git a/test/jqLiteSpec.js b/test/jqLiteSpec.js index 83d531bc18bc..68b9fd34d210 100644 --- a/test/jqLiteSpec.js +++ b/test/jqLiteSpec.js @@ -839,6 +839,42 @@ describe('jqLite', function() { expect(jqLite(b).hasClass('cde')).toBe(false); }); + + it('should allow function to be passed', function() { + var selector = jqLite([a, b]); + selector.addClass('abc'); + selector.addClass('cde'); + selector.addClass('fgh'); + selector.addClass('ijk'); + + expect(selector.toggleClass(function(index, className) { + return 'abc cde'; + })).toBe(selector); + + expect(jqLite(a).hasClass('abc')).toBe(false); + expect(jqLite(a).hasClass('cde')).toBe(false); + expect(jqLite(a).hasClass('fgh')).toBe(true); + expect(jqLite(a).hasClass('ijk')).toBe(true); + + expect(jqLite(b).hasClass('abc')).toBe(false); + expect(jqLite(b).hasClass('cde')).toBe(false); + expect(jqLite(b).hasClass('fgh')).toBe(true); + expect(jqLite(b).hasClass('ijk')).toBe(true); + }); + + it('should toggle all classes if no selector is passed', function() { + var selector = jqLite([a, b]); + selector.addClass('abc'); + selector.addClass('cde'); + + expect(selector.toggleClass()).toBe(selector); + + expect(jqLite(a).hasClass('abc')).toBe(false); + expect(jqLite(a).hasClass('cde')).toBe(false); + expect(jqLite(b).hasClass('abc')).toBe(false); + expect(jqLite(b).hasClass('cde')).toBe(false); + }); + it('should not break for null / undefined selectors', function() { var selector = jqLite([a, b]); expect(selector.toggleClass(null)).toBe(selector); @@ -869,6 +905,30 @@ describe('jqLite', function() { }); + it('should remove all classes if no class is specified', function() { + var element = jqLite('
'); + + expect(element.removeClass()).toEqual(element); + + expect(element.hasClass('foo')).toBe(false); + expect(element.hasClass('bar')).toBe(false); + expect(element.hasClass('baz')).toBe(false); + }); + + + it('should allow a function as a paramater', function() { + var element = jqLite(''); + + expect(element.removeClass(function(index, className) { + return 'foo bar'; + })).toEqual(element); + + expect(element.hasClass('foo')).toBe(false); + expect(element.hasClass('bar')).toBe(false); + expect(element.hasClass('baz')).toBe(true); + }); + + it('should remove multiple classes specified as one string', function() { var jqA = jqLite(a);