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