Skip to content

Commit

Permalink
fix(jqLite): use get/setAttribute so that jqLite works on SVG nodes
Browse files Browse the repository at this point in the history
jqLite previously used `elt.className` to add and remove classes from a DOM Node, but
because the className property is not writable on SVG elements, it doesn't work with
them. This patch replaces accesses to `className` with `get/setAttribute`.

`classList` was also considered as a solution, but because only IE10+ supports it, we
have to wait. :'(

Closes angular#3858
  • Loading branch information
btford committed Sep 24, 2013
1 parent 5eb1fb6 commit 3a515dc
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 9 deletions.
18 changes: 12 additions & 6 deletions src/jqLite.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,29 +279,35 @@ function JQLiteData(element, key, value) {
}

function JQLiteHasClass(element, selector) {
return ((" " + element.className + " ").replace(/[\n\t]/g, " ").
return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " ").
indexOf( " " + selector + " " ) > -1);
}

function JQLiteRemoveClass(element, cssClasses) {
if (cssClasses) {
forEach(cssClasses.split(' '), function(cssClass) {
element.className = trim(
(" " + element.className + " ")
element.setAttribute('class', trim(
(" " + (element.getAttribute('class') || '') + " ")
.replace(/[\n\t]/g, " ")
.replace(" " + trim(cssClass) + " ", " ")
.replace(" " + trim(cssClass) + " ", " "))
);
});
}
}

function JQLiteAddClass(element, cssClasses) {
if (cssClasses) {
var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
.replace(/[\n\t]/g, " ");

forEach(cssClasses.split(' '), function(cssClass) {
if (!JQLiteHasClass(element, cssClass)) {
element.className = trim(element.className + ' ' + trim(cssClass));
cssClass = trim(cssClass);
if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
existingClasses += cssClass + ' ';
}
});

element.setAttribute('class', trim(existingClasses));
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/ng/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ var $AnimateProvider = ['$provide', function($provide) {
className = isString(className) ?
className :
isArray(className) ? className.join(' ') : '';
element.addClass(className);
forEach(element, function (element) {
JQLiteAddClass(element, className);
});
done && $timeout(done, 0, false);
},

Expand All @@ -177,7 +179,9 @@ var $AnimateProvider = ['$provide', function($provide) {
className = isString(className) ?
className :
isArray(className) ? className.join(' ') : '';
element.removeClass(className);
forEach(element, function (element) {
JQLiteRemoveClass(element, className);
});
done && $timeout(done, 0, false);
},

Expand Down
9 changes: 8 additions & 1 deletion test/helpers/matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ beforeEach(function() {
}

function isNgElementHidden(element) {
return angular.element(element).hasClass('ng-hide');
// we need to check element.getAttribute for SVG nodes
var hidden = true;
forEach(angular.element(element), function (element) {
if ((' ' +(element.getAttribute('class') || '') + ' ').indexOf(' ng-hide ') === -1) {
hidden = false;
}
});
return hidden;
};

this.addMatchers({
Expand Down
12 changes: 12 additions & 0 deletions test/ng/animateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ describe("$animate", function() {
expect(element).toBeHidden();
}));

it("should add and remove classes on SVG elements", inject(function($animate) {
if (!window.SVGElement) return;
var svg = jqLite('<svg><rect></rect></svg>');
var rect = svg.children();
$animate.enabled(false);
expect(rect).toBeShown();
$animate.addClass(rect, 'ng-hide');
expect(rect).toBeHidden();
$animate.removeClass(rect, 'ng-hide');
expect(rect).not.toBeHidden();
}));

it("should throw error on wrong selector", function() {
module(function($animateProvider) {
expect(function() {
Expand Down

0 comments on commit 3a515dc

Please sign in to comment.