angular-l10n
Version:
An Angular library to translate messages, dates and numbers
227 lines • 8.32 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { LocaleService } from './locale.service';
import { TranslationService } from './translation.service';
import { IntlAPI } from './intl-api';
/**
* @record
*/
export function ICollator() { }
if (false) {
/**
* @param {?} key1
* @param {?} key2
* @param {?=} extension
* @param {?=} options
* @return {?}
*/
ICollator.prototype.compare = function (key1, key2, extension, options) { };
/**
* @param {?} list
* @param {?} keyName
* @param {?=} order
* @param {?=} extension
* @param {?=} options
* @return {?}
*/
ICollator.prototype.sort = function (list, keyName, order, extension, options) { };
/**
* @param {?} list
* @param {?} keyName
* @param {?=} order
* @param {?=} extension
* @param {?=} options
* @return {?}
*/
ICollator.prototype.sortAsync = function (list, keyName, order, extension, options) { };
/**
* @param {?} s
* @param {?} list
* @param {?} keyNames
* @param {?=} options
* @return {?}
*/
ICollator.prototype.search = function (s, list, keyNames, options) { };
/**
* @param {?} s
* @param {?} list
* @param {?} keyNames
* @param {?=} options
* @return {?}
*/
ICollator.prototype.searchAsync = function (s, list, keyNames, options) { };
}
/**
* Intl.Collator APIs.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator
*/
export class Collator {
/**
* @param {?} locale
* @param {?} translation
*/
constructor(locale, translation) {
this.locale = locale;
this.translation = translation;
}
/**
* Compares two keys by the value of translation according to the current language.
* @param {?} key1
* @param {?} key2
* @param {?=} extension Unicode extension key, e.g. 'co-phonebk'
* @param {?=} options Default is { usage: 'sort', sensitivity: 'variant' }
* @return {?} A negative value if the value of translation of key1 comes before the value of translation of key2;
* a positive value if key1 comes after key2;
* 0 if they are considered equal or Intl.Collator is not supported
*/
compare(key1, key2, extension, options = { usage: 'sort', sensitivity: 'variant' }) {
if (!IntlAPI.hasCollator())
return 0;
/** @type {?} */
const value1 = this.translation.translate(key1);
/** @type {?} */
const value2 = this.translation.translate(key2);
/** @type {?} */
const locale = this.addExtension(this.locale.getCurrentLocale(), extension);
return new Intl.Collator(locale, options).compare(value1, value2);
}
/**
* Sorts an array of objects or an array of arrays according to the current language.
* @param {?} list The array to be sorted
* @param {?} keyName The column that contains the keys of the values to be ordered
* @param {?=} order 'asc' or 'desc'. The default value is 'asc'
* @param {?=} extension Unicode extension key, e.g. 'co-phonebk'
* @param {?=} options Default is { usage: 'sort', sensitivity: 'variant' }
* @return {?} The same sorted list or the same list if Intl.Collator is not supported
*/
sort(list, keyName, order = "asc", extension, options = { usage: 'sort', sensitivity: 'variant' }) {
if (!list || !keyName || !IntlAPI.hasCollator())
return list;
list.sort((key1, key2) => {
return this.compare(key1[keyName], key2[keyName], extension, options);
});
if (order == "desc") {
list.reverse();
}
return list;
}
/**
* Sorts asynchronously an array of objects or an array of arrays according to the current language.
* @param {?} list The array to be sorted
* @param {?} keyName The column that contains the keys of the values to be ordered
* @param {?=} order 'asc' or 'desc'. The default value is 'asc'
* @param {?=} extension Unicode extension key, e.g. 'co-phonebk'
* @param {?=} options Default is { usage: 'sort', sensitivity: 'variant' }
* @return {?} An observable of the sorted list or of the same list if Intl.Collator is not supported
*/
sortAsync(list, keyName, order, extension, options = { usage: 'sort', sensitivity: 'variant' }) {
return new Observable((observer) => {
observer.next(this.sort(list, keyName, order, extension, options));
observer.complete();
});
}
/**
* Matches a string into an array of objects or an array of arrays according to the current language.
* @param {?} s The string to search
* @param {?} list The array in which to search
* @param {?} keyNames An array that contains the columns to look for
* @param {?=} options Default is { usage: 'search' }
* @return {?} A filtered list or the same list if Intl.Collator is not supported
*/
search(s, list, keyNames, options = { usage: 'search' }) {
if (!list || !keyNames || s == "" || s == null || !IntlAPI.hasCollator())
return list;
/** @type {?} */
const locale = this.locale.getCurrentLocale();
/** @type {?} */
const collator = new Intl.Collator(locale, options);
/** @type {?} */
const matches = list.filter((key) => {
/** @type {?} */
let found = false;
for (let i = 0; i < keyNames.length; i++) {
if (this.match(key[keyNames[i]], s, collator)) {
found = true;
break;
}
}
return found;
});
return matches;
}
/**
* Matches asynchronously a string into an array of objects or an array of arrays according to the current language.
* @param {?} s The string to search
* @param {?} list The array in which to search
* @param {?} keyNames An array that contains the columns to look for
* @param {?=} options Default is { usage: 'search' }
* @return {?} An observable of the filtered list or the same list if Intl.Collator is not supported
*/
searchAsync(s, list, keyNames, options = { usage: 'search' }) {
return new Observable((observer) => {
observer.next(this.search(s, list, keyNames, options));
observer.complete();
});
}
/**
* @param {?} locale
* @param {?=} extension
* @return {?}
*/
addExtension(locale, extension) {
if (!!extension) {
locale = locale + "-u-" + extension;
}
return locale;
}
/**
* @param {?} key
* @param {?} s
* @param {?} collator
* @return {?}
*/
match(key, s, collator) {
/** @type {?} */
const value = this.translation.translate(key);
/** @type {?} */
const valueLength = value.length;
/** @type {?} */
const sLength = s.length;
if (sLength > valueLength) {
return false;
}
if (sLength == valueLength) {
return collator.compare(value, s) == 0;
}
/** @type {?} */
let found = false;
for (let i = 0; i < valueLength - (sLength - 1); i++) {
/** @type {?} */
const str = value.substr(i, sLength);
if (collator.compare(str, s) == 0) {
found = true;
break;
}
}
return found;
}
}
Collator.decorators = [
{ type: Injectable }
];
/** @nocollapse */
Collator.ctorParameters = () => [
{ type: LocaleService },
{ type: TranslationService }
];
if (false) {
/** @type {?} */
Collator.prototype.locale;
/** @type {?} */
Collator.prototype.translation;
}
//# sourceMappingURL=collator.js.map