diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/i18n/messageformat.js')
-rw-r--r-- | contexts/data/lib/closure-library/closure/goog/i18n/messageformat.js | 771 |
1 files changed, 0 insertions, 771 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/i18n/messageformat.js b/contexts/data/lib/closure-library/closure/goog/i18n/messageformat.js deleted file mode 100644 index 92367e9..0000000 --- a/contexts/data/lib/closure-library/closure/goog/i18n/messageformat.js +++ /dev/null @@ -1,771 +0,0 @@ -// Copyright 2010 The Closure Library Authors. All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Message/plural format library with locale support. - * - * Message format grammar: - * - * messageFormatPattern := string ( "{" messageFormatElement "}" string )* - * messageFormatElement := argumentIndex [ "," elementFormat ] - * elementFormat := "plural" "," pluralStyle - * | "selectordinal" "," ordinalStyle - * | "select" "," selectStyle - * pluralStyle := pluralFormatPattern - * ordinalStyle := selectFormatPattern - * selectStyle := selectFormatPattern - * pluralFormatPattern := [ "offset" ":" offsetIndex ] pluralForms* - * selectFormatPattern := pluralForms* - * pluralForms := stringKey "{" ( "{" messageFormatElement "}"|string )* "}" - * - * This is a subset of the ICU MessageFormatSyntax: - * http://userguide.icu-project.org/formatparse/messages - * See also http://go/plurals and http://go/ordinals for internal details. - * - * - * Message example: - * - * I see {NUM_PEOPLE, plural, offset:1 - * =0 {no one at all} - * =1 {{WHO}} - * one {{WHO} and one other person} - * other {{WHO} and # other people}} - * in {PLACE}. - * - * Calling format({'NUM_PEOPLE': 2, 'WHO': 'Mark', 'PLACE': 'Athens'}) would - * produce "I see Mark and one other person in Athens." as output. - * - * OR: - * - * {NUM_FLOOR, selectordinal, - * one {Take the elevator to the #st floor.} - * two {Take the elevator to the #nd floor.} - * few {Take the elevator to the #rd floor.} - * other {Take the elevator to the #th floor.}} - * - * Calling format({'NUM_FLOOR': 22}) would produce - * "Take the elevator to the 22nd floor". - * - * See messageformat_test.html for more examples. - */ - -goog.provide('goog.i18n.MessageFormat'); - -goog.require('goog.asserts'); -goog.require('goog.i18n.NumberFormat'); -goog.require('goog.i18n.ordinalRules'); -goog.require('goog.i18n.pluralRules'); - - - -/** - * Constructor of MessageFormat. - * @param {string} pattern The pattern we parse and apply positional parameters - * to. - * @constructor - */ -goog.i18n.MessageFormat = function(pattern) { - /** - * All encountered literals during parse stage. Indices tell us the order of - * replacement. - * @type {!Array.<string>} - * @private - */ - this.literals_ = []; - - /** - * Input pattern gets parsed into objects for faster formatting. - * @type {!Array.<!Object>} - * @private - */ - this.parsedPattern_ = []; - - /** - * Locale aware number formatter. - * @type {goog.i18n.NumberFormat} - * @private - */ - this.numberFormatter_ = new goog.i18n.NumberFormat( - goog.i18n.NumberFormat.Format.DECIMAL); - - this.parsePattern_(pattern); -}; - - -/** - * Literal strings, including '', are replaced with \uFDDF_x_ for - * parsing purposes, and recovered during format phase. - * \uFDDF is a Unicode nonprinting character, not expected to be found in the - * typical message. - * @type {string} - * @private - */ -goog.i18n.MessageFormat.LITERAL_PLACEHOLDER_ = '\uFDDF_'; - - -/** - * Marks a string and block during parsing. - * @enum {number} - * @private - */ -goog.i18n.MessageFormat.Element_ = { - STRING: 0, - BLOCK: 1 -}; - - -/** - * Block type. - * @enum {number} - * @private - */ -goog.i18n.MessageFormat.BlockType_ = { - PLURAL: 0, - ORDINAL: 1, - SELECT: 2, - SIMPLE: 3, - STRING: 4, - UNKNOWN: 5 -}; - - -/** - * Mandatory option in both select and plural form. - * @type {string} - * @private - */ -goog.i18n.MessageFormat.OTHER_ = 'other'; - - -/** - * Regular expression for looking for string literals. - * @type {RegExp} - * @private - */ -goog.i18n.MessageFormat.REGEX_LITERAL_ = new RegExp("'([{}#].*?)'", 'g'); - - -/** - * Regular expression for looking for '' in the message. - * @type {RegExp} - * @private - */ -goog.i18n.MessageFormat.REGEX_DOUBLE_APOSTROPHE_ = new RegExp("''", 'g'); - - -/** - * Formats a message, treating '#' with special meaning representing - * the number (plural_variable - offset). - * @param {!Object} namedParameters Parameters that either - * influence the formatting or are used as actual data. - * I.e. in call to fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'}), - * object {'NUM_PEOPLE': 5, 'NAME': 'Angela'} holds positional parameters. - * 1st parameter could mean 5 people, which could influence plural format, - * and 2nd parameter is just a data to be printed out in proper position. - * @return {string} Formatted message. - */ -goog.i18n.MessageFormat.prototype.format = function(namedParameters) { - return this.format_(namedParameters, false); -}; - - -/** - * Formats a message, treating '#' as literary character. - * @param {!Object} namedParameters Parameters that either - * influence the formatting or are used as actual data. - * I.e. in call to fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'}), - * object {'NUM_PEOPLE': 5, 'NAME': 'Angela'} holds positional parameters. - * 1st parameter could mean 5 people, which could influence plural format, - * and 2nd parameter is just a data to be printed out in proper position. - * @return {string} Formatted message. - */ -goog.i18n.MessageFormat.prototype.formatIgnoringPound = - function(namedParameters) { - return this.format_(namedParameters, true); -}; - - -/** - * Formats a message. - * @param {!Object} namedParameters Parameters that either - * influence the formatting or are used as actual data. - * I.e. in call to fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'}), - * object {'NUM_PEOPLE': 5, 'NAME': 'Angela'} holds positional parameters. - * 1st parameter could mean 5 people, which could influence plural format, - * and 2nd parameter is just a data to be printed out in proper position. - * @param {boolean} ignorePound If true, treat '#' in plural messages as a - * literary character, else treat it as an ICU syntax character, resolving - * to the number (plural_variable - offset). - * @return {string} Formatted message. - * @private - */ -goog.i18n.MessageFormat.prototype.format_ = - function(namedParameters, ignorePound) { - if (this.parsedPattern_.length == 0) { - return ''; - } - - var result = []; - this.formatBlock_(this.parsedPattern_, namedParameters, ignorePound, result); - var message = result.join(''); - - if (!ignorePound) { - goog.asserts.assert(message.search('#') == -1, 'Not all # were replaced.'); - } - - while (this.literals_.length > 0) { - message = message.replace(this.buildPlaceholder_(this.literals_), - this.literals_.pop()); - } - - return message; -}; - - -/** - * Parses generic block and returns a formatted string. - * @param {!Array.<!Object>} parsedPattern Holds parsed tree. - * @param {!Object} namedParameters Parameters that either influence - * the formatting or are used as actual data. - * @param {boolean} ignorePound If true, treat '#' in plural messages as a - * literary character, else treat it as an ICU syntax character, resolving - * to the number (plural_variable - offset). - * @param {!Array.<!string>} result Each formatting stage appends its product - * to the result. - * @private - */ -goog.i18n.MessageFormat.prototype.formatBlock_ = function( - parsedPattern, namedParameters, ignorePound, result) { - for (var i = 0; i < parsedPattern.length; i++) { - switch (parsedPattern[i].type) { - case goog.i18n.MessageFormat.BlockType_.STRING: - result.push(parsedPattern[i].value); - break; - case goog.i18n.MessageFormat.BlockType_.SIMPLE: - var pattern = parsedPattern[i].value; - this.formatSimplePlaceholder_(pattern, namedParameters, result); - break; - case goog.i18n.MessageFormat.BlockType_.SELECT: - var pattern = parsedPattern[i].value; - this.formatSelectBlock_(pattern, namedParameters, ignorePound, result); - break; - case goog.i18n.MessageFormat.BlockType_.PLURAL: - var pattern = parsedPattern[i].value; - this.formatPluralOrdinalBlock_(pattern, - namedParameters, - goog.i18n.pluralRules.select, - ignorePound, - result); - break; - case goog.i18n.MessageFormat.BlockType_.ORDINAL: - var pattern = parsedPattern[i].value; - this.formatPluralOrdinalBlock_(pattern, - namedParameters, - goog.i18n.ordinalRules.select, - ignorePound, - result); - break; - default: - goog.asserts.fail('Unrecognized block type.'); - } - } -}; - - -/** - * Formats simple placeholder. - * @param {!Object} parsedPattern JSON object containing placeholder info. - * @param {!Object} namedParameters Parameters that are used as actual data. - * @param {!Array.<!string>} result Each formatting stage appends its product - * to the result. - * @private - */ -goog.i18n.MessageFormat.prototype.formatSimplePlaceholder_ = function( - parsedPattern, namedParameters, result) { - var value = namedParameters[parsedPattern]; - if (!goog.isDef(value)) { - result.push('Undefined parameter - ' + parsedPattern); - return; - } - - // Don't push the value yet, it may contain any of # { } in it which - // will break formatter. Insert a placeholder and replace at the end. - this.literals_.push(value); - result.push(this.buildPlaceholder_(this.literals_)); -}; - - -/** - * Formats select block. Only one option is selected. - * @param {!Object} parsedPattern JSON object containing select block info. - * @param {!Object} namedParameters Parameters that either influence - * the formatting or are used as actual data. - * @param {boolean} ignorePound If true, treat '#' in plural messages as a - * literary character, else treat it as an ICU syntax character, resolving - * to the number (plural_variable - offset). - * @param {!Array.<!string>} result Each formatting stage appends its product - * to the result. - * @private - */ -goog.i18n.MessageFormat.prototype.formatSelectBlock_ = function( - parsedPattern, namedParameters, ignorePound, result) { - var argumentIndex = parsedPattern.argumentIndex; - if (!goog.isDef(namedParameters[argumentIndex])) { - result.push('Undefined parameter - ' + argumentIndex); - return; - } - - var option = parsedPattern[namedParameters[argumentIndex]]; - if (!goog.isDef(option)) { - option = parsedPattern[goog.i18n.MessageFormat.OTHER_]; - goog.asserts.assertArray( - option, 'Invalid option or missing other option for select block.'); - } - - this.formatBlock_(option, namedParameters, ignorePound, result); -}; - - -/** - * Formats plural or selectordinal block. Only one option is selected and all # - * are replaced. - * @param {!Object} parsedPattern JSON object containing plural block info. - * @param {!Object} namedParameters Parameters that either influence - * the formatting or are used as actual data. - * @param {!function(number):string} pluralSelector A select function from - * goog.i18n.pluralRules or goog.i18n.ordinalRules which determines which - * plural/ordinal form to use based on the input number's cardinality. - * @param {boolean} ignorePound If true, treat '#' in plural messages as a - * literary character, else treat it as an ICU syntax character, resolving - * to the number (plural_variable - offset). - * @param {!Array.<!string>} result Each formatting stage appends its product - * to the result. - * @private - */ -goog.i18n.MessageFormat.prototype.formatPluralOrdinalBlock_ = function( - parsedPattern, namedParameters, pluralSelector, ignorePound, result) { - var argumentIndex = parsedPattern.argumentIndex; - var argumentOffset = parsedPattern.argumentOffset; - var pluralValue = +namedParameters[argumentIndex]; - if (isNaN(pluralValue)) { - // TODO(user): Distinguish between undefined and invalid parameters. - result.push('Undefined or invalid parameter - ' + argumentIndex); - return; - } - var diff = pluralValue - argumentOffset; - - // Check if there is an exact match. - var option = parsedPattern[namedParameters[argumentIndex]]; - if (!goog.isDef(option)) { - goog.asserts.assert(diff >= 0, 'Argument index smaller than offset.'); - - var item = pluralSelector(diff); - goog.asserts.assertString(item, 'Invalid plural key.'); - - option = parsedPattern[item]; - - // If option is not provided fall back to "other". - if (!goog.isDef(option)) { - option = parsedPattern[goog.i18n.MessageFormat.OTHER_]; - } - - goog.asserts.assertArray( - option, 'Invalid option or missing other option for plural block.'); - } - - var pluralResult = []; - this.formatBlock_(option, namedParameters, ignorePound, pluralResult); - var plural = pluralResult.join(''); - goog.asserts.assertString(plural, 'Empty block in plural.'); - if (ignorePound) { - result.push(plural); - } else { - var localeAwareDiff = this.numberFormatter_.format(diff); - result.push(plural.replace(/#/g, localeAwareDiff)); - } -}; - - -/** - * Parses input pattern into an array, for faster reformatting with - * different input parameters. - * Parsing is locale independent. - * @param {string} pattern MessageFormat pattern to parse. - * @private - */ -goog.i18n.MessageFormat.prototype.parsePattern_ = function(pattern) { - if (pattern) { - pattern = this.insertPlaceholders_(pattern); - - this.parsedPattern_ = this.parseBlock_(pattern); - } -}; - - -/** - * Replaces string literals with literal placeholders. - * Literals are string of the form '}...', '{...' and '#...' where ... is - * set of characters not containing ' - * Builds a dictionary so we can recover literals during format phase. - * @param {string} pattern Pattern to clean up. - * @return {string} Pattern with literals replaced with placeholders. - * @private - */ -goog.i18n.MessageFormat.prototype.insertPlaceholders_ = function(pattern) { - var literals = this.literals_; - var buildPlaceholder = goog.bind(this.buildPlaceholder_, this); - - // First replace '' with single quote placeholder since they can be found - // inside other literals. - pattern = pattern.replace( - goog.i18n.MessageFormat.REGEX_DOUBLE_APOSTROPHE_, - function() { - literals.push("'"); - return buildPlaceholder(literals); - }); - - pattern = pattern.replace( - goog.i18n.MessageFormat.REGEX_LITERAL_, - function(match, text) { - literals.push(text); - return buildPlaceholder(literals); - }); - - return pattern; -}; - - -/** - * Breaks pattern into strings and top level {...} blocks. - * @param {string} pattern (sub)Pattern to be broken. - * @return {Array.<Object>} Each item is {type, value}. - * @private - */ -goog.i18n.MessageFormat.prototype.extractParts_ = function(pattern) { - var prevPos = 0; - var inBlock = false; - var braceStack = []; - var results = []; - - var braces = /[{}]/g; - braces.lastIndex = 0; // lastIndex doesn't get set to 0 so we have to. - var match; - - while (match = braces.exec(pattern)) { - var pos = match.index; - if (match[0] == '}') { - var brace = braceStack.pop(); - goog.asserts.assert(goog.isDef(brace) && brace == '{', - 'No matching { for }.'); - - if (braceStack.length == 0) { - // End of the block. - var part = {}; - part.type = goog.i18n.MessageFormat.Element_.BLOCK; - part.value = pattern.substring(prevPos, pos); - results.push(part); - prevPos = pos + 1; - inBlock = false; - } - } else { - if (braceStack.length == 0) { - inBlock = true; - var substring = pattern.substring(prevPos, pos); - if (substring != '') { - results.push({ - type: goog.i18n.MessageFormat.Element_.STRING, - value: substring - }); - } - prevPos = pos + 1; - } - braceStack.push('{'); - } - } - - // Take care of the final string, and check if the braceStack is empty. - goog.asserts.assert(braceStack.length == 0, - 'There are mismatched { or } in the pattern.'); - - var substring = pattern.substring(prevPos); - if (substring != '') { - results.push({ - type: goog.i18n.MessageFormat.Element_.STRING, - value: substring - }); - } - - return results; -}; - - -/** - * A regular expression to parse the plural block, extracting the argument - * index and offset (if any). - * @type {RegExp} - * @private - */ -goog.i18n.MessageFormat.PLURAL_BLOCK_RE_ = - /^\s*(\w+)\s*,\s*plural\s*,(?:\s*offset:(\d+))?/; - - -/** - * A regular expression to parse the ordinal block, extracting the argument - * index. - * @type {RegExp} - * @private - */ -goog.i18n.MessageFormat.ORDINAL_BLOCK_RE_ = /^\s*(\w+)\s*,\s*selectordinal\s*,/; - - -/** - * A regular expression to parse the select block, extracting the argument - * index. - * @type {RegExp} - * @private - */ -goog.i18n.MessageFormat.SELECT_BLOCK_RE_ = /^\s*(\w+)\s*,\s*select\s*,/; - - -/** - * Detects which type of a block is the pattern. - * @param {string} pattern Content of the block. - * @return {goog.i18n.MessageFormat.BlockType_} One of the block types. - * @private - */ -goog.i18n.MessageFormat.prototype.parseBlockType_ = function(pattern) { - if (goog.i18n.MessageFormat.PLURAL_BLOCK_RE_.test(pattern)) { - return goog.i18n.MessageFormat.BlockType_.PLURAL; - } - - if (goog.i18n.MessageFormat.ORDINAL_BLOCK_RE_.test(pattern)) { - return goog.i18n.MessageFormat.BlockType_.ORDINAL; - } - - if (goog.i18n.MessageFormat.SELECT_BLOCK_RE_.test(pattern)) { - return goog.i18n.MessageFormat.BlockType_.SELECT; - } - - if (/^\s*\w+\s*/.test(pattern)) { - return goog.i18n.MessageFormat.BlockType_.SIMPLE; - } - - return goog.i18n.MessageFormat.BlockType_.UNKNOWN; -}; - - -/** - * Parses generic block. - * @param {string} pattern Content of the block to parse. - * @return {!Array.<!Object>} Subblocks marked as strings, select... - * @private - */ -goog.i18n.MessageFormat.prototype.parseBlock_ = function(pattern) { - var result = []; - var parts = this.extractParts_(pattern); - for (var i = 0; i < parts.length; i++) { - var block = {}; - if (goog.i18n.MessageFormat.Element_.STRING == parts[i].type) { - block.type = goog.i18n.MessageFormat.BlockType_.STRING; - block.value = parts[i].value; - } else if (goog.i18n.MessageFormat.Element_.BLOCK == parts[i].type) { - var blockType = this.parseBlockType_(parts[i].value); - - switch (blockType) { - case goog.i18n.MessageFormat.BlockType_.SELECT: - block.type = goog.i18n.MessageFormat.BlockType_.SELECT; - block.value = this.parseSelectBlock_(parts[i].value); - break; - case goog.i18n.MessageFormat.BlockType_.PLURAL: - block.type = goog.i18n.MessageFormat.BlockType_.PLURAL; - block.value = this.parsePluralBlock_(parts[i].value); - break; - case goog.i18n.MessageFormat.BlockType_.ORDINAL: - block.type = goog.i18n.MessageFormat.BlockType_.ORDINAL; - block.value = this.parseOrdinalBlock_(parts[i].value); - break; - case goog.i18n.MessageFormat.BlockType_.SIMPLE: - block.type = goog.i18n.MessageFormat.BlockType_.SIMPLE; - block.value = parts[i].value; - break; - default: - goog.asserts.fail('Unknown block type.'); - } - } else { - goog.asserts.fail('Unknown part of the pattern.'); - } - result.push(block); - } - - return result; -}; - - -/** - * Parses a select type of a block and produces JSON object for it. - * @param {string} pattern Subpattern that needs to be parsed as select pattern. - * @return {Object} Object with select block info. - * @private - */ -goog.i18n.MessageFormat.prototype.parseSelectBlock_ = function(pattern) { - var argumentIndex = ''; - var replaceRegex = goog.i18n.MessageFormat.SELECT_BLOCK_RE_; - pattern = pattern.replace(replaceRegex, function(string, name) { - argumentIndex = name; - return ''; - }); - var result = {}; - result.argumentIndex = argumentIndex; - - var parts = this.extractParts_(pattern); - // Looking for (key block)+ sequence. One of the keys has to be "other". - var pos = 0; - while (pos < parts.length) { - var key = parts[pos].value; - goog.asserts.assertString(key, 'Missing select key element.'); - - pos++; - goog.asserts.assert(pos < parts.length, - 'Missing or invalid select value element.'); - - if (goog.i18n.MessageFormat.Element_.BLOCK == parts[pos].type) { - var value = this.parseBlock_(parts[pos].value); - } else { - goog.asserts.fail('Expected block type.'); - } - result[key.replace(/\s/g, '')] = value; - pos++; - } - - goog.asserts.assertArray(result[goog.i18n.MessageFormat.OTHER_], - 'Missing other key in select statement.'); - return result; -}; - - -/** - * Parses a plural type of a block and produces JSON object for it. - * @param {string} pattern Subpattern that needs to be parsed as plural pattern. - * @return {Object} Object with select block info. - * @private - */ -goog.i18n.MessageFormat.prototype.parsePluralBlock_ = function(pattern) { - var argumentIndex = ''; - var argumentOffset = 0; - var replaceRegex = goog.i18n.MessageFormat.PLURAL_BLOCK_RE_; - pattern = pattern.replace(replaceRegex, function(string, name, offset) { - argumentIndex = name; - if (offset) { - argumentOffset = parseInt(offset, 10); - } - return ''; - }); - - var result = {}; - result.argumentIndex = argumentIndex; - result.argumentOffset = argumentOffset; - - var parts = this.extractParts_(pattern); - // Looking for (key block)+ sequence. - var pos = 0; - while (pos < parts.length) { - var key = parts[pos].value; - goog.asserts.assertString(key, 'Missing plural key element.'); - - pos++; - goog.asserts.assert(pos < parts.length, - 'Missing or invalid plural value element.'); - - if (goog.i18n.MessageFormat.Element_.BLOCK == parts[pos].type) { - var value = this.parseBlock_(parts[pos].value); - } else { - goog.asserts.fail('Expected block type.'); - } - result[key.replace(/\s*(?:=)?(\w+)\s*/, '$1')] = value; - pos++; - } - - goog.asserts.assertArray(result[goog.i18n.MessageFormat.OTHER_], - 'Missing other key in plural statement.'); - - return result; -}; - - -/** - * Parses an ordinal type of a block and produces JSON object for it. - * For example the input string: - * '{FOO, selectordinal, one {Message A}other {Message B}}' - * Should result in the output object: - * { - * argumentIndex: 'FOO', - * argumentOffest: 0, - * one: [ { type: 4, value: 'Message A' } ], - * other: [ { type: 4, value: 'Message B' } ] - * } - * @param {string} pattern Subpattern that needs to be parsed as plural pattern. - * @return {Object} Object with select block info. - * @private - */ -goog.i18n.MessageFormat.prototype.parseOrdinalBlock_ = function(pattern) { - var argumentIndex = ''; - var replaceRegex = goog.i18n.MessageFormat.ORDINAL_BLOCK_RE_; - pattern = pattern.replace(replaceRegex, function(string, name) { - argumentIndex = name; - return ''; - }); - - var result = {}; - result.argumentIndex = argumentIndex; - result.argumentOffset = 0; - - var parts = this.extractParts_(pattern); - // Looking for (key block)+ sequence. - var pos = 0; - while (pos < parts.length) { - var key = parts[pos].value; - goog.asserts.assertString(key, 'Missing ordinal key element.'); - - pos++; - goog.asserts.assert(pos < parts.length, - 'Missing or invalid ordinal value element.'); - - if (goog.i18n.MessageFormat.Element_.BLOCK == parts[pos].type) { - var value = this.parseBlock_(parts[pos].value); - } else { - goog.asserts.fail('Expected block type.'); - } - result[key.replace(/\s*(?:=)?(\w+)\s*/, '$1')] = value; - pos++; - } - - goog.asserts.assertArray(result[goog.i18n.MessageFormat.OTHER_], - 'Missing other key in selectordinal statement.'); - - return result; -}; - - -/** - * Builds a placeholder from the last index of the array. - * @param {!Array} literals All literals encountered during parse. - * @return {string} \uFDDF_ + last index + _. - * @private - */ -goog.i18n.MessageFormat.prototype.buildPlaceholder_ = function(literals) { - goog.asserts.assert(literals.length > 0, 'Literal array is empty.'); - - var index = (literals.length - 1).toString(10); - return goog.i18n.MessageFormat.LITERAL_PLACEHOLDER_ + index + '_'; -}; |