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