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