Update wmts-hidpi, add nicer-api-docs
This commit is contained in:
997
nicer-api-docs/closure-library/closure/goog/tweak/entries.js
Normal file
997
nicer-api-docs/closure-library/closure/goog/tweak/entries.js
Normal file
@@ -0,0 +1,997 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Definitions for all tweak entries.
|
||||
* The class hierarchy is as follows (abstract entries are denoted with a *):
|
||||
* BaseEntry(id, description) *
|
||||
* -> ButtonAction(buttons in the UI)
|
||||
* -> BaseSetting(query parameter) *
|
||||
* -> BooleanGroup(child booleans)
|
||||
* -> BasePrimitiveSetting(value, defaultValue) *
|
||||
* -> BooleanSetting
|
||||
* -> StringSetting
|
||||
* -> NumericSetting
|
||||
* -> BooleanInGroupSetting(token)
|
||||
* Most clients should not use these classes directly, but instead use the API
|
||||
* defined in tweak.js. One possible use case for directly using them is to
|
||||
* register tweaks that are not known at compile time.
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.tweak.BaseEntry');
|
||||
goog.provide('goog.tweak.BasePrimitiveSetting');
|
||||
goog.provide('goog.tweak.BaseSetting');
|
||||
goog.provide('goog.tweak.BooleanGroup');
|
||||
goog.provide('goog.tweak.BooleanInGroupSetting');
|
||||
goog.provide('goog.tweak.BooleanSetting');
|
||||
goog.provide('goog.tweak.ButtonAction');
|
||||
goog.provide('goog.tweak.NumericSetting');
|
||||
goog.provide('goog.tweak.StringSetting');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.log');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for all Registry entries.
|
||||
* @param {string} id The ID for the entry. Must contain only letters,
|
||||
* numbers, underscores and periods.
|
||||
* @param {string} description A description of what the entry does.
|
||||
* @constructor
|
||||
*/
|
||||
goog.tweak.BaseEntry = function(id, description) {
|
||||
/**
|
||||
* An ID to uniquely identify the entry.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.id_ = id;
|
||||
|
||||
/**
|
||||
* A descriptive label for the entry.
|
||||
* @type {string}
|
||||
*/
|
||||
this.label = id;
|
||||
|
||||
/**
|
||||
* A description of what this entry does.
|
||||
* @type {string}
|
||||
*/
|
||||
this.description = description;
|
||||
|
||||
/**
|
||||
* Functions to be called whenever a setting is changed or a button is
|
||||
* clicked.
|
||||
* @type {!Array.<!Function>}
|
||||
* @private
|
||||
*/
|
||||
this.callbacks_ = [];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @protected
|
||||
*/
|
||||
goog.tweak.BaseEntry.prototype.logger =
|
||||
goog.log.getLogger('goog.tweak.BaseEntry');
|
||||
|
||||
|
||||
/**
|
||||
* Whether a restart is required for changes to the setting to take effect.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.BaseEntry.prototype.restartRequired_ = true;
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Returns the entry's ID.
|
||||
*/
|
||||
goog.tweak.BaseEntry.prototype.getId = function() {
|
||||
return this.id_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether a restart is required for changes to the setting to take
|
||||
* effect.
|
||||
* @return {boolean} The value.
|
||||
*/
|
||||
goog.tweak.BaseEntry.prototype.isRestartRequired = function() {
|
||||
return this.restartRequired_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether a restart is required for changes to the setting to take
|
||||
* effect.
|
||||
* @param {boolean} value The new value.
|
||||
*/
|
||||
goog.tweak.BaseEntry.prototype.setRestartRequired = function(value) {
|
||||
this.restartRequired_ = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a callback that should be called when the setting has changed (or when
|
||||
* an action has been clicked).
|
||||
* @param {!Function} callback The callback to add.
|
||||
*/
|
||||
goog.tweak.BaseEntry.prototype.addCallback = function(callback) {
|
||||
this.callbacks_.push(callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a callback that was added by addCallback.
|
||||
* @param {!Function} callback The callback to add.
|
||||
*/
|
||||
goog.tweak.BaseEntry.prototype.removeCallback = function(callback) {
|
||||
goog.array.remove(this.callbacks_, callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls all registered callbacks.
|
||||
*/
|
||||
goog.tweak.BaseEntry.prototype.fireCallbacks = function() {
|
||||
for (var i = 0, callback; callback = this.callbacks_[i]; ++i) {
|
||||
callback(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for all tweak entries that are settings. Settings are entries
|
||||
* that are associated with a query parameter.
|
||||
* @param {string} id The ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BaseEntry}
|
||||
*/
|
||||
goog.tweak.BaseSetting = function(id, description) {
|
||||
goog.tweak.BaseEntry.call(this, id, description);
|
||||
// Apply this restriction for settings since they turn in to query
|
||||
// parameters. For buttons, it's not really important.
|
||||
goog.asserts.assert(!/[^A-Za-z0-9._]/.test(id),
|
||||
'Tweak id contains illegal characters: ', id);
|
||||
|
||||
/**
|
||||
* The value of this setting's query parameter.
|
||||
* @type {string|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.initialQueryParamValue;
|
||||
|
||||
/**
|
||||
* The query parameter that controls this setting.
|
||||
* @type {?string}
|
||||
* @private
|
||||
*/
|
||||
this.paramName_ = this.getId().toLowerCase();
|
||||
};
|
||||
goog.inherits(goog.tweak.BaseSetting, goog.tweak.BaseEntry);
|
||||
|
||||
|
||||
/**
|
||||
* States of initialization. Entries are initialized lazily in order to allow
|
||||
* their initialization to happen in multiple statements.
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.BaseSetting.InitializeState_ = {
|
||||
// The start state for all settings.
|
||||
NOT_INITIALIZED: 0,
|
||||
// This is used to allow concrete classes to call assertNotInitialized()
|
||||
// during their initialize() function.
|
||||
INITIALIZING: 1,
|
||||
// One a setting is initialized, it may no longer change its configuration
|
||||
// settings (associated query parameter, token, etc).
|
||||
INITIALIZED: 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.logger =
|
||||
goog.log.getLogger('goog.tweak.BaseSetting');
|
||||
|
||||
|
||||
/**
|
||||
* Whether initialize() has been called (or is in the middle of being called).
|
||||
* @type {goog.tweak.BaseSetting.InitializeState_}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.initializeState_ =
|
||||
goog.tweak.BaseSetting.InitializeState_.NOT_INITIALIZED;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the entry based on the value of the query parameter. Once
|
||||
* this is called, configuration settings (associated query parameter, token,
|
||||
* etc) may not be changed.
|
||||
* @param {?string} value The part of the query param for this setting after
|
||||
* the '='. Null if it is not present.
|
||||
* @protected
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.initialize = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value to be used in the query parameter for this tweak.
|
||||
* @return {?string} The encoded value. Null if the value is set to its
|
||||
* default.
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.getNewValueEncoded = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Asserts that this tweak has not been initialized yet.
|
||||
* @param {string} funcName Function name to use in the assertion message.
|
||||
* @protected
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.assertNotInitialized = function(funcName) {
|
||||
goog.asserts.assert(this.initializeState_ !=
|
||||
goog.tweak.BaseSetting.InitializeState_.INITIALIZED,
|
||||
'Cannot call ' + funcName + ' after the tweak as been initialized.');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the setting is currently being initialized.
|
||||
* @return {boolean} Whether the setting is currently being initialized.
|
||||
* @protected
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.isInitializing = function() {
|
||||
return this.initializeState_ ==
|
||||
goog.tweak.BaseSetting.InitializeState_.INITIALIZING;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the initial query parameter value for this setting. May not be called
|
||||
* after the setting has been initialized.
|
||||
* @param {string} value The inital query parameter value for this setting.
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.setInitialQueryParamValue = function(value) {
|
||||
this.assertNotInitialized('setInitialQueryParamValue');
|
||||
this.initialQueryParamValue = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the query parameter used for this setting.
|
||||
* @return {?string} The param name. Null if no query parameter is directly
|
||||
* associated with the setting.
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.getParamName = function() {
|
||||
return this.paramName_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the name of the query parameter used for this setting. If null is
|
||||
* passed the the setting will not appear in the top-level query string.
|
||||
* @param {?string} value The new value.
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.setParamName = function(value) {
|
||||
this.assertNotInitialized('setParamName');
|
||||
this.paramName_ = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Applies the default value or query param value if this is the first time
|
||||
* that the function has been called.
|
||||
* @protected
|
||||
*/
|
||||
goog.tweak.BaseSetting.prototype.ensureInitialized = function() {
|
||||
if (this.initializeState_ ==
|
||||
goog.tweak.BaseSetting.InitializeState_.NOT_INITIALIZED) {
|
||||
// Instead of having only initialized / not initialized, there is a
|
||||
// separate in-between state so that functions that call
|
||||
// assertNotInitialized() will not fail when called inside of the
|
||||
// initialize().
|
||||
this.initializeState_ =
|
||||
goog.tweak.BaseSetting.InitializeState_.INITIALIZING;
|
||||
var value = this.initialQueryParamValue == undefined ? null :
|
||||
this.initialQueryParamValue;
|
||||
this.initialize(value);
|
||||
this.initializeState_ =
|
||||
goog.tweak.BaseSetting.InitializeState_.INITIALIZED;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for all settings that wrap primitive values.
|
||||
* @param {string} id The ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @param {*} defaultValue The default value for this setting.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BaseSetting}
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting = function(id, description, defaultValue) {
|
||||
goog.tweak.BaseSetting.call(this, id, description);
|
||||
/**
|
||||
* The default value of the setting.
|
||||
* @type {*}
|
||||
* @private
|
||||
*/
|
||||
this.defaultValue_ = defaultValue;
|
||||
|
||||
/**
|
||||
* The value of the tweak.
|
||||
* @type {*}
|
||||
* @private
|
||||
*/
|
||||
this.value_;
|
||||
|
||||
/**
|
||||
* The value of the tweak once "Apply Tweaks" is pressed.
|
||||
* @type {*}
|
||||
* @private
|
||||
*/
|
||||
this.newValue_;
|
||||
};
|
||||
goog.inherits(goog.tweak.BasePrimitiveSetting, goog.tweak.BaseSetting);
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting.prototype.logger =
|
||||
goog.log.getLogger('goog.tweak.BasePrimitiveSetting');
|
||||
|
||||
|
||||
/**
|
||||
* Returns the query param encoded representation of the setting's value.
|
||||
* @return {string} The encoded value.
|
||||
* @protected
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting.prototype.encodeNewValue =
|
||||
goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* If the setting has the restartRequired option, then returns its inital
|
||||
* value. Otherwise, returns its current value.
|
||||
* @return {*} The value.
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting.prototype.getValue = function() {
|
||||
this.ensureInitialized();
|
||||
return this.value_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the setting to use once "Apply Tweaks" is clicked.
|
||||
* @return {*} The value.
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting.prototype.getNewValue = function() {
|
||||
this.ensureInitialized();
|
||||
return this.newValue_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the setting. If the setting has the restartRequired
|
||||
* option, then the value will not be changed until the "Apply Tweaks" button
|
||||
* is clicked. If it does not have the option, the value will be update
|
||||
* immediately and all registered callbacks will be called.
|
||||
* @param {*} value The value.
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting.prototype.setValue = function(value) {
|
||||
this.ensureInitialized();
|
||||
var changed = this.newValue_ != value;
|
||||
this.newValue_ = value;
|
||||
// Don't fire callbacks if we are currently in the initialize() method.
|
||||
if (this.isInitializing()) {
|
||||
this.value_ = value;
|
||||
} else {
|
||||
if (!this.isRestartRequired()) {
|
||||
// Update the current value only if the tweak has been marked as not
|
||||
// needing a restart.
|
||||
this.value_ = value;
|
||||
}
|
||||
if (changed) {
|
||||
this.fireCallbacks();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the default value for this setting.
|
||||
* @return {*} The default value.
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting.prototype.getDefaultValue = function() {
|
||||
return this.defaultValue_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the default value for the tweak.
|
||||
* @param {*} value The new value.
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting.prototype.setDefaultValue =
|
||||
function(value) {
|
||||
this.assertNotInitialized('setDefaultValue');
|
||||
this.defaultValue_ = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BasePrimitiveSetting.prototype.getNewValueEncoded = function() {
|
||||
this.ensureInitialized();
|
||||
return this.newValue_ == this.defaultValue_ ? null : this.encodeNewValue();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A registry setting for string values.
|
||||
* @param {string} id The ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BasePrimitiveSetting}
|
||||
*/
|
||||
goog.tweak.StringSetting = function(id, description) {
|
||||
goog.tweak.BasePrimitiveSetting.call(this, id, description, '');
|
||||
/**
|
||||
* Valid values for the setting.
|
||||
* @type {Array.<string>|undefined}
|
||||
*/
|
||||
this.validValues_;
|
||||
};
|
||||
goog.inherits(goog.tweak.StringSetting, goog.tweak.BasePrimitiveSetting);
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.logger =
|
||||
goog.log.getLogger('goog.tweak.StringSetting');
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {string} The tweaks's value.
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.getValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {string} The tweaks's new value.
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.getNewValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {string} value The tweaks's value.
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.setValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {string} value The default value.
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.setDefaultValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {string} The default value.
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.getDefaultValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.encodeNewValue = function() {
|
||||
return this.getNewValue();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the valid values for the setting.
|
||||
* @param {Array.<string>|undefined} values Valid values.
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.setValidValues = function(values) {
|
||||
this.assertNotInitialized('setValidValues');
|
||||
this.validValues_ = values;
|
||||
// Set the default value to the first value in the list if the current
|
||||
// default value is not within it.
|
||||
if (values && !goog.array.contains(values, this.getDefaultValue())) {
|
||||
this.setDefaultValue(values[0]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the valid values for the setting.
|
||||
* @return {Array.<string>|undefined} Valid values.
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.getValidValues = function() {
|
||||
return this.validValues_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.StringSetting.prototype.initialize = function(value) {
|
||||
if (value == null) {
|
||||
this.setValue(this.getDefaultValue());
|
||||
} else {
|
||||
var validValues = this.validValues_;
|
||||
if (validValues) {
|
||||
// Make the query parameter values case-insensitive since users might
|
||||
// type them by hand. Make the capitalization that is actual used come
|
||||
// from the list of valid values.
|
||||
value = value.toLowerCase();
|
||||
for (var i = 0, il = validValues.length; i < il; ++i) {
|
||||
if (value == validValues[i].toLowerCase()) {
|
||||
this.setValue(validValues[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Warn if the value is not in the list of allowed values.
|
||||
goog.log.warning(this.logger, 'Tweak ' + this.getId() +
|
||||
' has value outside of expected range:' + value);
|
||||
}
|
||||
this.setValue(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A registry setting for numeric values.
|
||||
* @param {string} id The ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BasePrimitiveSetting}
|
||||
*/
|
||||
goog.tweak.NumericSetting = function(id, description) {
|
||||
goog.tweak.BasePrimitiveSetting.call(this, id, description, 0);
|
||||
/**
|
||||
* Valid values for the setting.
|
||||
* @type {Array.<number>|undefined}
|
||||
*/
|
||||
this.validValues_;
|
||||
};
|
||||
goog.inherits(goog.tweak.NumericSetting, goog.tweak.BasePrimitiveSetting);
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.logger =
|
||||
goog.log.getLogger('goog.tweak.NumericSetting');
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {number} The tweaks's value.
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.getValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {number} The tweaks's new value.
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.getNewValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {number} value The tweaks's value.
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.setValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {number} value The default value.
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.setDefaultValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {number} The default value.
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.getDefaultValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.encodeNewValue = function() {
|
||||
return '' + this.getNewValue();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the valid values for the setting.
|
||||
* @param {Array.<number>|undefined} values Valid values.
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.setValidValues =
|
||||
function(values) {
|
||||
this.assertNotInitialized('setValidValues');
|
||||
this.validValues_ = values;
|
||||
// Set the default value to the first value in the list if the current
|
||||
// default value is not within it.
|
||||
if (values && !goog.array.contains(values, this.getDefaultValue())) {
|
||||
this.setDefaultValue(values[0]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the valid values for the setting.
|
||||
* @return {Array.<number>|undefined} Valid values.
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.getValidValues = function() {
|
||||
return this.validValues_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.NumericSetting.prototype.initialize = function(value) {
|
||||
if (value == null) {
|
||||
this.setValue(this.getDefaultValue());
|
||||
} else {
|
||||
var coercedValue = +value;
|
||||
// Warn if the value is not in the list of allowed values.
|
||||
if (this.validValues_ &&
|
||||
!goog.array.contains(this.validValues_, coercedValue)) {
|
||||
goog.log.warning(this.logger, 'Tweak ' + this.getId() +
|
||||
' has value outside of expected range: ' + value);
|
||||
}
|
||||
|
||||
if (isNaN(coercedValue)) {
|
||||
goog.log.warning(this.logger, 'Tweak ' + this.getId() +
|
||||
' has value of NaN, resetting to ' + this.getDefaultValue());
|
||||
this.setValue(this.getDefaultValue());
|
||||
} else {
|
||||
this.setValue(coercedValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A registry setting that can be either true of false.
|
||||
* @param {string} id The ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BasePrimitiveSetting}
|
||||
*/
|
||||
goog.tweak.BooleanSetting = function(id, description) {
|
||||
goog.tweak.BasePrimitiveSetting.call(this, id, description, false);
|
||||
};
|
||||
goog.inherits(goog.tweak.BooleanSetting, goog.tweak.BasePrimitiveSetting);
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BooleanSetting.prototype.logger =
|
||||
goog.log.getLogger('goog.tweak.BooleanSetting');
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {boolean} The tweaks's value.
|
||||
*/
|
||||
goog.tweak.BooleanSetting.prototype.getValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {boolean} The tweaks's new value.
|
||||
*/
|
||||
goog.tweak.BooleanSetting.prototype.getNewValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {boolean} value The tweaks's value.
|
||||
*/
|
||||
goog.tweak.BooleanSetting.prototype.setValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {boolean} value The default value.
|
||||
*/
|
||||
goog.tweak.BooleanSetting.prototype.setDefaultValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @return {boolean} The default value.
|
||||
*/
|
||||
goog.tweak.BooleanSetting.prototype.getDefaultValue;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BooleanSetting.prototype.encodeNewValue = function() {
|
||||
return this.getNewValue() ? '1' : '0';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BooleanSetting.prototype.initialize = function(value) {
|
||||
if (value == null) {
|
||||
this.setValue(this.getDefaultValue());
|
||||
} else {
|
||||
value = value.toLowerCase();
|
||||
this.setValue(value == 'true' || value == '1');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An entry in a BooleanGroup.
|
||||
* @param {string} id The ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @param {!goog.tweak.BooleanGroup} group The group that this entry belongs
|
||||
* to.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BooleanSetting}
|
||||
*/
|
||||
goog.tweak.BooleanInGroupSetting = function(id, description, group) {
|
||||
goog.tweak.BooleanSetting.call(this, id, description);
|
||||
|
||||
/**
|
||||
* The token to use in the query parameter.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.token_ = this.getId().toLowerCase();
|
||||
|
||||
/**
|
||||
* The BooleanGroup that this setting belongs to.
|
||||
* @type {!goog.tweak.BooleanGroup}
|
||||
* @private
|
||||
*/
|
||||
this.group_ = group;
|
||||
|
||||
// Take setting out of top-level query parameter list.
|
||||
goog.tweak.BooleanInGroupSetting.superClass_.setParamName.call(this,
|
||||
null);
|
||||
};
|
||||
goog.inherits(goog.tweak.BooleanInGroupSetting, goog.tweak.BooleanSetting);
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BooleanInGroupSetting.prototype.logger =
|
||||
goog.log.getLogger('goog.tweak.BooleanInGroupSetting');
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BooleanInGroupSetting.prototype.setParamName = function(value) {
|
||||
goog.asserts.fail('Use setToken() for BooleanInGroupSetting.');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the token to use in the query parameter.
|
||||
* @param {string} value The value.
|
||||
*/
|
||||
goog.tweak.BooleanInGroupSetting.prototype.setToken = function(value) {
|
||||
this.token_ = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the token to use in the query parameter.
|
||||
* @return {string} The value.
|
||||
*/
|
||||
goog.tweak.BooleanInGroupSetting.prototype.getToken = function() {
|
||||
return this.token_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the BooleanGroup that this setting belongs to.
|
||||
* @return {!goog.tweak.BooleanGroup} The BooleanGroup that this setting
|
||||
* belongs to.
|
||||
*/
|
||||
goog.tweak.BooleanInGroupSetting.prototype.getGroup = function() {
|
||||
return this.group_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A registry setting that contains a group of boolean subfield, where all
|
||||
* entries modify the same query parameter. For example:
|
||||
* ?foo=setting1,-setting2
|
||||
* @param {string} id The ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BaseSetting}
|
||||
*/
|
||||
goog.tweak.BooleanGroup = function(id, description) {
|
||||
goog.tweak.BaseSetting.call(this, id, description);
|
||||
|
||||
/**
|
||||
* A map of token->child entry.
|
||||
* @type {!Object.<!goog.tweak.BooleanSetting>}
|
||||
* @private
|
||||
*/
|
||||
this.entriesByToken_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* A map of token->true/false for all tokens that appeared in the query
|
||||
* parameter.
|
||||
* @type {!Object.<boolean>}
|
||||
* @private
|
||||
*/
|
||||
this.queryParamValues_ = {};
|
||||
|
||||
};
|
||||
goog.inherits(goog.tweak.BooleanGroup, goog.tweak.BaseSetting);
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BooleanGroup.prototype.logger =
|
||||
goog.log.getLogger('goog.tweak.BooleanGroup');
|
||||
|
||||
|
||||
/**
|
||||
* Returns the map of token->boolean settings.
|
||||
* @return {!Object.<!goog.tweak.BooleanSetting>} The child settings.
|
||||
*/
|
||||
goog.tweak.BooleanGroup.prototype.getChildEntries = function() {
|
||||
return this.entriesByToken_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds the given BooleanSetting to the group.
|
||||
* @param {goog.tweak.BooleanInGroupSetting} boolEntry The entry.
|
||||
*/
|
||||
goog.tweak.BooleanGroup.prototype.addChild = function(boolEntry) {
|
||||
this.ensureInitialized();
|
||||
|
||||
var token = boolEntry.getToken();
|
||||
var lcToken = token.toLowerCase();
|
||||
goog.asserts.assert(!this.entriesByToken_[lcToken],
|
||||
'Multiple bools registered with token "%s" in group: %s', token,
|
||||
this.getId());
|
||||
this.entriesByToken_[lcToken] = boolEntry;
|
||||
|
||||
// Initialize from query param.
|
||||
var value = this.queryParamValues_[lcToken];
|
||||
if (value != undefined) {
|
||||
boolEntry.initialQueryParamValue = value ? '1' : '0';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BooleanGroup.prototype.initialize = function(value) {
|
||||
var queryParamValues = {};
|
||||
|
||||
if (value) {
|
||||
var tokens = value.split(/\s*,\s*/);
|
||||
for (var i = 0; i < tokens.length; ++i) {
|
||||
var token = tokens[i].toLowerCase();
|
||||
var negative = token.charAt(0) == '-';
|
||||
if (negative) {
|
||||
token = token.substr(1);
|
||||
}
|
||||
queryParamValues[token] = !negative;
|
||||
}
|
||||
}
|
||||
this.queryParamValues_ = queryParamValues;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.tweak.BooleanGroup.prototype.getNewValueEncoded = function() {
|
||||
this.ensureInitialized();
|
||||
var nonDefaultValues = [];
|
||||
// Sort the keys so that the generate value is stable.
|
||||
var keys = goog.object.getKeys(this.entriesByToken_);
|
||||
keys.sort();
|
||||
for (var i = 0, entry; entry = this.entriesByToken_[keys[i]]; ++i) {
|
||||
var encodedValue = entry.getNewValueEncoded();
|
||||
if (encodedValue != null) {
|
||||
nonDefaultValues.push((entry.getNewValue() ? '' : '-') +
|
||||
entry.getToken());
|
||||
}
|
||||
}
|
||||
return nonDefaultValues.length ? nonDefaultValues.join(',') : null;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A registry action (a button).
|
||||
* @param {string} id The ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @param {!Function} callback Function to call when the button is clicked.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BaseEntry}
|
||||
*/
|
||||
goog.tweak.ButtonAction = function(id, description, callback) {
|
||||
goog.tweak.BaseEntry.call(this, id, description);
|
||||
this.addCallback(callback);
|
||||
this.setRestartRequired(false);
|
||||
};
|
||||
goog.inherits(goog.tweak.ButtonAction, goog.tweak.BaseEntry);
|
||||
|
||||
310
nicer-api-docs/closure-library/closure/goog/tweak/registry.js
Normal file
310
nicer-api-docs/closure-library/closure/goog/tweak/registry.js
Normal file
@@ -0,0 +1,310 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Definition for goog.tweak.Registry.
|
||||
* Most clients should not use this class directly, but instead use the API
|
||||
* defined in tweak.js. One possible use case for directly using TweakRegistry
|
||||
* is to register tweaks that are not known at compile time.
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.tweak.Registry');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.log');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.tweak.BaseEntry');
|
||||
goog.require('goog.uri.utils');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Singleton that manages all tweaks. This should be instantiated only from
|
||||
* goog.tweak.getRegistry().
|
||||
* @param {string} queryParams Value of window.location.search.
|
||||
* @param {!Object.<string|number|boolean>} compilerOverrides Default value
|
||||
* overrides set by the compiler.
|
||||
* @constructor
|
||||
*/
|
||||
goog.tweak.Registry = function(queryParams, compilerOverrides) {
|
||||
/**
|
||||
* A map of entry id -> entry object
|
||||
* @type {!Object.<!goog.tweak.BaseEntry>}
|
||||
* @private
|
||||
*/
|
||||
this.entryMap_ = {};
|
||||
|
||||
/**
|
||||
* The map of query params to use when initializing entry settings.
|
||||
* @type {!Object.<string>}
|
||||
* @private
|
||||
*/
|
||||
this.parsedQueryParams_ = goog.tweak.Registry.parseQueryParams(queryParams);
|
||||
|
||||
/**
|
||||
* List of callbacks to call when a new entry is registered.
|
||||
* @type {!Array.<!Function>}
|
||||
* @private
|
||||
*/
|
||||
this.onRegisterListeners_ = [];
|
||||
|
||||
/**
|
||||
* A map of entry ID -> default value override for overrides set by the
|
||||
* compiler.
|
||||
* @type {!Object.<string|number|boolean>}
|
||||
* @private
|
||||
*/
|
||||
this.compilerDefaultValueOverrides_ = compilerOverrides;
|
||||
|
||||
/**
|
||||
* A map of entry ID -> default value override for overrides set by
|
||||
* goog.tweak.overrideDefaultValue().
|
||||
* @type {!Object.<string|number|boolean>}
|
||||
* @private
|
||||
*/
|
||||
this.defaultValueOverrides_ = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
* @type {goog.log.Logger}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.Registry.prototype.logger_ =
|
||||
goog.log.getLogger('goog.tweak.Registry');
|
||||
|
||||
|
||||
/**
|
||||
* Simple parser for query params. Makes all keys lower-case.
|
||||
* @param {string} queryParams The part of the url between the ? and the #.
|
||||
* @return {!Object.<string>} map of key->value.
|
||||
*/
|
||||
goog.tweak.Registry.parseQueryParams = function(queryParams) {
|
||||
// Strip off the leading ? and split on &.
|
||||
var parts = queryParams.substr(1).split('&');
|
||||
var ret = {};
|
||||
|
||||
for (var i = 0, il = parts.length; i < il; ++i) {
|
||||
var entry = parts[i].split('=');
|
||||
if (entry[0]) {
|
||||
ret[goog.string.urlDecode(entry[0]).toLowerCase()] =
|
||||
goog.string.urlDecode(entry[1] || '');
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Registers the given tweak setting/action.
|
||||
* @param {goog.tweak.BaseEntry} entry The entry.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.register = function(entry) {
|
||||
var id = entry.getId();
|
||||
var oldBaseEntry = this.entryMap_[id];
|
||||
if (oldBaseEntry) {
|
||||
if (oldBaseEntry == entry) {
|
||||
goog.log.warning(this.logger_, 'Tweak entry registered twice: ' + id);
|
||||
return;
|
||||
}
|
||||
goog.asserts.fail(
|
||||
'Tweak entry registered twice and with different types: ' + id);
|
||||
}
|
||||
|
||||
// Check for a default value override, either from compiler flags or from a
|
||||
// call to overrideDefaultValue().
|
||||
var defaultValueOverride = (id in this.compilerDefaultValueOverrides_) ?
|
||||
this.compilerDefaultValueOverrides_[id] : this.defaultValueOverrides_[id];
|
||||
if (goog.isDef(defaultValueOverride)) {
|
||||
goog.asserts.assertInstanceof(entry, goog.tweak.BasePrimitiveSetting,
|
||||
'Cannot set the default value of non-primitive setting %s',
|
||||
entry.label);
|
||||
entry.setDefaultValue(defaultValueOverride);
|
||||
}
|
||||
|
||||
// Set its value from the query params.
|
||||
if (entry instanceof goog.tweak.BaseSetting) {
|
||||
if (entry.getParamName()) {
|
||||
entry.setInitialQueryParamValue(
|
||||
this.parsedQueryParams_[entry.getParamName()]);
|
||||
}
|
||||
}
|
||||
|
||||
this.entryMap_[id] = entry;
|
||||
// Call all listeners.
|
||||
for (var i = 0, callback; callback = this.onRegisterListeners_[i]; ++i) {
|
||||
callback(entry);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a callback to be called whenever a new tweak is added.
|
||||
* @param {!Function} func The callback.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.addOnRegisterListener = function(func) {
|
||||
this.onRegisterListeners_.push(func);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} id The unique string that identifies this entry.
|
||||
* @return {boolean} Whether a tweak with the given ID is registered.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.hasEntry = function(id) {
|
||||
return id in this.entryMap_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the BaseEntry with the given ID. Asserts if it does not exists.
|
||||
* @param {string} id The unique string that identifies this entry.
|
||||
* @return {!goog.tweak.BaseEntry} The entry.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.getEntry = function(id) {
|
||||
var ret = this.entryMap_[id];
|
||||
goog.asserts.assert(ret, 'Tweak not registered: %s', id);
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the boolean setting with the given ID. Asserts if the ID does not
|
||||
* refer to a registered entry or if it refers to one of the wrong type.
|
||||
* @param {string} id The unique string that identifies this entry.
|
||||
* @return {!goog.tweak.BooleanSetting} The entry.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.getBooleanSetting = function(id) {
|
||||
var entry = this.getEntry(id);
|
||||
goog.asserts.assertInstanceof(entry, goog.tweak.BooleanSetting,
|
||||
'getBooleanSetting called on wrong type of BaseSetting');
|
||||
return /** @type {!goog.tweak.BooleanSetting} */ (entry);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the string setting with the given ID. Asserts if the ID does not
|
||||
* refer to a registered entry or if it refers to one of the wrong type.
|
||||
* @param {string} id The unique string that identifies this entry.
|
||||
* @return {!goog.tweak.StringSetting} The entry.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.getStringSetting = function(id) {
|
||||
var entry = this.getEntry(id);
|
||||
goog.asserts.assertInstanceof(entry, goog.tweak.StringSetting,
|
||||
'getStringSetting called on wrong type of BaseSetting');
|
||||
return /** @type {!goog.tweak.StringSetting} */ (entry);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the numeric setting with the given ID. Asserts if the ID does not
|
||||
* refer to a registered entry or if it refers to one of the wrong type.
|
||||
* @param {string} id The unique string that identifies this entry.
|
||||
* @return {!goog.tweak.NumericSetting} The entry.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.getNumericSetting = function(id) {
|
||||
var entry = this.getEntry(id);
|
||||
goog.asserts.assertInstanceof(entry, goog.tweak.NumericSetting,
|
||||
'getNumericSetting called on wrong type of BaseSetting');
|
||||
return /** @type {!goog.tweak.NumericSetting} */ (entry);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and returns an array of all BaseSetting objects with an associted
|
||||
* query parameter.
|
||||
* @param {boolean} excludeChildEntries Exclude BooleanInGroupSettings.
|
||||
* @param {boolean} excludeNonSettings Exclude entries that are not subclasses
|
||||
* of BaseSetting.
|
||||
* @return {!Array.<!goog.tweak.BaseSetting>} The settings.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.extractEntries =
|
||||
function(excludeChildEntries, excludeNonSettings) {
|
||||
var entries = [];
|
||||
for (var id in this.entryMap_) {
|
||||
var entry = this.entryMap_[id];
|
||||
if (entry instanceof goog.tweak.BaseSetting) {
|
||||
if (excludeChildEntries && !entry.getParamName()) {
|
||||
continue;
|
||||
}
|
||||
} else if (excludeNonSettings) {
|
||||
continue;
|
||||
}
|
||||
entries.push(entry);
|
||||
}
|
||||
return entries;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the query part of the URL that will apply all set tweaks.
|
||||
* @param {string=} opt_existingSearchStr The part of the url between the ? and
|
||||
* the #. Uses window.location.search if not given.
|
||||
* @return {string} The query string.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.makeUrlQuery =
|
||||
function(opt_existingSearchStr) {
|
||||
var existingParams = opt_existingSearchStr == undefined ?
|
||||
window.location.search : opt_existingSearchStr;
|
||||
|
||||
var sortedEntries = this.extractEntries(true /* excludeChildEntries */,
|
||||
true /* excludeNonSettings */);
|
||||
// Sort the params so that the urlQuery has stable ordering.
|
||||
sortedEntries.sort(function(a, b) {
|
||||
return goog.array.defaultCompare(a.getParamName(), b.getParamName());
|
||||
});
|
||||
|
||||
// Add all values that are not set to their defaults.
|
||||
var keysAndValues = [];
|
||||
for (var i = 0, entry; entry = sortedEntries[i]; ++i) {
|
||||
var encodedValue = entry.getNewValueEncoded();
|
||||
if (encodedValue != null) {
|
||||
keysAndValues.push(entry.getParamName(), encodedValue);
|
||||
}
|
||||
// Strip all tweak query params from the existing query string. This will
|
||||
// make the final query string contain only the tweak settings that are set
|
||||
// to their non-default values and also maintain non-tweak related query
|
||||
// parameters.
|
||||
existingParams = goog.uri.utils.removeParam(existingParams,
|
||||
encodeURIComponent(/** @type {string} */ (entry.getParamName())));
|
||||
}
|
||||
|
||||
var tweakParams = goog.uri.utils.buildQueryData(keysAndValues);
|
||||
// Decode spaces and commas in order to make the URL more readable.
|
||||
tweakParams = tweakParams.replace(/%2C/g, ',').replace(/%20/g, '+');
|
||||
return !tweakParams ? existingParams :
|
||||
existingParams ? existingParams + '&' + tweakParams :
|
||||
'?' + tweakParams;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a default value to use for the given tweak instead of the one passed
|
||||
* to the register* function. This function must be called before the tweak is
|
||||
* registered.
|
||||
* @param {string} id The unique string that identifies the entry.
|
||||
* @param {string|number|boolean} value The replacement value to be used as the
|
||||
* default value for the setting.
|
||||
*/
|
||||
goog.tweak.Registry.prototype.overrideDefaultValue = function(id, value) {
|
||||
goog.asserts.assert(!this.hasEntry(id),
|
||||
'goog.tweak.overrideDefaultValue must be called before the tweak is ' +
|
||||
'registered. Tweak: %s', id);
|
||||
this.defaultValueOverrides_[id] = value;
|
||||
};
|
||||
|
||||
119
nicer-api-docs/closure-library/closure/goog/tweak/testhelpers.js
Normal file
119
nicer-api-docs/closure-library/closure/goog/tweak/testhelpers.js
Normal file
@@ -0,0 +1,119 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Common test functions for tweak unit tests.
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.tweak.testhelpers');
|
||||
|
||||
goog.require('goog.tweak');
|
||||
goog.require('goog.tweak.BooleanGroup');
|
||||
goog.require('goog.tweak.BooleanInGroupSetting');
|
||||
goog.require('goog.tweak.BooleanSetting');
|
||||
goog.require('goog.tweak.ButtonAction');
|
||||
goog.require('goog.tweak.NumericSetting');
|
||||
goog.require('goog.tweak.Registry');
|
||||
goog.require('goog.tweak.StringSetting');
|
||||
|
||||
|
||||
var boolEntry;
|
||||
var boolEntry2;
|
||||
var strEntry;
|
||||
var strEntry2;
|
||||
var strEnumEntry;
|
||||
var numEntry;
|
||||
var numEnumEntry;
|
||||
var boolGroup;
|
||||
var boolOneEntry;
|
||||
var boolTwoEntry;
|
||||
var buttonEntry;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a registry with some entries in it.
|
||||
* @param {string} queryParams The query parameter string to use for the
|
||||
* registry.
|
||||
* @param {!Object.<string|number|boolean>=} opt_compilerOverrides Compiler
|
||||
* overrides.
|
||||
*/
|
||||
function createRegistryEntries(queryParams, opt_compilerOverrides) {
|
||||
// Initialize the registry with the given query string.
|
||||
var registry =
|
||||
new goog.tweak.Registry(queryParams, opt_compilerOverrides || {});
|
||||
goog.tweak.registry_ = registry;
|
||||
|
||||
boolEntry = new goog.tweak.BooleanSetting('Bool', 'The bool1');
|
||||
registry.register(boolEntry);
|
||||
|
||||
boolEntry2 = new goog.tweak.BooleanSetting('Bool2', 'The bool2');
|
||||
boolEntry2.setDefaultValue(true);
|
||||
registry.register(boolEntry2);
|
||||
|
||||
strEntry = new goog.tweak.StringSetting('Str', 'The str1');
|
||||
strEntry.setParamName('s');
|
||||
registry.register(strEntry);
|
||||
|
||||
strEntry2 = new goog.tweak.StringSetting('Str2', 'The str2');
|
||||
strEntry2.setDefaultValue('foo');
|
||||
registry.register(strEntry2);
|
||||
|
||||
strEnumEntry = new goog.tweak.StringSetting('Enum', 'The enum');
|
||||
strEnumEntry.setValidValues(['A', 'B', 'C']);
|
||||
strEnumEntry.setRestartRequired(false);
|
||||
registry.register(strEnumEntry);
|
||||
|
||||
numEntry = new goog.tweak.NumericSetting('Num', 'The num');
|
||||
numEntry.setDefaultValue(99);
|
||||
registry.register(numEntry);
|
||||
|
||||
numEnumEntry = new goog.tweak.NumericSetting('Enum2', 'The 2nd enum');
|
||||
numEnumEntry.setValidValues([1, 2, 3]);
|
||||
numEnumEntry.setRestartRequired(false);
|
||||
numEnumEntry.label = 'Enum the second&';
|
||||
registry.register(numEnumEntry);
|
||||
|
||||
boolGroup = new goog.tweak.BooleanGroup('BoolGroup', 'The bool group');
|
||||
registry.register(boolGroup);
|
||||
|
||||
boolOneEntry = new goog.tweak.BooleanInGroupSetting('BoolOne', 'Desc for 1',
|
||||
boolGroup);
|
||||
boolOneEntry.setToken('B1');
|
||||
boolOneEntry.setRestartRequired(false);
|
||||
boolGroup.addChild(boolOneEntry);
|
||||
registry.register(boolOneEntry);
|
||||
|
||||
boolTwoEntry = new goog.tweak.BooleanInGroupSetting('BoolTwo', 'Desc for 2',
|
||||
boolGroup);
|
||||
boolTwoEntry.setDefaultValue(true);
|
||||
boolGroup.addChild(boolTwoEntry);
|
||||
registry.register(boolTwoEntry);
|
||||
|
||||
buttonEntry = new goog.tweak.ButtonAction('Button', 'The Btn',
|
||||
goog.nullFunction);
|
||||
buttonEntry.label = '<btn>';
|
||||
registry.register(buttonEntry);
|
||||
|
||||
var nsBoolGroup = new goog.tweak.BooleanGroup('foo.bar.BoolGroup',
|
||||
'Namespaced Bool Group');
|
||||
registry.register(nsBoolGroup);
|
||||
var nsBool = new goog.tweak.BooleanInGroupSetting('foo.bar.BoolOne',
|
||||
'Desc for Namespaced 1', nsBoolGroup);
|
||||
nsBoolGroup.addChild(nsBool);
|
||||
registry.register(nsBool);
|
||||
}
|
||||
|
||||
|
||||
301
nicer-api-docs/closure-library/closure/goog/tweak/tweak.js
Normal file
301
nicer-api-docs/closure-library/closure/goog/tweak/tweak.js
Normal file
@@ -0,0 +1,301 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Provides facilities for creating and querying tweaks.
|
||||
* @see http://code.google.com/p/closure-library/wiki/UsingTweaks
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.tweak');
|
||||
goog.provide('goog.tweak.ConfigParams');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.tweak.BaseSetting');
|
||||
goog.require('goog.tweak.BooleanGroup');
|
||||
goog.require('goog.tweak.BooleanInGroupSetting');
|
||||
goog.require('goog.tweak.BooleanSetting');
|
||||
goog.require('goog.tweak.ButtonAction');
|
||||
goog.require('goog.tweak.NumericSetting');
|
||||
goog.require('goog.tweak.Registry');
|
||||
goog.require('goog.tweak.StringSetting');
|
||||
|
||||
|
||||
/**
|
||||
* Calls to this function are overridden by the compiler by the processTweaks
|
||||
* pass. It returns the overrides to default values for tweaks set by compiler
|
||||
* options.
|
||||
* @return {!Object.<number|string|boolean>} A map of tweakId -> defaultValue.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.getCompilerOverrides_ = function() {
|
||||
return {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The global reference to the registry, if it exists.
|
||||
* @type {goog.tweak.Registry}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.registry_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The boolean group set by beginBooleanGroup and cleared by endBooleanGroup.
|
||||
* @type {goog.tweak.BooleanGroup}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.activeBooleanGroup_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Returns/creates the registry singleton.
|
||||
* @return {!goog.tweak.Registry} The tweak registry.
|
||||
*/
|
||||
goog.tweak.getRegistry = function() {
|
||||
if (!goog.tweak.registry_) {
|
||||
var queryString = window.location.search;
|
||||
var overrides = goog.tweak.getCompilerOverrides_();
|
||||
goog.tweak.registry_ = new goog.tweak.Registry(queryString, overrides);
|
||||
}
|
||||
return goog.tweak.registry_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type for configParams.
|
||||
* TODO(agrieve): Remove |Object when optional fields in struct types are
|
||||
* implemented.
|
||||
* @typedef {{
|
||||
* label:(string|undefined),
|
||||
* validValues:(!Array.<string>|!Array.<number>|undefined),
|
||||
* paramName:(string|undefined),
|
||||
* restartRequired:(boolean|undefined),
|
||||
* callback:(Function|undefined),
|
||||
* token:(string|undefined)
|
||||
* }|!Object}
|
||||
*/
|
||||
goog.tweak.ConfigParams;
|
||||
|
||||
|
||||
/**
|
||||
* Applies all extra configuration parameters in configParams.
|
||||
* @param {!goog.tweak.BaseEntry} entry The entry to apply them to.
|
||||
* @param {!goog.tweak.ConfigParams} configParams Extra configuration
|
||||
* parameters.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.applyConfigParams_ = function(entry, configParams) {
|
||||
if (configParams.label) {
|
||||
entry.label = configParams.label;
|
||||
delete configParams.label;
|
||||
}
|
||||
if (configParams.validValues) {
|
||||
goog.asserts.assert(entry instanceof goog.tweak.StringSetting ||
|
||||
entry instanceof goog.tweak.NumericSetting,
|
||||
'Cannot set validValues on tweak: %s', entry.getId());
|
||||
entry.setValidValues(configParams.validValues);
|
||||
delete configParams.validValues;
|
||||
}
|
||||
if (goog.isDef(configParams.paramName)) {
|
||||
goog.asserts.assertInstanceof(entry, goog.tweak.BaseSetting,
|
||||
'Cannot set paramName on tweak: %s', entry.getId());
|
||||
entry.setParamName(configParams.paramName);
|
||||
delete configParams.paramName;
|
||||
}
|
||||
if (goog.isDef(configParams.restartRequired)) {
|
||||
entry.setRestartRequired(configParams.restartRequired);
|
||||
delete configParams.restartRequired;
|
||||
}
|
||||
if (configParams.callback) {
|
||||
entry.addCallback(configParams.callback);
|
||||
delete configParams.callback;
|
||||
goog.asserts.assert(
|
||||
!entry.isRestartRequired() || (configParams.restartRequired == false),
|
||||
'Tweak %s should set restartRequired: false, when adding a callback.',
|
||||
entry.getId());
|
||||
}
|
||||
if (configParams.token) {
|
||||
goog.asserts.assertInstanceof(entry, goog.tweak.BooleanInGroupSetting,
|
||||
'Cannot set token on tweak: %s', entry.getId());
|
||||
entry.setToken(configParams.token);
|
||||
delete configParams.token;
|
||||
}
|
||||
for (var key in configParams) {
|
||||
goog.asserts.fail('Unknown config options (' + key + '=' +
|
||||
configParams[key] + ') for tweak ' + entry.getId());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Registers a tweak using the given factoryFunc.
|
||||
* @param {!goog.tweak.BaseEntry} entry The entry to register.
|
||||
* @param {boolean|string|number=} opt_defaultValue Default value.
|
||||
* @param {goog.tweak.ConfigParams=} opt_configParams Extra
|
||||
* configuration parameters.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.doRegister_ = function(entry, opt_defaultValue, opt_configParams) {
|
||||
if (opt_configParams) {
|
||||
goog.tweak.applyConfigParams_(entry, opt_configParams);
|
||||
}
|
||||
if (opt_defaultValue != undefined) {
|
||||
entry.setDefaultValue(opt_defaultValue);
|
||||
}
|
||||
if (goog.tweak.activeBooleanGroup_) {
|
||||
goog.asserts.assertInstanceof(entry, goog.tweak.BooleanInGroupSetting,
|
||||
'Forgot to end Boolean Group: %s',
|
||||
goog.tweak.activeBooleanGroup_.getId());
|
||||
goog.tweak.activeBooleanGroup_.addChild(
|
||||
/** @type {!goog.tweak.BooleanInGroupSetting} */ (entry));
|
||||
}
|
||||
goog.tweak.getRegistry().register(entry);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and registers a group of BooleanSettings that are all set by a
|
||||
* single query parameter. A call to goog.tweak.endBooleanGroup() must be used
|
||||
* to close this group. Only goog.tweak.registerBoolean() calls are allowed with
|
||||
* the beginBooleanGroup()/endBooleanGroup().
|
||||
* @param {string} id The unique ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @param {goog.tweak.ConfigParams=} opt_configParams Extra configuration
|
||||
* parameters.
|
||||
*/
|
||||
goog.tweak.beginBooleanGroup = function(id, description, opt_configParams) {
|
||||
var entry = new goog.tweak.BooleanGroup(id, description);
|
||||
goog.tweak.doRegister_(entry, undefined, opt_configParams);
|
||||
goog.tweak.activeBooleanGroup_ = entry;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stops adding boolean entries to the active boolean group.
|
||||
*/
|
||||
goog.tweak.endBooleanGroup = function() {
|
||||
goog.tweak.activeBooleanGroup_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and registers a BooleanSetting.
|
||||
* @param {string} id The unique ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @param {boolean=} opt_defaultValue The default value for the setting.
|
||||
* @param {goog.tweak.ConfigParams=} opt_configParams Extra configuration
|
||||
* parameters.
|
||||
*/
|
||||
goog.tweak.registerBoolean =
|
||||
function(id, description, opt_defaultValue, opt_configParams) {
|
||||
// TODO(agrieve): There is a bug in the compiler that causes these calls not
|
||||
// to be stripped without this outer if. Might be Issue #90.
|
||||
if (goog.tweak.activeBooleanGroup_) {
|
||||
var entry = new goog.tweak.BooleanInGroupSetting(id, description,
|
||||
goog.tweak.activeBooleanGroup_);
|
||||
} else {
|
||||
entry = new goog.tweak.BooleanSetting(id, description);
|
||||
}
|
||||
goog.tweak.doRegister_(entry, opt_defaultValue, opt_configParams);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and registers a StringSetting.
|
||||
* @param {string} id The unique ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @param {string=} opt_defaultValue The default value for the setting.
|
||||
* @param {goog.tweak.ConfigParams=} opt_configParams Extra configuration
|
||||
* parameters.
|
||||
*/
|
||||
goog.tweak.registerString =
|
||||
function(id, description, opt_defaultValue, opt_configParams) {
|
||||
goog.tweak.doRegister_(new goog.tweak.StringSetting(id, description),
|
||||
opt_defaultValue, opt_configParams);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and registers a NumericSetting.
|
||||
* @param {string} id The unique ID for the setting.
|
||||
* @param {string} description A description of what the setting does.
|
||||
* @param {number=} opt_defaultValue The default value for the setting.
|
||||
* @param {goog.tweak.ConfigParams=} opt_configParams Extra configuration
|
||||
* parameters.
|
||||
*/
|
||||
goog.tweak.registerNumber =
|
||||
function(id, description, opt_defaultValue, opt_configParams) {
|
||||
goog.tweak.doRegister_(new goog.tweak.NumericSetting(id, description),
|
||||
opt_defaultValue, opt_configParams);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and registers a ButtonAction.
|
||||
* @param {string} id The unique ID for the setting.
|
||||
* @param {string} description A description of what the action does.
|
||||
* @param {!Function} callback Function to call when the button is clicked.
|
||||
* @param {string=} opt_label The button text (instead of the ID).
|
||||
*/
|
||||
goog.tweak.registerButton = function(id, description, callback, opt_label) {
|
||||
var tweak = new goog.tweak.ButtonAction(id, description, callback);
|
||||
tweak.label = opt_label || tweak.label;
|
||||
goog.tweak.doRegister_(tweak);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a default value to use for the given tweak instead of the one passed
|
||||
* to the register* function. This function must be called before the tweak is
|
||||
* registered.
|
||||
* @param {string} id The unique string that identifies the entry.
|
||||
* @param {string|number|boolean} value The new default value for the tweak.
|
||||
*/
|
||||
goog.tweak.overrideDefaultValue = function(id, value) {
|
||||
goog.tweak.getRegistry().overrideDefaultValue(id, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the boolean setting with the given ID.
|
||||
* @param {string} id The unique string that identifies this entry.
|
||||
* @return {boolean} The value of the tweak.
|
||||
*/
|
||||
goog.tweak.getBoolean = function(id) {
|
||||
return goog.tweak.getRegistry().getBooleanSetting(id).getValue();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the string setting with the given ID,
|
||||
* @param {string} id The unique string that identifies this entry.
|
||||
* @return {string} The value of the tweak.
|
||||
*/
|
||||
goog.tweak.getString = function(id) {
|
||||
return goog.tweak.getRegistry().getStringSetting(id).getValue();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the numeric setting with the given ID.
|
||||
* @param {string} id The unique string that identifies this entry.
|
||||
* @return {number} The value of the tweak.
|
||||
*/
|
||||
goog.tweak.getNumber = function(id) {
|
||||
return goog.tweak.getRegistry().getNumericSetting(id).getValue();
|
||||
};
|
||||
|
||||
817
nicer-api-docs/closure-library/closure/goog/tweak/tweakui.js
Normal file
817
nicer-api-docs/closure-library/closure/goog/tweak/tweakui.js
Normal file
@@ -0,0 +1,817 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A UI for editing tweak settings / clicking tweak actions.
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.tweak.EntriesPanel');
|
||||
goog.provide('goog.tweak.TweakUi');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom.DomHelper');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.tweak');
|
||||
goog.require('goog.ui.Zippy');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A UI for editing tweak settings / clicking tweak actions.
|
||||
* @param {!goog.tweak.Registry} registry The registry to render.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DomHelper to render with.
|
||||
* @constructor
|
||||
*/
|
||||
goog.tweak.TweakUi = function(registry, opt_domHelper) {
|
||||
/**
|
||||
* The registry to create a UI from.
|
||||
* @type {!goog.tweak.Registry}
|
||||
* @private
|
||||
*/
|
||||
this.registry_ = registry;
|
||||
|
||||
/**
|
||||
* The element to display when the UI is visible.
|
||||
* @type {goog.tweak.EntriesPanel|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.entriesPanel_;
|
||||
|
||||
/**
|
||||
* The DomHelper to render with.
|
||||
* @type {!goog.dom.DomHelper}
|
||||
* @private
|
||||
*/
|
||||
this.domHelper_ = opt_domHelper || goog.dom.getDomHelper();
|
||||
|
||||
// Listen for newly registered entries (happens with lazy-loaded modules).
|
||||
registry.addOnRegisterListener(goog.bind(this.onNewRegisteredEntry_, this));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The CSS class name unique to the root tweak panel div.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.ROOT_PANEL_CLASS_ = goog.getCssName('goog-tweak-root');
|
||||
|
||||
|
||||
/**
|
||||
* The CSS class name unique to the tweak entry div.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.ENTRY_CSS_CLASS_ = goog.getCssName('goog-tweak-entry');
|
||||
|
||||
|
||||
/**
|
||||
* The CSS classes for each tweak entry div.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.ENTRY_CSS_CLASSES_ = goog.tweak.TweakUi.ENTRY_CSS_CLASS_ +
|
||||
' ' + goog.getCssName('goog-inline-block');
|
||||
|
||||
|
||||
/**
|
||||
* The CSS classes for each namespace tweak entry div.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.ENTRY_GROUP_CSS_CLASSES_ =
|
||||
goog.tweak.TweakUi.ENTRY_CSS_CLASS_;
|
||||
|
||||
|
||||
/**
|
||||
* Marker that the style sheet has already been installed.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.STYLE_SHEET_INSTALLED_MARKER_ =
|
||||
'__closure_tweak_installed_';
|
||||
|
||||
|
||||
/**
|
||||
* CSS used by TweakUI.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.CSS_STYLES_ = (function() {
|
||||
var MOBILE = goog.userAgent.MOBILE;
|
||||
var IE = goog.userAgent.IE;
|
||||
var ENTRY_CLASS = '.' + goog.tweak.TweakUi.ENTRY_CSS_CLASS_;
|
||||
var ROOT_PANEL_CLASS = '.' + goog.tweak.TweakUi.ROOT_PANEL_CLASS_;
|
||||
var GOOG_INLINE_BLOCK_CLASS = '.' + goog.getCssName('goog-inline-block');
|
||||
var ret = ROOT_PANEL_CLASS + '{background:#ffc; padding:0 4px}';
|
||||
// Make this work even if the user hasn't included common.css.
|
||||
if (!IE) {
|
||||
ret += GOOG_INLINE_BLOCK_CLASS + '{display:inline-block}';
|
||||
}
|
||||
// Space things out vertically for touch UIs.
|
||||
if (MOBILE) {
|
||||
ret += ROOT_PANEL_CLASS + ',' + ROOT_PANEL_CLASS + ' fieldset{' +
|
||||
'line-height:2em;' + '}';
|
||||
}
|
||||
return ret;
|
||||
})();
|
||||
|
||||
|
||||
/**
|
||||
* Creates a TweakUi if tweaks are enabled.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DomHelper to render with.
|
||||
* @return {Element|undefined} The root UI element or undefined if tweaks are
|
||||
* not enabled.
|
||||
*/
|
||||
goog.tweak.TweakUi.create = function(opt_domHelper) {
|
||||
var registry = goog.tweak.getRegistry();
|
||||
if (registry) {
|
||||
var ui = new goog.tweak.TweakUi(registry, opt_domHelper);
|
||||
ui.render();
|
||||
return ui.getRootElement();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a TweakUi inside of a show/hide link.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DomHelper to render with.
|
||||
* @return {Element|undefined} The root UI element or undefined if tweaks are
|
||||
* not enabled.
|
||||
*/
|
||||
goog.tweak.TweakUi.createCollapsible = function(opt_domHelper) {
|
||||
var registry = goog.tweak.getRegistry();
|
||||
if (registry) {
|
||||
var dh = opt_domHelper || goog.dom.getDomHelper();
|
||||
|
||||
// The following strings are for internal debugging only. No translation
|
||||
// necessary. Do NOT wrap goog.getMsg() around these strings.
|
||||
var showLink = dh.createDom('a', {href: 'javascript:;'}, 'Show Tweaks');
|
||||
var hideLink = dh.createDom('a', {href: 'javascript:;'}, 'Hide Tweaks');
|
||||
var ret = dh.createDom('div', null, showLink);
|
||||
|
||||
var lazyCreate = function() {
|
||||
// Lazily render the UI.
|
||||
var ui = new goog.tweak.TweakUi(
|
||||
/** @type {!goog.tweak.Registry} */ (registry), dh);
|
||||
ui.render();
|
||||
// Put the hide link on the same line as the "Show Descriptions" link.
|
||||
// Set the style lazily because we can.
|
||||
hideLink.style.marginRight = '10px';
|
||||
var tweakElem = ui.getRootElement();
|
||||
tweakElem.insertBefore(hideLink, tweakElem.firstChild);
|
||||
ret.appendChild(tweakElem);
|
||||
return tweakElem;
|
||||
};
|
||||
new goog.ui.Zippy(showLink, lazyCreate, false /* expanded */, hideLink);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares the given entries. Orders alphabetically and groups buttons and
|
||||
* expandable groups.
|
||||
* @param {goog.tweak.BaseEntry} a The first entry to compare.
|
||||
* @param {goog.tweak.BaseEntry} b The second entry to compare.
|
||||
* @return {number} Refer to goog.array.defaultCompare.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.entryCompare_ = function(a, b) {
|
||||
return (
|
||||
goog.array.defaultCompare(a instanceof goog.tweak.NamespaceEntry_,
|
||||
b instanceof goog.tweak.NamespaceEntry_) ||
|
||||
goog.array.defaultCompare(a instanceof goog.tweak.BooleanGroup,
|
||||
b instanceof goog.tweak.BooleanGroup) ||
|
||||
goog.array.defaultCompare(a instanceof goog.tweak.ButtonAction,
|
||||
b instanceof goog.tweak.ButtonAction) ||
|
||||
goog.array.defaultCompare(a.label, b.label) ||
|
||||
goog.array.defaultCompare(a.getId(), b.getId()));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.tweak.BaseEntry} entry The entry.
|
||||
* @return {boolean} Returns whether the given entry contains sub-entries.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.isGroupEntry_ = function(entry) {
|
||||
return entry instanceof goog.tweak.NamespaceEntry_ ||
|
||||
entry instanceof goog.tweak.BooleanGroup;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of entries from the given boolean group.
|
||||
* @param {!goog.tweak.BooleanGroup} group The group to get the entries from.
|
||||
* @return {!Array.<!goog.tweak.BaseEntry>} The sorted entries.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.extractBooleanGroupEntries_ = function(group) {
|
||||
var ret = goog.object.getValues(group.getChildEntries());
|
||||
ret.sort(goog.tweak.TweakUi.entryCompare_);
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.tweak.BaseEntry} entry The entry.
|
||||
* @return {string} Returns the namespace for the entry, or '' if it is not
|
||||
* namespaced.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.extractNamespace_ = function(entry) {
|
||||
var namespaceMatch = /.+(?=\.)/.exec(entry.getId());
|
||||
return namespaceMatch ? namespaceMatch[0] : '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.tweak.BaseEntry} entry The entry.
|
||||
* @return {string} Returns the part of the label after the last period, unless
|
||||
* the label has been explicly set (it is different from the ID).
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.getNamespacedLabel_ = function(entry) {
|
||||
var label = entry.label;
|
||||
if (label == entry.getId()) {
|
||||
label = label.substr(label.lastIndexOf('.') + 1);
|
||||
}
|
||||
return label;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Element} The root element. Must not be called before render().
|
||||
*/
|
||||
goog.tweak.TweakUi.prototype.getRootElement = function() {
|
||||
goog.asserts.assert(this.entriesPanel_,
|
||||
'TweakUi.getRootElement called before render().');
|
||||
return this.entriesPanel_.getRootElement();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reloads the page with query parameters set by the UI.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.prototype.restartWithAppliedTweaks_ = function() {
|
||||
var queryString = this.registry_.makeUrlQuery();
|
||||
var wnd = this.domHelper_.getWindow();
|
||||
if (queryString != wnd.location.search) {
|
||||
wnd.location.search = queryString;
|
||||
} else {
|
||||
wnd.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Installs the required CSS styles.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.prototype.installStyles_ = function() {
|
||||
// Use an marker to install the styles only once per document.
|
||||
// Styles are injected via JS instead of in a separate style sheet so that
|
||||
// they are automatically excluded when tweaks are stripped out.
|
||||
var doc = this.domHelper_.getDocument();
|
||||
if (!(goog.tweak.TweakUi.STYLE_SHEET_INSTALLED_MARKER_ in doc)) {
|
||||
goog.style.installStyles(
|
||||
goog.tweak.TweakUi.CSS_STYLES_, doc);
|
||||
doc[goog.tweak.TweakUi.STYLE_SHEET_INSTALLED_MARKER_] = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the element to display when the UI is visible.
|
||||
* @return {!Element} The root element.
|
||||
*/
|
||||
goog.tweak.TweakUi.prototype.render = function() {
|
||||
this.installStyles_();
|
||||
var dh = this.domHelper_;
|
||||
// The submit button
|
||||
var submitButton = dh.createDom('button', {style: 'font-weight:bold'},
|
||||
'Apply Tweaks');
|
||||
submitButton.onclick = goog.bind(this.restartWithAppliedTweaks_, this);
|
||||
|
||||
var rootPanel = new goog.tweak.EntriesPanel([], dh);
|
||||
var rootPanelDiv = rootPanel.render(submitButton);
|
||||
rootPanelDiv.className += ' ' + goog.tweak.TweakUi.ROOT_PANEL_CLASS_;
|
||||
this.entriesPanel_ = rootPanel;
|
||||
|
||||
var entries = this.registry_.extractEntries(true /* excludeChildEntries */,
|
||||
false /* excludeNonSettings */);
|
||||
for (var i = 0, entry; entry = entries[i]; i++) {
|
||||
this.insertEntry_(entry);
|
||||
}
|
||||
|
||||
return rootPanelDiv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Updates the UI with the given entry.
|
||||
* @param {!goog.tweak.BaseEntry} entry The newly registered entry.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.prototype.onNewRegisteredEntry_ = function(entry) {
|
||||
if (this.entriesPanel_) {
|
||||
this.insertEntry_(entry);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Updates the UI with the given entry.
|
||||
* @param {!goog.tweak.BaseEntry} entry The newly registered entry.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.TweakUi.prototype.insertEntry_ = function(entry) {
|
||||
var panel = this.entriesPanel_;
|
||||
var namespace = goog.tweak.TweakUi.extractNamespace_(entry);
|
||||
|
||||
if (namespace) {
|
||||
// Find the NamespaceEntry that the entry belongs to.
|
||||
var namespaceEntryId = goog.tweak.NamespaceEntry_.ID_PREFIX + namespace;
|
||||
var nsPanel = panel.childPanels[namespaceEntryId];
|
||||
if (nsPanel) {
|
||||
panel = nsPanel;
|
||||
} else {
|
||||
entry = new goog.tweak.NamespaceEntry_(namespace, [entry]);
|
||||
}
|
||||
}
|
||||
if (entry instanceof goog.tweak.BooleanInGroupSetting) {
|
||||
var group = entry.getGroup();
|
||||
// BooleanGroup entries are always registered before their
|
||||
// BooleanInGroupSettings.
|
||||
panel = panel.childPanels[group.getId()];
|
||||
}
|
||||
goog.asserts.assert(panel, 'Missing panel for entry %s', entry.getId());
|
||||
panel.insertEntry(entry);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The body of the tweaks UI and also used for BooleanGroup.
|
||||
* @param {!Array.<!goog.tweak.BaseEntry>} entries The entries to show in the
|
||||
* panel.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DomHelper to render with.
|
||||
* @constructor
|
||||
*/
|
||||
goog.tweak.EntriesPanel = function(entries, opt_domHelper) {
|
||||
/**
|
||||
* The entries to show in the panel.
|
||||
* @type {!Array.<!goog.tweak.BaseEntry>} entries
|
||||
* @private
|
||||
*/
|
||||
this.entries_ = entries;
|
||||
|
||||
var self = this;
|
||||
/**
|
||||
* The bound onclick handler for the help question marks.
|
||||
* @this {Element}
|
||||
* @private
|
||||
*/
|
||||
this.boundHelpOnClickHandler_ = function() {
|
||||
self.onHelpClick_(this.parentNode);
|
||||
};
|
||||
|
||||
/**
|
||||
* The element that contains the UI.
|
||||
* @type {Element}
|
||||
* @private
|
||||
*/
|
||||
this.rootElem_;
|
||||
|
||||
/**
|
||||
* The element that contains all of the settings and the endElement.
|
||||
* @type {Element}
|
||||
* @private
|
||||
*/
|
||||
this.mainPanel_;
|
||||
|
||||
/**
|
||||
* Flips between true/false each time the "Toggle Descriptions" link is
|
||||
* clicked.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.showAllDescriptionsState_;
|
||||
|
||||
/**
|
||||
* The DomHelper to render with.
|
||||
* @type {!goog.dom.DomHelper}
|
||||
* @private
|
||||
*/
|
||||
this.domHelper_ = opt_domHelper || goog.dom.getDomHelper();
|
||||
|
||||
/**
|
||||
* Map of tweak ID -> EntriesPanel for child panels (BooleanGroups).
|
||||
* @type {!Object.<!goog.tweak.EntriesPanel>}
|
||||
*/
|
||||
this.childPanels = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Element} Returns the expanded element. Must not be called before
|
||||
* render().
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.getRootElement = function() {
|
||||
goog.asserts.assert(this.rootElem_,
|
||||
'EntriesPanel.getRootElement called before render().');
|
||||
return /** @type {!Element} */ (this.rootElem_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and returns the expanded element.
|
||||
* The markup looks like:
|
||||
* <div>
|
||||
* <a>Show Descriptions</a>
|
||||
* <div>
|
||||
* ...
|
||||
* {endElement}
|
||||
* </div>
|
||||
* </div>
|
||||
* @param {Element|DocumentFragment=} opt_endElement Element to insert after all
|
||||
* tweak entries.
|
||||
* @return {!Element} The root element for the panel.
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.render = function(opt_endElement) {
|
||||
var dh = this.domHelper_;
|
||||
var entries = this.entries_;
|
||||
var ret = dh.createDom('div');
|
||||
|
||||
var showAllDescriptionsLink = dh.createDom('a', {
|
||||
href: 'javascript:;',
|
||||
onclick: goog.bind(this.toggleAllDescriptions, this)
|
||||
}, 'Toggle all Descriptions');
|
||||
ret.appendChild(showAllDescriptionsLink);
|
||||
|
||||
// Add all of the entries.
|
||||
var mainPanel = dh.createElement('div');
|
||||
this.mainPanel_ = mainPanel;
|
||||
for (var i = 0, entry; entry = entries[i]; i++) {
|
||||
mainPanel.appendChild(this.createEntryElem_(entry));
|
||||
}
|
||||
|
||||
if (opt_endElement) {
|
||||
mainPanel.appendChild(opt_endElement);
|
||||
}
|
||||
ret.appendChild(mainPanel);
|
||||
this.rootElem_ = ret;
|
||||
return /** @type {!Element} */ (ret);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Inserts the given entry into the panel.
|
||||
* @param {!goog.tweak.BaseEntry} entry The entry to insert.
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.insertEntry = function(entry) {
|
||||
var insertIndex = -goog.array.binarySearch(this.entries_, entry,
|
||||
goog.tweak.TweakUi.entryCompare_) - 1;
|
||||
goog.asserts.assert(insertIndex >= 0, 'insertEntry failed for %s',
|
||||
entry.getId());
|
||||
goog.array.insertAt(this.entries_, entry, insertIndex);
|
||||
this.mainPanel_.insertBefore(
|
||||
this.createEntryElem_(entry),
|
||||
// IE doesn't like 'undefined' here.
|
||||
this.mainPanel_.childNodes[insertIndex] || null);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and returns a form element for the given entry.
|
||||
* @param {!goog.tweak.BaseEntry} entry The entry.
|
||||
* @return {!Element} The root DOM element for the entry.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.createEntryElem_ = function(entry) {
|
||||
var dh = this.domHelper_;
|
||||
var isGroupEntry = goog.tweak.TweakUi.isGroupEntry_(entry);
|
||||
var classes = isGroupEntry ? goog.tweak.TweakUi.ENTRY_GROUP_CSS_CLASSES_ :
|
||||
goog.tweak.TweakUi.ENTRY_CSS_CLASSES_;
|
||||
// Containers should not use label tags or else all descendent inputs will be
|
||||
// connected on desktop browsers.
|
||||
var containerNodeName = isGroupEntry ? 'span' : 'label';
|
||||
var ret = dh.createDom('div', classes,
|
||||
dh.createDom(containerNodeName, {
|
||||
// Make the hover text the description.
|
||||
title: entry.description,
|
||||
style: 'color:' + (entry.isRestartRequired() ? '' : 'blue')
|
||||
}, this.createTweakEntryDom_(entry)),
|
||||
// Add the expandable help question mark.
|
||||
this.createHelpElem_(entry));
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Click handler for the help link.
|
||||
* @param {Node} entryDiv The div that contains the tweak.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.onHelpClick_ = function(entryDiv) {
|
||||
this.showDescription_(entryDiv, !entryDiv.style.display);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Twiddle the DOM so that the entry within the given span is shown/hidden.
|
||||
* @param {Node} entryDiv The div that contains the tweak.
|
||||
* @param {boolean} show True to show, false to hide.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.showDescription_ =
|
||||
function(entryDiv, show) {
|
||||
var descriptionElem = entryDiv.lastChild.lastChild;
|
||||
goog.style.setElementShown(/** @type {Element} */ (descriptionElem), show);
|
||||
entryDiv.style.display = show ? 'block' : '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates and returns a help element for the given entry.
|
||||
* @param {goog.tweak.BaseEntry} entry The entry.
|
||||
* @return {!Element} The root element of the created DOM.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.createHelpElem_ = function(entry) {
|
||||
// The markup looks like:
|
||||
// <span onclick=...><b>?</b><span>{description}</span></span>
|
||||
var ret = this.domHelper_.createElement('span');
|
||||
ret.innerHTML = '<b style="padding:0 1em 0 .5em">?</b>' +
|
||||
'<span style="display:none;color:#666"></span>';
|
||||
ret.onclick = this.boundHelpOnClickHandler_;
|
||||
var descriptionElem = ret.lastChild;
|
||||
goog.dom.setTextContent(/** @type {Element} */ (descriptionElem),
|
||||
entry.description);
|
||||
if (!entry.isRestartRequired()) {
|
||||
descriptionElem.innerHTML +=
|
||||
' <span style="color:blue">(no restart required)</span>';
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show all entry descriptions (has the same effect as clicking on all ?'s).
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.toggleAllDescriptions = function() {
|
||||
var show = !this.showAllDescriptionsState_;
|
||||
this.showAllDescriptionsState_ = show;
|
||||
var entryDivs = this.domHelper_.getElementsByTagNameAndClass('div',
|
||||
goog.tweak.TweakUi.ENTRY_CSS_CLASS_, this.rootElem_);
|
||||
for (var i = 0, div; div = entryDivs[i]; i++) {
|
||||
this.showDescription_(div, show);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM element to control the given enum setting.
|
||||
* @param {!goog.tweak.StringSetting|!goog.tweak.NumericSetting} tweak The
|
||||
* setting.
|
||||
* @param {string} label The label for the entry.
|
||||
* @param {!Function} onchangeFunc onchange event handler.
|
||||
* @return {!DocumentFragment} The DOM element.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.createComboBoxDom_ =
|
||||
function(tweak, label, onchangeFunc) {
|
||||
// The markup looks like:
|
||||
// Label: <select><option></option></select>
|
||||
var dh = this.domHelper_;
|
||||
var ret = dh.getDocument().createDocumentFragment();
|
||||
ret.appendChild(dh.createTextNode(label + ': '));
|
||||
var selectElem = dh.createElement('select');
|
||||
var values = tweak.getValidValues();
|
||||
for (var i = 0, il = values.length; i < il; ++i) {
|
||||
var optionElem = dh.createElement('option');
|
||||
optionElem.text = String(values[i]);
|
||||
// Setting the option tag's value is required for selectElem.value to work
|
||||
// properly.
|
||||
optionElem.value = String(values[i]);
|
||||
selectElem.appendChild(optionElem);
|
||||
}
|
||||
ret.appendChild(selectElem);
|
||||
|
||||
// Set the value and add a callback.
|
||||
selectElem.value = tweak.getNewValue();
|
||||
selectElem.onchange = onchangeFunc;
|
||||
tweak.addCallback(function() {
|
||||
selectElem.value = tweak.getNewValue();
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM element to control the given boolean setting.
|
||||
* @param {!goog.tweak.BooleanSetting} tweak The setting.
|
||||
* @param {string} label The label for the entry.
|
||||
* @return {!DocumentFragment} The DOM elements.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.createBooleanSettingDom_ =
|
||||
function(tweak, label) {
|
||||
var dh = this.domHelper_;
|
||||
var ret = dh.getDocument().createDocumentFragment();
|
||||
var checkbox = dh.createDom('input', {type: 'checkbox'});
|
||||
ret.appendChild(checkbox);
|
||||
ret.appendChild(dh.createTextNode(label));
|
||||
|
||||
// Needed on IE6 to ensure the textbox doesn't get cleared
|
||||
// when added to the DOM.
|
||||
checkbox.defaultChecked = tweak.getNewValue();
|
||||
|
||||
checkbox.checked = tweak.getNewValue();
|
||||
checkbox.onchange = function() {
|
||||
tweak.setValue(checkbox.checked);
|
||||
};
|
||||
tweak.addCallback(function() {
|
||||
checkbox.checked = tweak.getNewValue();
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM for a BooleanGroup or NamespaceEntry.
|
||||
* @param {!goog.tweak.BooleanGroup|!goog.tweak.NamespaceEntry_} entry The
|
||||
* entry.
|
||||
* @param {string} label The label for the entry.
|
||||
* @param {!Array.<goog.tweak.BaseEntry>} childEntries The child entries.
|
||||
* @return {!DocumentFragment} The DOM element.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.createSubPanelDom_ = function(entry, label,
|
||||
childEntries) {
|
||||
var dh = this.domHelper_;
|
||||
var toggleLink = dh.createDom('a', {href: 'javascript:;'},
|
||||
label + ' \xBB');
|
||||
var toggleLink2 = dh.createDom('a', {href: 'javascript:;'},
|
||||
'\xAB ' + label);
|
||||
toggleLink2.style.marginRight = '10px';
|
||||
|
||||
var innerUi = new goog.tweak.EntriesPanel(childEntries, dh);
|
||||
this.childPanels[entry.getId()] = innerUi;
|
||||
|
||||
var elem = innerUi.render();
|
||||
// Move the toggle descriptions link into the legend.
|
||||
var descriptionsLink = elem.firstChild;
|
||||
var childrenElem = dh.createDom('fieldset',
|
||||
goog.getCssName('goog-inline-block'),
|
||||
dh.createDom('legend', null, toggleLink2, descriptionsLink),
|
||||
elem);
|
||||
|
||||
new goog.ui.Zippy(toggleLink, childrenElem, false /* expanded */,
|
||||
toggleLink2);
|
||||
|
||||
var ret = dh.getDocument().createDocumentFragment();
|
||||
ret.appendChild(toggleLink);
|
||||
ret.appendChild(childrenElem);
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM element to control the given string setting.
|
||||
* @param {!goog.tweak.StringSetting|!goog.tweak.NumericSetting} tweak The
|
||||
* setting.
|
||||
* @param {string} label The label for the entry.
|
||||
* @param {!Function} onchangeFunc onchange event handler.
|
||||
* @return {!DocumentFragment} The DOM element.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.createTextBoxDom_ =
|
||||
function(tweak, label, onchangeFunc) {
|
||||
var dh = this.domHelper_;
|
||||
var ret = dh.getDocument().createDocumentFragment();
|
||||
ret.appendChild(dh.createTextNode(label + ': '));
|
||||
var textBox = dh.createDom('input', {
|
||||
value: tweak.getNewValue(),
|
||||
// TODO(agrieve): Make size configurable or autogrow.
|
||||
size: 5,
|
||||
onblur: onchangeFunc
|
||||
});
|
||||
ret.appendChild(textBox);
|
||||
tweak.addCallback(function() {
|
||||
textBox.value = tweak.getNewValue();
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM element to control the given button action.
|
||||
* @param {!goog.tweak.ButtonAction} tweak The action.
|
||||
* @param {string} label The label for the entry.
|
||||
* @return {!Element} The DOM element.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.createButtonActionDom_ =
|
||||
function(tweak, label) {
|
||||
return this.domHelper_.createDom('button', {
|
||||
onclick: goog.bind(tweak.fireCallbacks, tweak)
|
||||
}, label);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the DOM element to control the given entry.
|
||||
* @param {!goog.tweak.BaseEntry} entry The entry.
|
||||
* @return {!Element|!DocumentFragment} The DOM element.
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.EntriesPanel.prototype.createTweakEntryDom_ = function(entry) {
|
||||
var label = goog.tweak.TweakUi.getNamespacedLabel_(entry);
|
||||
if (entry instanceof goog.tweak.BooleanSetting) {
|
||||
return this.createBooleanSettingDom_(entry, label);
|
||||
} else if (entry instanceof goog.tweak.BooleanGroup) {
|
||||
var childEntries = goog.tweak.TweakUi.extractBooleanGroupEntries_(entry);
|
||||
return this.createSubPanelDom_(entry, label, childEntries);
|
||||
} else if (entry instanceof goog.tweak.StringSetting) {
|
||||
/** @this {Element} */
|
||||
var setValueFunc = function() {
|
||||
entry.setValue(this.value);
|
||||
};
|
||||
return entry.getValidValues() ?
|
||||
this.createComboBoxDom_(entry, label, setValueFunc) :
|
||||
this.createTextBoxDom_(entry, label, setValueFunc);
|
||||
} else if (entry instanceof goog.tweak.NumericSetting) {
|
||||
setValueFunc = function() {
|
||||
// Reset the value if it's not a number.
|
||||
if (isNaN(this.value)) {
|
||||
this.value = entry.getNewValue();
|
||||
} else {
|
||||
entry.setValue(+this.value);
|
||||
}
|
||||
};
|
||||
return entry.getValidValues() ?
|
||||
this.createComboBoxDom_(entry, label, setValueFunc) :
|
||||
this.createTextBoxDom_(entry, label, setValueFunc);
|
||||
} else if (entry instanceof goog.tweak.NamespaceEntry_) {
|
||||
return this.createSubPanelDom_(entry, entry.label, entry.entries);
|
||||
}
|
||||
goog.asserts.assertInstanceof(entry, goog.tweak.ButtonAction,
|
||||
'invalid entry: %s', entry);
|
||||
return this.createButtonActionDom_(
|
||||
/** @type {!goog.tweak.ButtonAction} */ (entry), label);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Entries used to represent the collapsible namespace links. These entries are
|
||||
* never registered with the TweakRegistry, but are contained within the
|
||||
* collection of entries within TweakPanels.
|
||||
* @param {string} namespace The namespace for the entry.
|
||||
* @param {!Array.<!goog.tweak.BaseEntry>} entries Entries within the namespace.
|
||||
* @constructor
|
||||
* @extends {goog.tweak.BaseEntry}
|
||||
* @private
|
||||
*/
|
||||
goog.tweak.NamespaceEntry_ = function(namespace, entries) {
|
||||
goog.tweak.BaseEntry.call(this,
|
||||
goog.tweak.NamespaceEntry_.ID_PREFIX + namespace,
|
||||
'Tweaks within the ' + namespace + ' namespace.');
|
||||
|
||||
/**
|
||||
* Entries within this namespace.
|
||||
* @type {!Array.<!goog.tweak.BaseEntry>}
|
||||
*/
|
||||
this.entries = entries;
|
||||
|
||||
this.label = namespace;
|
||||
};
|
||||
goog.inherits(goog.tweak.NamespaceEntry_, goog.tweak.BaseEntry);
|
||||
|
||||
|
||||
/**
|
||||
* Prefix for the IDs of namespace entries used to ensure that they do not
|
||||
* conflict with regular entries.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.tweak.NamespaceEntry_.ID_PREFIX = '!';
|
||||
|
||||
Reference in New Issue
Block a user