Commit 9ace848b authored by jlklein's avatar jlklein Committed by Commit bot

Fetch and actually set prefs (using chrome.send for now).

Required wiring up the options handler for now, but that can all go
away once settingsPrivate is ready.

BUG=

Review URL: https://codereview.chromium.org/1019403002

Cr-Commit-Position: refs/heads/master@{#321506}
parent 6fd3ad46
...@@ -14,22 +14,25 @@ ...@@ -14,22 +14,25 @@
<paper-shadow layout vertical cross-fade> <paper-shadow layout vertical cross-fade>
<cr-settings-page-header page="{{}}"></cr-settings-page-header> <cr-settings-page-header page="{{}}"></cr-settings-page-header>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.enableMenu}}" for> <cr-checkbox checked="{{prefs.settings.a11y.enable_menu.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Show accessibility options in the system menu</span> <span>Show accessibility options in the system menu</span>
</core-label> </core-label>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.largeCursorEnabled}}" for> <cr-checkbox
checked="{{prefs.settings.a11y.large_cursor_enabled.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Show large mouse cursor</span> <span>Show large mouse cursor</span>
</core-label> </core-label>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.highContrastEnabled}}" for> <cr-checkbox
checked="{{prefs.settings.a11y.high_contrast_enabled.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Use high contrast mode</span> <span>Use high contrast mode</span>
</core-label> </core-label>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.stickyKeysEnabled}}" for> <cr-checkbox
checked="{{prefs.settings.a11y.sticky_keys_enabled.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Enable sticky keys</span> <span>Enable sticky keys</span>
<span class="sub-label"> <span class="sub-label">
...@@ -37,7 +40,7 @@ ...@@ -37,7 +40,7 @@
</span> </span>
</core-label> </core-label>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.accessibility}}" for> <cr-checkbox checked="{{prefs.settings.accessibility.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Enable ChromeVox</span> <span>Enable ChromeVox</span>
<span class="sub-label"> <span class="sub-label">
...@@ -45,26 +48,27 @@ ...@@ -45,26 +48,27 @@
</span> </span>
</core-label> </core-label>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.screenMagnifier}}" for> <cr-checkbox checked="{{prefs.settings.a11y.screen_magnifier.value}}"
</cr-checkbox> for></cr-checkbox>
<span>Enable screen magnifier</span> <span>Enable screen magnifier</span>
</core-label> </core-label>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.touchpad.enableTapDragging}}" for> <cr-checkbox
checked="{{prefs.settings.touchpad.enable_tap_dragging.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Enable tap dragging</span> <span>Enable tap dragging</span>
</core-label> </core-label>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.autoclick}}" for> <cr-checkbox checked="{{prefs.settings.a11y.autoclick.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Automatically click when the mouse pointer stops</span> <span>Automatically click when the mouse pointer stops</span>
</core-label> </core-label>
<core-label horizontal layout center class="autoclick-delay-label" <core-label horizontal layout center class="autoclick-delay-label"
hidden?="{{!prefs.settings.a11y.autoclick}}"> hidden?="{{!prefs.settings.a11y.autoclick.value}}">
<span>Delay before click:</span> <span>Delay before click:</span>
<cr-dropdown-menu class="autoclick-dropdown"> <cr-dropdown-menu class="autoclick-dropdown">
<core-menu class="menu" valueAttr="value" selectedAttribute="" <core-menu class="menu" valueAttr="value" selectedAttribute=""
selected="{{prefs.settings.a11y.autoclickDelayMs}}"> selected="{{prefs.settings.a11y.autoclick_delay_ms.value}}">
<paper-item value="200">extremely short</paper-item> <paper-item value="200">extremely short</paper-item>
<paper-item value="400">very short</paper-item> <paper-item value="400">very short</paper-item>
<paper-item value="600">short</paper-item> <paper-item value="600">short</paper-item>
...@@ -74,7 +78,8 @@ ...@@ -74,7 +78,8 @@
</cr-dropdown-menu> </cr-dropdown-menu>
</core-label> </core-label>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.virtualKeyboard}}" for> <cr-checkbox
checked="{{prefs.settings.a11y.virtual_keyboard.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Enable on-screen keyboard</span> <span>Enable on-screen keyboard</span>
</core-label> </core-label>
......
...@@ -18,14 +18,14 @@ html"> ...@@ -18,14 +18,14 @@ html">
<core-label horizontal layout center> <core-label horizontal layout center>
<span class="location-label">Download location:</span> <span class="location-label">Download location:</span>
<cr-input id="downloadsPath" floatingLabel="false" <cr-input id="downloadsPath" floatingLabel="false"
value="{{prefs.settings.download.defaultDirectory}}" readonly for> value="{{prefs.settings.download.default_directory.value}}" readonly for>
</cr-input> </cr-input>
</core-label> </core-label>
<cr-button id="changeDownloadsPath" <cr-button id="changeDownloadsPath"
on-click="{{selectDownloadLocation}}">Change</cr-button> on-click="{{selectDownloadLocation}}">Change</cr-button>
</div> </div>
<core-label horizontal layout> <core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.download.promptForDownload}}" for> <cr-checkbox checked="{{prefs.settings.download.prompt_for_download.value}}" for>
</cr-checkbox> </cr-checkbox>
<span>Ask where to save each file before downloading</span> <span>Ask where to save each file before downloading</span>
</core-label> </core-label>
......
<link rel="import" href="chrome://resources/polymer/polymer/polymer.html"> <link rel="import" href="chrome://resources/polymer/polymer/polymer.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/cr.html">
<polymer-element name="cr-settings-prefs"> <polymer-element name="cr-settings-prefs">
<script src="prefs.js"></script> <script src="prefs.js"></script>
......
...@@ -16,96 +16,206 @@ ...@@ -16,96 +16,206 @@
* @group Chrome Settings Elements * @group Chrome Settings Elements
* @element cr-settings-a11y-page * @element cr-settings-a11y-page
*/ */
Polymer('cr-settings-prefs', { (function() {
publish: { 'use strict';
/**
* Accessibility preferences state.
*
* @attribute settings
* @type CrSettingsPrefs.Settings
* @default null
*/
settings: null,
},
/** @override */
created: function() {
'use strict';
this.settings = {};
this.initializeA11y_();
this.initializeDownloads_();
var observer = new ObjectObserver(this.settings);
observer.open(this.propertyChangeCallback_.bind(this, 'settings'));
// For all Object properties of settings, create an ObjectObserver.
for (let key in this.settings) {
if (typeof this.settings[key] == 'object') {
let keyObserver = new ObjectObserver(this.settings[key]);
keyObserver.open(
this.propertyChangeCallback_.bind(this, 'settings.' + key));
}
}
},
/** /**
* Initializes some defaults for the a11y settings. * A list of all pref paths used on all platforms in the UI.
* @private * TODO(jlklein): This is a temporary workaround that needs to be removed
* once settingsPrivate is implemented with the fetchAll function. We will
* not need to tell the settingsPrivate API which prefs to fetch.
* @const {!Array<string>}
*/ */
initializeA11y_: function() { var PREFS_TO_FETCH = [
this.settings.a11y = { 'download.default_directory',
enableMenu: true, 'download.prompt_for_download',
largeCursorEnabled: false, ];
highContrastEnabled: false,
stickyKeysEnabled: false,
screenMagnifier: false,
enableTapDragging: false,
autoclick: false,
autoclickDelayMs: 200,
virtualKeyboard: false,
};
this.settings.touchpad = {
enableTapDragging: false,
};
// ChromeVox is enbaled/disabled via the 'settings.accessibility' boolean
// pref.
this.settings.accessibility = false;
// TODO(jlklein): Actually pull the data out of prefs and initialize.
},
/** /**
* Initializes some defaults for the downloads settings. * A list of all CrOS-only pref paths used in the UI.
* @private * TODO(jlklein): This is a temporary workaround that needs to be removed
* once settingsPrivate is implemented with the fetchAll function. We will
* not need to tell the settingsPrivate API which prefs to fetch.
* @const {!Array<string>}
*/ */
initializeDownloads_: function() { var CROS_ONLY_PREFS = [
this.settings.download = { 'settings.accessibility',
downloadLocation: '', 'settings.a11y.autoclick',
promptForDownload: false, 'settings.a11y.autoclick_delay_ms',
}; 'settings.a11y.enable_menu',
}, 'settings.a11y.high_contrast_enabled',
'settings.a11y.large_cursor_enabled',
'settings.a11y.screen_magnifier',
'settings.a11y.sticky_keys_enabled',
'settings.a11y.virtual_keyboard',
'settings.touchpad.enable_tap_dragging',
];
/** Polymer('cr-settings-prefs', {
* @param {string} propertyPath The path before the property names. publish: {
* @param {!Array<string>} added An array of keys which were added. /**
* @param {!Array<string>} removed An array of keys which were removed. * Object containing all preferences.
* @param {!Array<string>} changed An array of keys of properties whose *
* values changed. * @attribute settings
* @param {function(string) : *} getOldValueFn A function which takes a * @type CrSettingsPrefs.Settings
* property name and returns the old value for that property. * @default null
* @private */
*/ settings: null,
propertyChangeCallback_: function( },
propertyPath, added, removed, changed, getOldValueFn) {
Object.keys(changed).forEach(function(property) { /** @override */
console.log( created: function() {
`${propertyPath}.${property}`, this.settings = {};
`old : ${getOldValueFn(property)}`, this.fetchSettings_();
`newValue : ${changed[property]}`); },
// TODO(jlklein): Actually set the changed property back to prefs. /**
}); * Fetches all settings from settingsPrivate.
}, * TODO(jlklein): Implement using settingsPrivate when it's available.
}); * @private
*/
fetchSettings_: function() {
// *Sigh* We need to export the function name to global scope. This is
// needed the CoreOptionsHandler can only call a function in the global
// scope.
var callbackName = 'CrSettingsPrefs_onPrefsFetched';
window[callbackName] = this.onPrefsFetched_.bind(this);
var prefsToFetch = PREFS_TO_FETCH;
if (cr.isChromeOS)
prefsToFetch.concat(CROS_ONLY_PREFS);
chrome.send('fetchPrefs', [callbackName].concat(prefsToFetch));
},
/**
* Fetches all settings from settingsPrivate.
* @param {!Object} dict Map of fetched property values.
* @private
*/
onPrefsFetched_: function(dict) {
this.parsePrefDict_('', dict);
},
/**
* Helper function for parsing the prefs dict and constructing Preference
* objects.
* @param {string} prefix The namespace prefix of the pref.
* @param {!Object} dict Map with preference values.
* @private
*/
parsePrefDict_: function(prefix, dict) {
for (let prefName in dict) {
let prefObj = dict[prefName];
if (!this.isPrefObject_(prefObj)) {
this.parsePrefDict_(prefix + prefName + '.', prefObj);
continue;
}
// prefObj is actually a pref object. Construct the path to pref using
// prefix, add the pref to this.settings, and observe changes.
let root = this.settings;
let pathPieces = prefix.slice(0, -1).split('.');
pathPieces.forEach(function(pathPiece) {
root[pathPiece] = root[pathPiece] || {};
root = root[pathPiece];
});
root[prefName] = prefObj;
let keyObserver = new ObjectObserver(prefObj);
keyObserver.open(
this.propertyChangeCallback_.bind(this, prefix + prefName));
}
},
/**
* Determines whether the passed object is a pref object from Chrome.
* @param {*} rawPref The object to check.
* @return {boolean} True if the passes object is a pref.
* @private
*/
isPrefObject_: function(rawPref) {
return rawPref && typeof rawPref == 'object' &&
rawPref.hasOwnProperty('value') &&
rawPref.hasOwnProperty('disabled');
},
/**
* Called when a property of a pref changes.
* @param {string} propertyPath The path before the property names.
* @param {!Array<string>} added An array of keys which were added.
* @param {!Array<string>} removed An array of keys which were removed.
* @param {!Array<string>} changed An array of keys of properties whose
* values changed.
* @param {function(string) : *} getOldValueFn A function which takes a
* property name and returns the old value for that property.
* @private
*/
propertyChangeCallback_: function(
propertyPath, added, removed, changed, getOldValueFn) {
for (let property in changed) {
// UI should only be able to change the value of a setting for now, not
// disabled, etc.
assert(property == 'value');
let newValue = changed[property];
assert(newValue !== undefined);
switch (typeof newValue) {
case 'boolean':
this.setBooleanPref_(
propertyPath, /** @type {boolean} */ (newValue));
break;
case 'number':
this.setNumberPref_(
propertyPath, /** @type {number} */ (newValue));
break;
case 'string':
this.setStringPref_(
propertyPath, /** @type {string} */ (newValue));
break;
case 'object':
assertInstanceof(newValue, Array);
this.setArrayPref_(
propertyPath, /** @type {!Array} */ (newValue));
}
}
},
/**
* @param {string} propertyPath The full path of the pref.
* @param {boolean} value The new value of the pref.
* @private
*/
setBooleanPref_: function(propertyPath, value) {
chrome.send('setBooleanPref', [propertyPath, value]);
},
/**
* @param {string} propertyPath The full path of the pref.
* @param {string} value The new value of the pref.
* @private
*/
setStringPref_: function(propertyPath, value) {
chrome.send('setStringPref', [propertyPath, value]);
},
/**
* @param {string} propertyPath The full path of the pref.
* @param {number} value The new value of the pref.
* @private
*/
setNumberPref_: function(propertyPath, value) {
var setFn = value % 1 == 0 ? 'setIntegerPref' : 'setDoublePref';
chrome.send(setFn, [propertyPath, value]);
},
/**
* @param {string} propertyPath The full path of the pref.
* @param {!Array} value The new value of the pref.
* @private
*/
setArrayPref_: function(propertyPath, value) {
chrome.send('setListPref', [propertyPath, value]);
},
});
})();
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <string> #include <string>
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/options/core_options_handler.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -16,8 +18,24 @@ ...@@ -16,8 +18,24 @@
#include "grit/settings_resources.h" #include "grit/settings_resources.h"
#include "grit/settings_resources_map.h" #include "grit/settings_resources_map.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
#endif
MdSettingsUI::MdSettingsUI(content::WebUI* web_ui) MdSettingsUI::MdSettingsUI(content::WebUI* web_ui)
: content::WebUIController(web_ui) { : content::WebUIController(web_ui) {
// TODO(jlklein): Remove handler logic once settingsPrivate is ready.
#if defined(OS_CHROMEOS)
core_handler_ = new chromeos::options::CoreChromeOSOptionsHandler();
#else
core_handler_ = new options::CoreOptionsHandler();
#endif
core_handler_->set_handlers_host(this);
scoped_ptr<options::OptionsPageUIHandler> handler(core_handler_);
if (handler->IsEnabled())
web_ui->AddMessageHandler(handler.release());
content::WebUIDataSource* html_source = content::WebUIDataSource* html_source =
content::WebUIDataSource::Create(chrome::kChromeUIMdSettingsHost); content::WebUIDataSource::Create(chrome::kChromeUIMdSettingsHost);
...@@ -36,3 +54,11 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui) ...@@ -36,3 +54,11 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui)
MdSettingsUI::~MdSettingsUI() { MdSettingsUI::~MdSettingsUI() {
} }
void MdSettingsUI::InitializeHandlers() {
Profile* profile = Profile::FromWebUI(web_ui());
DCHECK(!profile->IsOffTheRecord() || profile->IsGuestSession());
core_handler_->InitializeHandler();
core_handler_->InitializePage();
}
...@@ -5,15 +5,23 @@ ...@@ -5,15 +5,23 @@
#ifndef CHROME_BROWSER_UI_WEBUI_MD_SETTINGS_UI_H_ #ifndef CHROME_BROWSER_UI_WEBUI_MD_SETTINGS_UI_H_
#define CHROME_BROWSER_UI_WEBUI_MD_SETTINGS_UI_H_ #define CHROME_BROWSER_UI_WEBUI_MD_SETTINGS_UI_H_
#include "chrome/browser/ui/webui/options/core_options_handler.h"
#include "chrome/browser/ui/webui/options/options_ui.h"
#include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_controller.h"
// The WebUI handler for chrome://md-settings. // The WebUI handler for chrome://md-settings.
class MdSettingsUI : public content::WebUIController { class MdSettingsUI : public content::WebUIController,
public options::OptionsPageUIHandlerHost {
public: public:
explicit MdSettingsUI(content::WebUI* web_ui); explicit MdSettingsUI(content::WebUI* web_ui);
~MdSettingsUI() override; ~MdSettingsUI() override;
// OptionsPageUIHandlerHost:
void InitializeHandlers() override;
private: private:
options::CoreOptionsHandler* core_handler_;
DISALLOW_COPY_AND_ASSIGN(MdSettingsUI); DISALLOW_COPY_AND_ASSIGN(MdSettingsUI);
}; };
......
<link rel="import" href="chrome://resources/polymer/polymer/polymer.html"> <link rel="import" href="chrome://resources/polymer/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/paper-dropdown-menu/paper-dropdown-menu.html"> <link rel="import" href="chrome://resources/polymer/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="chrome://resources/polymer/paper-dropdown/paper-dropdown.html"> <link rel="import" href="chrome://resources/polymer/paper-dropdown/paper-dropdown.html">
<script src="chrome://resources/js/assert.js"></script> <link rel="import" href="chrome://resources/html/assert.html">
<polymer-element name="cr-dropdown-menu"> <polymer-element name="cr-dropdown-menu">
<template> <template>
......
<!-- This file can be imported via HTML imports to avoid duplicating asserts.js -->
<script src="chrome://resources/js/assert.js"></script>
\ No newline at end of file
<!-- This file can be imported via HTML imports to avoid duplicating cr.js -->
<script src="chrome://resources/js/cr.js"></script>
\ No newline at end of file
...@@ -260,8 +260,12 @@ without changes to the corresponding grd file. --> ...@@ -260,8 +260,12 @@ without changes to the corresponding grd file. -->
file="js/action_link.js" type="chrome_html" /> file="js/action_link.js" type="chrome_html" />
<structure name="IDR_WEBUI_JS_ASSERT" <structure name="IDR_WEBUI_JS_ASSERT"
file="js/assert.js" type="chrome_html" /> file="js/assert.js" type="chrome_html" />
<structure name="IDR_WEBUI_HTML_ASSERT"
file="html/assert.html" type="chrome_html" />
<structure name="IDR_WEBUI_JS_CR" <structure name="IDR_WEBUI_JS_CR"
file="js/cr.js" type="chrome_html" /> file="js/cr.js" type="chrome_html" />
<structure name="IDR_WEBUI_HTML_CR"
file="html/cr.html" type="chrome_html" />
<structure name="IDR_WEBUI_JS_CR_EVENT_TARGET" <structure name="IDR_WEBUI_JS_CR_EVENT_TARGET"
file="js/cr/event_target.js" type="chrome_html" /> file="js/cr/event_target.js" type="chrome_html" />
<structure name="IDR_WEBUI_JS_CR_LINK_CONTROLLER" <structure name="IDR_WEBUI_JS_CR_LINK_CONTROLLER"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment