| 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..8ef7ba149224075c515e830c85b89843a4f4fb5a 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"
|
| @@ -28,9 +34,13 @@ 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 +49,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 +74,31 @@ 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())
|
| + 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())
|
| + 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 +113,96 @@ 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());
|
| + // We're only observing pref changes on the regular profile.
|
| + DCHECK(!incognito);
|
| + 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);
|
| +
|
| + extension_preference_helpers::DispatchEventToExtensions(
|
| + profile_,
|
| + kOnFontNameChanged,
|
| + &args,
|
| + ExtensionAPIPermission::kExperimental,
|
| + incognito,
|
| + *pref_key);
|
| +}
|
| +
|
| bool GetFontNameFunction::RunImpl() {
|
| DictionaryValue* details = NULL;
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
|
|
|