diff --git a/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts b/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts
index 425e263584..152ea3521f 100644
--- a/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts
+++ b/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts
@@ -16,6 +16,27 @@ describe('template i18n extraction output', () => {
it('should extract i18n messages', () => {
const EXPECTED = ` xml version="1.0" encoding="UTF-8" ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]>
translate me
`;
diff --git a/modules/@angular/compiler/src/i18n/serializers/xmb.ts b/modules/@angular/compiler/src/i18n/serializers/xmb.ts
index edefda47d0..05976e7577 100644
--- a/modules/@angular/compiler/src/i18n/serializers/xmb.ts
+++ b/modules/@angular/compiler/src/i18n/serializers/xmb.ts
@@ -18,11 +18,29 @@ const _MESSAGE_TAG = 'msg';
const _PLACEHOLDER_TAG = 'ph';
const _EXEMPLE_TAG = 'ex';
+const _DOCTYPE = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
export class Xmb implements Serializer {
- // TODO(vicb): DOCTYPE
write(messageMap: {[k: string]: i18n.Message}): string {
const visitor = new _Visitor();
- const declaration = new xml.Declaration({version: '1.0', encoding: 'UTF-8'});
let rootNode = new xml.Tag(_MESSAGES_TAG);
rootNode.children.push(new xml.Text('\n'));
@@ -44,7 +62,9 @@ export class Xmb implements Serializer {
});
return xml.serialize([
- declaration,
+ new xml.Declaration({version: '1.0', encoding: 'UTF-8'}),
+ new xml.Text('\n'),
+ new xml.Doctype(_MESSAGES_TAG, _DOCTYPE),
new xml.Text('\n'),
rootNode,
]);
diff --git a/modules/@angular/compiler/src/i18n/serializers/xml_helper.ts b/modules/@angular/compiler/src/i18n/serializers/xml_helper.ts
index e088fb5f8b..3adf5b7f36 100644
--- a/modules/@angular/compiler/src/i18n/serializers/xml_helper.ts
+++ b/modules/@angular/compiler/src/i18n/serializers/xml_helper.ts
@@ -10,6 +10,7 @@ export interface IVisitor {
visitTag(tag: Tag): any;
visitText(text: Text): any;
visitDeclaration(decl: Declaration): any;
+ visitDoctype(doctype: Doctype): any;
}
class _Visitor implements IVisitor {
@@ -36,6 +37,10 @@ class _Visitor implements IVisitor {
.join(' ');
return strAttrs.length > 0 ? ' ' + strAttrs : '';
}
+
+ visitDoctype(doctype: Doctype): any {
+ return ``;
+ }
}
const _visitor = new _Visitor();
@@ -58,6 +63,12 @@ export class Declaration implements Node {
visit(visitor: IVisitor): any { return visitor.visitDeclaration(this); }
}
+export class Doctype implements Node {
+ constructor(public rootTag: string, public dtd: string){};
+
+ visit(visitor: IVisitor): any { return visitor.visitDoctype(this); }
+}
+
export class Tag implements Node {
public attrs: {[k: string]: string} = {};
diff --git a/modules/@angular/compiler/test/i18n/serializers/xmb_spec.ts b/modules/@angular/compiler/test/i18n/serializers/xmb_spec.ts
index fbfb4a36a5..9c35f75fea 100644
--- a/modules/@angular/compiler/test/i18n/serializers/xmb_spec.ts
+++ b/modules/@angular/compiler/test/i18n/serializers/xmb_spec.ts
@@ -23,6 +23,27 @@ export function main(): void {
{ count, plural, =0 { { sex, gender, other {
deeply nested
}} }}`;
const XMB = ` xml version="1.0" encoding="UTF-8" ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]>
translatable element <b>with placeholders</b>
{ count, plural, =0 {<p>test</p>}}
diff --git a/modules/@angular/compiler/test/i18n/serializers/xtb_spec.ts b/modules/@angular/compiler/test/i18n/serializers/xtb_spec.ts
index 434d48692b..372d22b345 100644
--- a/modules/@angular/compiler/test/i18n/serializers/xtb_spec.ts
+++ b/modules/@angular/compiler/test/i18n/serializers/xtb_spec.ts
@@ -32,9 +32,26 @@ export function main(): void {
describe('load', () => {
+ it('should load XTB files with a doctype', () => {
+ const XTB = `
+
+
+
+
+
+
+
+
+]>
+
+ bar
+`;
+
+ expect(loadAsText(XTB, {})).toEqual({foo: 'bar'});
+ });
+
it('should load XTB files without placeholders', () => {
- const XTB = `
-
+ const XTB = `
bar
`;
@@ -43,8 +60,7 @@ export function main(): void {
});
it('should load XTB files with placeholders', () => {
- const XTB = `
-
+ const XTB = `
bar
`;
@@ -53,8 +69,7 @@ export function main(): void {
});
it('should load complex XTB files', () => {
- const XTB = `
- xml version="1.0" encoding="UTF-8" ?>
+ const XTB = ` xml version="1.0" encoding="UTF-8" ?>
translatable element <b>with placeholders</b>
{ count, plural, =0 {<p>test</p>}}
@@ -98,8 +113,7 @@ export function main(): void {
});
it('should throw on nested ', () => {
- const XTB = `
-
+ const XTB = `
@@ -112,8 +126,7 @@ export function main(): void {
});
it('should throw when a has no id attribute', () => {
- const XTB = `
-
+ const XTB = `
`;
@@ -123,8 +136,7 @@ export function main(): void {
});
it('should throw when a placeholder has no name attribute', () => {
- const XTB = `
-
+ const XTB = `
`;
@@ -134,8 +146,7 @@ export function main(): void {
});
it('should throw when a placeholder is not present in the source message', () => {
- const XTB = `
-
+ const XTB = `
`;
@@ -146,8 +157,7 @@ export function main(): void {
});
it('should throw when the translation results in invalid html', () => {
- const XTB = `
-
+ const XTB = `
foobar
`;