Skip to content

Commit

Permalink
feat(compiler): do not parse xtb messages not needed by angular (angu…
Browse files Browse the repository at this point in the history
  • Loading branch information
vicb authored and juleskremer committed Aug 24, 2017
1 parent ca309ba commit 1113ee0
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
28 changes: 25 additions & 3 deletions modules/@angular/compiler/src/i18n/serializers/xtb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,19 @@ export class Xtb extends Serializer {
// xml nodes to i18n nodes
const i18nNodesByMsgId: {[msgId: string]: i18n.Node[]} = {};
const converter = new XmlToI18n();

// Because we should be able to load xtb files that rely on features not supported by angular,
// we need to delay the conversion of html to i18n nodes so that non angular messages are not
// converted
Object.keys(mlNodesByMsgId).forEach(msgId => {
const {i18nNodes, errors: e} = converter.convert(mlNodesByMsgId[msgId]);
errors.push(...e);
i18nNodesByMsgId[msgId] = i18nNodes;
const valueFn = function() {
const {i18nNodes, errors} = converter.convert(mlNodesByMsgId[msgId]);
if (errors.length) {
throw new Error(`xtb parse errors:\n${errors.join('\n')}`);
}
return i18nNodes;
};
createLazyProperty(i18nNodesByMsgId, msgId, valueFn);
});

if (errors.length) {
Expand All @@ -49,6 +58,19 @@ export class Xtb extends Serializer {
}
}

function createLazyProperty(messages: any, id: string, valueFn: () => any) {
Object.defineProperty(messages, id, {
configurable: true,
enumerable: true,
get: function() {
const value = valueFn();
Object.defineProperty(messages, id, {enumerable: true, value});
return value;
},
set: _ => { throw new Error('Could not overwrite an XTB translation'); },
});
}

// Extract messages as xml nodes from the xtb file
class XtbParser implements ml.Visitor {
private _bundleDepth: number;
Expand Down
21 changes: 21 additions & 0 deletions modules/@angular/compiler/test/i18n/serializers/xtb_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import {escapeRegExp} from '@angular/core/src/facade/lang';

import {serializeNodes} from '../../../src/i18n/digest';
import * as i18n from '../../../src/i18n/i18n_ast';
import {Xtb} from '../../../src/i18n/serializers/xtb';


export function main(): void {
describe('XTB serializer', () => {
const serializer = new Xtb();
Expand Down Expand Up @@ -100,6 +102,25 @@ export function main(): void {
});

describe('errors', () => {
it('should be able to parse non-angular xtb files without error', () => {
const XTB = `<?xml version="1.0" encoding="UTF-8" ?>
<translationbundle>
<translation id="angular">is great</translation>
<translation id="non angular">is <invalid>less</invalid> great</translation>
</translationbundle>`;

// Invalid messages should not cause the parser to throw
let i18nNodesByMsgId: {[id: string]: i18n.Node[]};
expect(() => { i18nNodesByMsgId = serializer.load(XTB, 'url'); }).not.toThrow();

expect(Object.keys(i18nNodesByMsgId).length).toEqual(2);
expect(serializeNodes(i18nNodesByMsgId['angular']).join('')).toEqual('is great');
// Messages that contain unsupported feature should throw on access
expect(() => {
const read = i18nNodesByMsgId['non angular'];
}).toThrowError(/xtb parse errors/);
});

it('should throw on nested <translationbundle>', () => {
const XTB =
'<translationbundle><translationbundle></translationbundle></translationbundle>';
Expand Down

0 comments on commit 1113ee0

Please sign in to comment.