1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/prefs/prefs_tab_helper.h" 6 7 #include <string> 8 9 #include "base/prefs/overlay_user_pref_store.h" 10 #include "base/prefs/pref_service.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/stringprintf.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/renderer_preferences_util.h" 18 #include "chrome/common/pref_font_webkit_names.h" 19 #include "chrome/common/pref_names.h" 20 #include "chrome/common/pref_names_util.h" 21 #include "components/pref_registry/pref_registry_syncable.h" 22 #include "content/public/browser/notification_details.h" 23 #include "content/public/browser/notification_service.h" 24 #include "content/public/browser/render_view_host.h" 25 #include "content/public/browser/web_contents.h" 26 #include "grit/locale_settings.h" 27 #include "grit/platform_locale_settings.h" 28 #include "third_party/icu/source/common/unicode/uchar.h" 29 #include "third_party/icu/source/common/unicode/uscript.h" 30 #include "ui/base/l10n/l10n_util.h" 31 #include "webkit/common/webpreferences.h" 32 33 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES) 34 #include "chrome/browser/themes/theme_service.h" 35 #include "chrome/browser/themes/theme_service_factory.h" 36 #endif 37 38 #if defined(OS_WIN) 39 #include "base/win/windows_version.h" 40 #endif 41 42 using content::WebContents; 43 44 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PrefsTabHelper); 45 46 namespace { 47 48 // The list of prefs we want to observe. 49 const char* kPrefsToObserve[] = { 50 prefs::kDefaultCharset, 51 prefs::kWebKitAllowDisplayingInsecureContent, 52 prefs::kWebKitAllowRunningInsecureContent, 53 prefs::kWebKitDefaultFixedFontSize, 54 prefs::kWebKitDefaultFontSize, 55 #if defined(OS_ANDROID) 56 prefs::kWebKitFontScaleFactor, 57 prefs::kWebKitForceEnableZoom, 58 prefs::kWebKitPasswordEchoEnabled, 59 #endif 60 prefs::kWebKitJavascriptEnabled, 61 prefs::kWebKitJavaEnabled, 62 prefs::kWebKitLoadsImagesAutomatically, 63 prefs::kWebKitMinimumFontSize, 64 prefs::kWebKitMinimumLogicalFontSize, 65 prefs::kWebKitPluginsEnabled, 66 prefs::kWebkitTabsToLinks, 67 prefs::kWebKitUsesUniversalDetector 68 }; 69 70 const int kPrefsToObserveLength = arraysize(kPrefsToObserve); 71 72 #if !defined(OS_ANDROID) 73 // Registers a preference under the path |pref_name| for each script used for 74 // per-script font prefs. 75 // For example, for WEBKIT_WEBPREFS_FONTS_SERIF ("fonts.serif"): 76 // "fonts.serif.Arab", "fonts.serif.Hang", etc. are registered. 77 // |fonts_with_defaults| contains all |pref_names| already registered since they 78 // have a specified default value. 79 // On Android there are no default values for these properties and there is no 80 // way to set them (because extensions are not supported so the Font Settings 81 // API cannot be used), so we can avoid registering them altogether. 82 void RegisterFontFamilyPrefs(user_prefs::PrefRegistrySyncable* registry, 83 const std::set<std::string>& fonts_with_defaults) { 84 85 // Expand the font concatenated with script name so this stays at RO memory 86 // rather than allocated in heap. 87 static const char* const kFontFamilyMap[] = { 88 #define EXPAND_SCRIPT_FONT(map_name, script_name) map_name "." script_name, 89 90 #include "chrome/common/pref_font_script_names-inl.h" 91 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_CURSIVE) 92 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_FANTASY) 93 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_FIXED) 94 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_PICTOGRAPH) 95 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_SANSERIF) 96 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_SERIF) 97 ALL_FONT_SCRIPTS(WEBKIT_WEBPREFS_FONTS_STANDARD) 98 99 #undef EXPAND_SCRIPT_FONT 100 }; 101 102 for (size_t i = 0; i < arraysize(kFontFamilyMap); ++i) { 103 const char* pref_name = kFontFamilyMap[i]; 104 if (fonts_with_defaults.find(pref_name) == fonts_with_defaults.end()) { 105 // We haven't already set a default value for this font preference, so set 106 // an empty string as the default. 107 registry->RegisterStringPref( 108 pref_name, 109 std::string(), 110 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 111 } 112 } 113 } 114 115 // Registers |obs| to observe per-script font prefs under the path |map_name|. 116 // On android, there's no exposed way to change these prefs, so we can save 117 // ~715KB of heap and some startup cycles by avoiding observing these prefs 118 // since they will never change. 119 void RegisterFontFamilyMapObserver( 120 PrefChangeRegistrar* registrar, 121 const char* map_name, 122 const PrefChangeRegistrar::NamedChangeCallback& obs) { 123 DCHECK(StartsWithASCII(map_name, "webkit.webprefs.", true)); 124 for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) { 125 const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i]; 126 std::string pref_name = base::StringPrintf("%s.%s", map_name, script); 127 registrar->Add(pref_name.c_str(), obs); 128 } 129 } 130 #endif // !defined(OS_ANDROID) 131 132 #if defined(OS_WIN) 133 // On Windows with antialising we want to use an alternate fixed font like 134 // Consolas, which looks much better than Courier New. 135 bool ShouldUseAlternateDefaultFixedFont(const std::string& script) { 136 if (!StartsWithASCII(script, "courier", false)) 137 return false; 138 UINT smooth_type = 0; 139 SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &smooth_type, 0); 140 return (base::win::GetVersion() >= base::win::VERSION_WIN7) && 141 (smooth_type == FE_FONTSMOOTHINGCLEARTYPE); 142 } 143 #endif 144 145 struct FontDefault { 146 const char* pref_name; 147 int resource_id; 148 }; 149 150 // Font pref defaults. The prefs that have defaults vary by platform, since not 151 // all platforms have fonts for all scripts for all generic families. 152 // TODO(falken): add proper defaults when possible for all 153 // platforms/scripts/generic families. 154 const FontDefault kFontDefaults[] = { 155 { prefs::kWebKitStandardFontFamily, IDS_STANDARD_FONT_FAMILY }, 156 { prefs::kWebKitFixedFontFamily, IDS_FIXED_FONT_FAMILY }, 157 { prefs::kWebKitSerifFontFamily, IDS_SERIF_FONT_FAMILY }, 158 { prefs::kWebKitSansSerifFontFamily, IDS_SANS_SERIF_FONT_FAMILY }, 159 { prefs::kWebKitCursiveFontFamily, IDS_CURSIVE_FONT_FAMILY }, 160 { prefs::kWebKitFantasyFontFamily, IDS_FANTASY_FONT_FAMILY }, 161 { prefs::kWebKitPictographFontFamily, IDS_PICTOGRAPH_FONT_FAMILY }, 162 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN) 163 { prefs::kWebKitStandardFontFamilyJapanese, 164 IDS_STANDARD_FONT_FAMILY_JAPANESE }, 165 { prefs::kWebKitFixedFontFamilyJapanese, IDS_FIXED_FONT_FAMILY_JAPANESE }, 166 { prefs::kWebKitSerifFontFamilyJapanese, IDS_SERIF_FONT_FAMILY_JAPANESE }, 167 { prefs::kWebKitSansSerifFontFamilyJapanese, 168 IDS_SANS_SERIF_FONT_FAMILY_JAPANESE }, 169 { prefs::kWebKitStandardFontFamilyKorean, IDS_STANDARD_FONT_FAMILY_KOREAN }, 170 { prefs::kWebKitSerifFontFamilyKorean, IDS_SERIF_FONT_FAMILY_KOREAN }, 171 { prefs::kWebKitSansSerifFontFamilyKorean, 172 IDS_SANS_SERIF_FONT_FAMILY_KOREAN }, 173 { prefs::kWebKitStandardFontFamilySimplifiedHan, 174 IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN }, 175 { prefs::kWebKitSerifFontFamilySimplifiedHan, 176 IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN }, 177 { prefs::kWebKitSansSerifFontFamilySimplifiedHan, 178 IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN }, 179 { prefs::kWebKitStandardFontFamilyTraditionalHan, 180 IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN }, 181 { prefs::kWebKitSerifFontFamilyTraditionalHan, 182 IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN }, 183 { prefs::kWebKitSansSerifFontFamilyTraditionalHan, 184 IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN }, 185 #endif 186 #if defined(OS_CHROMEOS) 187 { prefs::kWebKitStandardFontFamilyArabic, IDS_STANDARD_FONT_FAMILY_ARABIC }, 188 { prefs::kWebKitSerifFontFamilyArabic, IDS_SERIF_FONT_FAMILY_ARABIC }, 189 { prefs::kWebKitSansSerifFontFamilyArabic, 190 IDS_SANS_SERIF_FONT_FAMILY_ARABIC }, 191 { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN }, 192 { prefs::kWebKitFixedFontFamilySimplifiedHan, 193 IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN }, 194 { prefs::kWebKitFixedFontFamilyTraditionalHan, 195 IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN }, 196 #elif defined(OS_WIN) 197 { prefs::kWebKitStandardFontFamilyCyrillic, 198 IDS_STANDARD_FONT_FAMILY_CYRILLIC }, 199 { prefs::kWebKitFixedFontFamilyCyrillic, IDS_FIXED_FONT_FAMILY_CYRILLIC }, 200 { prefs::kWebKitSerifFontFamilyCyrillic, IDS_SERIF_FONT_FAMILY_CYRILLIC }, 201 { prefs::kWebKitSansSerifFontFamilyCyrillic, 202 IDS_SANS_SERIF_FONT_FAMILY_CYRILLIC }, 203 { prefs::kWebKitStandardFontFamilyGreek, IDS_STANDARD_FONT_FAMILY_GREEK }, 204 { prefs::kWebKitFixedFontFamilyGreek, IDS_FIXED_FONT_FAMILY_GREEK }, 205 { prefs::kWebKitSerifFontFamilyGreek, IDS_SERIF_FONT_FAMILY_GREEK }, 206 { prefs::kWebKitSansSerifFontFamilyGreek, IDS_SANS_SERIF_FONT_FAMILY_GREEK }, 207 { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN }, 208 { prefs::kWebKitCursiveFontFamilyKorean, IDS_CURSIVE_FONT_FAMILY_KOREAN }, 209 { prefs::kWebKitFixedFontFamilySimplifiedHan, 210 IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN }, 211 { prefs::kWebKitFixedFontFamilyTraditionalHan, 212 IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN }, 213 #endif 214 }; 215 216 const size_t kFontDefaultsLength = arraysize(kFontDefaults); 217 218 // Returns the script of the font pref |pref_name|. For example, suppose 219 // |pref_name| is "webkit.webprefs.fonts.serif.Hant". Since the script code for 220 // the script name "Hant" is USCRIPT_TRADITIONAL_HAN, the function returns 221 // USCRIPT_TRADITIONAL_HAN. |pref_name| must be a valid font pref name. 222 UScriptCode GetScriptOfFontPref(const char* pref_name) { 223 // ICU script names are four letters. 224 static const size_t kScriptNameLength = 4; 225 226 size_t len = strlen(pref_name); 227 DCHECK_GT(len, kScriptNameLength); 228 const char* scriptName = &pref_name[len - kScriptNameLength]; 229 int32 code = u_getPropertyValueEnum(UCHAR_SCRIPT, scriptName); 230 DCHECK(code >= 0 && code < USCRIPT_CODE_LIMIT); 231 return static_cast<UScriptCode>(code); 232 } 233 234 // If |scriptCode| is a member of a family of "similar" script codes, returns 235 // the script code in that family that is used in font pref names. For example, 236 // USCRIPT_HANGUL and USCRIPT_KOREAN are considered equivalent for the purposes 237 // of font selection. Chrome uses the script code USCRIPT_HANGUL (script name 238 // "Hang") in Korean font pref names (for example, 239 // "webkit.webprefs.fonts.serif.Hang"). So, if |scriptCode| is USCRIPT_KOREAN, 240 // the function returns USCRIPT_HANGUL. If |scriptCode| is not a member of such 241 // a family, returns |scriptCode|. 242 UScriptCode GetScriptForFontPrefMatching(UScriptCode scriptCode) { 243 switch (scriptCode) { 244 case USCRIPT_HIRAGANA: 245 case USCRIPT_KATAKANA: 246 case USCRIPT_KATAKANA_OR_HIRAGANA: 247 return USCRIPT_JAPANESE; 248 case USCRIPT_KOREAN: 249 return USCRIPT_HANGUL; 250 default: 251 return scriptCode; 252 } 253 } 254 255 // Returns the primary script used by the browser's UI locale. For example, if 256 // the locale is "ru", the function returns USCRIPT_CYRILLIC, and if the locale 257 // is "en", the function returns USCRIPT_LATIN. 258 UScriptCode GetScriptOfBrowserLocale() { 259 std::string locale = g_browser_process->GetApplicationLocale(); 260 261 // For Chinese locales, uscript_getCode() just returns USCRIPT_HAN but our 262 // per-script fonts are for USCRIPT_SIMPLIFIED_HAN and 263 // USCRIPT_TRADITIONAL_HAN. 264 if (locale == "zh-CN") 265 return USCRIPT_SIMPLIFIED_HAN; 266 if (locale == "zh-TW") 267 return USCRIPT_TRADITIONAL_HAN; 268 269 UScriptCode code = USCRIPT_INVALID_CODE; 270 UErrorCode err = U_ZERO_ERROR; 271 uscript_getCode(locale.c_str(), &code, 1, &err); 272 273 // Ignore the error that multiple scripts could be returned, since we only 274 // want one script. 275 if (U_FAILURE(err) && err != U_BUFFER_OVERFLOW_ERROR) 276 code = USCRIPT_INVALID_CODE; 277 return GetScriptForFontPrefMatching(code); 278 } 279 280 // Sets a font family pref in |prefs| to |pref_value|. 281 void OverrideFontFamily(WebPreferences* prefs, 282 const std::string& generic_family, 283 const std::string& script, 284 const std::string& pref_value) { 285 webkit_glue::ScriptFontFamilyMap* map = NULL; 286 if (generic_family == "standard") 287 map = &prefs->standard_font_family_map; 288 else if (generic_family == "fixed") 289 map = &prefs->fixed_font_family_map; 290 else if (generic_family == "serif") 291 map = &prefs->serif_font_family_map; 292 else if (generic_family == "sansserif") 293 map = &prefs->sans_serif_font_family_map; 294 else if (generic_family == "cursive") 295 map = &prefs->cursive_font_family_map; 296 else if (generic_family == "fantasy") 297 map = &prefs->fantasy_font_family_map; 298 else if (generic_family == "pictograph") 299 map = &prefs->pictograph_font_family_map; 300 else 301 NOTREACHED() << "Unknown generic font family: " << generic_family; 302 (*map)[script] = base::UTF8ToUTF16(pref_value); 303 } 304 305 } // namespace 306 307 PrefsTabHelper::PrefsTabHelper(WebContents* contents) 308 : web_contents_(contents), 309 weak_ptr_factory_(this) { 310 PrefService* prefs = GetProfile()->GetPrefs(); 311 pref_change_registrar_.Init(prefs); 312 if (prefs) { 313 base::Closure renderer_callback = base::Bind( 314 &PrefsTabHelper::UpdateRendererPreferences, base::Unretained(this)); 315 pref_change_registrar_.Add(prefs::kAcceptLanguages, renderer_callback); 316 pref_change_registrar_.Add(prefs::kDefaultZoomLevel, renderer_callback); 317 pref_change_registrar_.Add(prefs::kEnableDoNotTrack, renderer_callback); 318 pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback); 319 320 #if !defined(OS_MACOSX) 321 pref_change_registrar_.Add(prefs::kFullscreenAllowed, renderer_callback); 322 #endif 323 324 PrefChangeRegistrar::NamedChangeCallback webkit_callback = base::Bind( 325 &PrefsTabHelper::OnWebPrefChanged, base::Unretained(this)); 326 for (int i = 0; i < kPrefsToObserveLength; ++i) { 327 const char* pref_name = kPrefsToObserve[i]; 328 DCHECK(std::string(pref_name) == prefs::kDefaultCharset || 329 StartsWithASCII(pref_name, "webkit.webprefs.", true)); 330 pref_change_registrar_.Add(pref_name, webkit_callback); 331 } 332 333 #if !defined(OS_ANDROID) 334 RegisterFontFamilyMapObserver(&pref_change_registrar_, 335 prefs::kWebKitStandardFontFamilyMap, 336 webkit_callback); 337 RegisterFontFamilyMapObserver(&pref_change_registrar_, 338 prefs::kWebKitFixedFontFamilyMap, 339 webkit_callback); 340 RegisterFontFamilyMapObserver(&pref_change_registrar_, 341 prefs::kWebKitSerifFontFamilyMap, 342 webkit_callback); 343 RegisterFontFamilyMapObserver(&pref_change_registrar_, 344 prefs::kWebKitSansSerifFontFamilyMap, 345 webkit_callback); 346 RegisterFontFamilyMapObserver(&pref_change_registrar_, 347 prefs::kWebKitCursiveFontFamilyMap, 348 webkit_callback); 349 RegisterFontFamilyMapObserver(&pref_change_registrar_, 350 prefs::kWebKitFantasyFontFamilyMap, 351 webkit_callback); 352 RegisterFontFamilyMapObserver(&pref_change_registrar_, 353 prefs::kWebKitPictographFontFamilyMap, 354 webkit_callback); 355 #endif // !defined(OS_ANDROID) 356 } 357 358 renderer_preferences_util::UpdateFromSystemSettings( 359 web_contents_->GetMutableRendererPrefs(), GetProfile()); 360 361 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES) 362 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, 363 content::Source<ThemeService>( 364 ThemeServiceFactory::GetForProfile(GetProfile()))); 365 #endif 366 #if defined(USE_AURA) 367 registrar_.Add(this, 368 chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED, 369 content::NotificationService::AllSources()); 370 #endif 371 } 372 373 PrefsTabHelper::~PrefsTabHelper() { 374 } 375 376 // static 377 void PrefsTabHelper::InitIncognitoUserPrefStore( 378 OverlayUserPrefStore* pref_store) { 379 // List of keys that cannot be changed in the user prefs file by the incognito 380 // profile. All preferences that store information about the browsing history 381 // or behavior of the user should have this property. 382 pref_store->RegisterOverlayPref(prefs::kBrowserWindowPlacement); 383 pref_store->RegisterOverlayPref(prefs::kSaveFileDefaultDirectory); 384 #if defined(OS_ANDROID) || defined(OS_IOS) 385 pref_store->RegisterOverlayPref(prefs::kProxy); 386 #endif // defined(OS_ANDROID) || defined(OS_IOS) 387 } 388 389 // static 390 void PrefsTabHelper::RegisterProfilePrefs( 391 user_prefs::PrefRegistrySyncable* registry) { 392 WebPreferences pref_defaults; 393 registry->RegisterBooleanPref( 394 prefs::kWebKitJavascriptEnabled, 395 pref_defaults.javascript_enabled, 396 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 397 registry->RegisterBooleanPref( 398 prefs::kWebKitWebSecurityEnabled, 399 pref_defaults.web_security_enabled, 400 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 401 registry->RegisterBooleanPref( 402 prefs::kWebKitJavascriptCanOpenWindowsAutomatically, 403 true, 404 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 405 registry->RegisterBooleanPref( 406 prefs::kWebKitLoadsImagesAutomatically, 407 pref_defaults.loads_images_automatically, 408 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 409 registry->RegisterBooleanPref( 410 prefs::kWebKitPluginsEnabled, 411 pref_defaults.plugins_enabled, 412 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 413 registry->RegisterBooleanPref( 414 prefs::kWebKitDomPasteEnabled, 415 pref_defaults.dom_paste_enabled, 416 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 417 registry->RegisterBooleanPref( 418 prefs::kWebKitShrinksStandaloneImagesToFit, 419 pref_defaults.shrinks_standalone_images_to_fit, 420 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 421 registry->RegisterDictionaryPref( 422 prefs::kWebKitInspectorSettings, 423 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 424 registry->RegisterBooleanPref( 425 prefs::kWebKitTextAreasAreResizable, 426 pref_defaults.text_areas_are_resizable, 427 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 428 registry->RegisterBooleanPref( 429 prefs::kWebKitJavaEnabled, 430 pref_defaults.java_enabled, 431 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 432 registry->RegisterBooleanPref( 433 prefs::kWebkitTabsToLinks, 434 pref_defaults.tabs_to_links, 435 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 436 registry->RegisterBooleanPref( 437 prefs::kWebKitAllowRunningInsecureContent, 438 false, 439 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 440 registry->RegisterBooleanPref( 441 prefs::kWebKitAllowDisplayingInsecureContent, 442 true, 443 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 444 registry->RegisterBooleanPref( 445 prefs::kEnableReferrers, 446 true, 447 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 448 #if defined(OS_ANDROID) 449 registry->RegisterDoublePref( 450 prefs::kWebKitFontScaleFactor, 451 1.0, 452 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 453 registry->RegisterBooleanPref( 454 prefs::kWebKitForceEnableZoom, 455 pref_defaults.force_enable_zoom, 456 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 457 registry->RegisterBooleanPref( 458 prefs::kWebKitPasswordEchoEnabled, 459 pref_defaults.password_echo_enabled, 460 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 461 #endif 462 registry->RegisterLocalizedStringPref( 463 prefs::kAcceptLanguages, 464 IDS_ACCEPT_LANGUAGES, 465 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 466 registry->RegisterLocalizedStringPref( 467 prefs::kDefaultCharset, 468 IDS_DEFAULT_ENCODING, 469 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 470 471 // Register font prefs that have defaults. 472 std::set<std::string> fonts_with_defaults; 473 UScriptCode browser_script = GetScriptOfBrowserLocale(); 474 for (size_t i = 0; i < kFontDefaultsLength; ++i) { 475 FontDefault pref = kFontDefaults[i]; 476 477 #if defined(OS_WIN) 478 if (pref.pref_name == prefs::kWebKitFixedFontFamily) { 479 if (ShouldUseAlternateDefaultFixedFont( 480 l10n_util::GetStringUTF8(pref.resource_id))) 481 pref.resource_id = IDS_FIXED_FONT_FAMILY_ALT_WIN; 482 } 483 #endif 484 485 UScriptCode pref_script = GetScriptOfFontPref(pref.pref_name); 486 487 // Suppress this default font pref value if it is for the primary script of 488 // the browser's UI locale. For example, if the pref is for the sans-serif 489 // font for the Cyrillic script, and the browser locale is "ru" (Russian), 490 // the default is suppressed. Otherwise, the default would override the 491 // user's font preferences when viewing pages in their native language. 492 // This is because users have no way yet of customizing their per-script 493 // font preferences. The font prefs accessible in the options UI are for 494 // the default, unknown script; these prefs have less priority than the 495 // per-script font prefs when the script of the content is known. This code 496 // can possibly be removed later if users can easily access per-script font 497 // prefs (e.g., via the extensions workflow), or the problem turns out to 498 // not be really critical after all. 499 if (browser_script != pref_script) { 500 registry->RegisterLocalizedStringPref( 501 pref.pref_name, 502 pref.resource_id, 503 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 504 fonts_with_defaults.insert(pref.pref_name); 505 } 506 } 507 508 // Register per-script font prefs that don't have defaults. 509 #if !defined(OS_ANDROID) 510 RegisterFontFamilyPrefs(registry, fonts_with_defaults); 511 #endif 512 513 registry->RegisterLocalizedIntegerPref( 514 prefs::kWebKitDefaultFontSize, 515 IDS_DEFAULT_FONT_SIZE, 516 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 517 registry->RegisterLocalizedIntegerPref( 518 prefs::kWebKitDefaultFixedFontSize, 519 IDS_DEFAULT_FIXED_FONT_SIZE, 520 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 521 registry->RegisterLocalizedIntegerPref( 522 prefs::kWebKitMinimumFontSize, 523 IDS_MINIMUM_FONT_SIZE, 524 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 525 registry->RegisterLocalizedIntegerPref( 526 prefs::kWebKitMinimumLogicalFontSize, 527 IDS_MINIMUM_LOGICAL_FONT_SIZE, 528 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 529 registry->RegisterLocalizedBooleanPref( 530 prefs::kWebKitUsesUniversalDetector, 531 IDS_USES_UNIVERSAL_DETECTOR, 532 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 533 registry->RegisterLocalizedStringPref( 534 prefs::kStaticEncodings, 535 IDS_STATIC_ENCODING_LIST, 536 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 537 registry->RegisterStringPref( 538 prefs::kRecentlySelectedEncoding, 539 std::string(), 540 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 541 } 542 543 void PrefsTabHelper::Observe(int type, 544 const content::NotificationSource& source, 545 const content::NotificationDetails& details) { 546 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES) 547 if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) { 548 UpdateRendererPreferences(); 549 return; 550 } 551 #endif 552 553 #if defined(USE_AURA) 554 if (type == chrome::NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED) { 555 UpdateRendererPreferences(); 556 return; 557 } 558 #endif // defined(USE_AURA) 559 560 NOTREACHED(); 561 } 562 563 void PrefsTabHelper::UpdateWebPreferences() { 564 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences( 565 web_contents_->GetRenderViewHost()->GetWebkitPreferences()); 566 } 567 568 void PrefsTabHelper::UpdateRendererPreferences() { 569 renderer_preferences_util::UpdateFromSystemSettings( 570 web_contents_->GetMutableRendererPrefs(), GetProfile()); 571 web_contents_->GetRenderViewHost()->SyncRendererPrefs(); 572 } 573 574 Profile* PrefsTabHelper::GetProfile() { 575 return Profile::FromBrowserContext(web_contents_->GetBrowserContext()); 576 } 577 578 void PrefsTabHelper::OnWebPrefChanged(const std::string& pref_name) { 579 // When a font family pref's value goes from non-empty to the empty string, we 580 // must add it to the usual WebPreferences struct passed to the renderer. 581 // 582 // The empty string means to fall back to the pref for the Common script 583 // ("Zyyy"). For example, if chrome.fonts.serif.Cyrl is the empty string, it 584 // means to use chrome.fonts.serif.Zyyy for Cyrillic script. Prefs that are 585 // the empty string are normally not passed to WebKit, since there are so many 586 // of them that it would cause a performance regression. Not passing the pref 587 // is normally okay since WebKit does the desired fallback behavior regardless 588 // of whether the empty string is passed or the pref is not passed at all. But 589 // if the pref has changed from non-empty to the empty string, we must let 590 // WebKit know. 591 std::string generic_family; 592 std::string script; 593 if (pref_names_util::ParseFontNamePrefPath(pref_name, 594 &generic_family, 595 &script)) { 596 PrefService* prefs = GetProfile()->GetPrefs(); 597 std::string pref_value = prefs->GetString(pref_name.c_str()); 598 if (pref_value.empty()) { 599 WebPreferences web_prefs = 600 web_contents_->GetRenderViewHost()->GetWebkitPreferences(); 601 OverrideFontFamily(&web_prefs, generic_family, script, std::string()); 602 web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(web_prefs); 603 return; 604 } 605 } 606 607 UpdateWebPreferences(); 608 } 609