Chromium Code Reviews| 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 |