Skip to content

Commit c5869f5

Browse files
TinyManvikerman
authored andcommitted
feat(@angular-devkit/build-angular): set document locale when using i18nLocale
Fixes #8102
1 parent 5a2a055 commit c5869f5

File tree

7 files changed

+58
-0
lines changed

7 files changed

+58
-0
lines changed

packages/angular_devkit/build_angular/src/angular-cli-files/plugins/index-html-webpack-plugin.ts

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export interface IndexHtmlWebpackPluginOptions {
2727
moduleEntrypoints: string[];
2828
postTransform?: IndexHtmlTransform;
2929
crossOrigin?: CrossOriginValue;
30+
lang?: string;
3031
}
3132

3233
function readFile(filename: string, compilation: compilation.Compilation): Promise<string> {
@@ -100,6 +101,7 @@ export class IndexHtmlWebpackPlugin {
100101
loadOutputFile,
101102
moduleFiles,
102103
entrypoints: this._options.entrypoints,
104+
lang: this._options.lang,
103105
});
104106

105107
if (this._options.postTransform) {

packages/angular_devkit/build_angular/src/angular-cli-files/utilities/index-file/augment-index-html.ts

+32
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ export interface AugmentIndexHtmlOptions {
4242
loadOutputFile: LoadOutputFileFunctionType;
4343
/** Used to sort the inseration of files in the HTML file */
4444
entrypoints: string[];
45+
/** Used to set the document default locale */
46+
lang?: string;
4547
}
4648

4749
export interface FileInfo {
@@ -56,6 +58,7 @@ export interface FileInfo {
5658
* after processing several configurations in order to build different sets of
5759
* bundles for differential serving.
5860
*/
61+
// tslint:disable-next-line: no-big-function
5962
export async function augmentIndexHtml(params: AugmentIndexHtmlOptions): Promise<string> {
6063
const { loadOutputFile, files, noModuleFiles = [], moduleFiles = [], entrypoints } = params;
6164

@@ -91,8 +94,10 @@ export async function augmentIndexHtml(params: AugmentIndexHtmlOptions): Promise
9194
const document = parse5.parse(params.inputContent, { treeAdapter, locationInfo: true });
9295
let headElement;
9396
let bodyElement;
97+
let htmlElement;
9498
for (const docChild of document.childNodes) {
9599
if (docChild.tagName === 'html') {
100+
htmlElement = docChild;
96101
for (const htmlChild of docChild.childNodes) {
97102
if (htmlChild.tagName === 'head') {
98103
headElement = htmlChild;
@@ -241,6 +246,33 @@ export async function augmentIndexHtml(params: AugmentIndexHtmlOptions): Promise
241246

242247
indexSource.insert(styleInsertionPoint, parse5.serialize(styleElements, { treeAdapter }));
243248

249+
// Adjust document locale if specified
250+
if (typeof params.lang == 'string') {
251+
252+
const htmlFragment = treeAdapter.createDocumentFragment();
253+
254+
let langAttribute;
255+
for (const attribute of htmlElement.attrs) {
256+
if (attribute.name === 'lang') {
257+
langAttribute = attribute;
258+
}
259+
}
260+
if (langAttribute) {
261+
langAttribute.value = params.lang;
262+
} else {
263+
htmlElement.attrs.push({ name: 'lang', value: params.lang });
264+
}
265+
// we want only openning tag
266+
htmlElement.childNodes = [];
267+
268+
treeAdapter.appendChild(htmlFragment, htmlElement);
269+
indexSource.replace(
270+
htmlElement.__location.startTag.startOffset,
271+
htmlElement.__location.startTag.endOffset - 1,
272+
parse5.serialize(htmlFragment, { treeAdapter }).replace('</html>', ''),
273+
);
274+
}
275+
244276
return indexSource.source();
245277
}
246278

packages/angular_devkit/build_angular/src/angular-cli-files/utilities/index-file/augment-index-html_spec.ts

+17
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,21 @@ describe('augment-index-html', () => {
132132
`);
133133
});
134134

135+
it('should add lang attribute', async () => {
136+
const source = augmentIndexHtml({
137+
...indexGeneratorOptions,
138+
lang: 'fr',
139+
});
140+
141+
const html = await source;
142+
expect(html).toEqual(oneLineHtml`
143+
<html lang="fr">
144+
<head>
145+
<base href="/">
146+
</head>
147+
<body>
148+
</body>
149+
</html>
150+
`);
151+
});
135152
});

packages/angular_devkit/build_angular/src/angular-cli-files/utilities/index-file/write-index-html.ts

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export interface WriteIndexHtmlOptions {
3131
styles?: ExtraEntryPoint[];
3232
postTransform?: IndexHtmlTransform;
3333
crossOrigin?: CrossOriginValue;
34+
lang?: string;
3435
}
3536

3637
export type IndexHtmlTransform = (content: string) => Promise<string>;
@@ -49,6 +50,7 @@ export function writeIndexHtml({
4950
styles = [],
5051
postTransform,
5152
crossOrigin,
53+
lang,
5254
}: WriteIndexHtmlOptions): Observable<void> {
5355
return host.read(indexPath).pipe(
5456
map(content => stripBom(virtualFs.fileBufferToString(content))),
@@ -70,6 +72,7 @@ export function writeIndexHtml({
7072
.pipe(map(data => virtualFs.fileBufferToString(data)))
7173
.toPromise();
7274
},
75+
lang: lang,
7376
}),
7477
),
7578
switchMap(content => (postTransform ? postTransform(content) : of(content))),

packages/angular_devkit/build_angular/src/browser/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ export function buildWebpackBrowser(
708708
styles: options.styles,
709709
postTransform: transforms.indexHtml,
710710
crossOrigin: options.crossOrigin,
711+
lang: options.i18nLocale,
711712
})
712713
.pipe(
713714
map(() => ({ success: true })),

packages/angular_devkit/build_angular/src/dev-server/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export function serveWebpackBrowser(
209209
noModuleEntrypoints: ['polyfills-es5'],
210210
postTransform: transforms.indexHtml,
211211
crossOrigin: browserOptions.crossOrigin,
212+
lang: browserOptions.i18nLocale,
212213
}),
213214
);
214215
}

tests/legacy-cli/e2e/tests/i18n/build-locale.ts

+2
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ export default function () {
1919
.then(() => expectFileToMatch('dist/test-project/main-es5.js', /angular_common_locales_fr/))
2020
.then(() => expectFileToMatch('dist/test-project/main-es2015.js', /registerLocaleData/))
2121
.then(() => expectFileToMatch('dist/test-project/main-es2015.js', /angular_common_locales_fr/))
22+
.then(() => expectFileToMatch('dist/test-project/index.html', /lang="fr"/))
2223
.then(() => rimraf('dist'))
2324
.then(() => ng('build', '--aot', '--i18n-locale=fr_FR'))
2425
.then(() => expectFileToMatch('dist/test-project/main-es2015.js', /registerLocaleData/))
2526
.then(() => expectFileToMatch('dist/test-project/main-es2015.js', /angular_common_locales_fr/))
2627
.then(() => expectFileToMatch('dist/test-project/main-es5.js', /registerLocaleData/))
2728
.then(() => expectFileToMatch('dist/test-project/main-es5.js', /angular_common_locales_fr/))
29+
.then(() => expectFileToMatch('dist/test-project/index.html', /lang="fr_FR"/))
2830
.then(() => rimraf('dist'));
2931
}

0 commit comments

Comments
 (0)