From 89b8b436f4ee33dd4397ab69b802206de665faeb Mon Sep 17 00:00:00 2001 From: Chirayu Krishnappa Date: Tue, 14 Apr 2015 12:17:37 -0700 Subject: [PATCH] fix(ngMessageFormat): minified symbol and nested required expression Add an E2E test that works against the minified module to test that the minified build works correctly. Fix a bug where mustHaveExpression was passed through to submessages unchanged. Use of the messageFormat syntax automatically means that you are using an expression. Therefore, submessages should not be required to also have messages. This closes #11414 --- src/ngMessageFormat/messageFormatCommon.js | 8 +-- src/ngMessageFormat/messageFormatParser.js | 2 +- src/ngMessageFormat/messageFormatService.js | 54 ++++++++++++++++++++- test/ngMessageFormat/messageFormatSpec.js | 8 +-- 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/ngMessageFormat/messageFormatCommon.js b/src/ngMessageFormat/messageFormatCommon.js index b8870ed4fe57..7831c82b1924 100644 --- a/src/ngMessageFormat/messageFormatCommon.js +++ b/src/ngMessageFormat/messageFormatCommon.js @@ -5,11 +5,11 @@ // This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using // constructs incompatible with that mode. -var $interpolateMinErr = angular['$interpolateMinErr']; +var $interpolateMinErr = window['angular']['$interpolateMinErr']; -var noop = angular['noop'], - isFunction = angular['isFunction'], - toJson = angular['toJson']; +var noop = window['angular']['noop'], + isFunction = window['angular']['isFunction'], + toJson = window['angular']['toJson']; function stringify(value) { if (value == null /* null/undefined */) { return ''; } diff --git a/src/ngMessageFormat/messageFormatParser.js b/src/ngMessageFormat/messageFormatParser.js index 66b94bcba40b..75327ffedc80 100644 --- a/src/ngMessageFormat/messageFormatParser.js +++ b/src/ngMessageFormat/messageFormatParser.js @@ -334,7 +334,7 @@ MessageFormatParser.prototype.ruleInInterpolationOrMessageText = function ruleIn this.ruleStack.push(this.ruleEndMustacheInInterpolationOrMessage); this.rule = this.ruleEnteredMustache; } else if (token == "}") { - this.choices[this.choiceKey] = this.interpolationParts.toParsedFn(this.mustHaveExpression, this.text); + this.choices[this.choiceKey] = this.interpolationParts.toParsedFn(/*mustHaveExpression=*/false, this.text); this.rule = this.ruleChoiceKeyword; } else if (token == "#") { this.interpolationParts.addExpressionFn(this.expressionMinusOffsetFn); diff --git a/src/ngMessageFormat/messageFormatService.js b/src/ngMessageFormat/messageFormatService.js index 21c8b2488a77..75148be123f3 100644 --- a/src/ngMessageFormat/messageFormatService.js +++ b/src/ngMessageFormat/messageFormatService.js @@ -17,6 +17,58 @@ * Angular internal service to recognize MessageFormat extensions in interpolation expressions. * For more information, see: * https://docs.google.com/a/google.com/document/d/1pbtW2yvtmFBikfRrJd8VAsabiFkKezmYZ_PbgdjQOVU/edit + * + * ## Example + * + * + * + *
+ *
+ * {{recipients.length, plural, offset:1 + * =0 {{{sender.name}} gave no gifts (\#=#)} + * =1 {{{sender.name}} gave one gift to {{recipients[0].name}} (\#=#)} + * one {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\#=#)} + * other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\#=#)} + * }} + *
+ *
+ * + * + * function Person(name, gender) { + * this.name = name; + * this.gender = gender; + * } + * + * var alice = new Person("Alice", "female"), + * bob = new Person("Bob", "male"), + * charlie = new Person("Charlie", "male"), + * harry = new Person("Harry Potter", "male"); + * + * angular.module('msgFmtExample', ['ngMessageFormat']) + * .controller('AppController', ['$scope', function($scope) { + * $scope.recipients = [alice, bob, charlie]; + * $scope.sender = harry; + * $scope.decreaseRecipients = function() { + * --$scope.recipients.length; + * }; + * }]); + * + * + * + * describe('MessageFormat plural', function() { + * it('should pluralize initial values', function() { + * var messageElem = element(by.id('message')), decreaseRecipientsBtn = element(by.id('decreaseRecipients')); + * expect(messageElem.getText()).toEqual('Harry Potter gave Alice and 2 other people a gift (#=2)'); + * decreaseRecipientsBtn.click(); + * expect(messageElem.getText()).toEqual('Harry Potter gave Alice and one other person a gift (#=1)'); + * decreaseRecipientsBtn.click(); + * expect(messageElem.getText()).toEqual('Harry Potter gave one gift to Alice (#=0)'); + * decreaseRecipientsBtn.click(); + * expect(messageElem.getText()).toEqual('Harry Potter gave no gifts (#=-1)'); + * }); + * }); + * + *
*/ var $$MessageFormatFactory = ['$parse', '$locale', '$sce', '$exceptionHandler', function $$messageFormat( $parse, $locale, $sce, $exceptionHandler) { @@ -61,7 +113,7 @@ var $$interpolateDecorator = ['$$messageFormat', '$delegate', function $$interpo * @name ngMessageFormat * @description */ -var module = angular['module']('ngMessageFormat', ['ng']); +var module = window['angular']['module']('ngMessageFormat', ['ng']); module['factory']('$$messageFormat', $$MessageFormatFactory); module['config'](['$provide', function($provide) { $provide['decorator']('$interpolate', $$interpolateDecorator); diff --git a/test/ngMessageFormat/messageFormatSpec.js b/test/ngMessageFormat/messageFormatSpec.js index fefe3b1d05da..86bbc824ad7f 100644 --- a/test/ngMessageFormat/messageFormatSpec.js +++ b/test/ngMessageFormat/messageFormatSpec.js @@ -125,7 +125,7 @@ describe('$$ngMessageFormat', function() { " one {YOU SHOULD NEVER SEE THIS MESSAGE}\n" + " other {You gave some people gifts}\n" + "}}"; - var parsedFn = $interpolate(text); + var parsedFn = $interpolate(text, /*mustHaveExpression=*/true); $rootScope.recipients.length=2; expect(parsedFn($rootScope)).toEqual("You gave some people gifts"); @@ -146,7 +146,7 @@ describe('$$ngMessageFormat', function() { " one {YOU SHOULD NEVER SEE THIS MESSAGE}\n" + " other {{{sender.name}} gave them a gift}\n" + "}}"; - var parsedFn = $interpolate(text); + var parsedFn = $interpolate(text, /*mustHaveExpression=*/true); $rootScope.recipients.length=2; expect(parsedFn($rootScope)).toEqual("Harry Potter gave them a gift"); @@ -167,7 +167,7 @@ describe('$$ngMessageFormat', function() { " one {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\\#=#)}\n" + " other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\\#=#)}\n" + "}}"; - var parsedFn = $interpolate(text); + var parsedFn = $interpolate(text, /*mustHaveExpression=*/true); $rootScope.recipients.length=3; // "#" should get replaced with the value of "recipients.length - offset" @@ -196,7 +196,7 @@ describe('$$ngMessageFormat', function() { " }\n" + " other {You gave {{recipients.length}} people gifts. -{{sender.name}}}\n" + "}}"; - var parsedFn = $interpolate(text); + var parsedFn = $interpolate(text, /*mustHaveExpression=*/true); var result = parsedFn($rootScope); expect(result).toEqual("You gave 3 people gifts. -Harry Potter"); });