X Tutup
Skip to content

Commit 6cc9464

Browse files
committed
Fixed negation grouping bug
Make 'this' of validation be scope
1 parent b2a8a08 commit 6cc9464

File tree

10 files changed

+180
-167
lines changed

10 files changed

+180
-167
lines changed

angular-minified.js

Lines changed: 87 additions & 87 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

angular.js

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,7 +1635,7 @@ var angularFilterGoogleChartApi;
16351635

16361636
foreach({
16371637
'currency': function(amount){
1638-
jQuery(this.element).toggleClass('ng-format-negative', amount < 0);
1638+
jQuery(this.$element).toggleClass('ng-format-negative', amount < 0);
16391639
return '$' + angularFilter['number'].apply(this, [amount, 2]);
16401640
},
16411641

@@ -1671,7 +1671,7 @@ foreach({
16711671
},
16721672

16731673
'json': function(object) {
1674-
jQuery(this.element).addClass("ng-monospace");
1674+
jQuery(this.$element).addClass("ng-monospace");
16751675
return toJson(object, true);
16761676
},
16771677

@@ -2488,7 +2488,16 @@ Parser.prototype = {
24882488
for ( var i = 0; i < argsFn.length; i++) {
24892489
args.push(argsFn[i](self));
24902490
}
2491-
return fn.apply(self, args);
2491+
var pipeThis = function(){
2492+
var _this = this;
2493+
foreach(self, function(v, k) {
2494+
if (k.charAt(0) == '$') {
2495+
_this[k] = v;
2496+
}
2497+
});
2498+
};
2499+
pipeThis.prototype = self.self;
2500+
return fn.apply(new pipeThis(), args);
24922501
};
24932502
return function(){
24942503
return fnInvoke;
@@ -2541,48 +2550,30 @@ Parser.prototype = {
25412550
},
25422551

25432552
logicalAND: function(){
2544-
var left = this.negated();
2553+
var left = this.equality();
25452554
var token;
2546-
while(true) {
2547-
if ((token = this.expect('&&'))) {
2548-
left = this._binary(left, token.fn, this.negated());
2549-
} else {
2550-
return left;
2551-
}
2552-
}
2553-
},
2554-
2555-
negated: function(){
2556-
var token;
2557-
if (token = this.expect('!')) {
2558-
return this._unary(token.fn, this.assignment());
2559-
} else {
2560-
return this.equality();
2555+
if ((token = this.expect('&&'))) {
2556+
left = this._binary(left, token.fn, this.logicalAND());
25612557
}
2558+
return left;
25622559
},
25632560

25642561
equality: function(){
25652562
var left = this.relational();
25662563
var token;
2567-
while(true) {
2568-
if ((token = this.expect('==','!='))) {
2569-
left = this._binary(left, token.fn, this.relational());
2570-
} else {
2571-
return left;
2572-
}
2564+
if ((token = this.expect('==','!='))) {
2565+
left = this._binary(left, token.fn, this.equality());
25732566
}
2567+
return left;
25742568
},
25752569

25762570
relational: function(){
25772571
var left = this.additive();
25782572
var token;
2579-
while(true) {
2580-
if ((token = this.expect('<', '>', '<=', '>='))) {
2581-
left = this._binary(left, token.fn, this.additive());
2582-
} else {
2583-
return left;
2584-
}
2573+
if (token = this.expect('<', '>', '<=', '>=')) {
2574+
left = this._binary(left, token.fn, this.relational());
25852575
}
2576+
return left;
25862577
},
25872578

25882579
additive: function(){
@@ -2608,7 +2599,9 @@ Parser.prototype = {
26082599
if (this.expect('+')) {
26092600
return this.primary();
26102601
} else if (token = this.expect('-')) {
2611-
return this._binary(Parser.ZERO, token.fn, this.multiplicative());
2602+
return this._binary(Parser.ZERO, token.fn, this.unary());
2603+
} else if (token = this.expect('!')) {
2604+
return this._unary(token.fn, this.unary());
26122605
} else {
26132606
return this.primary();
26142607
}
@@ -3001,13 +2994,13 @@ Scope.prototype = {
30012994
}
30022995
},
30032996

3004-
validate: function(expressionText, value) {
2997+
validate: function(expressionText, value, element) {
30052998
var expression = Scope.expressionCache[expressionText];
30062999
if (!expression) {
30073000
expression = new Parser(expressionText).validator();
30083001
Scope.expressionCache[expressionText] = expression;
30093002
}
3010-
var self = {scope:this};
3003+
var self = {scope:this, self:this.state, '$element':element};
30113004
return expression(self)(self, value);
30123005
},
30133006

@@ -3485,7 +3478,7 @@ TextController.prototype = {
34853478
}
34863479
var errorText = isValidationError ? "Required Value" : null;
34873480
if (!isValidationError && this.validator && value) {
3488-
errorText = scope.validate(this.validator, value);
3481+
errorText = scope.validate(this.validator, value, view);
34893482
isValidationError = !!errorText;
34903483
}
34913484
if (this.lastErrorText !== errorText) {
@@ -3731,7 +3724,7 @@ BindUpdater.prototype = {
37313724
var part = parts[i];
37323725
var binding = Binder.binding(part);
37333726
if (binding) {
3734-
scope.evalWidget(this, binding, {element:this.view}, function(value){
3727+
scope.evalWidget(this, binding, {$element:this.view}, function(value){
37353728
html.push(BindUpdater.toText(value));
37363729
}, function(e, text){
37373730
setHtml(this.view, text);
@@ -3771,7 +3764,7 @@ BindAttrUpdater.prototype = {
37713764
var binding = Binder.binding(attributeTemplate[i]);
37723765
if (binding) {
37733766
try {
3774-
var value = scope.eval(binding, {element:jNode[0], attrName:attrName});
3767+
var value = scope.eval(binding, {$element:jNode[0], attrName:attrName});
37753768
if (value && (value.constructor !== array || value.length !== 0))
37763769
attrValues.push(value);
37773770
} catch (e) {

src/Filters.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ var angularFilterGoogleChartApi;
2424

2525
foreach({
2626
'currency': function(amount){
27-
jQuery(this.element).toggleClass('ng-format-negative', amount < 0);
27+
jQuery(this.$element).toggleClass('ng-format-negative', amount < 0);
2828
return '$' + angularFilter['number'].apply(this, [amount, 2]);
2929
},
3030

@@ -60,7 +60,7 @@ foreach({
6060
},
6161

6262
'json': function(object) {
63-
jQuery(this.element).addClass("ng-monospace");
63+
jQuery(this.$element).addClass("ng-monospace");
6464
return toJson(object, true);
6565
},
6666

src/Parser.js

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,16 @@ Parser.prototype = {
369369
for ( var i = 0; i < argsFn.length; i++) {
370370
args.push(argsFn[i](self));
371371
}
372-
return fn.apply(self, args);
372+
var pipeThis = function(){
373+
var _this = this;
374+
foreach(self, function(v, k) {
375+
if (k.charAt(0) == '$') {
376+
_this[k] = v;
377+
}
378+
});
379+
};
380+
pipeThis.prototype = self.self;
381+
return fn.apply(new pipeThis(), args);
373382
};
374383
return function(){
375384
return fnInvoke;
@@ -422,48 +431,30 @@ Parser.prototype = {
422431
},
423432

424433
logicalAND: function(){
425-
var left = this.negated();
434+
var left = this.equality();
426435
var token;
427-
while(true) {
428-
if ((token = this.expect('&&'))) {
429-
left = this._binary(left, token.fn, this.negated());
430-
} else {
431-
return left;
432-
}
433-
}
434-
},
435-
436-
negated: function(){
437-
var token;
438-
if (token = this.expect('!')) {
439-
return this._unary(token.fn, this.assignment());
440-
} else {
441-
return this.equality();
436+
if ((token = this.expect('&&'))) {
437+
left = this._binary(left, token.fn, this.logicalAND());
442438
}
439+
return left;
443440
},
444441

445442
equality: function(){
446443
var left = this.relational();
447444
var token;
448-
while(true) {
449-
if ((token = this.expect('==','!='))) {
450-
left = this._binary(left, token.fn, this.relational());
451-
} else {
452-
return left;
453-
}
445+
if ((token = this.expect('==','!='))) {
446+
left = this._binary(left, token.fn, this.equality());
454447
}
448+
return left;
455449
},
456450

457451
relational: function(){
458452
var left = this.additive();
459453
var token;
460-
while(true) {
461-
if ((token = this.expect('<', '>', '<=', '>='))) {
462-
left = this._binary(left, token.fn, this.additive());
463-
} else {
464-
return left;
465-
}
454+
if (token = this.expect('<', '>', '<=', '>=')) {
455+
left = this._binary(left, token.fn, this.relational());
466456
}
457+
return left;
467458
},
468459

469460
additive: function(){
@@ -489,7 +480,9 @@ Parser.prototype = {
489480
if (this.expect('+')) {
490481
return this.primary();
491482
} else if (token = this.expect('-')) {
492-
return this._binary(Parser.ZERO, token.fn, this.multiplicative());
483+
return this._binary(Parser.ZERO, token.fn, this.unary());
484+
} else if (token = this.expect('!')) {
485+
return this._unary(token.fn, this.unary());
493486
} else {
494487
return this.primary();
495488
}

src/Scope.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,13 @@ Scope.prototype = {
138138
}
139139
},
140140

141-
validate: function(expressionText, value) {
141+
validate: function(expressionText, value, element) {
142142
var expression = Scope.expressionCache[expressionText];
143143
if (!expression) {
144144
expression = new Parser(expressionText).validator();
145145
Scope.expressionCache[expressionText] = expression;
146146
}
147-
var self = {scope:this};
147+
var self = {scope:this, self:this.state, '$element':element};
148148
return expression(self)(self, value);
149149
},
150150

src/Widgets.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ TextController.prototype = {
234234
}
235235
var errorText = isValidationError ? "Required Value" : null;
236236
if (!isValidationError && this.validator && value) {
237-
errorText = scope.validate(this.validator, value);
237+
errorText = scope.validate(this.validator, value, view);
238238
isValidationError = !!errorText;
239239
}
240240
if (this.lastErrorText !== errorText) {
@@ -480,7 +480,7 @@ BindUpdater.prototype = {
480480
var part = parts[i];
481481
var binding = Binder.binding(part);
482482
if (binding) {
483-
scope.evalWidget(this, binding, {element:this.view}, function(value){
483+
scope.evalWidget(this, binding, {$element:this.view}, function(value){
484484
html.push(BindUpdater.toText(value));
485485
}, function(e, text){
486486
setHtml(this.view, text);
@@ -520,7 +520,7 @@ BindAttrUpdater.prototype = {
520520
var binding = Binder.binding(attributeTemplate[i]);
521521
if (binding) {
522522
try {
523-
var value = scope.eval(binding, {element:jNode[0], attrName:attrName});
523+
var value = scope.eval(binding, {$element:jNode[0], attrName:attrName});
524524
if (value && (value.constructor !== array || value.length !== 0))
525525
attrValues.push(value);
526526
} catch (e) {

test/FiltersTest.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FiltersTest = TestCase('FiltersTest');
22

33
FiltersTest.prototype.testCurrency = function(){
44
var html = $('<span/>');
5-
var context = {element:html[0]};
5+
var context = {$element:html[0]};
66
var currency = bind(context, angular.filter.currency);
77

88
assertEquals(currency(0), '$0.00');
@@ -17,10 +17,10 @@ FiltersTest.prototype.testFilterThisIsContext = function(){
1717
expectAsserts(2);
1818
var scope = new Scope();
1919
Scope.expressionCache = {};
20-
var context = {element:123};
20+
var context = {$element:123, self:{name:'misko'}};
2121
angular.filter.testFn = function () {
22-
assertEquals('Context not equal', this, context);
23-
assertEquals('scope not equal', this.scope, scope);
22+
assertEquals('Context not equal', 123, this.$element);
23+
assertEquals('scope not equal', 'misko', this.name);
2424
};
2525
scope.eval("0|testFn", context);
2626
delete angular.filter['testFn'];

test/ParserTest.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ ParserTest.prototype.testComparison = function(){
160160
assertEquals(scope.eval("1<=1"), true);
161161
assertEquals(scope.eval("1>2"), 1>2);
162162
assertEquals(scope.eval("2>=1"), 2>=1);
163+
164+
assertEquals(true==2<3, scope.eval("true==2<3"));
165+
163166
};
164167

165168
ParserTest.prototype.testLogical = function(){
@@ -467,3 +470,10 @@ ParserTest.prototype.testDoubleNegationBug = function (){
467470
assertEquals('a', scope.eval('{true:"a", false:"b"}[!!true]'));
468471
};
469472

473+
ParserTest.prototype.testNegationBug = function () {
474+
var scope = new Scope();
475+
assertEquals(!false || true, scope.eval("!false || true"));
476+
assertEquals(!11 == 10, scope.eval("!11 == 10"));
477+
assertEquals(12/6/2, scope.eval("12/6/2"));
478+
};
479+

test/ScopeTest.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ ScopeTest.prototype.testGlobalFunctionAccess =function(){
8383
ScopeTest.prototype.testValidationEval = function(){
8484
expectAsserts(4);
8585
var scope = new Scope();
86+
scope.set("name", "misko");
8687
angular.validator.testValidator = function(value, expect){
87-
assertEquals(scope, this.scope);
88+
assertEquals("misko", this.name);
8889
return value == expect ? null : "Error text";
8990
};
9091

test/ValidatorsTest.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
ValidatorTest = TestCase('ValidatorTest');
22

3+
ValidatorTest.prototype.testItShouldHaveThisSet = function() {
4+
expectAsserts(5);
5+
var self;
6+
angular.validator.myValidator = function(first, last){
7+
assertEquals('misko', first);
8+
assertEquals('hevery', last);
9+
self = this;
10+
};
11+
var c = compile('<input name="name" ng-validate="myValidator:\'hevery\'"/>');
12+
c.scope.set('name', 'misko');
13+
c.scope.set('state', 'abc');
14+
c.binder.updateView();
15+
assertEquals('abc', self.state);
16+
assertEquals('misko', self.name);
17+
assertEquals('name', self.$element.name);
18+
};
19+
320
ValidatorTest.prototype.testRegexp = function() {
421
assertEquals(angular.validator.regexp("abc", /x/, "E1"), "E1");
522
assertEquals(angular.validator.regexp("abc", '/x/'),
@@ -64,4 +81,3 @@ ValidatorTest.prototype.testJson = function() {
6481
assertNotNull(angular.validator.json("''X"));
6582
assertNull(angular.validator.json("{}"));
6683
};
67-

0 commit comments

Comments
 (0)
X Tutup