X Tutup
Skip to content

Commit 930f587

Browse files
author
Robert Messerle
committed
Revert "feat(i18n): add support for custom placeholder names"
This reverts commit 2abb414.
1 parent 2b34c88 commit 930f587

File tree

6 files changed

+16
-133
lines changed

6 files changed

+16
-133
lines changed

modules/angular2/src/compiler/expression_parser/parser.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ import {
4949
var _implicitReceiver = new ImplicitReceiver();
5050
// TODO(tbosch): Cannot make this const/final right now because of the transpiler...
5151
var INTERPOLATION_REGEXP = /\{\{([\s\S]*?)\}\}/g;
52-
var COMMENT_REGEX = /\/\//g;
5352

5453
class ParseException extends BaseException {
5554
constructor(message: string, input: string, errLocation: string, ctxLocation?: any) {
@@ -68,7 +67,7 @@ export class Parser {
6867

6968
parseAction(input: string, location: any): ASTWithSource {
7069
this._checkNoInterpolation(input, location);
71-
var tokens = this._lexer.tokenize(this._stripComments(input));
70+
var tokens = this._lexer.tokenize(input);
7271
var ast = new _ParseAST(input, location, tokens, true).parseChain();
7372
return new ASTWithSource(ast, input, location);
7473
}
@@ -97,7 +96,7 @@ export class Parser {
9796
}
9897

9998
this._checkNoInterpolation(input, location);
100-
var tokens = this._lexer.tokenize(this._stripComments(input));
99+
var tokens = this._lexer.tokenize(input);
101100
return new _ParseAST(input, location, tokens, false).parseChain();
102101
}
103102

@@ -123,7 +122,7 @@ export class Parser {
123122
let expressions = [];
124123

125124
for (let i = 0; i < split.expressions.length; ++i) {
126-
var tokens = this._lexer.tokenize(this._stripComments(split.expressions[i]));
125+
var tokens = this._lexer.tokenize(split.expressions[i]);
127126
var ast = new _ParseAST(input, location, tokens, false).parseChain();
128127
expressions.push(ast);
129128
}
@@ -159,10 +158,6 @@ export class Parser {
159158
return new ASTWithSource(new LiteralPrimitive(input), input, location);
160159
}
161160

162-
private _stripComments(input: string): string {
163-
return StringWrapper.split(input, COMMENT_REGEX)[0].trim();
164-
}
165-
166161
private _checkNoInterpolation(input: string, location: any): void {
167162
var parts = StringWrapper.split(input, INTERPOLATION_REGEXP);
168163
if (parts.length > 1) {

modules/angular2/src/i18n/i18n_html_parser.ts

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,14 @@ import {
2222
partition,
2323
Part,
2424
stringifyNodes,
25-
meaning,
26-
getPhNameFromBinding,
27-
dedupePhName
25+
meaning
2826
} from './shared';
2927

3028
const _I18N_ATTR = "i18n";
3129
const _PLACEHOLDER_ELEMENT = "ph";
3230
const _NAME_ATTR = "name";
3331
const _I18N_ATTR_PREFIX = "i18n-";
34-
let _PLACEHOLDER_EXPANDED_REGEXP = RegExpWrapper.create(`\\<ph(\\s)+name=("(\\w)+")\\>\\<\\/ph\\>`);
32+
let _PLACEHOLDER_EXPANDED_REGEXP = RegExpWrapper.create(`\\<ph(\\s)+name=("(\\d)+")\\>\\<\\/ph\\>`);
3533

3634
/**
3735
* Creates an i18n-ed version of the parsed template.
@@ -315,31 +313,19 @@ export class I18nHtmlParser implements HtmlParser {
315313

316314
private _replacePlaceholdersWithExpressions(message: string, exps: string[],
317315
sourceSpan: ParseSourceSpan): string {
318-
let expMap = this._buildExprMap(exps);
319316
return RegExpWrapper.replaceAll(_PLACEHOLDER_EXPANDED_REGEXP, message, (match) => {
320317
let nameWithQuotes = match[2];
321318
let name = nameWithQuotes.substring(1, nameWithQuotes.length - 1);
322-
return this._convertIntoExpression(name, expMap, sourceSpan);
319+
let index = NumberWrapper.parseInt(name, 10);
320+
return this._convertIntoExpression(index, exps, sourceSpan);
323321
});
324322
}
325323

326-
private _buildExprMap(exps: string[]): Map<string, string> {
327-
let expMap = new Map<string, string>();
328-
let usedNames = new Map<string, number>();
329-
330-
for (var i = 0; i < exps.length; i++) {
331-
let phName = getPhNameFromBinding(exps[i], i);
332-
expMap.set(dedupePhName(usedNames, phName), exps[i]);
333-
}
334-
return expMap;
335-
}
336-
337-
private _convertIntoExpression(name: string, expMap: Map<string, string>,
338-
sourceSpan: ParseSourceSpan) {
339-
if (expMap.has(name)) {
340-
return `{{${expMap.get(name)}}}`;
324+
private _convertIntoExpression(index: number, exps: string[], sourceSpan: ParseSourceSpan) {
325+
if (index >= 0 && index < exps.length) {
326+
return `{{${exps[index]}}}`;
341327
} else {
342-
throw new I18nError(sourceSpan, `Invalid interpolation name '${name}'`);
328+
throw new I18nError(sourceSpan, `Invalid interpolation index '${index}'`);
343329
}
344330
}
345331
}
@@ -361,4 +347,4 @@ class _CreateNodeMapping implements HtmlAstVisitor {
361347
}
362348

363349
visitComment(ast: HtmlCommentAst, context: any): any { return ""; }
364-
}
350+
}

modules/angular2/src/i18n/shared.ts

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ import {
88
HtmlCommentAst,
99
htmlVisitAll
1010
} from 'angular2/src/compiler/html_ast';
11-
import {isPresent, isBlank, StringWrapper} from 'angular2/src/facade/lang';
11+
import {isPresent, isBlank} from 'angular2/src/facade/lang';
1212
import {Message} from './message';
1313
import {Parser} from 'angular2/src/compiler/expression_parser/parser';
1414

1515
export const I18N_ATTR = "i18n";
1616
export const I18N_ATTR_PREFIX = "i18n-";
17-
var CUSTOM_PH_EXP = /\/\/[\s\S]*i18n[\s\S]*\([\s\S]*ph[\s\S]*=[\s\S]*"([\s\S]*?)"[\s\S]*\)/g;
1817

1918
/**
2019
* An i18n error.
@@ -114,15 +113,12 @@ export function removeInterpolation(value: string, source: ParseSourceSpan,
114113
parser: Parser): string {
115114
try {
116115
let parsed = parser.splitInterpolation(value, source.toString());
117-
let usedNames = new Map<string, number>();
118116
if (isPresent(parsed)) {
119117
let res = "";
120118
for (let i = 0; i < parsed.strings.length; ++i) {
121119
res += parsed.strings[i];
122120
if (i != parsed.strings.length - 1) {
123-
let customPhName = getPhNameFromBinding(parsed.expressions[i], i);
124-
customPhName = dedupePhName(usedNames, customPhName);
125-
res += `<ph name="${customPhName}"/>`;
121+
res += `<ph name="${i}"/>`;
126122
}
127123
}
128124
return res;
@@ -134,22 +130,6 @@ export function removeInterpolation(value: string, source: ParseSourceSpan,
134130
}
135131
}
136132

137-
export function getPhNameFromBinding(input: string, index: number): string {
138-
let customPhMatch = StringWrapper.split(input, CUSTOM_PH_EXP);
139-
return customPhMatch.length > 1 ? customPhMatch[1] : `${index}`;
140-
}
141-
142-
export function dedupePhName(usedNames: Map<string, number>, name: string): string {
143-
let duplicateNameCount = usedNames.get(name);
144-
if (isPresent(duplicateNameCount)) {
145-
usedNames.set(name, duplicateNameCount + 1);
146-
return `${name}_${duplicateNameCount}`;
147-
} else {
148-
usedNames.set(name, 1);
149-
return name;
150-
}
151-
}
152-
153133
export function stringifyNodes(nodes: HtmlAst[], parser: Parser): string {
154134
let visitor = new _StringifyVisitor(parser);
155135
return htmlVisitAll(visitor, nodes).join("");

modules/angular2/test/compiler/expression_parser/parser_spec.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,6 @@ export function main() {
103103

104104
it('should parse grouped expressions', () => { checkAction("(1 + 2) * 3", "1 + 2 * 3"); });
105105

106-
it('should ignore comments in expressions', () => { checkAction('a //comment', 'a'); });
107-
108106
it('should parse an empty string', () => { checkAction(''); });
109107

110108
describe("literals", () => {
@@ -271,8 +269,6 @@ export function main() {
271269
});
272270

273271
it('should parse conditional expression', () => { checkBinding('a < b ? a : b'); });
274-
275-
it('should ignore comments in bindings', () => { checkBinding('a //comment', 'a'); });
276272
});
277273

278274
describe('parseTemplateBindings', () => {
@@ -428,9 +424,6 @@ export function main() {
428424
it('should parse expression with newline characters', () => {
429425
checkInterpolation(`{{ 'foo' +\n 'bar' +\r 'baz' }}`, `{{ "foo" + "bar" + "baz" }}`);
430426
});
431-
432-
it('should ignore comments in interpolation expressions',
433-
() => { checkInterpolation('{{a //comment}}', '{{ a }}'); });
434427
});
435428

436429
describe("parseSimpleBinding", () => {

modules/angular2/test/i18n/i18n_html_parser_spec.ts

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -76,36 +76,6 @@ export function main() {
7676
.toEqual([[HtmlElementAst, 'div', 0], [HtmlAttrAst, 'value', '{{b}} or {{a}}']]);
7777
});
7878

79-
it('should handle interpolation with custom placeholder names', () => {
80-
let translations: {[key: string]: string} = {};
81-
translations[id(new Message('<ph name="FIRST"/> and <ph name="SECOND"/>', null, null))] =
82-
'<ph name="SECOND"/> or <ph name="FIRST"/>';
83-
84-
expect(
85-
humanizeDom(parse(
86-
`<div value='{{a //i18n(ph="FIRST")}} and {{b //i18n(ph="SECOND")}}' i18n-value></div>`,
87-
translations)))
88-
.toEqual([
89-
[HtmlElementAst, 'div', 0],
90-
[HtmlAttrAst, 'value', '{{b //i18n(ph="SECOND")}} or {{a //i18n(ph="FIRST")}}']
91-
]);
92-
});
93-
94-
it('should handle interpolation with duplicate placeholder names', () => {
95-
let translations: {[key: string]: string} = {};
96-
translations[id(new Message('<ph name="FIRST"/> and <ph name="FIRST_1"/>', null, null))] =
97-
'<ph name="FIRST_1"/> or <ph name="FIRST"/>';
98-
99-
expect(
100-
humanizeDom(parse(
101-
`<div value='{{a //i18n(ph="FIRST")}} and {{b //i18n(ph="FIRST")}}' i18n-value></div>`,
102-
translations)))
103-
.toEqual([
104-
[HtmlElementAst, 'div', 0],
105-
[HtmlAttrAst, 'value', '{{b //i18n(ph="FIRST")}} or {{a //i18n(ph="FIRST")}}']
106-
]);
107-
});
108-
10979
it("should handle nested html", () => {
11080
let translations: {[key: string]: string} = {};
11181
translations[id(new Message('<ph name="e0">a</ph><ph name="e2">b</ph>', null, null))] =
@@ -228,7 +198,7 @@ export function main() {
228198

229199
expect(
230200
humanizeErrors(parse("<div value='hi {{a}}' i18n-value></div>", translations).errors))
231-
.toEqual(["Invalid interpolation name '99'"]);
201+
.toEqual(["Invalid interpolation index '99'"]);
232202
});
233203

234204
});
@@ -237,4 +207,4 @@ export function main() {
237207

238208
function humanizeErrors(errors: ParseError[]): string[] {
239209
return errors.map(error => error.msg);
240-
}
210+
}

modules/angular2/test/i18n/message_extractor_spec.ts

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -93,47 +93,6 @@ export function main() {
9393
.toEqual([new Message('Hi <ph name="0"/> and <ph name="1"/>', null, null)]);
9494
});
9595

96-
it('should replace interpolation with named placeholders if provided (text nodes)', () => {
97-
let res = extractor.extract(`
98-
<div i18n>Hi {{one //i18n(ph="FIRST")}} and {{two //i18n(ph="SECOND")}}</div>`,
99-
'someurl');
100-
expect(res.messages)
101-
.toEqual([
102-
new Message('<ph name="t0">Hi <ph name="FIRST"/> and <ph name="SECOND"/></ph>', null,
103-
null)
104-
]);
105-
});
106-
107-
it('should replace interpolation with named placeholders if provided (attributes)', () => {
108-
let res = extractor.extract(`
109-
<div title='Hi {{one //i18n(ph="FIRST")}} and {{two //i18n(ph="SECOND")}}'
110-
i18n-title></div>`,
111-
'someurl');
112-
expect(res.messages)
113-
.toEqual([new Message('Hi <ph name="FIRST"/> and <ph name="SECOND"/>', null, null)]);
114-
});
115-
116-
it('should match named placeholders with extra spacing', () => {
117-
let res = extractor.extract(`
118-
<div title='Hi {{one // i18n ( ph = "FIRST" )}} and {{two // i18n ( ph = "SECOND" )}}'
119-
i18n-title></div>`,
120-
'someurl');
121-
expect(res.messages)
122-
.toEqual([new Message('Hi <ph name="FIRST"/> and <ph name="SECOND"/>', null, null)]);
123-
});
124-
125-
it('should suffix duplicate placeholder names with numbers', () => {
126-
let res = extractor.extract(`
127-
<div title='Hi {{one //i18n(ph="FIRST")}} and {{two //i18n(ph="FIRST")}} and {{three //i18n(ph="FIRST")}}'
128-
i18n-title></div>`,
129-
'someurl');
130-
expect(res.messages)
131-
.toEqual([
132-
new Message('Hi <ph name="FIRST"/> and <ph name="FIRST_1"/> and <ph name="FIRST_2"/>',
133-
null, null)
134-
]);
135-
});
136-
13796
it("should handle html content", () => {
13897
let res = extractor.extract(
13998
'<div i18n><div attr="value">zero<div>one</div></div><div>two</div></div>', "someurl");

0 commit comments

Comments
 (0)
X Tutup