Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

fix(compile): properly handle false value for boolean attrs with jQuery #16779

Merged
merged 1 commit into from Dec 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/ng/compile.js
Expand Up @@ -2231,7 +2231,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
this.$$element.removeAttr(attrName);
} else {
if (SIMPLE_ATTR_NAME.test(attrName)) {
this.$$element.attr(attrName, value);
// jQuery skips special boolean attrs treatment in XML nodes for
// historical reasons and hence AngularJS cannot freely call
// `.attr(attrName, false) with such attributes. To avoid issues
// in XHTML, call `removeAttr` in such cases instead.
// See https://github.com/jquery/jquery/issues/4249
if (booleanKey && value === false) {
this.$$element.removeAttr(attrName);
} else {
this.$$element.attr(attrName, value);
}
} else {
setSpecialAttr(this.$$element[0], attrName, value);
}
Expand Down
34 changes: 34 additions & 0 deletions test/ng/compileSpec.js
Expand Up @@ -4222,6 +4222,40 @@ describe('$compile', function() {
expect(element.attr('ng-my-attr')).toBeUndefined();
});

it('should set the value to lowercased keys for boolean attrs', function() {
attr.$set('disabled', 'value');
expect(element.attr('disabled')).toEqual('disabled');

element.removeAttr('disabled');

attr.$set('dISaBlEd', 'VaLuE');
expect(element.attr('disabled')).toEqual('disabled');
});

it('should call removeAttr for boolean attrs when value is `false`', function() {
attr.$set('disabled', 'value');

spyOn(jqLite.prototype, 'attr').and.callThrough();
spyOn(jqLite.prototype, 'removeAttr').and.callThrough();

attr.$set('disabled', false);

expect(element.attr).not.toHaveBeenCalled();
expect(element.removeAttr).toHaveBeenCalledWith('disabled');
expect(element.attr('disabled')).toEqual(undefined);

attr.$set('disabled', 'value');

element.attr.calls.reset();
element.removeAttr.calls.reset();

attr.$set('dISaBlEd', false);

expect(element.attr).not.toHaveBeenCalled();
expect(element.removeAttr).toHaveBeenCalledWith('disabled');
expect(element.attr('disabled')).toEqual(undefined);
});


it('should not set DOM element attr if writeAttr false', function() {
attr.$set('test', 'value', false);
Expand Down