Files
cappuccino/Foundation/CPLocale.j
T
2026-03-24 21:34:39 +01:00

260 lines
8.6 KiB
Plaintext

/* CPLocale.j
* Foundation
*
* Created by Alexandre Wilhelm
* Copyright 2012 <alexandre.wilhelmfr@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPObject.j"
@class CPDictionary
CPLocaleIdentifier = @"CPLocaleIdentifier";
CPLocaleLanguageCode = @"CPLocaleLanguageCode";
CPLocaleCountryCode = @"CPLocaleCountryCode";
CPLocaleScriptCode = @"CPLocaleScriptCode";
CPLocaleVariantCode = @"CPLocaleVariantCode";
CPLocaleExemplarCharacterSet = @"CPLocaleExemplarCharacterSet";
CPLocaleCalendar = @"CPLocaleCalendar";
CPLocaleCollationIdentifier = @"CPLocaleCollationIdentifier";
CPLocaleUsesMetricSystem = @"CPLocaleUsesMetricSystem";
CPLocaleMeasurementSystem = @"CPLocaleMeasurementSystem";
CPLocaleDecimalSeparator = @"CPLocaleDecimalSeparator";
CPLocaleGroupingSeparator = @"CPLocaleGroupingSeparator";
CPLocaleCurrencySymbol = @"CPLocaleCurrencySymbol";
CPLocaleCurrencyCode = @"CPLocaleCurrencyCode";
CPLocaleCollatorIdentifier = @"CPLocaleCollatorIdentifier";
CPLocaleQuotationBeginDelimiterKey = @"CPLocaleQuotationBeginDelimiterKey";
CPLocaleQuotationEndDelimiterKey = @"CPLocaleQuotationEndDelimiterKey";
CPLocaleAlternateQuotationBeginDelimiterKey = @"CPLocaleAlternateQuotationBeginDelimiterKey";
CPLocaleAlternateQuotationEndDelimiterKey = @"CPLocaleAlternateQuotationEndDelimiterKey";
CPGregorianCalendar = @"CPGregorianCalendar";
CPBuddhistCalendar = @"CPBuddhistCalendar";
CPChineseCalendar = @"CPChineseCalendar";
CPHebrewCalendar = @"CPHebrewCalendar";
CPIslamicCalendar = @"CPIslamicCalendar";
CPIslamicCivilCalendar = @"CPIslamicCivilCalendar";
CPJapaneseCalendar = @"CPJapaneseCalendar";
CPRepublicOfChinaCalendar = @"CPRepublicOfChinaCalendar";
CPPersianCalendar = @"CPPersianCalendar";
CPIndianCalendar = @"CPIndianCalendar";
CPISO8601Calendar = @"CPISO8601Calendar";
CPLocaleLanguageDirectionUnknown = @"CPLocaleLanguageDirectionUnknown";
CPLocaleLanguageDirectionLeftToRight = @"CPLocaleLanguageDirectionLeftToRight";
CPLocaleLanguageDirectionRightToLeft = @"CPLocaleLanguageDirectionRightToLeft";
CPLocaleLanguageDirectionTopToBottom = @"CPLocaleLanguageDirectionTopToBottom";
CPLocaleLanguageDirectionBottomToTop = @"CPLocaleLanguageDirectionBottomToTop";
var countryCodes = [@"DE", @"FR", @"ES", @"GB", @"US", @"SE"],
languageCodes = [@"en", @"de", @"es", @"fr", @"sv"],
availableLocaleIdentifiers = [@"de_DE", @"en_GB", @"en_US", @"es_ES", @"fr_FR", @"sv_SE"];
var sharedSystemLocale = nil,
sharedCurrentLocale = nil;
@implementation CPLocale : CPObject
{
CPDictionary _locale;
}
/*! Return the system locale. By default is en_US
*/
+ (id)systemLocale
{
if (!sharedSystemLocale)
sharedSystemLocale = [[CPLocale alloc] initWithLocaleIdentifier:@"en_US"];
return sharedSystemLocale;
}
/*! Return the current locale based on the navigator string.
*/
+ (id)currentLocale
{
if (!sharedCurrentLocale)
{
var localeIdentifier = @"en_US",
language;
if (typeof navigator !== "undefined")
{
// userLanguage is an IE only property.
language = (typeof navigator.language !== "undefined") ? navigator.language : navigator.userLanguage;
if (language)
{
// Split the BCP 47 tag into parts (e.g.,["zh", "Hans", "CN"] or ["en", "US"] or ["fr"])
var parts = language.split("-");
if (parts.length > 1)
{
// Chrome behavior: e.g., "de-DE" or "en-US"
var langCode = parts[0].toLowerCase();
var regionCode = parts[parts.length - 1].toUpperCase();
// Update localeIdentifier!
localeIdentifier = langCode + "_" + regionCode;
}
else
{
// Firefox behavior: e.g., "de", "fr", "en"
var langCode = parts[0].toLowerCase();
// Create a mapping of 2-letter language codes to default region codes
var defaultRegions = {
"de": "DE",
"en": "US",
"es": "ES",
"fr": "FR",
"sv": "SE"
};
// Look up the default region, or fallback to the uppercased language code (e.g. "it" -> "IT")
var regionCode = defaultRegions[langCode] || langCode.toUpperCase();
// Update localeIdentifier!
localeIdentifier = langCode + "_" + regionCode;
}
}
}
sharedCurrentLocale = [[CPLocale alloc] initWithLocaleIdentifier:localeIdentifier];
}
return sharedCurrentLocale;
}
/*! Return an array of the availableLocaleIdentifiers
*/
+ (CPArray)availableLocaleIdentifiers
{
return availableLocaleIdentifiers;
}
/*! Return an array with the ISOCountryCodes
*/
+ (CPArray)ISOCountryCodes
{
return countryCodes;
}
// + (CPArray)ISOCurrencyCodes
// {
// // TODO
// return;
// }
/*! Return an array with the ISOLanguageCodes
*/
+ (CPArray)ISOLanguageCodes
{
return languageCodes;
}
// + (CPArray)commonISOCurrencyCodes
// {
// // TODO
// return;
// }
/*! Init a new instance of CPLocale with a given identifier.
This method will call the class method _platformLocaleAdditionalDescriptionForIdentifier:. It's usefull if you want to implement your CPLocale.
@parameter anIdentifier
*/
- (id)initWithLocaleIdentifier:(CPString)anIdentifier
{
if (self == [super init])
{
var parts = [anIdentifier componentsSeparatedByString:@"_"],
language = [parts objectAtIndex:0],
country = nil;
if ([parts count] > 1)
country = [parts objectAtIndex:1];
else
country = anIdentifier;
_locale = [[CPDictionary alloc] init];
[_locale setObject:anIdentifier forKey:CPLocaleIdentifier];
[_locale setObject:language forKey:CPLocaleLanguageCode];
[_locale setObject:country forKey:CPLocaleCountryCode];
if ([[self class] respondsToSelector:@selector(_platformLocaleAdditionalDescriptionForIdentifier:)])
{
// Use any platform specific method to fill the locale info if one is defined
var info = [[self class] performSelector:@selector(_platformLocaleAdditionalDescriptionForIdentifier:) withObject:anIdentifier];
[_locale addEntriesFromDictionary:info];
}
else
{
[_locale setObject:CPGregorianCalendar forKey:CPLocaleCalendar];
}
}
return self;
}
// - (CPString)displayNameForKey:(id)aKey value:(id)aValue
// {
// // TODO
// return;
// }
/*! Return the CPLocaleIdentifier
*/
- (CPString)localeIdentifier
{
return [_locale objectForKey:CPLocaleIdentifier];
}
/*! Return the object depending of the key
@param aKey
@return an object
*/
- (id)objectForKey:(id)aKey
{
return [_locale objectForKey:aKey];
}
@end
var CPLocaleIdentifierLocaleKey = @"CPLocaleIdentifierLocaleKey";
@implementation CPLocale (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self)
{
_locale = [aCoder decodeObjectForKey:CPLocaleIdentifierLocaleKey];
}
return self
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
//[super encodeWithCoder:aCoder];
[aCoder encodeObject:_locale forKey:CPLocaleIdentifierLocaleKey];
}
@end