Chromium Code Reviews| Index: chrome/browser/extensions/extension_font_settings_api.cc |
| diff --git a/chrome/browser/extensions/extension_font_settings_api.cc b/chrome/browser/extensions/extension_font_settings_api.cc |
| index 3d96e1536ba84fd9eaa0f69409c62953155c9dbe..3b19c6996558d2f9d55d1178f1c7ef38f4173dcf 100644 |
| --- a/chrome/browser/extensions/extension_font_settings_api.cc |
| +++ b/chrome/browser/extensions/extension_font_settings_api.cc |
| @@ -6,14 +6,20 @@ |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| +#include "base/json/json_writer.h" |
| #include "base/stringprintf.h" |
| +#include "base/string_util.h" |
| #include "base/values.h" |
| +#include "chrome/browser/extensions/extension_event_router.h" |
| #include "chrome/browser/extensions/extension_preference_helpers.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| #include "chrome/common/extensions/extension_error_utils.h" |
| #include "chrome/common/pref_names.h" |
| #include "content/public/browser/font_list_async.h" |
| +#include "content/public/browser/notification_details.h" |
| +#include "content/public/browser/notification_source.h" |
| #if defined(OS_WIN) |
| #include "ui/gfx/font.h" |
| @@ -24,13 +30,18 @@ namespace { |
| const char kGenericFamilyKey[] = "genericFamily"; |
| const char kFontNameKey[] = "fontName"; |
| +const char kLevelOfControlKey[] = "levelOfControl"; |
| const char kLocalizedNameKey[] = "localizedName"; |
| const char kPixelSizeKey[] = "pixelSize"; |
| const char kScriptKey[] = "script"; |
| +const char kOnFontNameChanged[] = |
| + "experimental.fontSettings.onFontNameChanged"; |
| + |
| // Format for per-script font preference keys. |
| // E.g., "webkit.webprefs.fonts.standard.Hrkt" |
| const char kWebKitPerScriptFontPrefFormat[] = "webkit.webprefs.fonts.%s.%s"; |
| +const char kWebKitPerScriptFontPrefPrefix[] = "webkit.webprefs.fonts."; |
| // Format for global (non per-script) font preference keys. |
| // E.g., "webkit.webprefs.global.fixed_font_family" |
| @@ -39,6 +50,8 @@ const char kWebKitPerScriptFontPrefFormat[] = "webkit.webprefs.fonts.%s.%s"; |
| // (per-profile). |
| const char kWebKitGlobalFontPrefFormat[] = |
| "webkit.webprefs.global.%s_font_family"; |
| +const char kWebKitGlobalFontPrefPrefix[] = "webkit.webprefs.global."; |
| +const char kWebKitGlobalFontPrefSuffix[] = "_font_family"; |
| // Gets the font name preference path from |details| which contains key |
| // |kGenericFamilyKey| and optionally |kScriptKey|. |
| @@ -62,6 +75,35 @@ bool GetFontNamePrefPath(DictionaryValue* details, std::string* pref_path) { |
| return true; |
| } |
| +// Extracts the generic family and script from font name pref path |pref_path|. |
| +bool ParseFontNamePrefPath(std::string pref_path, |
| + std::string* generic_family, |
| + std::string* script) { |
| + if (StartsWithASCII(pref_path, kWebKitPerScriptFontPrefPrefix, true)) { |
| + size_t start = strlen(kWebKitPerScriptFontPrefPrefix); |
| + size_t pos = pref_path.find('.', start); |
| + if (pos == std::string::npos || pos + 1 == pref_path.length()) { |
| + 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.
|
| + return false; |
| + } |
| + *generic_family = pref_path.substr(start, pos - start); |
| + *script = pref_path.substr(pos + 1); |
| + return true; |
| + } else if (StartsWithASCII(pref_path, kWebKitGlobalFontPrefPrefix, true) && |
| + EndsWith(pref_path, kWebKitGlobalFontPrefSuffix, true)) { |
| + size_t start = strlen(kWebKitGlobalFontPrefPrefix); |
| + size_t pos = pref_path.find('_', start); |
| + if (pos == std::string::npos || pos + 1 == pref_path.length()) { |
| + NOTREACHED(); |
| + return false; |
| + } |
| + *generic_family = pref_path.substr(start, pos - start); |
| + *script = ""; |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| // Returns the localized name of a font so that it can be matched within the |
| // list of system fonts. On Windows, the list of system fonts has names only |
| // for the system locale, but the pref value may be in the English name. |
| @@ -76,8 +118,114 @@ std::string MaybeGetLocalizedFontName(const std::string& font_name) { |
| return font_name; |
| } |
| +// Registers |obs| to observe per-script font prefs under the path |map_name|. |
| +void RegisterFontFamilyMapObserver(PrefChangeRegistrar* registrar, |
| + const char* map_name, |
| + content::NotificationObserver* obs) { |
| + for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) { |
| + const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i]; |
| + std::string pref_name = base::StringPrintf("%s.%s", map_name, script); |
| + registrar->Add(pref_name.c_str(), obs); |
| + } |
| +} |
| + |
| } // namespace |
| +ExtensionFontSettingsEventRouter::ExtensionFontSettingsEventRouter( |
| + Profile* profile) : profile_(profile) {} |
| + |
| +ExtensionFontSettingsEventRouter::~ExtensionFontSettingsEventRouter() {} |
| + |
| +void ExtensionFontSettingsEventRouter::Init() { |
| + registrar_.Init(profile_->GetPrefs()); |
| + registrar_.Add(prefs::kWebKitGlobalStandardFontFamily, this); |
| + registrar_.Add(prefs::kWebKitGlobalSerifFontFamily, this); |
| + registrar_.Add(prefs::kWebKitGlobalSansSerifFontFamily, this); |
| + registrar_.Add(prefs::kWebKitGlobalFixedFontFamily, this); |
| + registrar_.Add(prefs::kWebKitGlobalCursiveFontFamily, this); |
| + registrar_.Add(prefs::kWebKitGlobalFantasyFontFamily, this); |
| + RegisterFontFamilyMapObserver(®istrar_, |
| + prefs::kWebKitStandardFontFamilyMap, this); |
| + RegisterFontFamilyMapObserver(®istrar_, |
| + prefs::kWebKitSerifFontFamilyMap, this); |
| + RegisterFontFamilyMapObserver(®istrar_, |
| + prefs::kWebKitSansSerifFontFamilyMap, this); |
| + RegisterFontFamilyMapObserver(®istrar_, |
| + prefs::kWebKitFixedFontFamilyMap, this); |
| + RegisterFontFamilyMapObserver(®istrar_, |
| + prefs::kWebKitCursiveFontFamilyMap, this); |
| + RegisterFontFamilyMapObserver(®istrar_, |
| + prefs::kWebKitFantasyFontFamilyMap, this); |
| +} |
| + |
| +void ExtensionFontSettingsEventRouter::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + if (type != chrome::NOTIFICATION_PREF_CHANGED) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + const std::string* pref_key = |
| + content::Details<const std::string>(details).ptr(); |
| + std::string generic_family; |
| + std::string script; |
| + if (!ParseFontNamePrefPath(*pref_key, &generic_family, &script)) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + PrefService* pref_service = content::Source<PrefService>(source).ptr(); |
| + bool incognito = (pref_service != profile_->GetPrefs()); |
| + // Assume incognito font prefs don't exist. |
| + 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
|
| + const PrefService::Preference* pref = pref_service->FindPreference( |
| + pref_key->c_str()); |
| + CHECK(pref); |
| + |
| + std::string font_name; |
| + if (!pref->GetValue()->GetAsString(&font_name)) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + font_name = MaybeGetLocalizedFontName(font_name); |
| + |
| + ListValue args; |
| + DictionaryValue* dict = new DictionaryValue(); |
| + args.Append(dict); |
| + dict->SetString(kFontNameKey, font_name); |
| + dict->SetString(kGenericFamilyKey, generic_family); |
| + if (!script.empty()) |
| + dict->SetString(kScriptKey, script); |
| + |
| + 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
|
| + if (!router || !router->HasEventListener(kOnFontNameChanged)) |
| + return; |
| + |
| + ExtensionService* extension_service = profile_->GetExtensionService(); |
| + const ExtensionSet* extensions = extension_service->extensions(); |
| + for (ExtensionSet::const_iterator it = extensions->begin(); |
| + it != extensions->end(); ++it) { |
| + std::string extension_id = (*it)->id(); |
| + if (router->ExtensionHasEventListener(extension_id, kOnFontNameChanged) && |
| + (*it)->HasAPIPermission(ExtensionAPIPermission::kExperimental)) { |
| + std::string level_of_control = |
| + extension_preference_helpers::GetLevelOfControl(profile_, |
| + extension_id, |
| + *pref_key, |
| + incognito); |
| + dict->SetString(kLevelOfControlKey, level_of_control); |
| + |
| + std::string json_args; |
| + base::JSONWriter::Write(&args, &json_args); |
| + |
| + profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
| + 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.
|
| + } |
| + } |
| +} |
| + |
| bool GetFontNameFunction::RunImpl() { |
| DictionaryValue* details = NULL; |
| EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); |