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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/options/font_settings_handler.h"
9 #include "base/basictypes.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/i18n/rtl.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/character_encoding.h"
20 #include "chrome/browser/extensions/extension_service.h"
21 #include "chrome/browser/extensions/extension_tab_util.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/browser_finder.h"
24 #include "chrome/browser/ui/webui/options/font_settings_utils.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/grit/generated_resources.h"
27 #include "content/public/browser/font_list_async.h"
28 #include "content/public/browser/notification_details.h"
29 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/web_ui.h"
31 #include "extensions/browser/extension_registry.h"
32 #include "extensions/browser/extension_system.h"
33 #include "extensions/common/extension.h"
34 #include "extensions/common/extension_urls.h"
35 #include "ui/base/l10n/l10n_util.h"
39 #include "ui/gfx/font.h"
40 #include "ui/gfx/platform_font_win.h"
45 // Returns the localized name of a font so that settings can find it within the
46 // list of system fonts. On Windows, the list of system fonts has names only
47 // for the system locale, but the pref value may be in the English name.
48 std::string
MaybeGetLocalizedFontName(const std::string
& font_name
) {
50 gfx::Font
font(font_name
, 12); // dummy font size
51 return static_cast<gfx::PlatformFontWin
*>(font
.platform_font())->
52 GetLocalizedFontName();
58 const char kAdvancedFontSettingsExtensionId
[] =
59 "caclkomlalccbpcdllchkeecicepbmbm";
66 FontSettingsHandler::FontSettingsHandler()
67 : extension_registry_observer_(this) {
70 FontSettingsHandler::~FontSettingsHandler() {
73 void FontSettingsHandler::GetLocalizedValues(
74 base::DictionaryValue
* localized_strings
) {
75 DCHECK(localized_strings
);
77 static OptionsStringResource resources
[] = {
78 { "fontSettingsStandard",
79 IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_STANDARD_LABEL
},
80 { "fontSettingsSerif",
81 IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SERIF_LABEL
},
82 { "fontSettingsSansSerif",
83 IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_SANS_SERIF_LABEL
},
84 { "fontSettingsFixedWidth",
85 IDS_FONT_LANGUAGE_SETTING_FONT_SELECTOR_FIXED_WIDTH_LABEL
},
86 { "fontSettingsMinimumSize",
87 IDS_FONT_LANGUAGE_SETTING_MINIMUM_FONT_SIZE_TITLE
},
88 { "fontSettingsEncoding",
89 IDS_FONT_LANGUAGE_SETTING_FONT_SUB_DIALOG_ENCODING_TITLE
},
90 { "fontSettingsSizeTiny",
91 IDS_FONT_LANGUAGE_SETTING_FONT_SIZE_TINY
},
92 { "fontSettingsSizeHuge",
93 IDS_FONT_LANGUAGE_SETTING_FONT_SIZE_HUGE
},
94 { "fontSettingsLoremIpsum",
95 IDS_FONT_LANGUAGE_SETTING_LOREM_IPSUM
},
96 { "advancedFontSettingsOptions",
97 IDS_FONT_LANGUAGE_SETTING_ADVANCED_FONT_SETTINGS_OPTIONS
}
100 RegisterStrings(localized_strings
, resources
, arraysize(resources
));
101 RegisterTitle(localized_strings
, "fontSettingsPage",
102 IDS_FONT_LANGUAGE_SETTING_FONT_TAB_TITLE
);
103 localized_strings
->SetString("fontSettingsPlaceholder",
104 l10n_util::GetStringUTF16(
105 IDS_FONT_LANGUAGE_SETTING_PLACEHOLDER
));
107 GURL
install_url(extension_urls::GetWebstoreItemDetailURLPrefix());
108 localized_strings
->SetString("advancedFontSettingsInstall",
109 l10n_util::GetStringFUTF16(
110 IDS_FONT_LANGUAGE_SETTING_ADVANCED_FONT_SETTINGS_INSTALL
,
112 install_url
.Resolve(kAdvancedFontSettingsExtensionId
).spec())));
115 void FontSettingsHandler::InitializeHandler() {
116 Profile
* profile
= Profile::FromWebUI(web_ui());
117 extension_registry_observer_
.Add(extensions::ExtensionRegistry::Get(profile
));
120 void FontSettingsHandler::InitializePage() {
122 SetUpStandardFontSample();
123 SetUpSerifFontSample();
124 SetUpSansSerifFontSample();
125 SetUpFixedFontSample();
126 SetUpMinimumFontSample();
127 NotifyAdvancedFontSettingsAvailability();
130 void FontSettingsHandler::RegisterMessages() {
131 // Perform validation for saved fonts.
132 PrefService
* pref_service
= Profile::FromWebUI(web_ui())->GetPrefs();
133 FontSettingsUtilities::ValidateSavedFonts(pref_service
);
135 // Register for preferences that we need to observe manually.
136 font_encoding_
.Init(prefs::kDefaultCharset
, pref_service
);
138 standard_font_
.Init(prefs::kWebKitStandardFontFamily
,
140 base::Bind(&FontSettingsHandler::SetUpStandardFontSample
,
141 base::Unretained(this)));
142 serif_font_
.Init(prefs::kWebKitSerifFontFamily
,
144 base::Bind(&FontSettingsHandler::SetUpSerifFontSample
,
145 base::Unretained(this)));
146 sans_serif_font_
.Init(
147 prefs::kWebKitSansSerifFontFamily
,
149 base::Bind(&FontSettingsHandler::SetUpSansSerifFontSample
,
150 base::Unretained(this)));
152 base::Closure callback
= base::Bind(
153 &FontSettingsHandler::SetUpFixedFontSample
, base::Unretained(this));
155 fixed_font_
.Init(prefs::kWebKitFixedFontFamily
, pref_service
, callback
);
156 default_fixed_font_size_
.Init(prefs::kWebKitDefaultFixedFontSize
,
157 pref_service
, callback
);
158 default_font_size_
.Init(
159 prefs::kWebKitDefaultFontSize
,
161 base::Bind(&FontSettingsHandler::OnWebKitDefaultFontSizeChanged
,
162 base::Unretained(this)));
163 minimum_font_size_
.Init(
164 prefs::kWebKitMinimumFontSize
,
166 base::Bind(&FontSettingsHandler::SetUpMinimumFontSample
,
167 base::Unretained(this)));
169 web_ui()->RegisterMessageCallback("fetchFontsData",
170 base::Bind(&FontSettingsHandler::HandleFetchFontsData
,
171 base::Unretained(this)));
172 web_ui()->RegisterMessageCallback("openAdvancedFontSettingsOptions",
173 base::Bind(&FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions
,
174 base::Unretained(this)));
177 void FontSettingsHandler::OnExtensionLoaded(
178 content::BrowserContext
* browser_context
,
179 const extensions::Extension
* extension
) {
180 NotifyAdvancedFontSettingsAvailability();
183 void FontSettingsHandler::OnExtensionUnloaded(
184 content::BrowserContext
* browser_context
,
185 const extensions::Extension
* extension
,
186 extensions::UnloadedExtensionInfo::Reason reason
) {
187 NotifyAdvancedFontSettingsAvailability();
190 void FontSettingsHandler::HandleFetchFontsData(const base::ListValue
* args
) {
191 content::GetFontListAsync(
192 base::Bind(&FontSettingsHandler::FontsListHasLoaded
,
193 base::Unretained(this)));
196 void FontSettingsHandler::FontsListHasLoaded(
197 scoped_ptr
<base::ListValue
> list
) {
198 // Selects the directionality for the fonts in the given list.
199 for (size_t i
= 0; i
< list
->GetSize(); i
++) {
200 base::ListValue
* font
;
201 bool has_font
= list
->GetList(i
, &font
);
203 base::string16 value
;
204 bool has_value
= font
->GetString(1, &value
);
206 bool has_rtl_chars
= base::i18n::StringContainsStrongRTLChars(value
);
207 font
->Append(new base::StringValue(has_rtl_chars
? "rtl" : "ltr"));
210 base::ListValue encoding_list
;
211 const std::vector
<CharacterEncoding::EncodingInfo
>* encodings
;
212 PrefService
* pref_service
= Profile::FromWebUI(web_ui())->GetPrefs();
213 encodings
= CharacterEncoding::GetCurrentDisplayEncodings(
214 g_browser_process
->GetApplicationLocale(),
215 pref_service
->GetString(prefs::kStaticEncodings
),
216 pref_service
->GetString(prefs::kRecentlySelectedEncoding
));
218 DCHECK(!encodings
->empty());
220 std::vector
<CharacterEncoding::EncodingInfo
>::const_iterator it
;
221 for (it
= encodings
->begin(); it
!= encodings
->end(); ++it
) {
222 base::ListValue
* option
= new base::ListValue();
223 if (it
->encoding_id
) {
224 int cmd_id
= it
->encoding_id
;
225 std::string encoding
=
226 CharacterEncoding::GetCanonicalEncodingNameByCommandId(cmd_id
);
227 base::string16 name
= it
->encoding_display_name
;
228 bool has_rtl_chars
= base::i18n::StringContainsStrongRTLChars(name
);
229 option
->Append(new base::StringValue(encoding
));
230 option
->Append(new base::StringValue(name
));
231 option
->Append(new base::StringValue(has_rtl_chars
? "rtl" : "ltr"));
233 // Add empty name/value to indicate a separator item.
234 option
->Append(new base::StringValue(std::string()));
235 option
->Append(new base::StringValue(std::string()));
237 encoding_list
.Append(option
);
240 base::ListValue selected_values
;
241 selected_values
.Append(new base::StringValue(MaybeGetLocalizedFontName(
242 standard_font_
.GetValue())));
243 selected_values
.Append(new base::StringValue(MaybeGetLocalizedFontName(
244 serif_font_
.GetValue())));
245 selected_values
.Append(new base::StringValue(MaybeGetLocalizedFontName(
246 sans_serif_font_
.GetValue())));
247 selected_values
.Append(new base::StringValue(MaybeGetLocalizedFontName(
248 fixed_font_
.GetValue())));
249 selected_values
.Append(new base::StringValue(font_encoding_
.GetValue()));
251 web_ui()->CallJavascriptFunction("FontSettings.setFontsData",
252 *list
.get(), encoding_list
,
256 void FontSettingsHandler::SetUpStandardFontSample() {
257 base::StringValue
font_value(standard_font_
.GetValue());
258 base::FundamentalValue
size_value(default_font_size_
.GetValue());
259 web_ui()->CallJavascriptFunction(
260 "FontSettings.setUpStandardFontSample", font_value
, size_value
);
263 void FontSettingsHandler::SetUpSerifFontSample() {
264 base::StringValue
font_value(serif_font_
.GetValue());
265 base::FundamentalValue
size_value(default_font_size_
.GetValue());
266 web_ui()->CallJavascriptFunction(
267 "FontSettings.setUpSerifFontSample", font_value
, size_value
);
270 void FontSettingsHandler::SetUpSansSerifFontSample() {
271 base::StringValue
font_value(sans_serif_font_
.GetValue());
272 base::FundamentalValue
size_value(default_font_size_
.GetValue());
273 web_ui()->CallJavascriptFunction(
274 "FontSettings.setUpSansSerifFontSample", font_value
, size_value
);
277 void FontSettingsHandler::SetUpFixedFontSample() {
278 base::StringValue
font_value(fixed_font_
.GetValue());
279 base::FundamentalValue
size_value(default_fixed_font_size_
.GetValue());
280 web_ui()->CallJavascriptFunction(
281 "FontSettings.setUpFixedFontSample", font_value
, size_value
);
284 void FontSettingsHandler::SetUpMinimumFontSample() {
285 base::FundamentalValue
size_value(minimum_font_size_
.GetValue());
286 web_ui()->CallJavascriptFunction("FontSettings.setUpMinimumFontSample",
290 const extensions::Extension
*
291 FontSettingsHandler::GetAdvancedFontSettingsExtension() {
292 Profile
* profile
= Profile::FromWebUI(web_ui());
293 ExtensionService
* service
=
294 extensions::ExtensionSystem::Get(profile
)->extension_service();
295 if (!service
->IsExtensionEnabled(kAdvancedFontSettingsExtensionId
))
297 return service
->GetInstalledExtension(kAdvancedFontSettingsExtensionId
);
300 void FontSettingsHandler::NotifyAdvancedFontSettingsAvailability() {
301 web_ui()->CallJavascriptFunction(
302 "FontSettings.notifyAdvancedFontSettingsAvailability",
303 base::FundamentalValue(GetAdvancedFontSettingsExtension() != NULL
));
306 void FontSettingsHandler::HandleOpenAdvancedFontSettingsOptions(
307 const base::ListValue
* args
) {
308 const extensions::Extension
* extension
= GetAdvancedFontSettingsExtension();
311 extensions::ExtensionTabUtil::OpenOptionsPage(extension
,
312 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()));
315 void FontSettingsHandler::OnWebKitDefaultFontSizeChanged() {
316 SetUpStandardFontSample();
317 SetUpSerifFontSample();
318 SetUpSansSerifFontSample();
321 } // namespace options