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