18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Copyright (C) 2003, 2005, 2006, 2010 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
13a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "config.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "Language.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "BlockExceptions.h"
30a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#import "WebCoreSystemInterface.h"
31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#import <wtf/Assertions.h>
32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#import <wtf/MainThread.h>
33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#import <wtf/text/WTFString.h>
34a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
35a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochusing namespace WebCore;
36a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
37a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic NSString *preferredLanguageCode;
38a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch@interface LanguageChangeObserver : NSObject {
40a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
41a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch@end
42a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
43a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch@implementation LanguageChangeObserver
44a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
45a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch+ (void)_webkit_languagePreferencesDidChange
46a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
47a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(isMainThread());
48a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    [preferredLanguageCode release];
50a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    preferredLanguageCode = nil;
51a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
52a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    languageDidChange();
53a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
54a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
55a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch@end
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
59a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic NSString *createHTTPStyleLanguageCode(NSString *languageCode)
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
61a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(isMainThread());
62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Look up the language code using CFBundle.
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CFStringRef preferredLanguageCode = wkCopyCFLocalizationPreferredName((CFStringRef)languageCode);
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
66a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (preferredLanguageCode)
67a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        languageCode = (NSString *)preferredLanguageCode;
68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
69a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Make the string lowercase.
70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    NSString *lowercaseLanguageCode = [languageCode lowercaseString];
71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
7228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    NSString *httpStyleLanguageCode;
7328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Turn a '_' into a '-' if it appears after a 2-letter language code.
7528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if ([lowercaseLanguageCode length] >= 3 && [lowercaseLanguageCode characterAtIndex:2] == '_') {
7628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        NSMutableString *mutableLanguageCode = [lowercaseLanguageCode mutableCopy];
7728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        [mutableLanguageCode replaceCharactersInRange:NSMakeRange(2, 1) withString:@"-"];
7828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        httpStyleLanguageCode = mutableLanguageCode;
7928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } else
8028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        httpStyleLanguageCode = [lowercaseLanguageCode retain];
8128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
82a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (preferredLanguageCode)
83a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        CFRelease(preferredLanguageCode);
84a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
8528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return httpStyleLanguageCode;
86a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
87a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
88a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochString platformDefaultLanguage()
89a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(isMainThread());
91a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    BEGIN_BLOCK_OBJC_EXCEPTIONS;
93a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!preferredLanguageCode) {
95a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        [[NSUserDefaults standardUserDefaults] synchronize];
96a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        NSArray *languages = [[NSUserDefaults standardUserDefaults] stringArrayForKey:@"AppleLanguages"];
97a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (![languages count])
98a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            preferredLanguageCode = @"en";
99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            preferredLanguageCode = createHTTPStyleLanguageCode([languages objectAtIndex:0]);
101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    NSString *code = [[preferredLanguageCode retain] autorelease];
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    static bool languageChangeObserverAdded;
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!languageChangeObserverAdded) {
107a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        [[NSDistributedNotificationCenter defaultCenter] addObserver:[LanguageChangeObserver self]
108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                            selector:@selector(_webkit_languagePreferencesDidChange)
109a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                                name:@"AppleLanguagePreferencesChangedNotification"
110a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                                              object:nil];
111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        languageChangeObserverAdded = true;
112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return code;
115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    END_BLOCK_OBJC_EXCEPTIONS;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return String();
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
121