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 @@
<paper-shadow layout vertical cross-fade>
<cr-settings-page-header page="{{}}"></cr-settings-page-header>
<core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.enableMenu}}" for>
<cr-checkbox checked="{{prefs.settings.a11y.enable_menu.value}}" for>
</cr-checkbox>
<span>Show accessibility options in the system menu</span>
</core-label>
<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>
<span>Show large mouse cursor</span>
</core-label>
<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>
<span>Use high contrast mode</span>
</core-label>
<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>
<span>Enable sticky keys</span>
<span class="sub-label">
......@@ -37,7 +40,7 @@
</span>
</core-label>
<core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.accessibility}}" for>
<cr-checkbox checked="{{prefs.settings.accessibility.value}}" for>
</cr-checkbox>
<span>Enable ChromeVox</span>
<span class="sub-label">
......@@ -45,26 +48,27 @@
</span>
</core-label>
<core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.screenMagnifier}}" for>
</cr-checkbox>
<cr-checkbox checked="{{prefs.settings.a11y.screen_magnifier.value}}"
for></cr-checkbox>
<span>Enable screen magnifier</span>
</core-label>
<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>
<span>Enable tap dragging</span>
</core-label>
<core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.autoclick}}" for>
<cr-checkbox checked="{{prefs.settings.a11y.autoclick.value}}" for>
</cr-checkbox>
<span>Automatically click when the mouse pointer stops</span>
</core-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>
<cr-dropdown-menu class="autoclick-dropdown">
<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="400">very short</paper-item>
<paper-item value="600">short</paper-item>
......@@ -74,7 +78,8 @@
</cr-dropdown-menu>
</core-label>
<core-label horizontal layout>
<cr-checkbox checked="{{prefs.settings.a11y.virtualKeyboard}}" for>
<cr-checkbox
checked="{{prefs.settings.a11y.virtual_keyboard.value}}" for>
</cr-checkbox>
<span>Enable on-screen keyboard</span>
</core-label>
......
......@@ -18,14 +18,14 @@ html">
<core-label horizontal layout center>
<span class="location-label">Download location:</span>
<cr-input id="downloadsPath" floatingLabel="false"
value="{{prefs.settings.download.defaultDirectory}}" readonly for>
value="{{prefs.settings.download.default_directory.value}}" readonly for>
</cr-input>
</core-label>
<cr-button id="changeDownloadsPath"
on-click="{{selectDownloadLocation}}">Change</cr-button>
</div>
<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>
<span>Ask where to save each file before downloading</span>
</core-label>
......
<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">
<script src="prefs.js"></script>
......
......@@ -16,96 +16,206 @@
* @group Chrome Settings Elements
* @element cr-settings-a11y-page
*/
Polymer('cr-settings-prefs', {
publish: {
/**
* 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));
}
}
},
(function() {
'use strict';
/**
* Initializes some defaults for the a11y settings.
* @private
* A list of all pref paths used on all platforms in the UI.
* 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() {
this.settings.a11y = {
enableMenu: true,
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.
},
var PREFS_TO_FETCH = [
'download.default_directory',
'download.prompt_for_download',
];
/**
* Initializes some defaults for the downloads settings.
* @private
* A list of all CrOS-only pref paths used in the UI.
* 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() {
this.settings.download = {
downloadLocation: '',
promptForDownload: false,
};
},
var CROS_ONLY_PREFS = [
'settings.accessibility',
'settings.a11y.autoclick',
'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',
];
/**
* @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) {
Object.keys(changed).forEach(function(property) {
console.log(
`${propertyPath}.${property}`,
`old : ${getOldValueFn(property)}`,
`newValue : ${changed[property]}`);
// TODO(jlklein): Actually set the changed property back to prefs.
});
},
});
Polymer('cr-settings-prefs', {
publish: {
/**
* Object containing all preferences.
*
* @attribute settings
* @type CrSettingsPrefs.Settings
* @default null
*/
settings: null,
},
/** @override */
created: function() {
this.settings = {};
this.fetchSettings_();
},
/**
* 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 @@
#include <string>
#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/grit/generated_resources.h"
#include "content/public/browser/web_contents.h"
......@@ -16,8 +18,24 @@
#include "grit/settings_resources.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)
: 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::Create(chrome::kChromeUIMdSettingsHost);
......@@ -36,3 +54,11 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui)
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 @@
#ifndef 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"
// The WebUI handler for chrome://md-settings.
class MdSettingsUI : public content::WebUIController {
class MdSettingsUI : public content::WebUIController,
public options::OptionsPageUIHandlerHost {
public:
explicit MdSettingsUI(content::WebUI* web_ui);
~MdSettingsUI() override;
// OptionsPageUIHandlerHost:
void InitializeHandlers() override;
private:
options::CoreOptionsHandler* core_handler_;
DISALLOW_COPY_AND_ASSIGN(MdSettingsUI);
};
......
<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/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">
<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. -->
file="js/action_link.js" type="chrome_html" />
<structure name="IDR_WEBUI_JS_ASSERT"
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"
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"
file="js/cr/event_target.js" type="chrome_html" />
<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