OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_font_settings_api.h" | 5 #include "chrome/browser/extensions/extension_font_settings_api.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/json/json_writer.h" |
9 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "base/string_util.h" |
10 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "chrome/browser/extensions/extension_event_router.h" |
11 #include "chrome/browser/extensions/extension_preference_helpers.h" | 14 #include "chrome/browser/extensions/extension_preference_helpers.h" |
12 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
13 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 17 #include "chrome/common/chrome_notification_types.h" |
14 #include "chrome/common/extensions/extension_error_utils.h" | 18 #include "chrome/common/extensions/extension_error_utils.h" |
15 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
16 #include "content/public/browser/font_list_async.h" | 20 #include "content/public/browser/font_list_async.h" |
| 21 #include "content/public/browser/notification_details.h" |
| 22 #include "content/public/browser/notification_source.h" |
17 | 23 |
18 #if defined(OS_WIN) | 24 #if defined(OS_WIN) |
19 #include "ui/gfx/font.h" | 25 #include "ui/gfx/font.h" |
20 #include "ui/gfx/platform_font_win.h" | 26 #include "ui/gfx/platform_font_win.h" |
21 #endif | 27 #endif |
22 | 28 |
23 namespace { | 29 namespace { |
24 | 30 |
25 const char kGenericFamilyKey[] = "genericFamily"; | 31 const char kGenericFamilyKey[] = "genericFamily"; |
26 const char kFontNameKey[] = "fontName"; | 32 const char kFontNameKey[] = "fontName"; |
27 const char kLocalizedNameKey[] = "localizedName"; | 33 const char kLocalizedNameKey[] = "localizedName"; |
28 const char kPixelSizeKey[] = "pixelSize"; | 34 const char kPixelSizeKey[] = "pixelSize"; |
29 const char kScriptKey[] = "script"; | 35 const char kScriptKey[] = "script"; |
30 | 36 |
| 37 const char kOnFontNameChanged[] = |
| 38 "experimental.fontSettings.onFontNameChanged"; |
| 39 |
31 // Format for per-script font preference keys. | 40 // Format for per-script font preference keys. |
32 // E.g., "webkit.webprefs.fonts.standard.Hrkt" | 41 // E.g., "webkit.webprefs.fonts.standard.Hrkt" |
33 const char kWebKitPerScriptFontPrefFormat[] = "webkit.webprefs.fonts.%s.%s"; | 42 const char kWebKitPerScriptFontPrefFormat[] = "webkit.webprefs.fonts.%s.%s"; |
| 43 const char kWebKitPerScriptFontPrefPrefix[] = "webkit.webprefs.fonts."; |
34 | 44 |
35 // Format for global (non per-script) font preference keys. | 45 // Format for global (non per-script) font preference keys. |
36 // E.g., "webkit.webprefs.global.fixed_font_family" | 46 // E.g., "webkit.webprefs.global.fixed_font_family" |
37 // Note: there are two meanings of "global" here. The "Global" in the const name | 47 // Note: there are two meanings of "global" here. The "Global" in the const name |
38 // means "not per-script". The "global" in the key itself means "not per-tab" | 48 // means "not per-script". The "global" in the key itself means "not per-tab" |
39 // (per-profile). | 49 // (per-profile). |
40 const char kWebKitGlobalFontPrefFormat[] = | 50 const char kWebKitGlobalFontPrefFormat[] = |
41 "webkit.webprefs.global.%s_font_family"; | 51 "webkit.webprefs.global.%s_font_family"; |
| 52 const char kWebKitGlobalFontPrefPrefix[] = "webkit.webprefs.global."; |
| 53 const char kWebKitGlobalFontPrefSuffix[] = "_font_family"; |
42 | 54 |
43 // Gets the font name preference path from |details| which contains key | 55 // Gets the font name preference path from |details| which contains key |
44 // |kGenericFamilyKey| and optionally |kScriptKey|. | 56 // |kGenericFamilyKey| and optionally |kScriptKey|. |
45 bool GetFontNamePrefPath(DictionaryValue* details, std::string* pref_path) { | 57 bool GetFontNamePrefPath(DictionaryValue* details, std::string* pref_path) { |
46 std::string generic_family; | 58 std::string generic_family; |
47 if (!details->GetString(kGenericFamilyKey, &generic_family)) | 59 if (!details->GetString(kGenericFamilyKey, &generic_family)) |
48 return false; | 60 return false; |
49 | 61 |
50 if (details->HasKey(kScriptKey)) { | 62 if (details->HasKey(kScriptKey)) { |
51 std::string script; | 63 std::string script; |
52 if (!details->GetString(kScriptKey, &script)) | 64 if (!details->GetString(kScriptKey, &script)) |
53 return false; | 65 return false; |
54 *pref_path = StringPrintf(kWebKitPerScriptFontPrefFormat, | 66 *pref_path = StringPrintf(kWebKitPerScriptFontPrefFormat, |
55 generic_family.c_str(), | 67 generic_family.c_str(), |
56 script.c_str()); | 68 script.c_str()); |
57 } else { | 69 } else { |
58 *pref_path = StringPrintf(kWebKitGlobalFontPrefFormat, | 70 *pref_path = StringPrintf(kWebKitGlobalFontPrefFormat, |
59 generic_family.c_str()); | 71 generic_family.c_str()); |
60 } | 72 } |
61 | 73 |
62 return true; | 74 return true; |
63 } | 75 } |
64 | 76 |
| 77 // Extracts the generic family and script from font name pref path |pref_path|. |
| 78 bool ParseFontNamePrefPath(std::string pref_path, |
| 79 std::string* generic_family, |
| 80 std::string* script) { |
| 81 if (StartsWithASCII(pref_path, kWebKitPerScriptFontPrefPrefix, true)) { |
| 82 size_t start = strlen(kWebKitPerScriptFontPrefPrefix); |
| 83 size_t pos = pref_path.find('.', start); |
| 84 if (pos == std::string::npos || pos + 1 == pref_path.length()) |
| 85 return false; |
| 86 *generic_family = pref_path.substr(start, pos - start); |
| 87 *script = pref_path.substr(pos + 1); |
| 88 return true; |
| 89 } else if (StartsWithASCII(pref_path, kWebKitGlobalFontPrefPrefix, true) && |
| 90 EndsWith(pref_path, kWebKitGlobalFontPrefSuffix, true)) { |
| 91 size_t start = strlen(kWebKitGlobalFontPrefPrefix); |
| 92 size_t pos = pref_path.find('_', start); |
| 93 if (pos == std::string::npos || pos + 1 == pref_path.length()) |
| 94 return false; |
| 95 *generic_family = pref_path.substr(start, pos - start); |
| 96 *script = ""; |
| 97 return true; |
| 98 } |
| 99 return false; |
| 100 } |
| 101 |
65 // Returns the localized name of a font so that it can be matched within the | 102 // Returns the localized name of a font so that it can be matched within the |
66 // list of system fonts. On Windows, the list of system fonts has names only | 103 // list of system fonts. On Windows, the list of system fonts has names only |
67 // for the system locale, but the pref value may be in the English name. | 104 // for the system locale, but the pref value may be in the English name. |
68 std::string MaybeGetLocalizedFontName(const std::string& font_name) { | 105 std::string MaybeGetLocalizedFontName(const std::string& font_name) { |
69 #if defined(OS_WIN) | 106 #if defined(OS_WIN) |
70 if (!font_name.empty()) { | 107 if (!font_name.empty()) { |
71 gfx::Font font(font_name, 12); // dummy font size | 108 gfx::Font font(font_name, 12); // dummy font size |
72 return static_cast<gfx::PlatformFontWin*>(font.platform_font())-> | 109 return static_cast<gfx::PlatformFontWin*>(font.platform_font())-> |
73 GetLocalizedFontName(); | 110 GetLocalizedFontName(); |
74 } | 111 } |
75 #endif | 112 #endif |
76 return font_name; | 113 return font_name; |
77 } | 114 } |
78 | 115 |
| 116 // Registers |obs| to observe per-script font prefs under the path |map_name|. |
| 117 void RegisterFontFamilyMapObserver(PrefChangeRegistrar* registrar, |
| 118 const char* map_name, |
| 119 content::NotificationObserver* obs) { |
| 120 for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) { |
| 121 const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i]; |
| 122 std::string pref_name = base::StringPrintf("%s.%s", map_name, script); |
| 123 registrar->Add(pref_name.c_str(), obs); |
| 124 } |
| 125 } |
| 126 |
79 } // namespace | 127 } // namespace |
80 | 128 |
| 129 ExtensionFontSettingsEventRouter::ExtensionFontSettingsEventRouter( |
| 130 Profile* profile) : profile_(profile) {} |
| 131 |
| 132 ExtensionFontSettingsEventRouter::~ExtensionFontSettingsEventRouter() {} |
| 133 |
| 134 void ExtensionFontSettingsEventRouter::Init() { |
| 135 registrar_.Init(profile_->GetPrefs()); |
| 136 registrar_.Add(prefs::kWebKitGlobalStandardFontFamily, this); |
| 137 registrar_.Add(prefs::kWebKitGlobalSerifFontFamily, this); |
| 138 registrar_.Add(prefs::kWebKitGlobalSansSerifFontFamily, this); |
| 139 registrar_.Add(prefs::kWebKitGlobalFixedFontFamily, this); |
| 140 registrar_.Add(prefs::kWebKitGlobalCursiveFontFamily, this); |
| 141 registrar_.Add(prefs::kWebKitGlobalFantasyFontFamily, this); |
| 142 RegisterFontFamilyMapObserver(®istrar_, |
| 143 prefs::kWebKitStandardFontFamilyMap, this); |
| 144 RegisterFontFamilyMapObserver(®istrar_, |
| 145 prefs::kWebKitSerifFontFamilyMap, this); |
| 146 RegisterFontFamilyMapObserver(®istrar_, |
| 147 prefs::kWebKitSansSerifFontFamilyMap, this); |
| 148 RegisterFontFamilyMapObserver(®istrar_, |
| 149 prefs::kWebKitFixedFontFamilyMap, this); |
| 150 RegisterFontFamilyMapObserver(®istrar_, |
| 151 prefs::kWebKitCursiveFontFamilyMap, this); |
| 152 RegisterFontFamilyMapObserver(®istrar_, |
| 153 prefs::kWebKitFantasyFontFamilyMap, this); |
| 154 } |
| 155 |
| 156 void ExtensionFontSettingsEventRouter::Observe( |
| 157 int type, |
| 158 const content::NotificationSource& source, |
| 159 const content::NotificationDetails& details) { |
| 160 if (type != chrome::NOTIFICATION_PREF_CHANGED) { |
| 161 NOTREACHED(); |
| 162 return; |
| 163 } |
| 164 |
| 165 const std::string* pref_key = |
| 166 content::Details<const std::string>(details).ptr(); |
| 167 std::string generic_family; |
| 168 std::string script; |
| 169 if (!ParseFontNamePrefPath(*pref_key, &generic_family, &script)) { |
| 170 NOTREACHED(); |
| 171 return; |
| 172 } |
| 173 |
| 174 PrefService* pref_service = content::Source<PrefService>(source).ptr(); |
| 175 bool incognito = (pref_service != profile_->GetPrefs()); |
| 176 // We're only observing pref changes on the regular profile. |
| 177 DCHECK(!incognito); |
| 178 const PrefService::Preference* pref = pref_service->FindPreference( |
| 179 pref_key->c_str()); |
| 180 CHECK(pref); |
| 181 |
| 182 std::string font_name; |
| 183 if (!pref->GetValue()->GetAsString(&font_name)) { |
| 184 NOTREACHED(); |
| 185 return; |
| 186 } |
| 187 font_name = MaybeGetLocalizedFontName(font_name); |
| 188 |
| 189 ListValue args; |
| 190 DictionaryValue* dict = new DictionaryValue(); |
| 191 args.Append(dict); |
| 192 dict->SetString(kFontNameKey, font_name); |
| 193 dict->SetString(kGenericFamilyKey, generic_family); |
| 194 if (!script.empty()) |
| 195 dict->SetString(kScriptKey, script); |
| 196 |
| 197 extension_preference_helpers::DispatchEventToExtensions( |
| 198 profile_, |
| 199 kOnFontNameChanged, |
| 200 &args, |
| 201 ExtensionAPIPermission::kExperimental, |
| 202 incognito, |
| 203 *pref_key); |
| 204 } |
| 205 |
81 bool GetFontNameFunction::RunImpl() { | 206 bool GetFontNameFunction::RunImpl() { |
82 DictionaryValue* details = NULL; | 207 DictionaryValue* details = NULL; |
83 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); | 208 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
84 | 209 |
85 std::string pref_path; | 210 std::string pref_path; |
86 EXTENSION_FUNCTION_VALIDATE(GetFontNamePrefPath(details, &pref_path)); | 211 EXTENSION_FUNCTION_VALIDATE(GetFontNamePrefPath(details, &pref_path)); |
87 | 212 |
88 PrefService* prefs = profile_->GetPrefs(); | 213 PrefService* prefs = profile_->GetPrefs(); |
89 const PrefService::Preference* pref = | 214 const PrefService::Preference* pref = |
90 prefs->FindPreference(pref_path.c_str()); | 215 prefs->FindPreference(pref_path.c_str()); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 return prefs::kWebKitGlobalDefaultFixedFontSize; | 329 return prefs::kWebKitGlobalDefaultFixedFontSize; |
205 } | 330 } |
206 | 331 |
207 const char* GetMinimumFontSizeFunction::GetPrefName() { | 332 const char* GetMinimumFontSizeFunction::GetPrefName() { |
208 return prefs::kWebKitGlobalMinimumFontSize; | 333 return prefs::kWebKitGlobalMinimumFontSize; |
209 } | 334 } |
210 | 335 |
211 const char* SetMinimumFontSizeFunction::GetPrefName() { | 336 const char* SetMinimumFontSizeFunction::GetPrefName() { |
212 return prefs::kWebKitGlobalMinimumFontSize; | 337 return prefs::kWebKitGlobalMinimumFontSize; |
213 } | 338 } |
OLD | NEW |