156 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * @license
 | |
|  * Copyright Google Inc. All Rights Reserved.
 | |
|  *
 | |
|  * Use of this source code is governed by an MIT-style license that can be
 | |
|  * found in the LICENSE file at https://angular.io/license
 | |
|  */
 | |
| 
 | |
| const fs = require('fs');
 | |
| const yargs = require('yargs').argv;
 | |
| const {I18N_DATA_FOLDER, RELATIVE_I18N_DATA_FOLDER, HEADER} = require('./extract');
 | |
| const OUTPUT_NAME = `closure-locale.ts`;
 | |
| 
 | |
| // tslint:disable:no-console
 | |
| module.exports = (gulp, done) => {
 | |
|   // the locales used by closure that will be used to generate the closure-locale file
 | |
|   // extracted from:
 | |
|   // https://github.com/google/closure-library/blob/master/closure/goog/i18n/datetimepatterns.js#L2136
 | |
|   let GOOG_LOCALES = [
 | |
|     'af',    'am',    'ar',    'ar-DZ', 'az',    'be',    'bg',    'bn',     'br',    'bs',
 | |
|     'ca',    'chr',   'cs',    'cy',    'da',    'de',    'de-AT', 'de-CH',  'el',    'en-AU',
 | |
|     'en-CA', 'en-GB', 'en-IE', 'en-IN', 'en-SG', 'en-ZA', 'es',    'es-419', 'es-MX', 'es-US',
 | |
|     'et',    'eu',    'fa',    'fi',    'fr',    'fr-CA', 'ga',    'gl',     'gsw',   'gu',
 | |
|     'haw',   'hi',    'hr',    'hu',    'hy',    'in',    'is',    'it',     'iw',    'ja',
 | |
|     'ka',    'kk',    'km',    'kn',    'ko',    'ky',    'ln',    'lo',     'lt',    'lv',
 | |
|     'mk',    'ml',    'mn',    'mo',    'mr',    'ms',    'mt',    'my',     'ne',    'nl',
 | |
|     'no',    'or',    'pa',    'pl',    'pt',    'pt-PT', 'ro',    'ru',     'sh',    'si',
 | |
|     'sk',    'sl',    'sq',    'sr',    'sv',    'sw',    'ta',    'te',     'th',    'tl',
 | |
|     'tr',    'uk',    'ur',    'uz',    'vi',    'zh',    'zh-CN', 'zh-HK',  'zh-TW', 'zu'
 | |
|   ];
 | |
| 
 | |
|   // locale id aliases to support deprecated locale ids used by closure
 | |
|   // it maps deprecated ids --> new ids
 | |
|   // manually extracted from ./cldr-data/supplemental/aliases.json
 | |
|   const ALIASES = {
 | |
|     'in': 'id',
 | |
|     'iw': 'he',
 | |
|     'mo': 'ro-MD',
 | |
|     'no': 'nb',
 | |
|     'nb': 'no-NO',
 | |
|     'sh': 'sr-Latn',
 | |
|     'tl': 'fil',
 | |
|     'pt': 'pt-BR',
 | |
|     'zh-CN': 'zh-Hans-CN',
 | |
|     'zh-Hans-CN': 'zh-Hans',
 | |
|     'zh-HK': 'zh-Hant-HK',
 | |
|     'zh-TW': 'zh-Hant-TW',
 | |
|     'zh-Hant-TW': 'zh-Hant',
 | |
|   };
 | |
| 
 | |
|   if (yargs.locales) {
 | |
|     GOOG_LOCALES = yargs.locales.split(',');
 | |
|   }
 | |
| 
 | |
|   console.log(`Writing file ${I18N_DATA_FOLDER}/${OUTPUT_NAME}`);
 | |
|   fs.writeFileSync(
 | |
|       `${RELATIVE_I18N_DATA_FOLDER}/${OUTPUT_NAME}`, generateAllLocalesFile(GOOG_LOCALES, ALIASES));
 | |
| 
 | |
|   console.log(`Formatting ${I18N_DATA_FOLDER}/${OUTPUT_NAME}..."`);
 | |
|   const format = require('gulp-clang-format');
 | |
|   const clangFormat = require('clang-format');
 | |
|   return gulp.src([`${I18N_DATA_FOLDER}/${OUTPUT_NAME}`], {base: '.'})
 | |
|       .pipe(format.format('file', clangFormat))
 | |
|       .pipe(gulp.dest('.'));
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Generate a file that contains all locale to import for closure.
 | |
|  * Tree shaking will only keep the data for the `goog.LOCALE` locale.
 | |
|  */
 | |
| function generateAllLocalesFile(LOCALES, ALIASES) {
 | |
|   const existingLocalesAliases = {};
 | |
|   const existingLocalesData = {};
 | |
| 
 | |
|   // for each locale, get the data and the list of equivalent locales
 | |
|   LOCALES.forEach(locale => {
 | |
|     const eqLocales = new Set();
 | |
|     eqLocales.add(locale);
 | |
|     if (locale.match(/-/)) {
 | |
|       eqLocales.add(locale.replace(/-/g, '_'));
 | |
|     }
 | |
| 
 | |
|     // check for aliases
 | |
|     const alias = ALIASES[locale];
 | |
|     if (alias) {
 | |
|       eqLocales.add(alias);
 | |
| 
 | |
|       if (alias.match(/-/)) {
 | |
|         eqLocales.add(alias.replace(/-/g, '_'));
 | |
|       }
 | |
| 
 | |
|       // to avoid duplicated "case" we regroup all locales in the same "case"
 | |
|       // the simplest way to do that is to have alias aliases
 | |
|       // e.g. 'no' --> 'nb', 'nb' --> 'no-NO'
 | |
|       // which means that we'll have 'no', 'nb' and 'no-NO' in the same "case"
 | |
|       const aliasKeys = Object.keys(ALIASES);
 | |
|       for (let i = 0; i < aliasKeys.length; i++) {
 | |
|         const aliasValue = ALIASES[alias];
 | |
|         if (aliasKeys.indexOf(alias) !== -1 && !eqLocales.has(aliasValue)) {
 | |
|           eqLocales.add(aliasValue);
 | |
| 
 | |
|           if (aliasValue.match(/-/)) {
 | |
|             eqLocales.add(aliasValue.replace(/-/g, '_'));
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     for (let l of eqLocales) {
 | |
|       // find the existing content file
 | |
|       const path = `${RELATIVE_I18N_DATA_FOLDER}/${l}.ts`;
 | |
|       if (fs.existsSync(`${RELATIVE_I18N_DATA_FOLDER}/${l}.ts`)) {
 | |
|         const localeName = formatLocale(locale);
 | |
|         existingLocalesData[locale] =
 | |
|             fs.readFileSync(path, 'utf8')
 | |
|                 .replace(`${HEADER}\n`, '')
 | |
|                 .replace('export default ', `export const locale_${localeName} = `)
 | |
|                 .replace('function plural', `function plural_${localeName}`)
 | |
|                 .replace(/,(\n  | )plural/, `, plural_${localeName}`);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     existingLocalesAliases[locale] = eqLocales;
 | |
|   });
 | |
| 
 | |
|   function generateCases(locale) {
 | |
|     let str = '';
 | |
|     const eqLocales = existingLocalesAliases[locale];
 | |
|     for (let l of eqLocales) {
 | |
|       str += `case '${l}':\n`;
 | |
|     }
 | |
| 
 | |
|     str += `  l = locale_${formatLocale(locale)};
 | |
|     break;\n`;
 | |
|     return str;
 | |
|   }
 | |
| 
 | |
|   function formatLocale(locale) { return locale.replace(/-/g, '_'); }
 | |
|   // clang-format off
 | |
|   return `${HEADER}
 | |
| import {registerLocaleData} from '../src/i18n/locale_data';
 | |
| 
 | |
| ${LOCALES.map(locale => `${existingLocalesData[locale]}`).join('\n')}
 | |
| 
 | |
| let l: any;
 | |
| 
 | |
| switch (goog.LOCALE) {
 | |
| ${LOCALES.map(locale => generateCases(locale)).join('')}}
 | |
| 
 | |
| if(l) {
 | |
|   registerLocaleData(l, goog.LOCALE);
 | |
| }
 | |
| `;
 | |
|   // clang-format on
 | |
| }
 |