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"; |
33 const char kLevelOfControlKey[] = "levelOfControl"; | |
27 const char kLocalizedNameKey[] = "localizedName"; | 34 const char kLocalizedNameKey[] = "localizedName"; |
28 const char kPixelSizeKey[] = "pixelSize"; | 35 const char kPixelSizeKey[] = "pixelSize"; |
29 const char kScriptKey[] = "script"; | 36 const char kScriptKey[] = "script"; |
30 | 37 |
38 const char kOnFontNameChanged[] = | |
39 "experimental.fontSettings.onFontNameChanged"; | |
40 | |
31 // Format for per-script font preference keys. | 41 // Format for per-script font preference keys. |
32 // E.g., "webkit.webprefs.fonts.standard.Hrkt" | 42 // E.g., "webkit.webprefs.fonts.standard.Hrkt" |
33 const char kWebKitPerScriptFontPrefFormat[] = "webkit.webprefs.fonts.%s.%s"; | 43 const char kWebKitPerScriptFontPrefFormat[] = "webkit.webprefs.fonts.%s.%s"; |
44 const char kWebKitPerScriptFontPrefPrefix[] = "webkit.webprefs.fonts."; | |
34 | 45 |
35 // Format for global (non per-script) font preference keys. | 46 // Format for global (non per-script) font preference keys. |
36 // E.g., "webkit.webprefs.global.fixed_font_family" | 47 // E.g., "webkit.webprefs.global.fixed_font_family" |
37 // Note: there are two meanings of "global" here. The "Global" in the const name | 48 // 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" | 49 // means "not per-script". The "global" in the key itself means "not per-tab" |
39 // (per-profile). | 50 // (per-profile). |
40 const char kWebKitGlobalFontPrefFormat[] = | 51 const char kWebKitGlobalFontPrefFormat[] = |
41 "webkit.webprefs.global.%s_font_family"; | 52 "webkit.webprefs.global.%s_font_family"; |
53 const char kWebKitGlobalFontPrefPrefix[] = "webkit.webprefs.global."; | |
54 const char kWebKitGlobalFontPrefSuffix[] = "_font_family"; | |
42 | 55 |
43 // Gets the font name preference path from |details| which contains key | 56 // Gets the font name preference path from |details| which contains key |
44 // |kGenericFamilyKey| and optionally |kScriptKey|. | 57 // |kGenericFamilyKey| and optionally |kScriptKey|. |
45 bool GetFontNamePrefPath(DictionaryValue* details, std::string* pref_path) { | 58 bool GetFontNamePrefPath(DictionaryValue* details, std::string* pref_path) { |
46 std::string generic_family; | 59 std::string generic_family; |
47 if (!details->GetString(kGenericFamilyKey, &generic_family)) | 60 if (!details->GetString(kGenericFamilyKey, &generic_family)) |
48 return false; | 61 return false; |
49 | 62 |
50 if (details->HasKey(kScriptKey)) { | 63 if (details->HasKey(kScriptKey)) { |
51 std::string script; | 64 std::string script; |
52 if (!details->GetString(kScriptKey, &script)) | 65 if (!details->GetString(kScriptKey, &script)) |
53 return false; | 66 return false; |
54 *pref_path = StringPrintf(kWebKitPerScriptFontPrefFormat, | 67 *pref_path = StringPrintf(kWebKitPerScriptFontPrefFormat, |
55 generic_family.c_str(), | 68 generic_family.c_str(), |
56 script.c_str()); | 69 script.c_str()); |
57 } else { | 70 } else { |
58 *pref_path = StringPrintf(kWebKitGlobalFontPrefFormat, | 71 *pref_path = StringPrintf(kWebKitGlobalFontPrefFormat, |
59 generic_family.c_str()); | 72 generic_family.c_str()); |
60 } | 73 } |
61 | 74 |
62 return true; | 75 return true; |
63 } | 76 } |
64 | 77 |
78 // Extracts the generic family and script from font name pref path |pref_path|. | |
79 bool ParseFontNamePrefPath(std::string pref_path, | |
80 std::string* generic_family, | |
81 std::string* script) { | |
82 if (StartsWithASCII(pref_path, kWebKitPerScriptFontPrefPrefix, true)) { | |
83 size_t start = strlen(kWebKitPerScriptFontPrefPrefix); | |
84 size_t pos = pref_path.find('.', start); | |
85 if (pos == std::string::npos || pos + 1 == pref_path.length()) { | |
86 NOTREACHED(); | |
Bernhard Bauer
2012/04/12 13:14:01
If you're already DCHECKing the return value, you
falken
2012/04/13 10:33:46
Good point, thanks. Removed the check.
| |
87 return false; | |
88 } | |
89 *generic_family = pref_path.substr(start, pos - start); | |
90 *script = pref_path.substr(pos + 1); | |
91 return true; | |
92 } else if (StartsWithASCII(pref_path, kWebKitGlobalFontPrefPrefix, true) && | |
93 EndsWith(pref_path, kWebKitGlobalFontPrefSuffix, true)) { | |
94 size_t start = strlen(kWebKitGlobalFontPrefPrefix); | |
95 size_t pos = pref_path.find('_', start); | |
96 if (pos == std::string::npos || pos + 1 == pref_path.length()) { | |
97 NOTREACHED(); | |
98 return false; | |
99 } | |
100 *generic_family = pref_path.substr(start, pos - start); | |
101 *script = ""; | |
102 return true; | |
103 } | |
104 return false; | |
105 } | |
106 | |
65 // Returns the localized name of a font so that it can be matched within the | 107 // 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 | 108 // 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. | 109 // for the system locale, but the pref value may be in the English name. |
68 std::string MaybeGetLocalizedFontName(const std::string& font_name) { | 110 std::string MaybeGetLocalizedFontName(const std::string& font_name) { |
69 #if defined(OS_WIN) | 111 #if defined(OS_WIN) |
70 if (!font_name.empty()) { | 112 if (!font_name.empty()) { |
71 gfx::Font font(font_name, 12); // dummy font size | 113 gfx::Font font(font_name, 12); // dummy font size |
72 return static_cast<gfx::PlatformFontWin*>(font.platform_font())-> | 114 return static_cast<gfx::PlatformFontWin*>(font.platform_font())-> |
73 GetLocalizedFontName(); | 115 GetLocalizedFontName(); |
74 } | 116 } |
75 #endif | 117 #endif |
76 return font_name; | 118 return font_name; |
77 } | 119 } |
78 | 120 |
121 // Registers |obs| to observe per-script font prefs under the path |map_name|. | |
122 void RegisterFontFamilyMapObserver(PrefChangeRegistrar* registrar, | |
123 const char* map_name, | |
124 content::NotificationObserver* obs) { | |
125 for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) { | |
126 const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i]; | |
127 std::string pref_name = base::StringPrintf("%s.%s", map_name, script); | |
128 registrar->Add(pref_name.c_str(), obs); | |
129 } | |
130 } | |
131 | |
79 } // namespace | 132 } // namespace |
80 | 133 |
134 ExtensionFontSettingsEventRouter::ExtensionFontSettingsEventRouter( | |
135 Profile* profile) : profile_(profile) {} | |
136 | |
137 ExtensionFontSettingsEventRouter::~ExtensionFontSettingsEventRouter() {} | |
138 | |
139 void ExtensionFontSettingsEventRouter::Init() { | |
140 registrar_.Init(profile_->GetPrefs()); | |
141 registrar_.Add(prefs::kWebKitGlobalStandardFontFamily, this); | |
142 registrar_.Add(prefs::kWebKitGlobalSerifFontFamily, this); | |
143 registrar_.Add(prefs::kWebKitGlobalSansSerifFontFamily, this); | |
144 registrar_.Add(prefs::kWebKitGlobalFixedFontFamily, this); | |
145 registrar_.Add(prefs::kWebKitGlobalCursiveFontFamily, this); | |
146 registrar_.Add(prefs::kWebKitGlobalFantasyFontFamily, this); | |
147 RegisterFontFamilyMapObserver(®istrar_, | |
148 prefs::kWebKitStandardFontFamilyMap, this); | |
149 RegisterFontFamilyMapObserver(®istrar_, | |
150 prefs::kWebKitSerifFontFamilyMap, this); | |
151 RegisterFontFamilyMapObserver(®istrar_, | |
152 prefs::kWebKitSansSerifFontFamilyMap, this); | |
153 RegisterFontFamilyMapObserver(®istrar_, | |
154 prefs::kWebKitFixedFontFamilyMap, this); | |
155 RegisterFontFamilyMapObserver(®istrar_, | |
156 prefs::kWebKitCursiveFontFamilyMap, this); | |
157 RegisterFontFamilyMapObserver(®istrar_, | |
158 prefs::kWebKitFantasyFontFamilyMap, this); | |
159 } | |
160 | |
161 void ExtensionFontSettingsEventRouter::Observe( | |
162 int type, | |
163 const content::NotificationSource& source, | |
164 const content::NotificationDetails& details) { | |
165 if (type != chrome::NOTIFICATION_PREF_CHANGED) { | |
166 NOTREACHED(); | |
167 return; | |
168 } | |
169 | |
170 const std::string* pref_key = | |
171 content::Details<const std::string>(details).ptr(); | |
172 std::string generic_family; | |
173 std::string script; | |
174 if (!ParseFontNamePrefPath(*pref_key, &generic_family, &script)) { | |
175 NOTREACHED(); | |
176 return; | |
177 } | |
178 | |
179 PrefService* pref_service = content::Source<PrefService>(source).ptr(); | |
180 bool incognito = (pref_service != profile_->GetPrefs()); | |
181 // Assume incognito font prefs don't exist. | |
182 DCHECK(!incognito); | |
Bernhard Bauer
2012/04/12 13:14:01
This DCHECK will always succeed, but that's becaus
falken
2012/04/13 10:33:46
Ah, I see. I've updated the comment. I think it's
| |
183 const PrefService::Preference* pref = pref_service->FindPreference( | |
184 pref_key->c_str()); | |
185 CHECK(pref); | |
186 | |
187 std::string font_name; | |
188 if (!pref->GetValue()->GetAsString(&font_name)) { | |
189 NOTREACHED(); | |
190 return; | |
191 } | |
192 font_name = MaybeGetLocalizedFontName(font_name); | |
193 | |
194 ListValue args; | |
195 DictionaryValue* dict = new DictionaryValue(); | |
196 args.Append(dict); | |
197 dict->SetString(kFontNameKey, font_name); | |
198 dict->SetString(kGenericFamilyKey, generic_family); | |
199 if (!script.empty()) | |
200 dict->SetString(kScriptKey, script); | |
201 | |
202 ExtensionEventRouter* router = profile_->GetExtensionEventRouter(); | |
Bernhard Bauer
2012/04/12 13:14:01
I would be very happy if we could pull everything
falken
2012/04/13 10:33:46
Done. I moved them to extension_preference_helpers
Bernhard Bauer
2012/04/13 12:19:31
I don't think that would be a huge problem. This i
falken
2012/04/16 03:47:06
OK, sounds right. I've removed the EventArgsTransf
| |
203 if (!router || !router->HasEventListener(kOnFontNameChanged)) | |
204 return; | |
205 | |
206 ExtensionService* extension_service = profile_->GetExtensionService(); | |
207 const ExtensionSet* extensions = extension_service->extensions(); | |
208 for (ExtensionSet::const_iterator it = extensions->begin(); | |
209 it != extensions->end(); ++it) { | |
210 std::string extension_id = (*it)->id(); | |
211 if (router->ExtensionHasEventListener(extension_id, kOnFontNameChanged) && | |
212 (*it)->HasAPIPermission(ExtensionAPIPermission::kExperimental)) { | |
213 std::string level_of_control = | |
214 extension_preference_helpers::GetLevelOfControl(profile_, | |
215 extension_id, | |
216 *pref_key, | |
217 incognito); | |
218 dict->SetString(kLevelOfControlKey, level_of_control); | |
219 | |
220 std::string json_args; | |
221 base::JSONWriter::Write(&args, &json_args); | |
222 | |
223 profile_->GetExtensionEventRouter()->DispatchEventToExtension( | |
224 extension_id, kOnFontNameChanged, json_args, NULL, GURL()); | |
Matt Perry
2012/04/12 20:31:44
indent += 2
falken
2012/04/13 10:33:46
Done.
| |
225 } | |
226 } | |
227 } | |
228 | |
81 bool GetFontNameFunction::RunImpl() { | 229 bool GetFontNameFunction::RunImpl() { |
82 DictionaryValue* details = NULL; | 230 DictionaryValue* details = NULL; |
83 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); | 231 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |
84 | 232 |
85 std::string pref_path; | 233 std::string pref_path; |
86 EXTENSION_FUNCTION_VALIDATE(GetFontNamePrefPath(details, &pref_path)); | 234 EXTENSION_FUNCTION_VALIDATE(GetFontNamePrefPath(details, &pref_path)); |
87 | 235 |
88 PrefService* prefs = profile_->GetPrefs(); | 236 PrefService* prefs = profile_->GetPrefs(); |
89 const PrefService::Preference* pref = | 237 const PrefService::Preference* pref = |
90 prefs->FindPreference(pref_path.c_str()); | 238 prefs->FindPreference(pref_path.c_str()); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 return prefs::kWebKitGlobalDefaultFixedFontSize; | 352 return prefs::kWebKitGlobalDefaultFixedFontSize; |
205 } | 353 } |
206 | 354 |
207 const char* GetMinimumFontSizeFunction::GetPrefName() { | 355 const char* GetMinimumFontSizeFunction::GetPrefName() { |
208 return prefs::kWebKitGlobalMinimumFontSize; | 356 return prefs::kWebKitGlobalMinimumFontSize; |
209 } | 357 } |
210 | 358 |
211 const char* SetMinimumFontSizeFunction::GetPrefName() { | 359 const char* SetMinimumFontSizeFunction::GetPrefName() { |
212 return prefs::kWebKitGlobalMinimumFontSize; | 360 return prefs::kWebKitGlobalMinimumFontSize; |
213 } | 361 } |
OLD | NEW |