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

Commit 4995d0e

Browse files
committed
fixup! feat($compile): add support for arbitrary property and event bindings
1 parent 1ba411e commit 4995d0e

File tree

2 files changed

+80
-16
lines changed

2 files changed

+80
-16
lines changed

src/ng/compile.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2336,7 +2336,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
23362336
directiveNormalize(nodeName), 'E', maxPriority, ignoreDirective);
23372337

23382338
// iterate over the attributes
2339-
for (var attr, name, nName, ngAttrName, value, ngPrefixMatch, nAttrs = node.attributes,
2339+
for (var attr, name, nName, value, ngPrefixMatch, nAttrs = node.attributes,
23402340
j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
23412341
var attrStartName = false;
23422342
var attrEndName = false;
@@ -2349,8 +2349,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
23492349
value = attr.value;
23502350

23512351
// support ng-attr-*, ng-prop-* and ng-on-*
2352-
ngAttrName = directiveNormalize(name);
2353-
if ((ngPrefixMatch = ngAttrName.match(NG_PREFIX_BINDING))) {
2352+
nName = directiveNormalize(name);
2353+
if ((ngPrefixMatch = nName.match(NG_PREFIX_BINDING))) {
23542354
isNgAttr = ngPrefixMatch[1] === 'Attr';
23552355
isNgProp = ngPrefixMatch[1] === 'Prop';
23562356
isNgEvent = ngPrefixMatch[1] === 'On';
@@ -2361,27 +2361,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
23612361
});
23622362

23632363
// support *-start / *-end multi element directives
2364-
} else if ((multiElementMatch = ngAttrName.match(MULTI_ELEMENT_DIR_RE)) && directiveIsMultiElement(multiElementMatch[1])) {
2364+
} else if ((multiElementMatch = nName.match(MULTI_ELEMENT_DIR_RE)) && directiveIsMultiElement(multiElementMatch[1])) {
23652365
attrStartName = name;
23662366
attrEndName = name.substr(0, name.length - 5) + 'end';
23672367
name = name.substr(0, name.length - 6);
23682368
}
23692369

2370-
nName = directiveNormalize(name.toLowerCase());
2371-
attrsMap[nName] = name;
2370+
if (isNgProp || isNgEvent) {
2371+
attrs[nName] = value;
2372+
attrsMap[nName] = attr.name;
23722373

2373-
if (isNgProp) {
2374-
attrs[ngAttrName] = value;
2375-
addPropertyDirective(node, directives, ngAttrName, name);
2376-
} else if (isNgEvent) {
2377-
attrs[ngAttrName] = value;
2378-
addEventDirective(directives, ngAttrName, name);
2374+
if (isNgProp) {
2375+
addPropertyDirective(node, directives, nName, name);
2376+
} else {
2377+
addEventDirective(directives, nName, name);
2378+
}
23792379
} else {
2380+
//Update nName for cases where a prefix was removed
2381+
nName = directiveNormalize(name.toLowerCase());
2382+
attrsMap[nName] = name;
2383+
23802384
if (isNgAttr || !attrs.hasOwnProperty(nName)) {
2381-
attrs[nName] = value;
2382-
if (getBooleanAttrName(node, nName)) {
2383-
attrs[nName] = true; // presence means true
2384-
}
2385+
attrs[nName] = value;
2386+
if (getBooleanAttrName(node, nName)) {
2387+
attrs[nName] = true; // presence means true
2388+
}
23852389
}
23862390

23872391
addAttrInterpolateDirective(node, directives, value, nName, isNgAttr);

test/ng/compileSpec.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12026,6 +12026,29 @@ describe('$compile', function() {
1202612026
expect(element.attr('test3')).toBe('Misko');
1202712027
}));
1202812028

12029+
it('should use the non-prefixed name in $attr mappings', function() {
12030+
var attrs;
12031+
module(function() {
12032+
directive('attrExposer', valueFn({
12033+
link: function($scope, $element, $attrs) {
12034+
attrs = $attrs;
12035+
}
12036+
}));
12037+
});
12038+
inject(function($compile, $rootScope) {
12039+
$compile('<div attr-exposer ng-attr-title="12" ng-attr-super-title="34">')($rootScope);
12040+
$rootScope.$apply();
12041+
expect(attrs.title).toBe('12');
12042+
expect(attrs.$attr.title).toBe('title');
12043+
expect(attrs.ngAttrTitle).toBeUndefined();
12044+
expect(attrs.$attr.ngAttrTitle).toBeUndefined();
12045+
expect(attrs.superTitle).toBe('34');
12046+
expect(attrs.$attr.superTitle).toBe('super-title');
12047+
expect(attrs.ngAttrSuperTitle).toBeUndefined();
12048+
expect(attrs.$attr.ngAttrSuperTitle).toBeUndefined();
12049+
});
12050+
})
12051+
1202912052
it('should work with the "href" attribute', inject(function() {
1203012053
$rootScope.value = 'test';
1203112054
element = $compile('<a ng-attr-href="test/{{value}}"></a>')($rootScope);
@@ -12270,6 +12293,43 @@ describe('$compile', function() {
1227012293
expect(element.attr('asdf')).toBe('foo');
1227112294
}));
1227212295

12296+
it('should use the full ng-prop-* attribute name in $attr mappings', function() {
12297+
var attrs;
12298+
module(function() {
12299+
directive('attrExposer', valueFn({
12300+
link: function($scope, $element, $attrs) {
12301+
attrs = $attrs;
12302+
}
12303+
}));
12304+
});
12305+
inject(function($compile, $rootScope) {
12306+
$compile('<div attr-exposer ng-prop-title="42">')($rootScope);
12307+
$rootScope.$apply();
12308+
expect(attrs.title).toBeUndefined();
12309+
expect(attrs.$attr.title).toBeUndefined();
12310+
expect(attrs.ngPropTitle).toBe('42');
12311+
expect(attrs.$attr.ngPropTitle).toBe('ng-prop-title');
12312+
});
12313+
});
12314+
12315+
it('should not conflict with (ng-attr-)attribute mappings of the same name', function() {
12316+
var attrs;
12317+
module(function() {
12318+
directive('attrExposer', valueFn({
12319+
link: function($scope, $element, $attrs) {
12320+
attrs = $attrs;
12321+
}
12322+
}));
12323+
});
12324+
inject(function($compile, $rootScope) {
12325+
$compile('<div attr-exposer ng-prop-title="42" ng-attr-title="foo" title="bar">')($rootScope);
12326+
$rootScope.$apply();
12327+
expect(attrs.title).toBe('foo');
12328+
expect(attrs.$attr.title).toBe('title');
12329+
expect(attrs.$attr.ngPropTitle).toBe("ng-prop-title");
12330+
});
12331+
});
12332+
1227312333
it('should disallow property binding on onclick', inject(function($compile, $rootScope) {
1227412334
// All event prop bindings are disallowed.
1227512335
$rootScope.onClickJs = function() {};

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy