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