b8295c88bb67d0a7a8451322fad9f57aefacc034
[WebKit.git] / WebKit / WebView.subproj / WebPreferences.m
1 /*
2  * Copyright (C) 2005 Apple Computer, 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import <WebKit/WebPreferencesPrivate.h>
30 #import <WebKit/WebPreferenceKeysPrivate.h>
31
32 #import <WebKit/WebKitLogging.h>
33 #import <WebKit/WebKitNSStringExtras.h>
34 #import <WebKit/WebNSDictionaryExtras.h>
35 #import <WebKit/WebNSURLExtras.h>
36
37 #import <WebCore/WebCoreSettings.h>
38
39 #import <Carbon/Carbon.h>                           // For TEC
40 #import <CoreFoundation/CFStringDefaultEncoding.h>  // For __CFStringGetUserDefaultEncoding
41
42 NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification";
43
44 #define KEY(x) (_private->identifier ? [_private->identifier stringByAppendingString:(x)] : (x))
45
46 enum { WebPreferencesVersion = 1 };
47
48 @interface WebPreferencesPrivate : NSObject
49 {
50 @public
51     NSMutableDictionary *values;
52     NSString *identifier;
53     NSString *IBCreatorID;
54     BOOL autosaves;
55 }
56 @end
57
58 @implementation WebPreferencesPrivate
59 - (void)dealloc
60 {
61     [values release];
62     [identifier release];
63     [IBCreatorID release];
64     [super dealloc];
65 }
66 @end
67
68 @interface WebPreferences (WebInternal)
69 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key;
70 + (NSString *)_IBCreatorID;
71 @end
72
73 @interface WebPreferences (WebForwardDeclarations)
74 // This pseudo-category is needed so these methods can be used from within other category implementations
75 // without being in the public header file.
76 - (BOOL)_boolValueForKey:(NSString *)key;
77 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key;
78 @end
79
80 @implementation WebPreferences
81
82 - init
83 {
84     // Create fake identifier
85     static int instanceCount = 1;
86     NSString *fakeIdentifier;
87     
88     // At least ensure that identifier hasn't been already used.  
89     fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
90     while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){
91         fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
92     }
93     
94     return [self initWithIdentifier:fakeIdentifier];
95 }
96
97 static WebPreferences *_standardPreferences = nil;
98
99 - (id)initWithIdentifier:(NSString *)anIdentifier
100 {
101     [super init];
102
103     _private = [[WebPreferencesPrivate alloc] init];
104     _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
105
106     WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier];
107     if (instance){
108         [self release];
109         return [instance retain];
110     }
111
112     _private->values = [[NSMutableDictionary alloc] init];
113     _private->identifier = [anIdentifier copy];
114     
115     [[self class] _setInstance:self forIdentifier:_private->identifier];
116
117     [[NSNotificationCenter defaultCenter]
118        postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil];
119
120     return self;
121 }
122
123 - (id)initWithCoder:(NSCoder *)decoder
124 {
125     volatile id result = nil;
126
127 NS_DURING
128
129     int version;
130
131     _private = [[WebPreferencesPrivate alloc] init];
132     _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
133     
134     if ([decoder allowsKeyedCoding]){
135         _private->identifier = [[decoder decodeObjectForKey:@"Identifier"] retain];
136         _private->values = [[decoder decodeObjectForKey:@"Values"] retain];
137         LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
138     }
139     else {
140         [decoder decodeValueOfObjCType:@encode(int) at:&version];
141         if (version == 1){
142             _private->identifier = [[decoder decodeObject] retain];
143             _private->values = [[decoder decodeObject] retain];
144         }
145     }
146     
147     // If we load a nib multiple times, or have instances in multiple
148     // nibs with the same name, the first guy up wins.
149     WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier];
150     if (instance){
151         [self release];
152         result = [instance retain];
153     }
154     else {
155         [[self class] _setInstance:self forIdentifier:_private->identifier];
156         result = self;
157     }
158     
159 NS_HANDLER
160
161     result = nil;
162     [self release];
163     
164 NS_ENDHANDLER
165
166     return result;
167 }
168
169 - (void)encodeWithCoder:(NSCoder *)encoder
170 {
171     if ([encoder allowsKeyedCoding]){
172         [encoder encodeObject:_private->identifier forKey:@"Identifier"];
173         [encoder encodeObject:_private->values forKey:@"Values"];
174         LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
175     }
176     else {
177         int version = WebPreferencesVersion;
178         [encoder encodeValueOfObjCType:@encode(int) at:&version];
179         [encoder encodeObject:_private->identifier];
180         [encoder encodeObject:_private->values];
181     }
182 }
183
184 + (WebPreferences *)standardPreferences
185 {
186     if (_standardPreferences == nil) {
187         _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil];
188         [_standardPreferences setAutosaves:YES];
189         [_standardPreferences _postPreferencesChangesNotification];
190     }
191
192     return _standardPreferences;
193 }
194
195 // if we ever have more than one WebPreferences object, this would move to init
196 + (void)initialize
197 {
198     NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
199         @"0x0",                         WebKitLogLevelPreferenceKey,
200         @"Times",                       WebKitStandardFontPreferenceKey,
201         @"Courier",                     WebKitFixedFontPreferenceKey,
202         @"Times",                       WebKitSerifFontPreferenceKey,
203         @"Helvetica",                   WebKitSansSerifFontPreferenceKey,
204         @"Apple Chancery",              WebKitCursiveFontPreferenceKey,
205         @"Papyrus",                     WebKitFantasyFontPreferenceKey,
206         @"1",                           WebKitMinimumFontSizePreferenceKey,
207         @"9",                           WebKitMinimumLogicalFontSizePreferenceKey, 
208         @"16",                          WebKitDefaultFontSizePreferenceKey,
209         @"13",                          WebKitDefaultFixedFontSizePreferenceKey,
210         @"ISO-8859-1",                  WebKitDefaultTextEncodingNamePreferenceKey,
211         @"4",                           WebKitPageCacheSizePreferenceKey,
212         @"8388608",                     WebKitObjectCacheSizePreferenceKey,
213         [NSNumber numberWithBool:NO],   WebKitUserStyleSheetEnabledPreferenceKey,
214         @"",                            WebKitUserStyleSheetLocationPreferenceKey,
215         [NSNumber numberWithBool:NO],   WebKitShouldPrintBackgroundsPreferenceKey,
216         [NSNumber numberWithBool:NO],   WebKitTextAreasAreResizablePreferenceKey,
217         [NSNumber numberWithBool:YES],  WebKitJavaEnabledPreferenceKey,
218         [NSNumber numberWithBool:YES],  WebKitJavaScriptEnabledPreferenceKey,
219         [NSNumber numberWithBool:YES],  WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
220         [NSNumber numberWithBool:YES],  WebKitPluginsEnabledPreferenceKey,
221         [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImagesPreferenceKey,
222         [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImageLoopingPreferenceKey,
223         [NSNumber numberWithBool:YES],  WebKitDisplayImagesKey,
224         @"1800",                        WebKitBackForwardCacheExpirationIntervalKey,
225         [NSNumber numberWithBool:NO],   WebKitTabToLinksPreferenceKey,
226         [NSNumber numberWithBool:NO],   WebKitPrivateBrowsingEnabledPreferenceKey,
227         [NSNumber numberWithBool:NO],   WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
228         [NSNumber numberWithBool:NO],   WebKitShowsURLsInToolTipsPreferenceKey,
229         nil];
230
231     [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
232 }
233
234 - (void)dealloc
235 {
236     [_private release];
237     [super dealloc];
238 }
239
240 - (NSString *)identifier
241 {
242     return _private->identifier;
243 }
244
245 - (id)_valueForKey:(NSString *)key
246 {
247     NSString *_key = KEY(key);
248     id o = [_private->values objectForKey:_key];
249     if (o)
250         return o;
251     o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
252     if (!o && key != _key)
253         o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
254     return o;
255 }
256
257 - (NSString *)_stringValueForKey:(NSString *)key
258 {
259     id s = [self _valueForKey:key];
260     return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
261 }
262
263 - (void)_setStringValue:(NSString *)value forKey:(NSString *)key
264 {
265     NSString *_key = KEY(key);
266     [_private->values setObject:value forKey:_key];
267     if (_private->autosaves)
268         [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
269     [self _postPreferencesChangesNotification];
270 }
271
272 - (int)_integerValueForKey:(NSString *)key
273 {
274     id o = [self _valueForKey:key];
275     // 
276     return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
277 }
278
279 - (void)_setIntegerValue:(int)value forKey:(NSString *)key
280 {
281     NSString *_key = KEY(key);
282     [_private->values _webkit_setInt:value forKey:_key];
283     if (_private->autosaves)
284         [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
285     [self _postPreferencesChangesNotification];
286 }
287
288 - (BOOL)_boolValueForKey:(NSString *)key
289 {
290     return [self _integerValueForKey:key] != 0;
291 }
292
293 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
294 {
295     NSString *_key = KEY(key);
296     [_private->values _webkit_setBool:value forKey:_key];
297     if (_private->autosaves)
298         [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
299     [self _postPreferencesChangesNotification];
300 }
301
302 - (NSString *)standardFontFamily
303 {
304     return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
305 }
306
307 - (void)setStandardFontFamily:(NSString *)family
308 {
309     [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
310 }
311
312 - (NSString *)fixedFontFamily
313 {
314     return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
315 }
316
317 - (void)setFixedFontFamily:(NSString *)family
318 {
319     [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
320 }
321
322 - (NSString *)serifFontFamily
323 {
324     return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
325 }
326
327 - (void)setSerifFontFamily:(NSString *)family 
328 {
329     [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
330 }
331
332 - (NSString *)sansSerifFontFamily
333 {
334     return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
335 }
336
337 - (void)setSansSerifFontFamily:(NSString *)family
338 {
339     [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
340 }
341
342 - (NSString *)cursiveFontFamily
343 {
344     return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
345 }
346
347 - (void)setCursiveFontFamily:(NSString *)family
348 {
349     [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
350 }
351
352 - (NSString *)fantasyFontFamily
353 {
354     return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
355 }
356
357 - (void)setFantasyFontFamily:(NSString *)family
358 {
359     [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
360 }
361
362 - (int)defaultFontSize
363 {
364     return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
365 }
366
367 - (void)setDefaultFontSize:(int)size
368 {
369     [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
370 }
371
372 - (int)defaultFixedFontSize
373 {
374     return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
375 }
376
377 - (void)setDefaultFixedFontSize:(int)size
378 {
379     [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
380 }
381
382 - (int)minimumFontSize
383 {
384     return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
385 }
386
387 - (void)setMinimumFontSize:(int)size
388 {
389     [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
390 }
391
392 - (int)minimumLogicalFontSize
393 {
394   return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
395 }
396
397 - (void)setMinimumLogicalFontSize:(int)size
398 {
399   [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
400 }
401
402 - (NSString *)defaultTextEncodingName
403 {
404     return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
405 }
406
407 - (void)setDefaultTextEncodingName:(NSString *)encoding
408 {
409     [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
410 }
411
412 - (BOOL)userStyleSheetEnabled
413 {
414     return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
415 }
416
417 - (void)setUserStyleSheetEnabled:(BOOL)flag
418 {
419     [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
420 }
421
422 - (NSURL *)userStyleSheetLocation
423 {
424     NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
425     
426     if ([locationString _webkit_looksLikeAbsoluteURL]) {
427         return [NSURL _web_URLWithDataAsString:locationString];
428     } else {
429         locationString = [locationString stringByExpandingTildeInPath];
430         return [NSURL fileURLWithPath:locationString];
431     }
432 }
433
434 - (void)setUserStyleSheetLocation:(NSURL *)URL
435 {
436     NSString *locationString;
437     
438     if ([URL isFileURL]) {
439         locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
440     } else {
441         locationString = [URL _web_originalDataAsString];
442     }
443     
444     [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
445 }
446
447 - (BOOL)shouldPrintBackgrounds
448 {
449     return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
450 }
451
452 - (void)setShouldPrintBackgrounds:(BOOL)flag
453 {
454     [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
455 }
456
457 - (BOOL)isJavaEnabled
458 {
459     return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
460 }
461
462 - (void)setJavaEnabled:(BOOL)flag
463 {
464     [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
465 }
466
467 - (BOOL)isJavaScriptEnabled
468 {
469     return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
470 }
471
472 - (void)setJavaScriptEnabled:(BOOL)flag
473 {
474     [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
475 }
476
477 - (BOOL)javaScriptCanOpenWindowsAutomatically
478 {
479     return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
480 }
481
482 - (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
483 {
484     [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
485 }
486
487 - (BOOL)arePlugInsEnabled
488 {
489     return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
490 }
491
492 - (void)setPlugInsEnabled:(BOOL)flag
493 {
494     [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
495 }
496
497 - (BOOL)allowsAnimatedImages
498 {
499     return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
500 }
501
502 - (void)setAllowsAnimatedImages:(BOOL)flag;
503 {
504     [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
505 }
506
507 - (BOOL)allowsAnimatedImageLooping
508 {
509     return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
510 }
511
512 - (void)setAllowsAnimatedImageLooping: (BOOL)flag
513 {
514     [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
515 }
516
517 - (void)setLoadsImagesAutomatically: (BOOL)flag
518 {
519     [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
520 }
521
522 - (BOOL)loadsImagesAutomatically
523 {
524     return [self _boolValueForKey: WebKitDisplayImagesKey];
525 }
526
527 - (void)setAutosaves:(BOOL)flag;
528 {
529     _private->autosaves = flag;
530 }
531
532 - (BOOL)autosaves
533 {
534     return _private->autosaves;
535 }
536
537 - (void)setTabsToLinks:(BOOL)flag
538 {
539     [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
540 }
541
542 - (BOOL)tabsToLinks
543 {
544     return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
545 }
546
547 - (void)setPrivateBrowsingEnabled:(BOOL)flag
548 {
549     [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
550 }
551
552 - (BOOL)privateBrowsingEnabled
553 {
554     return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
555 }
556
557 @end
558
559 @implementation WebPreferences (WebPrivate)
560
561 - (BOOL)respectStandardStyleKeyEquivalents
562 {
563     return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
564 }
565
566 - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
567 {
568     [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
569 }
570
571 - (BOOL)showsURLsInToolTips
572 {
573     return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
574 }
575
576 - (void)setShowsURLsInToolTips:(BOOL)flag
577 {
578     [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
579 }
580
581 - (BOOL)textAreasAreResizable
582 {
583     return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
584 }
585
586 - (void)setTextAreasAreResizable:(BOOL)flag
587 {
588     [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
589 }
590
591 - (int)_pageCacheSize
592 {
593     return [[NSUserDefaults standardUserDefaults] integerForKey:WebKitPageCacheSizePreferenceKey];
594 }
595
596 - (int)_objectCacheSize
597 {
598     return [[NSUserDefaults standardUserDefaults] integerForKey:WebKitObjectCacheSizePreferenceKey];
599 }
600
601 - (NSTimeInterval)_backForwardCacheExpirationInterval
602 {
603     return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey];
604 }
605
606 static NSMutableDictionary *webPreferencesInstances = nil;
607
608 + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
609 {
610         LOG (Encoding, "requesting for %@\n", ident);
611
612     if (!ident){
613         if(_standardPreferences)
614             return _standardPreferences;
615         return nil;
616     }    
617     
618     WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
619
620     return instance;
621 }
622
623 + (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
624 {
625     if (!webPreferencesInstances)
626         webPreferencesInstances = [[NSMutableDictionary alloc] init];
627     if (ident) {
628         [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
629         LOG (Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
630     }
631 }
632
633 + (void)_removeReferenceForIdentifier:(NSString *)ident
634 {
635     if (ident != nil) {
636         [webPreferencesInstances performSelector:@selector(_web_checkLastReferenceForIdentifier:) withObject: [self _concatenateKeyWithIBCreatorID:ident] afterDelay:.1];
637     }
638 }
639
640 - (void)_postPreferencesChangesNotification
641 {
642     [[NSNotificationCenter defaultCenter]
643         postNotificationName:WebPreferencesChangedNotification object:self
644                     userInfo:nil];
645 }
646
647 + (CFStringEncoding)_systemCFStringEncoding
648 {
649 #if OMIT_TIGER_FEATURES
650     CFStringEncoding encoding = CFStringGetSystemEncoding();
651
652     // Map from system encodings to the appropriate default web encoding.
653     // Web pages that are not labeled will be decoded assuming this encoding,
654     // so it's important that this be the most likely encoding to encounter
655     // on a web page. MacArabic, MacHebrew, and MacRoman are not common on
656     // the web, so instead we map to the most common similar encoding actually used.
657     switch (encoding) {
658         case kCFStringEncodingMacArabic:
659             encoding = kCFStringEncodingDOSArabic;
660             break;
661         case kCFStringEncodingMacHebrew:
662             encoding = kCFStringEncodingDOSHebrew;
663             break;
664         case kCFStringEncodingMacRoman:
665             encoding = kCFStringEncodingISOLatin1;
666             break;
667     }
668
669     // We must not use any encoding that has no IANA character set name.
670     if (CFStringConvertEncodingToIANACharSetName(encoding) == NULL)
671         return kCFStringEncodingISOLatin1;
672 #else
673     UInt32 script = 0;
674     UInt32 region = 0;
675     TextEncoding encoding;
676     OSErr err;
677     ItemCount dontcare;
678
679     // We can't use the Script Manager as it will not return things that use
680     // a script that is not supported on Mac OS X.
681     __CFStringGetUserDefaultEncoding(&script, &region);
682     err = TECGetWebTextEncodings(region, &encoding, 1, &dontcare);
683     if (err != noErr)
684         encoding = kCFStringEncodingISOLatin1;
685 #endif
686
687     return encoding;
688 }
689
690 + (void)_setInitialDefaultTextEncodingToSystemEncoding
691 {
692     [[NSUserDefaults standardUserDefaults] registerDefaults:
693         [NSDictionary dictionaryWithObject:(NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding])
694                                     forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
695 }
696
697 static NSString *classIBCreatorID = nil;
698
699 + (void)_setIBCreatorID:(NSString *)string
700 {
701     NSString *old = classIBCreatorID;
702     classIBCreatorID = [string copy];
703     [old release];
704 }
705
706 @end
707
708 @implementation WebPreferences (WebInternal)
709
710 + (NSString *)_IBCreatorID
711 {
712     return classIBCreatorID;
713 }
714
715 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
716 {
717     NSString *IBCreatorID = [WebPreferences _IBCreatorID];
718     if (!IBCreatorID)
719         return key;
720     return [IBCreatorID stringByAppendingString:key];
721 }
722
723 @end
724
725 @implementation NSMutableDictionary (WebInternal)
726
727 - (void)_web_checkLastReferenceForIdentifier:(NSString *)identifier
728 {
729     WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
730     if ([instance retainCount] == 1)
731         [webPreferencesInstances removeObjectForKey:identifier];
732 }
733
734 @end