Basic code structures for rewritten options dialogs as DOM UI. Also includes the initial implementation of System page in ChromeOS options.
BUG=chromium-os:
TEST=none yet, work in progress
Review URL: http://codereview.chromium.org/2781005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50117 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 1c3f1bb..330e0df 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -38,11 +38,12 @@
<include name="IDR_CREDITS_HTML" file="resources\about_credits.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_HISTORY_HTML" file="resources\history.html" flattenhtml="true" type="BINDATA" />
<if expr="pp_ifdef('chromeos') or pp_ifdef('toolkit_views')">
- <include name="IDR_FILEBROWSE_HTML" file="resources\filebrowse.html" flattenhtml="true" type="BINDATA" />
- <include name="IDR_OS_CREDITS_HTML" file="resources\about_os_credits.html" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MEDIAPLAYER_HTML" file="resources\mediaplayer.html" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MEDIAPLAYERPLAYLIST_HTML" file="resources\playlist.html" flattenhtml="true" type="BINDATA" />
- <include name="IDR_ABOUT_SYS_HTML" file="resources\about_sys.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_FILEBROWSE_HTML" file="resources\filebrowse.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_OS_CREDITS_HTML" file="resources\about_os_credits.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_MEDIAPLAYER_HTML" file="resources\mediaplayer.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_MEDIAPLAYERPLAYLIST_HTML" file="resources\playlist.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_ABOUT_SYS_HTML" file="resources\about_sys.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_OPTIONS_HTML" file="resources\options.html" flattenhtml="true" type="BINDATA" />
</if>
<include name="IDR_APP_GALLERY_ICON" file="resources\app_gallery_icon.png" type="BINDATA" />
<include name="IDR_BOOKMARKS_MANIFEST" file="resources\bookmark_manager\manifest.json" type="BINDATA" />
diff --git a/chrome/browser/chromeos/dom_ui/system_options_handler.cc b/chrome/browser/chromeos/dom_ui/system_options_handler.cc
new file mode 100644
index 0000000..32469025
--- /dev/null
+++ b/chrome/browser/chromeos/dom_ui/system_options_handler.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/dom_ui/system_options_handler.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/i18n/time_formatting.h"
+#include "base/stl_util-inl.h"
+#include "base/time.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/notification_service.h"
+#include "grit/browser_resources.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "grit/theme_resources.h"
+
+static const char* kTimeZonesUtf8[] = {
+ "Pacific/Samoa",
+ "US/Hawaii",
+ "US/Alaska",
+ "US/Pacific",
+ "US/Mountain",
+ "US/Central",
+ "US/Eastern",
+ "America/Santiago",
+ "America/Sao_Paulo",
+ "Atlantic/South_Georgia",
+ "Atlantic/Cape_Verde",
+ "Europe/London",
+ "Europe/Rome",
+ "Europe/Helsinki",
+ "Europe/Moscow",
+ "Asia/Dubai",
+ "Asia/Karachi",
+ "Asia/Dhaka",
+ "Asia/Bangkok",
+ "Asia/Hong_Kong",
+ "Asia/Tokyo",
+ "Australia/Sydney",
+ "Asia/Magadan",
+ "Pacific/Auckland" };
+
+SystemOptionsHandler::SystemOptionsHandler() {
+ // TODO(chocobo): For now, add all the GMT timezones.
+ // We may eventually want to use icu::TimeZone::createEnumeration()
+ // to list all the timezones and pick the ones we want to show.
+ // NOTE: This currently does not handle daylight savings properly
+ // b/c this is just a manually selected list of timezones that
+ // happen to span the GMT-11 to GMT+12 Today. When daylight savings
+ // kick in, this list might have more than one timezone in the same
+ // GMT bucket.
+ for (size_t i = 0; i < arraysize(kTimeZonesUtf8); i++) {
+ timezones_.push_back(icu::TimeZone::createTimeZone(
+ icu::UnicodeString::fromUTF8(kTimeZonesUtf8[i])));
+ }
+}
+
+SystemOptionsHandler::~SystemOptionsHandler() {
+ STLDeleteElements(&timezones_);
+}
+
+void SystemOptionsHandler::GetLocalizedValues(
+ DictionaryValue* localized_strings) {
+ DCHECK(localized_strings);
+ // System page - ChromeOS
+ localized_strings->SetString(L"datetime_title",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME));
+ localized_strings->SetString(L"timezone",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION));
+
+ localized_strings->SetString(L"touchpad",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SECTION_TITLE_TOUCHPAD));
+ localized_strings->SetString(L"enable_tap_to_click",
+ l10n_util::GetString(
+ IDS_OPTIONS_SETTINGS_TAP_TO_CLICK_ENABLED_DESCRIPTION));
+ localized_strings->SetString(L"enable_vert_edge_scroll",
+ l10n_util::GetString(
+ IDS_OPTIONS_SETTINGS_VERT_EDGE_SCROLL_ENABLED_DESCRIPTION));
+ localized_strings->SetString(L"sensitivity",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SENSITIVITY_DESCRIPTION));
+ localized_strings->SetString(L"speed_factor",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SPEED_FACTOR_DESCRIPTION));
+
+ localized_strings->SetString(L"language",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SECTION_TITLE_LANGUAGE));
+ localized_strings->SetString(L"language_customize",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_LANGUAGES_CUSTOMIZE));
+
+ localized_strings->SetString(L"accessibility_title",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY));
+ localized_strings->SetString(L"accessibility",
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_ACCESSIBILITY_DESCRIPTION));
+
+ localized_strings->Set(L"timezoneMap", GetTimezoneMap());
+}
+
+DictionaryValue* SystemOptionsHandler::GetTimezoneMap() {
+ DictionaryValue* timezoneMap = new DictionaryValue();
+ for (std::vector<icu::TimeZone*>::iterator iter = timezones_.begin();
+ iter != timezones_.end(); ++iter) {
+ const icu::TimeZone* timezone = *iter;
+ timezoneMap->SetString(GetTimezoneID(timezone).c_str(),
+ GetTimezoneName(timezone));
+ }
+ return timezoneMap;
+}
+
+std::string SystemOptionsHandler::GetTimezoneName(
+ const icu::TimeZone* timezone) {
+ DCHECK(timezone);
+ icu::UnicodeString name;
+ timezone->getDisplayName(name);
+ std::string output;
+ UTF16ToUTF8(name.getBuffer(), name.length(), &output);
+ int hour_offset = timezone->getRawOffset() / 3600000;
+ const char* format;
+ if (hour_offset == 0)
+ format = "(GMT) ";
+ else
+ format = "(GMT%+d) ";
+
+ return StringPrintf(format, hour_offset) + output;
+}
+
+std::wstring SystemOptionsHandler::GetTimezoneID(
+ const icu::TimeZone* timezone) {
+ DCHECK(timezone);
+ icu::UnicodeString id;
+ timezone->getID(id);
+ std::wstring output;
+ UTF16ToWide(id.getBuffer(), id.length(), &output);
+ return output;
+}
diff --git a/chrome/browser/chromeos/dom_ui/system_options_handler.h b/chrome/browser/chromeos/dom_ui/system_options_handler.h
new file mode 100644
index 0000000..488eccdd3
--- /dev/null
+++ b/chrome/browser/chromeos/dom_ui/system_options_handler.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DOM_UI_SYSTEM_OPTIONS_HANDLER_H_
+#define CHROME_BROWSER_CHROMEOS_DOM_UI_SYSTEM_OPTIONS_HANDLER_H_
+
+#include <string>
+#include <vector>
+
+#include "chrome/browser/dom_ui/options_ui.h"
+#include "third_party/icu/public/i18n/unicode/timezone.h"
+
+// ChromeOS system options page UI handler.
+class SystemOptionsHandler : public OptionsPageUIHandler {
+ public:
+ SystemOptionsHandler();
+ virtual ~SystemOptionsHandler();
+
+ // OptionsUIHandler implementation.
+ virtual void GetLocalizedValues(DictionaryValue* localized_strings);
+
+ private:
+ // Creates the map of timezones used by the options page.
+ DictionaryValue* GetTimezoneMap();
+
+ // Gets timezone name.
+ std::string GetTimezoneName(const icu::TimeZone* timezone);
+
+ // Gets timezone ID which is also used as timezone pref value.
+ std::wstring GetTimezoneID(const icu::TimeZone* timezone);
+
+ // Timezones.
+ std::vector<icu::TimeZone*> timezones_;
+
+ DISALLOW_COPY_AND_ASSIGN(SystemOptionsHandler);
+};
+
+#endif // CHROME_BROWSER_CHROMEOS_DOM_UI_SYSTEM_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/dom_ui/core_options_handler.cc b/chrome/browser/dom_ui/core_options_handler.cc
new file mode 100644
index 0000000..3aa1587
--- /dev/null
+++ b/chrome/browser/dom_ui/core_options_handler.cc
@@ -0,0 +1,213 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/dom_ui/core_options_handler.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "grit/browser_resources.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "grit/theme_resources.h"
+
+CoreOptionsHandler::CoreOptionsHandler() {
+}
+
+void CoreOptionsHandler::GetLocalizedValues(
+ DictionaryValue* localized_strings) {
+ DCHECK(localized_strings);
+ // Main
+ localized_strings->SetString(L"title",
+ l10n_util::GetStringF(IDS_OPTIONS_DIALOG_TITLE,
+ l10n_util::GetString(IDS_PRODUCT_NAME)));
+
+#if defined(OS_CHROMEOS)
+ localized_strings->SetString(L"systemPage",
+ l10n_util::GetString(IDS_OPTIONS_SYSTEM_TAB_LABEL));
+ localized_strings->SetString(L"internetPage",
+ l10n_util::GetString(IDS_OPTIONS_INTERNET_TAB_LABEL));
+#endif
+
+ localized_strings->SetString(L"basicsPage",
+ l10n_util::GetString(IDS_OPTIONS_GENERAL_TAB_LABEL));
+ localized_strings->SetString(L"personalStuffPage",
+ l10n_util::GetString(IDS_OPTIONS_CONTENT_TAB_LABEL));
+ localized_strings->SetString(L"underHoodPage",
+ l10n_util::GetString(IDS_OPTIONS_ADVANCED_TAB_LABEL));
+}
+
+void CoreOptionsHandler::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::PREF_CHANGED)
+ NotifyPrefChanged(Details<std::wstring>(details).ptr());
+}
+
+void CoreOptionsHandler::RegisterMessages() {
+ dom_ui_->RegisterMessageCallback("fetchPrefs",
+ NewCallback(this, &CoreOptionsHandler::HandleFetchPrefs));
+ dom_ui_->RegisterMessageCallback("observePrefs",
+ NewCallback(this, &CoreOptionsHandler::HandleFetchPrefs));
+ dom_ui_->RegisterMessageCallback("setBooleanPref",
+ NewCallback(this, &CoreOptionsHandler::HandleSetBooleanPref));
+ dom_ui_->RegisterMessageCallback("setIntegerPref",
+ NewCallback(this, &CoreOptionsHandler::HandleSetIntegerPref));
+ dom_ui_->RegisterMessageCallback("setStringPref",
+ NewCallback(this, &CoreOptionsHandler::HandleSetStringPref));
+}
+
+
+void CoreOptionsHandler::HandleFetchPrefs(const Value* value) {
+ if (!value || !value->IsType(Value::TYPE_LIST))
+ return;
+
+ const ListValue* param_values = static_cast<const ListValue*>(value);
+
+ // First param is name of callback function, the second one is the value of
+ // context that is just passed through - so, there needs to be at least one
+ // more for the actual preference identifier.
+ const size_t kMinFetchPrefsParamCount = 3;
+ if (param_values->GetSize() < kMinFetchPrefsParamCount)
+ return;
+
+ size_t idx = param_values->GetSize();
+ LOG(INFO) << "param_values->GetSize() = " << idx;
+ // Get callback JS function name.
+ Value* callback;
+ if (!param_values->Get(0, &callback) || !callback->IsType(Value::TYPE_STRING))
+ return;
+
+ std::wstring callback_function;
+ if (!callback->GetAsString(&callback_function))
+ return;
+
+ // Get context param (just passthrough value)
+ Value* context;
+ if (!param_values->Get(1, &context) || !context)
+ return;
+
+ // Get the list of name for prefs to build the response dictionary.
+ DictionaryValue result_value;
+ Value* list_member;
+ DCHECK(dom_ui_);
+ PrefService* pref_service = dom_ui_->GetProfile()->GetPrefs();
+
+ for (size_t i = 2; i < param_values->GetSize(); i++) {
+ if (!param_values->Get(i, &list_member))
+ break;
+
+ if (!list_member->IsType(Value::TYPE_STRING))
+ continue;
+
+ std::wstring pref_name;
+ if (!list_member->GetAsString(&pref_name))
+ continue;
+
+ const PrefService::Preference* pref =
+ pref_service->FindPreference(pref_name.c_str());
+ result_value.Set(pref_name.c_str(),
+ pref ? pref->GetValue()->DeepCopy() : Value::CreateNullValue());
+ }
+ dom_ui_->CallJavascriptFunction(callback_function.c_str(), *context,
+ result_value);
+}
+
+void CoreOptionsHandler::HandleObservePefs(const Value* value) {
+ if (!value || !value->IsType(Value::TYPE_LIST))
+ return;
+
+ DCHECK(dom_ui_);
+ PrefService* pref_service = dom_ui_->GetProfile()->GetPrefs();
+ DictionaryValue result_value;
+ const ListValue* list_value = static_cast<const ListValue*>(value);
+ Value* list_member;
+ for (size_t i = 0; i < list_value->GetSize(); i++) {
+ if (!list_value->Get(i, &list_member))
+ break;
+
+ if (!list_member->IsType(Value::TYPE_STRING))
+ continue;
+
+ std::wstring pref_name;
+ if (!list_member->GetAsString(&pref_name))
+ continue;
+
+ pref_service->AddPrefObserver(pref_name.c_str(), this);
+ }
+}
+
+void CoreOptionsHandler::HandleSetBooleanPref(const Value* value) {
+ HandleSetPref(value, Value::TYPE_BOOLEAN);
+}
+
+void CoreOptionsHandler::HandleSetIntegerPref(const Value* value) {
+ HandleSetPref(value, Value::TYPE_INTEGER);
+}
+
+void CoreOptionsHandler::HandleSetStringPref(const Value* value) {
+ HandleSetPref(value, Value::TYPE_STRING);
+}
+
+void CoreOptionsHandler::HandleSetPref(const Value* value,
+ Value::ValueType type) {
+ if (!value || !value->IsType(Value::TYPE_LIST))
+ return;
+ const ListValue* param_values = static_cast<const ListValue*>(value);
+ size_t size = param_values->GetSize();
+ LOG(INFO) << "Array size = " << size;
+ if (param_values->GetSize() != 2)
+ return;
+
+ DCHECK(dom_ui_);
+ PrefService* pref_service = dom_ui_->GetProfile()->GetPrefs();
+
+ Value* name_element;
+ std::wstring pref_name;
+ if (!param_values->Get(0, &name_element) ||
+ !name_element->IsType(Value::TYPE_STRING) ||
+ !name_element->GetAsString(&pref_name))
+ return;
+
+ Value* value_element;
+ std::string value_string;
+ if (!param_values->Get(1, &value_element) ||
+ !value_element->IsType(Value::TYPE_STRING) ||
+ !value_element->GetAsString(&value_string))
+ return;
+
+ switch (type) {
+ case Value::TYPE_BOOLEAN:
+ pref_service->SetBoolean(pref_name.c_str(), value_string == "true");
+ break;
+ case Value::TYPE_INTEGER:
+ int int_value;
+ if (StringToInt(value_string, &int_value))
+ pref_service->SetInteger(pref_name.c_str(), int_value);
+ break;
+ case Value::TYPE_STRING:
+ pref_service->SetString(pref_name.c_str(), UTF8ToWide(value_string));
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void CoreOptionsHandler::NotifyPrefChanged(const std::wstring* pref_name) {
+ DCHECK(dom_ui_);
+ PrefService* pref_service = dom_ui_->GetProfile()->GetPrefs();
+ const PrefService::Preference* pref =
+ pref_service->FindPreference(pref_name->c_str());
+ if (pref) {
+ DictionaryValue result_value;
+ result_value.Set(pref_name->c_str(), pref->GetValue()->DeepCopy());
+ dom_ui_->CallJavascriptFunction(L"prefsChanged", result_value);
+ }
+}
diff --git a/chrome/browser/dom_ui/core_options_handler.h b/chrome/browser/dom_ui/core_options_handler.h
new file mode 100644
index 0000000..a71489f4
--- /dev/null
+++ b/chrome/browser/dom_ui/core_options_handler.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_DOM_UI_CORE_OPTIONS_HANDLER_H_
+#define CHROME_BROWSER_DOM_UI_CORE_OPTIONS_HANDLER_H_
+
+#include "base/values.h"
+#include "chrome/browser/dom_ui/options_ui.h"
+
+// Core options UI handler.
+// Handles resource and JS calls common to all options sub-pages.
+class CoreOptionsHandler : public OptionsPageUIHandler {
+ public:
+ CoreOptionsHandler();
+
+ // OptionsUIHandler implementation.
+ virtual void GetLocalizedValues(DictionaryValue* localized_strings);
+
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // DOMMessageHandler implementation.
+ virtual void RegisterMessages();
+
+ private:
+ // Callback for the "fetchPrefs" message. This message accepts the list of
+ // preference names passed as |value| parameter (ListValue). It passes results
+ // dictionary of preference values by calling prefsFetched() JS method on the
+ // page.
+ void HandleFetchPrefs(const Value* value);
+
+ // Callback for the "observePrefs" message. This message initiates
+ // notification observing for given array of preference names.
+ void HandleObservePefs(const Value* value);
+
+ // Callbacks for the "set<type>Pref" message. This message saves the new
+ // preference value. The input value is an array of strings representing
+ // name-value preference pair.
+ void HandleSetBooleanPref(const Value* value);
+ void HandleSetIntegerPref(const Value* value);
+ void HandleSetStringPref(const Value* value);
+
+ void HandleSetPref(const Value* value, Value::ValueType type);
+
+ void NotifyPrefChanged(const std::wstring* pref_name);
+
+ DISALLOW_COPY_AND_ASSIGN(CoreOptionsHandler);
+};
+
+#endif // CHROME_BROWSER_DOM_UI_CORE_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/dom_ui/dom_ui_factory.cc b/chrome/browser/dom_ui/dom_ui_factory.cc
index 0ef066a7..4ddfac6 100644
--- a/chrome/browser/dom_ui/dom_ui_factory.cc
+++ b/chrome/browser/dom_ui/dom_ui_factory.cc
@@ -8,10 +8,8 @@
#include "chrome/browser/dom_ui/bookmarks_ui.h"
#include "chrome/browser/dom_ui/downloads_ui.h"
#include "chrome/browser/dom_ui/devtools_ui.h"
-#include "chrome/browser/dom_ui/filebrowse_ui.h"
#include "chrome/browser/dom_ui/history_ui.h"
#include "chrome/browser/dom_ui/html_dialog_ui.h"
-#include "chrome/browser/dom_ui/mediaplayer_ui.h"
#include "chrome/browser/dom_ui/net_internals_ui.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
#include "chrome/browser/dom_ui/plugins_ui.h"
@@ -24,6 +22,12 @@
#include "chrome/common/url_constants.h"
#include "googleurl/src/gurl.h"
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/dom_ui/filebrowse_ui.h"
+#include "chrome/browser/dom_ui/mediaplayer_ui.h"
+#include "chrome/browser/dom_ui/options_ui.h"
+#endif
+
const DOMUITypeID DOMUIFactory::kNoDOMUI = NULL;
// A function for creating a new DOMUI. The caller owns the return value, which
@@ -106,9 +110,10 @@
#if defined(OS_CHROMEOS)
if (url.host() == chrome::kChromeUIFileBrowseHost)
return &NewDOMUI<FileBrowseUI>;
-
if (url.host() == chrome::kChromeUIMediaplayerHost)
return &NewDOMUI<MediaplayerUI>;
+ if (url.host() == chrome::kChromeUIOptionsHost)
+ return &NewDOMUI<OptionsUI>;
#endif
return NULL;
diff --git a/chrome/browser/dom_ui/options_ui.cc b/chrome/browser/dom_ui/options_ui.cc
new file mode 100644
index 0000000..652a168
--- /dev/null
+++ b/chrome/browser/dom_ui/options_ui.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/dom_ui/options_ui.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/callback.h"
+#include "base/i18n/time_formatting.h"
+#include "base/message_loop.h"
+#include "base/singleton.h"
+#include "base/string_piece.h"
+#include "base/string_util.h"
+#include "base/thread.h"
+#include "base/time.h"
+#include "base/values.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/dom_ui/core_options_handler.h"
+#include "chrome/browser/metrics/user_metrics.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_delegate.h"
+#include "chrome/common/jstemplate_builder.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/common/time_format.h"
+#include "chrome/common/url_constants.h"
+#include "net/base/escape.h"
+
+#include "grit/browser_resources.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "grit/theme_resources.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/dom_ui/system_options_handler.h"
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// OptionsUIHTMLSource
+//
+////////////////////////////////////////////////////////////////////////////////
+
+OptionsUIHTMLSource::OptionsUIHTMLSource(DictionaryValue* localized_strings)
+ : DataSource(chrome::kChromeUIOptionsHost, MessageLoop::current()) {
+ DCHECK(localized_strings);
+ localized_strings_.reset(localized_strings);
+}
+
+void OptionsUIHTMLSource::StartDataRequest(const std::string& path,
+ bool is_off_the_record,
+ int request_id) {
+ SetFontAndTextDirection(localized_strings_.get());
+
+ static const base::StringPiece options_html(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_OPTIONS_HTML));
+ const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
+ options_html, localized_strings_.get());
+
+ scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
+ html_bytes->data.resize(full_html.size());
+ std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
+
+ SendResponse(request_id, html_bytes);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// OptionsUIHandler
+//
+////////////////////////////////////////////////////////////////////////////////
+
+OptionsPageUIHandler::OptionsPageUIHandler() {
+}
+
+OptionsPageUIHandler::~OptionsPageUIHandler() {
+}
+
+void OptionsPageUIHandler::UserMetricsRecordAction(
+ const UserMetricsAction& action, PrefService* prefs) {
+ UserMetrics::RecordAction(action, dom_ui_->GetProfile());
+ if (prefs)
+ prefs->ScheduleSavePersistentPrefs();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// OptionsUIContents
+//
+////////////////////////////////////////////////////////////////////////////////
+
+OptionsUI::OptionsUI(TabContents* contents) : DOMUI(contents) {
+ DictionaryValue* localized_strings = new DictionaryValue();
+
+ // TODO(zelidrag): Add all other page handlers here as we implement them.
+ AddOptionsPageUIHandler(localized_strings, new CoreOptionsHandler());
+#if defined(OS_CHROMEOS)
+ AddOptionsPageUIHandler(localized_strings, new SystemOptionsHandler());
+#endif
+
+ // |localized_strings| ownership is taken over by this constructor.
+ OptionsUIHTMLSource* html_source =
+ new OptionsUIHTMLSource(localized_strings);
+
+ // Set up the chrome://options/ source.
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ Singleton<ChromeURLDataManager>::get(),
+ &ChromeURLDataManager::AddDataSource,
+ make_scoped_refptr(html_source)));
+}
+
+void OptionsUI::AddOptionsPageUIHandler(DictionaryValue* localized_strings,
+ OptionsPageUIHandler* handler) {
+ DCHECK(handler);
+ handler->GetLocalizedValues(localized_strings);
+ AddMessageHandler(handler->Attach(this));
+}
diff --git a/chrome/browser/dom_ui/options_ui.h b/chrome/browser/dom_ui/options_ui.h
new file mode 100644
index 0000000..a79b3bb
--- /dev/null
+++ b/chrome/browser/dom_ui/options_ui.h
@@ -0,0 +1,83 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_DOM_UI_OPTIONS_UI_H_
+#define CHROME_BROWSER_DOM_UI_OPTIONS_UI_H_
+
+#include <string>
+#include <vector>
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
+#include "chrome/browser/dom_ui/dom_ui.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_type.h"
+
+class GURL;
+class PrefService;
+struct UserMetricsAction;
+
+class OptionsUIHTMLSource : public ChromeURLDataManager::DataSource {
+ public:
+ // The constructor takes over ownership of |localized_strings|.
+ explicit OptionsUIHTMLSource(DictionaryValue* localized_strings);
+ virtual ~OptionsUIHTMLSource() {}
+
+ // Called when the network layer has requested a resource underneath
+ // the path we registered.
+ virtual void StartDataRequest(const std::string& path,
+ bool is_off_the_record,
+ int request_id);
+ virtual std::string GetMimeType(const std::string&) const {
+ return "text/html";
+ }
+
+ private:
+ // Localized strings collection.
+ scoped_ptr<DictionaryValue> localized_strings_;
+
+ DISALLOW_COPY_AND_ASSIGN(OptionsUIHTMLSource);
+};
+
+// The base class handler of Javascript messages of options pages.
+class OptionsPageUIHandler : public DOMMessageHandler,
+ public NotificationObserver {
+ public:
+ OptionsPageUIHandler();
+ virtual ~OptionsPageUIHandler();
+
+ // Collects localized strings for options page.
+ virtual void GetLocalizedValues(DictionaryValue* localized_strings) = 0;
+
+ // DOMMessageHandler implementation.
+ virtual void RegisterMessages() {}
+
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {}
+
+ void UserMetricsRecordAction(const UserMetricsAction& action,
+ PrefService* prefs);
+
+ protected:
+ NotificationRegistrar registrar_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OptionsPageUIHandler);
+};
+
+class OptionsUI : public DOMUI {
+ public:
+ explicit OptionsUI(TabContents* contents);
+ virtual ~OptionsUI() {}
+
+ private:
+ void AddOptionsPageUIHandler(DictionaryValue* localized_strings,
+ OptionsPageUIHandler* handler);
+
+ DISALLOW_COPY_AND_ASSIGN(OptionsUI);
+};
+
+#endif // CHROME_BROWSER_DOM_UI_OPTIONS_UI_H_
diff --git a/chrome/browser/resources/options.html b/chrome/browser/resources/options.html
new file mode 100644
index 0000000..8bdec64
--- /dev/null
+++ b/chrome/browser/resources/options.html
@@ -0,0 +1,258 @@
+<!DOCTYPE HTML>
+<html i18n-values="dir:textdirection;" id="t">
+<head>
+<meta charset="utf-8">
+<title i18n-content="title"></title>
+<link rel="icon" href="../../app/theme/history_favicon.png">
+<script src="shared/js/local_strings.js"></script>
+<script>
+///////////////////////////////////////////////////////////////////////////////
+// Globals:
+
+function $(o) {return document.getElementById(o);}
+
+// Extracts preference value out of reponse callback of fetchPrefs call.
+function getPref(dict, name) {
+ return eval('dict.'+name);
+}
+
+// Sets new value for preference.
+function setBooleanPref(name, value) {
+ chrome.send('setBooleanPref', [name, String(value)]);
+}
+
+function setIntegerPref(name, value) {
+ chrome.send('setIntegerPref', [name, String(value)]);
+}
+
+function setStringPref(name, value) {
+ chrome.send('setStringPref', [name, value]);
+}
+///////////////////////////////////////////////////////////////////////////////
+// Document Functions:
+/**
+ * Window onload handler, sets up the page.
+ */
+function load() {
+ localStrings = new LocalStrings();
+ loadSystemPrefs();
+
+ selectPage('system');
+ // TODO(zelidrag): preserve first that needs to be shown.
+}
+
+function selectPage(name) {
+ var page = $(name+'Page');
+ var nav = $(name+'PageNav');
+ page.style.visibility = 'visible';
+ nav.class = 'navbar_item navbar_item_selected';
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// System (ChromeOS) Functions:
+
+var kTimeZone = 'settings.datetime.timezone';
+var kTapToClickEnabled = 'settings.touchpad.enable_tap_to_click';
+var kVertEdgeScrollEnabled = 'settings.touchpad.enable_vert_edge_scroll';
+var kTouchpadSpeedFactor = 'settings.touchpad.speed_factor';
+var kTouchpadSensitivity = 'settings.touchpad.sensitivity';
+var kAccessibilityEnabled = 'settings.accessibility';
+
+/**
+ * Loads ChromeOS System preferences.
+ */
+function loadSystemPrefs() {
+ chrome.send("fetchPrefs", ['systemPrefsFetched', '',
+ kTimeZone,
+ kTapToClickEnabled,
+ kVertEdgeScrollEnabled,
+ kTouchpadSpeedFactor,
+ kTouchpadSensitivity,
+ kAccessibilityEnabled]);
+}
+
+function setupTimezones(selectedValue) {
+ timezoneSel = $('timezoneSel');
+ for (key in templateData.timezoneMap) {
+ var selected = key == selectedValue;
+ timezoneSel.options[timezoneSel.options.length] =
+ new Option(templateData.timezoneMap[key], key, false, selected);
+ }
+}
+
+function systemPrefsFetched(context, dict) {
+ $('tapToClickChk').checked = getPref(dict, kTapToClickEnabled);
+ $('vertScrollChk').checked = getPref(dict, kVertEdgeScrollEnabled);
+ $('sensitivityRng').value = getPref(dict, kTouchpadSensitivity);
+ $('speedRng').value = getPref(dict, kTouchpadSpeedFactor);
+ $('accesibilityChk').checked = getPref(dict, kAccessibilityEnabled);
+ setupTimezones(getPref(dict, kTimeZone));
+}
+
+function selectChanged(control) {
+ if (control.id == 'timezoneSel') {
+ setStringPref(kTimeZone, control.options[control.selectedIndex].value);
+ }
+}
+
+function checkboxChanged(control) {
+ if (control.id == 'tapToClickChk') {
+ setBooleanPref(kTapToClickEnabled, control.checked);
+ } else if (control.id == 'vertScrollChk') {
+ setBooleanPref(kVertEdgeScrollEnabled, control.checked);
+ } else if (control.id == 'vertScrollChk') {
+ setBooleanPref(kTapToClickEnabled, control.checked);
+ } else if (control.id == 'accesibilityChk') {
+ setBooleanPref(kAccessibilityEnabled, control.checked);
+ }
+}
+
+function rangeChanged(control) {
+ if (control.id == 'sensitivityRng') {
+ setIntegerPref(kTouchpadSensitivity, control.value);
+ } else if (control.id == 'speedRng') {
+ setIntegerPref(kTouchpadSpeedFactor, control.value);
+ }
+}
+
+function buttonClicked(control) {
+ if (conrol.id == 'languageBtn') {
+ // TODO: Open ChromeOS language settings page.
+ }
+}
+
+
+</script>
+<link rel="stylesheet" href="dom_ui.css">
+<!-- TODO(zelidrag) just a temp style placeholder until redesign -->
+<style>
+.navbar_container {
+ border: 1px solid black;
+ background-color: #dfdfdf;
+ cursor:pointer;
+ font-weight: bold;
+ float:left;
+ height: 400px;
+ padding: 10px;
+ position:relative;
+ width: 200px;
+}
+.navbar_item, .navbar_item2 {
+ margin: 5px;
+ padding: 5px;
+}
+.navbar_item_selected {
+ background-color: #000000;
+}
+.navbar_item_normal {
+ background-color: #dfdfdf;
+}
+#mainview {
+ border: 1px solid black;
+ float:left;
+ height: 400px;
+ width: 600px;
+ padding: 10px;
+ position:relative;
+}
+.section {
+ margin-top: 10px;
+}
+.option {
+ margin-top: 5px;
+}
+.section_title {
+ font-weight: bold;
+}
+.option_control_table {
+ padding-left:10px;
+}
+.navbar2 {
+ visibility: hidden;
+}
+.page {
+ visibility: hidden;
+}
+</style>
+</head>
+<body onload="load();" i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
+<div class="header">
+</div>
+<div class="main">
+ <div class="navbar_container">
+ <ul class="navbar">
+ <li class="navbar_item navbar_item_normal" id="systemPageNav" i18n-values=".innerText:systemPage"></li>
+ <li class="navbar_item navbar_item_normal" id="internetPageNav" i18n-values=".innerText:internetPage"></li>
+ <li class="navbar_item navbar_item_normal" id="basicsPageNav" i18n-values=".innerText:basicsPage"></li>
+ <li class="navbar_item navbar_item_normal" id="personalStuffPageNav" i18n-values=".innerText:personalStuffPage"></li>
+ <li class="navbar_item navbar_item_normal" id="underHoodPageNav" i18n-values=".innerText:underHoodPage"></li>
+ </ul>
+ <hr/>
+ <ul class="navbar2">
+ </ul>
+ </div>
+ <div id="mainview">
+ <div class="page" id="systemPage">
+ <div class="section">
+ <div class="section_title" i18n-values=".innerText:datetime_title"></div>
+ <div class="option">
+ <table class="option_control_table">
+ <tr>
+ <td class="option_name" i18n-values=".innerText:timezone"></td>
+ <td class="option_value">
+ <select id="timezoneSel" class="control timezone_dropdown" onchange="selectChanged(this)"></select>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ <div class="section">
+ <div class="section_title" i18n-values=".innerText:touchpad"></div>
+ <div class="option">
+ <table class="option_control_table">
+ <tr>
+ <td class="option_name" i18n-values=".innerText:sensitivity"></td>
+ <td class="option_value">
+ <input id="sensitivityRng" type="range" min="1" max="10" class="touchSlider" style="-webkit-appearance:slider-horizontal;" onchange="rangeChanged(this)">
+ </td>
+ </tr>
+ <tr>
+ <td class="option_name" i18n-values=".innerText:speed_factor"></td>
+ <td class="option_value">
+ <input id="speedRng" type="range" min="1" max="10" class="touchSlider" style="-webkit-appearance:slider-horizontal;" onchange="rangeChanged(this)">
+ </td>
+ </tr>
+ <tr>
+ <td class="option_name" colspan="2"><input id="tapToClickChk" type="checkbox" onchange="checkboxChanged(this)"/><span i18n-values=".innerText:enable_tap_to_click"></span></td>
+ </tr>
+ <tr>
+ <td class="option_name" colspan="2"><input id="vertScrollChk" type="checkbox" onchange="checkboxChanged(this)"/><span i18n-values=".innerText:enable_vert_edge_scroll"></span></td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ <div class="section">
+ <div class="section_title" i18n-values=".innerText:language"></div>
+ <div class="option">
+ <table class="option_control_table">
+ <tr>
+ <td class="option_name"><button id="languageBtn" onclick="buttonClicked" i18n-values=".innerText:language_customize"></button></td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ <div class="section">
+ <div class="section_title" i18n-values=".innerText:accessibility_title"></div>
+ <div class="option">
+ <table class="option_control_table">
+ <tr>
+ <td class="option_name"><input id="accesibilityChk" onchange="checkboxChanged(this)" type="checkbox"/><span i18n-values=".innerText:accessibility"></span></td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 119b1a9..38d609c9 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -379,8 +379,10 @@
'browser/chromeos/cros/synaptics_library.h',
'browser/chromeos/cros/syslogs_library.cc',
'browser/chromeos/cros/syslogs_library.h',
- 'browser/chromeos/customization_document.h',
'browser/chromeos/customization_document.cc',
+ 'browser/chromeos/customization_document.h',
+ 'browser/chromeos/dom_ui/system_options_handler.cc',
+ 'browser/chromeos/dom_ui/system_options_handler.h',
'browser/chromeos/external_cookie_handler.cc',
'browser/chromeos/external_cookie_handler.h',
'browser/chromeos/external_metrics.cc',
@@ -966,6 +968,8 @@
'browser/dom_ui/bookmarks_ui.h',
'browser/dom_ui/chrome_url_data_manager.cc',
'browser/dom_ui/chrome_url_data_manager.h',
+ 'browser/dom_ui/core_options_handler.cc',
+ 'browser/dom_ui/core_options_handler.h',
'browser/dom_ui/devtools_ui.cc',
'browser/dom_ui/devtools_ui.h',
'browser/dom_ui/dom_ui.cc',
@@ -1006,6 +1010,8 @@
'browser/dom_ui/new_tab_ui.h',
'browser/dom_ui/ntp_resource_cache.cc',
'browser/dom_ui/ntp_resource_cache.h',
+ 'browser/dom_ui/options_ui.cc',
+ 'browser/dom_ui/options_ui.h',
'browser/dom_ui/plugins_ui.cc',
'browser/dom_ui/plugins_ui.h',
'browser/dom_ui/shown_sections_handler.cc',
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 9a9cb66..6f06ab6 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -67,6 +67,7 @@
const char kChromeUIFavIconURL[] = "chrome://favicon/";
const char kChromeUIFileBrowseURL[] = "chrome://filebrowse/";
const char kChromeUIMediaplayerURL[] = "chrome://mediaplayer/";
+const char kChromeUIOptionsURL[] = "chrome://options/";
const char kChromeUIIPCURL[] = "chrome://about/ipc";
const char kChromeUINetworkURL[] = "chrome://about/network";
const char kChromeUINewTabURL[] = "chrome://newtab";
@@ -83,6 +84,7 @@
const char kChromeUIResourcesHost[] = "resources";
const char kChromeUIFileBrowseHost[] = "filebrowse";
const char kChromeUIMediaplayerHost[] = "mediaplayer";
+const char kChromeUIOptionsHost[] = "options";
const char kChromeUIInspectorHost[] = "inspector";
const char kChromeUINetInternalsHost[] = "net-internals";
const char kChromeUINewTabHost[] = "newtab";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 8da164d..991c9e1 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -54,15 +54,16 @@
extern const char kChromeUIDevToolsURL[];
extern const char kChromeUIDownloadsURL[];
extern const char kChromeUIExtensionsURL[];
-extern const char kChromeUIHistoryURL[];
-extern const char kChromeUIPluginsURL[];
-extern const char kChromeUIPrintURL[];
extern const char kChromeUIFavIconURL[];
extern const char kChromeUIFileBrowseURL[];
-extern const char kChromeUIMediaplayerURL[];
+extern const char kChromeUIHistoryURL[];
extern const char kChromeUIIPCURL[];
+extern const char kChromeUIMediaplayerURL[];
+extern const char kChromeUIOptionsURL[];
extern const char kChromeUINetworkURL[];
extern const char kChromeUINewTabURL[];
+extern const char kChromeUIPluginsURL[];
+extern const char kChromeUIPrintURL[];
// chrome components of URLs. Should be kept in sync with the full URLs
// above.
@@ -72,15 +73,16 @@
extern const char kChromeUIDownloadsHost[];
extern const char kChromeUIExtensionsHost[];
extern const char kChromeUIFavIconHost[];
+extern const char kChromeUIFileBrowseHost[];
extern const char kChromeUIHistoryHost[];
+extern const char kChromeUIInspectorHost[];
+extern const char kChromeUIMediaplayerHost[];
+extern const char kChromeUINetInternalsHost[];
+extern const char kChromeUINewTabHost[];
+extern const char kChromeUIOptionsHost[];
extern const char kChromeUIPluginsHost[];
extern const char kChromeUIPrintHost[];
extern const char kChromeUIResourcesHost[];
-extern const char kChromeUIFileBrowseHost[];
-extern const char kChromeUIMediaplayerHost[];
-extern const char kChromeUIInspectorHost[];
-extern const char kChromeUINetInternalsHost[];
-extern const char kChromeUINewTabHost[];
extern const char kChromeUIThumbnailPath[];
extern const char kChromeUIThemePath[];