From 5da78ff3085c5cb6d93440218313b35a32bdc2d2 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Wed, 4 Jun 2014 11:42:37 -0700 Subject: [PATCH 1/2] perf(jqLite): use classList for adding classes if available All elements/browsers that don't have classList will still use the old setTimeout method. --- src/jqLite.js | 34 ++++++++++++++++++++++++---------- test/ngAnimate/animateSpec.js | 9 +++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/jqLite.js b/src/jqLite.js index ec6ca09e9717..77f163ac375b 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -349,18 +349,32 @@ function jqLiteRemoveClass(element, cssClasses) { } function jqLiteAddClass(element, cssClasses) { - if (cssClasses && element.setAttribute) { - var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ') - .replace(/[\n\t]/g, " "); - - forEach(cssClasses.split(' '), function(cssClass) { - cssClass = trim(cssClass); - if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) { - existingClasses += cssClass + ' '; + if (cssClasses) { + + // if browser and element support classList api use it + if (element.classList) { + cssClasses = trim(cssClasses); + if (cssClasses) { + cssClasses = cssClasses.split(/\s+/); + if (cssClasses.length === 1) { + element.classList.add(cssClasses[0]); + } else { + element.classList.add.apply(element.classList, cssClasses); + } } - }); + } else if (element.setAttribute) { + var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ') + .replace(/[\n\t]/g, " "); + + forEach(cssClasses.split(' '), function (cssClass) { + cssClass = trim(cssClass); + if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) { + existingClasses += cssClass + ' '; + } + }); - element.setAttribute('class', trim(existingClasses)); + element.setAttribute('class', trim(existingClasses)); + } } } diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index 56fcd7f5968c..21fc9317652e 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -3532,6 +3532,15 @@ describe("ngAnimate", function() { } node._setAttribute(prop, val); }; + node._classListAdd = node.classList.add; + node.classList.add = function(cssClass) { + if (cssClass === 'trigger-class') { + var propertyKey = ($sniffer.vendorPrefix == 'Webkit' ? '-webkit-' : '') + 'transition-property'; + capturedProperty = element.css(propertyKey); + } + + return node._classListAdd.apply(node.classList, arguments); + }; expect(capturedProperty).toBe('none'); $animate.addClass(element, 'trigger-class'); From bd52525c2ec01726aafa99794a93367bf73f164b Mon Sep 17 00:00:00 2001 From: rodyhaddad Date: Fri, 13 Jun 2014 09:16:41 -0700 Subject: [PATCH 2/2] perf(jqLite): use classList for removing classes if available All elements/browsers that don't have classList will still use the old setAttribute method --- src/jqLite.js | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/jqLite.js b/src/jqLite.js index 77f163ac375b..054eba65c3a4 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -337,14 +337,28 @@ function jqLiteHasClass(element, selector) { } 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) + " ", " ")) - ); - }); + if (cssClasses) { + + // if browser and element support classList api use it + if (element.classList) { + cssClasses = trim(cssClasses); + if (cssClasses) { + cssClasses = cssClasses.split(/\s+/); + if (cssClasses.length === 1) { + element.classList.remove(cssClasses[0]); + } else { + element.classList.remove.apply(element.classList, cssClasses); + } + } + } else if (element.setAttribute) { + forEach(cssClasses.split(' '), function(cssClass) { + element.setAttribute('class', trim( + (" " + (element.getAttribute('class') || '') + " ") + .replace(/[\n\t]/g, " ") + .replace(" " + trim(cssClass) + " ", " ")) + ); + }); + } } }