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

Commit e75fbc4

Browse files
frederikprijckgkalpak
authored andcommitted
fix($compile): allow the usage of "$" in isolate scope property alias
Previously, when using an alias for an isolate scope or `bindings` property (e.g. `alias: '<attrName'` instead of `attrName: '<'`), a `$compile:iscp` error was thrown if the attribute name contained a "$". This commit removes the error by changing the regex to allow "$" characters in the attribute name when using a property alias. Fixes: #15586 Closes #15594
1 parent 5e28b6e commit e75fbc4

File tree

2 files changed

+55
-14
lines changed

2 files changed

+55
-14
lines changed

src/ng/compile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
983983
var bindingCache = createMap();
984984

985985
function parseIsolateBindings(scope, directiveName, isController) {
986-
var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*(\w*)\s*$/;
986+
var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*([\w$]*)\s*$/;
987987

988988
var bindings = createMap();
989989

test/ng/compileSpec.js

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4701,21 +4701,28 @@ describe('$compile', function() {
47014701
scope: {
47024702
attr: '@',
47034703
attrAlias: '@attr',
4704+
$attrAlias: '@$attr$',
47044705
ref: '=',
47054706
refAlias: '= ref',
4707+
$refAlias: '= $ref$',
47064708
reference: '=',
47074709
optref: '=?',
47084710
optrefAlias: '=? optref',
4711+
$optrefAlias: '=? $optref$',
47094712
optreference: '=?',
47104713
colref: '=*',
47114714
colrefAlias: '=* colref',
4715+
$colrefAlias: '=* $colref$',
47124716
owRef: '<',
47134717
owRefAlias: '< owRef',
4718+
$owRefAlias: '< $owRef$',
47144719
owOptref: '<?',
47154720
owOptrefAlias: '<? owOptref',
4721+
$owOptrefAlias: '<? $owOptref$',
47164722
expr: '&',
47174723
optExpr: '&?',
47184724
exprAlias: '&expr',
4725+
$exprAlias: '&$expr$',
47194726
constructor: '&?'
47204727
},
47214728
link: function(scope) {
@@ -5134,68 +5141,77 @@ describe('$compile', function() {
51345141

51355142
describe('attribute', function() {
51365143
it('should copy simple attribute', inject(function() {
5137-
compile('<div><span my-component attr="some text">');
5144+
compile('<div><span my-component attr="some text" $attr$="some other text">');
51385145

51395146
expect(componentScope.attr).toEqual('some text');
51405147
expect(componentScope.attrAlias).toEqual('some text');
5148+
expect(componentScope.$attrAlias).toEqual('some other text');
51415149
expect(componentScope.attrAlias).toEqual(componentScope.attr);
51425150
}));
51435151

5152+
expect(componentScope.$attrAlias).toEqual(' some other text ');
51445153
it('should set up the interpolation before it reaches the link function', inject(function() {
51455154
$rootScope.name = 'misko';
5146-
compile('<div><span my-component attr="hello {{name}}">');
5155+
compile('<div><span my-component attr="hello {{name}}" $attr$="hi {{name}}">');
51475156
expect(componentScope.attr).toEqual('hello misko');
51485157
expect(componentScope.attrAlias).toEqual('hello misko');
5158+
expect(componentScope.$attrAlias).toEqual('hi misko');
51495159
}));
51505160

51515161
it('should update when interpolated attribute updates', inject(function() {
5152-
compile('<div><span my-component attr="hello {{name}}">');
5162+
compile('<div><span my-component attr="hello {{name}}" $attr$="hi {{name}}">');
51535163

51545164
$rootScope.name = 'igor';
51555165
$rootScope.$apply();
51565166

51575167
expect(componentScope.attr).toEqual('hello igor');
51585168
expect(componentScope.attrAlias).toEqual('hello igor');
5169+
expect(componentScope.$attrAlias).toEqual('hi igor');
51595170
}));
51605171
});
51615172

51625173

51635174
describe('object reference', function() {
51645175
it('should update local when origin changes', inject(function() {
5165-
compile('<div><span my-component ref="name">');
5176+
compile('<div><span my-component ref="name" $ref$="name">');
51665177
expect(componentScope.ref).toBeUndefined();
51675178
expect(componentScope.refAlias).toBe(componentScope.ref);
5179+
expect(componentScope.$refAlias).toBe(componentScope.ref);
51685180

51695181
$rootScope.name = 'misko';
51705182
$rootScope.$apply();
51715183

51725184
expect($rootScope.name).toBe('misko');
51735185
expect(componentScope.ref).toBe('misko');
51745186
expect(componentScope.refAlias).toBe('misko');
5187+
expect(componentScope.$refAlias).toBe('misko');
51755188

51765189
$rootScope.name = {};
51775190
$rootScope.$apply();
51785191
expect(componentScope.ref).toBe($rootScope.name);
51795192
expect(componentScope.refAlias).toBe($rootScope.name);
5193+
expect(componentScope.$refAlias).toBe($rootScope.name);
51805194
}));
51815195

51825196

51835197
it('should update local when both change', inject(function() {
5184-
compile('<div><span my-component ref="name">');
5198+
compile('<div><span my-component ref="name" $ref$="name">');
51855199
$rootScope.name = {mark:123};
51865200
componentScope.ref = 'misko';
51875201

51885202
$rootScope.$apply();
51895203
expect($rootScope.name).toEqual({mark:123});
51905204
expect(componentScope.ref).toBe($rootScope.name);
51915205
expect(componentScope.refAlias).toBe($rootScope.name);
5206+
expect(componentScope.$refAlias).toBe($rootScope.name);
51925207

51935208
$rootScope.name = 'igor';
51945209
componentScope.ref = {};
51955210
$rootScope.$apply();
51965211
expect($rootScope.name).toEqual('igor');
51975212
expect(componentScope.ref).toBe($rootScope.name);
51985213
expect(componentScope.refAlias).toBe($rootScope.name);
5214+
expect(componentScope.$refAlias).toBe($rootScope.name);
51995215
}));
52005216

52015217
it('should not break if local and origin both change to the same value', inject(function() {
@@ -5325,26 +5341,30 @@ describe('$compile', function() {
53255341

53265342
describe('optional object reference', function() {
53275343
it('should update local when origin changes', inject(function() {
5328-
compile('<div><span my-component optref="name">');
5344+
compile('<div><span my-component optref="name" $optref$="name">');
53295345
expect(componentScope.optRef).toBeUndefined();
53305346
expect(componentScope.optRefAlias).toBe(componentScope.optRef);
5347+
expect(componentScope.$optRefAlias).toBe(componentScope.optRef);
53315348

53325349
$rootScope.name = 'misko';
53335350
$rootScope.$apply();
53345351
expect(componentScope.optref).toBe($rootScope.name);
53355352
expect(componentScope.optrefAlias).toBe($rootScope.name);
5353+
expect(componentScope.$optrefAlias).toBe($rootScope.name);
53365354

53375355
$rootScope.name = {};
53385356
$rootScope.$apply();
53395357
expect(componentScope.optref).toBe($rootScope.name);
53405358
expect(componentScope.optrefAlias).toBe($rootScope.name);
5359+
expect(componentScope.$optrefAlias).toBe($rootScope.name);
53415360
}));
53425361

53435362
it('should not throw exception when reference does not exist', inject(function() {
53445363
compile('<div><span my-component>');
53455364

53465365
expect(componentScope.optref).toBeUndefined();
53475366
expect(componentScope.optrefAlias).toBeUndefined();
5367+
expect(componentScope.$optrefAlias).toBeUndefined();
53485368
expect(componentScope.optreference).toBeUndefined();
53495369
}));
53505370
});
@@ -5362,16 +5382,18 @@ describe('$compile', function() {
53625382
$rootScope.query = '';
53635383
$rootScope.$apply();
53645384

5365-
compile('<div><span my-component colref="collection | filter:query">');
5385+
compile('<div><span my-component colref="collection | filter:query" $colref$="collection | filter:query">');
53665386

53675387
expect(componentScope.colref).toEqual($rootScope.collection);
53685388
expect(componentScope.colrefAlias).toEqual(componentScope.colref);
5389+
expect(componentScope.$colrefAlias).toEqual(componentScope.colref);
53695390

53705391
$rootScope.query = 'Gab';
53715392
$rootScope.$apply();
53725393

53735394
expect(componentScope.colref).toEqual([$rootScope.collection[0]]);
53745395
expect(componentScope.colrefAlias).toEqual([$rootScope.collection[0]]);
5396+
expect(componentScope.$colrefAlias).toEqual([$rootScope.collection[0]]);
53755397
}));
53765398

53775399
it('should update origin scope when isolate scope changes', inject(function() {
@@ -5399,23 +5421,26 @@ describe('$compile', function() {
53995421

54005422
describe('one-way binding', function() {
54015423
it('should update isolate when the identity of origin changes', inject(function() {
5402-
compile('<div><span my-component ow-ref="obj">');
5424+
compile('<div><span my-component ow-ref="obj" $ow-ref$="obj">');
54035425

54045426
expect(componentScope.owRef).toBeUndefined();
54055427
expect(componentScope.owRefAlias).toBe(componentScope.owRef);
5428+
expect(componentScope.$owRefAlias).toBe(componentScope.owRef);
54065429

54075430
$rootScope.obj = {value: 'initial'};
54085431
$rootScope.$apply();
54095432

54105433
expect($rootScope.obj).toEqual({value: 'initial'});
54115434
expect(componentScope.owRef).toEqual({value: 'initial'});
54125435
expect(componentScope.owRefAlias).toBe(componentScope.owRef);
5436+
expect(componentScope.$owRefAlias).toBe(componentScope.owRef);
54135437

54145438
// This changes in both scopes because of reference
54155439
$rootScope.obj.value = 'origin1';
54165440
$rootScope.$apply();
54175441
expect(componentScope.owRef.value).toBe('origin1');
54185442
expect(componentScope.owRefAlias.value).toBe('origin1');
5443+
expect(componentScope.$owRefAlias.value).toBe('origin1');
54195444

54205445
componentScope.owRef = {value: 'isolate1'};
54215446
componentScope.$apply();
@@ -5426,17 +5451,19 @@ describe('$compile', function() {
54265451
$rootScope.$apply();
54275452
expect(componentScope.owRef.value).toBe('isolate1');
54285453
expect(componentScope.owRefAlias.value).toBe('origin2');
5454+
expect(componentScope.$owRefAlias.value).toBe('origin2');
54295455

54305456
// Change does propagate because object identity changes
54315457
$rootScope.obj = {value: 'origin3'};
54325458
$rootScope.$apply();
54335459
expect(componentScope.owRef.value).toBe('origin3');
54345460
expect(componentScope.owRef).toBe($rootScope.obj);
54355461
expect(componentScope.owRefAlias).toBe($rootScope.obj);
5462+
expect(componentScope.$owRefAlias).toBe($rootScope.obj);
54365463
}));
54375464

54385465
it('should update isolate when both change', inject(function() {
5439-
compile('<div><span my-component ow-ref="name">');
5466+
compile('<div><span my-component ow-ref="name" $ow-ref$="name">');
54405467

54415468
$rootScope.name = {mark:123};
54425469
componentScope.owRef = 'misko';
@@ -5445,13 +5472,15 @@ describe('$compile', function() {
54455472
expect($rootScope.name).toEqual({mark:123});
54465473
expect(componentScope.owRef).toBe($rootScope.name);
54475474
expect(componentScope.owRefAlias).toBe($rootScope.name);
5475+
expect(componentScope.$owRefAlias).toBe($rootScope.name);
54485476

54495477
$rootScope.name = 'igor';
54505478
componentScope.owRef = {};
54515479
$rootScope.$apply();
54525480
expect($rootScope.name).toEqual('igor');
54535481
expect(componentScope.owRef).toBe($rootScope.name);
54545482
expect(componentScope.owRefAlias).toBe($rootScope.name);
5483+
expect(componentScope.$owRefAlias).toBe($rootScope.name);
54555484
}));
54565485

54575486
describe('initialization', function() {
@@ -5648,17 +5677,19 @@ describe('$compile', function() {
56485677

56495678
it('should not update origin when identity of isolate changes', inject(function() {
56505679
$rootScope.name = {mark:123};
5651-
compile('<div><span my-component ow-ref="name">');
5680+
compile('<div><span my-component ow-ref="name" $ow-ref$="name">');
56525681

56535682
expect($rootScope.name).toEqual({mark:123});
56545683
expect(componentScope.owRef).toBe($rootScope.name);
56555684
expect(componentScope.owRefAlias).toBe($rootScope.name);
5685+
expect(componentScope.$owRefAlias).toBe($rootScope.name);
56565686

56575687
componentScope.owRef = 'martin';
56585688
$rootScope.$apply();
56595689
expect($rootScope.name).toEqual({mark: 123});
56605690
expect(componentScope.owRef).toBe('martin');
56615691
expect(componentScope.owRefAlias).toEqual({mark: 123});
5692+
expect(componentScope.$owRefAlias).toEqual({mark: 123});
56625693
}));
56635694

56645695

@@ -5805,45 +5836,51 @@ describe('$compile', function() {
58055836

58065837
describe('optional one-way binding', function() {
58075838
it('should update local when origin changes', inject(function() {
5808-
compile('<div><span my-component ow-optref="name">');
5839+
compile('<div><span my-component ow-optref="name" $ow-optref$="name">');
58095840

58105841
expect(componentScope.owOptref).toBeUndefined();
58115842
expect(componentScope.owOptrefAlias).toBe(componentScope.owOptref);
5843+
expect(componentScope.$owOptrefAlias).toBe(componentScope.owOptref);
58125844

58135845
$rootScope.name = 'misko';
58145846
$rootScope.$apply();
58155847
expect(componentScope.owOptref).toBe($rootScope.name);
58165848
expect(componentScope.owOptrefAlias).toBe($rootScope.name);
5849+
expect(componentScope.$owOptrefAlias).toBe($rootScope.name);
58175850

58185851
$rootScope.name = {};
58195852
$rootScope.$apply();
58205853
expect(componentScope.owOptref).toBe($rootScope.name);
58215854
expect(componentScope.owOptrefAlias).toBe($rootScope.name);
5855+
expect(componentScope.$owOptrefAlias).toBe($rootScope.name);
58225856
}));
58235857

58245858
it('should not throw exception when reference does not exist', inject(function() {
58255859
compile('<div><span my-component>');
58265860

58275861
expect(componentScope.owOptref).toBeUndefined();
58285862
expect(componentScope.owOptrefAlias).toBeUndefined();
5863+
expect(componentScope.$owOptrefAlias).toBeUndefined();
58295864
}));
58305865
});
58315866
});
58325867
});
58335868

58345869
describe('executable expression', function() {
58355870
it('should allow expression execution with locals', inject(function() {
5836-
compile('<div><span my-component expr="count = count + offset">');
5871+
compile('<div><span my-component expr="count = count + offset" $expr$="count = count + offset">');
58375872
$rootScope.count = 2;
58385873

58395874
expect(typeof componentScope.expr).toBe('function');
58405875
expect(typeof componentScope.exprAlias).toBe('function');
5876+
expect(typeof componentScope.$exprAlias).toBe('function');
58415877

58425878
expect(componentScope.expr({offset: 1})).toEqual(3);
58435879
expect($rootScope.count).toEqual(3);
58445880

58455881
expect(componentScope.exprAlias({offset: 10})).toEqual(13);
5846-
expect($rootScope.count).toEqual(13);
5882+
expect(componentScope.$exprAlias({offset: 10})).toEqual(23);
5883+
expect($rootScope.count).toEqual(23);
58475884
}));
58485885
});
58495886

@@ -5861,17 +5898,21 @@ describe('$compile', function() {
58615898
expect(componentScope.$$isolateBindings.attr.mode).toBe('@');
58625899
expect(componentScope.$$isolateBindings.attr.attrName).toBe('attr');
58635900
expect(componentScope.$$isolateBindings.attrAlias.attrName).toBe('attr');
5901+
expect(componentScope.$$isolateBindings.$attrAlias.attrName).toBe('$attr$');
58645902
expect(componentScope.$$isolateBindings.ref.mode).toBe('=');
58655903
expect(componentScope.$$isolateBindings.ref.attrName).toBe('ref');
58665904
expect(componentScope.$$isolateBindings.refAlias.attrName).toBe('ref');
5905+
expect(componentScope.$$isolateBindings.$refAlias.attrName).toBe('$ref$');
58675906
expect(componentScope.$$isolateBindings.reference.mode).toBe('=');
58685907
expect(componentScope.$$isolateBindings.reference.attrName).toBe('reference');
58695908
expect(componentScope.$$isolateBindings.owRef.mode).toBe('<');
58705909
expect(componentScope.$$isolateBindings.owRef.attrName).toBe('owRef');
58715910
expect(componentScope.$$isolateBindings.owRefAlias.attrName).toBe('owRef');
5911+
expect(componentScope.$$isolateBindings.$owRefAlias.attrName).toBe('$owRef$');
58725912
expect(componentScope.$$isolateBindings.expr.mode).toBe('&');
58735913
expect(componentScope.$$isolateBindings.expr.attrName).toBe('expr');
58745914
expect(componentScope.$$isolateBindings.exprAlias.attrName).toBe('expr');
5915+
expect(componentScope.$$isolateBindings.$exprAlias.attrName).toBe('$expr$');
58755916

58765917
var firstComponentScope = componentScope,
58775918
first$$isolateBindings = componentScope.$$isolateBindings;

0 commit comments

Comments
 (0)