tweak.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. // Copyright 2009 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Provides facilities for creating and querying tweaks.
  16. * @see http://code.google.com/p/closure-library/wiki/UsingTweaks
  17. *
  18. * @author agrieve@google.com (Andrew Grieve)
  19. */
  20. goog.provide('goog.tweak');
  21. goog.provide('goog.tweak.ConfigParams');
  22. goog.require('goog.asserts');
  23. goog.require('goog.tweak.BaseSetting');
  24. goog.require('goog.tweak.BooleanGroup');
  25. goog.require('goog.tweak.BooleanInGroupSetting');
  26. goog.require('goog.tweak.BooleanSetting');
  27. goog.require('goog.tweak.ButtonAction');
  28. goog.require('goog.tweak.NumericSetting');
  29. goog.require('goog.tweak.Registry');
  30. goog.require('goog.tweak.StringSetting');
  31. /**
  32. * Calls to this function are overridden by the compiler by the processTweaks
  33. * pass. It returns the overrides to default values for tweaks set by compiler
  34. * options.
  35. * @return {!Object<number|string|boolean>} A map of tweakId -> defaultValue.
  36. * @private
  37. */
  38. goog.tweak.getCompilerOverrides_ = function() {
  39. return {};
  40. };
  41. /**
  42. * The global reference to the registry, if it exists.
  43. * @type {goog.tweak.Registry}
  44. * @private
  45. */
  46. goog.tweak.registry_ = null;
  47. /**
  48. * The boolean group set by beginBooleanGroup and cleared by endBooleanGroup.
  49. * @type {goog.tweak.BooleanGroup}
  50. * @private
  51. */
  52. goog.tweak.activeBooleanGroup_ = null;
  53. /**
  54. * Returns/creates the registry singleton.
  55. * @return {!goog.tweak.Registry} The tweak registry.
  56. */
  57. goog.tweak.getRegistry = function() {
  58. if (!goog.tweak.registry_) {
  59. var queryString = window.location.search;
  60. var overrides = goog.tweak.getCompilerOverrides_();
  61. goog.tweak.registry_ = new goog.tweak.Registry(queryString, overrides);
  62. }
  63. return goog.tweak.registry_;
  64. };
  65. /**
  66. * Type for configParams.
  67. * TODO(agrieve): Remove |Object when optional fields in struct types are
  68. * implemented.
  69. * @typedef {{
  70. * label:(string|undefined),
  71. * validValues:(!Array<string>|!Array<number>|undefined),
  72. * paramName:(string|undefined),
  73. * restartRequired:(boolean|undefined),
  74. * callback:(Function|undefined),
  75. * token:(string|undefined)
  76. * }|!Object}
  77. */
  78. goog.tweak.ConfigParams;
  79. /**
  80. * Applies all extra configuration parameters in configParams.
  81. * @param {!goog.tweak.BaseEntry} entry The entry to apply them to.
  82. * @param {!goog.tweak.ConfigParams} configParams Extra configuration
  83. * parameters.
  84. * @private
  85. */
  86. goog.tweak.applyConfigParams_ = function(entry, configParams) {
  87. if (configParams.label) {
  88. entry.label = configParams.label;
  89. delete configParams.label;
  90. }
  91. if (configParams.validValues) {
  92. goog.asserts.assert(
  93. entry instanceof goog.tweak.StringSetting ||
  94. entry instanceof goog.tweak.NumericSetting,
  95. 'Cannot set validValues on tweak: %s', entry.getId());
  96. entry.setValidValues(configParams.validValues);
  97. delete configParams.validValues;
  98. }
  99. if (goog.isDef(configParams.paramName)) {
  100. goog.asserts.assertInstanceof(
  101. entry, goog.tweak.BaseSetting, 'Cannot set paramName on tweak: %s',
  102. entry.getId());
  103. entry.setParamName(configParams.paramName);
  104. delete configParams.paramName;
  105. }
  106. if (goog.isDef(configParams.restartRequired)) {
  107. entry.setRestartRequired(configParams.restartRequired);
  108. delete configParams.restartRequired;
  109. }
  110. if (configParams.callback) {
  111. entry.addCallback(configParams.callback);
  112. delete configParams.callback;
  113. goog.asserts.assert(
  114. !entry.isRestartRequired() || (configParams.restartRequired == false),
  115. 'Tweak %s should set restartRequired: false, when adding a callback.',
  116. entry.getId());
  117. }
  118. if (configParams.token) {
  119. goog.asserts.assertInstanceof(
  120. entry, goog.tweak.BooleanInGroupSetting,
  121. 'Cannot set token on tweak: %s', entry.getId());
  122. entry.setToken(configParams.token);
  123. delete configParams.token;
  124. }
  125. for (var key in configParams) {
  126. goog.asserts.fail(
  127. 'Unknown config options (' + key + '=' + configParams[key] +
  128. ') for tweak ' + entry.getId());
  129. }
  130. };
  131. /**
  132. * Registers a tweak using the given factoryFunc.
  133. * @param {!goog.tweak.BaseEntry} entry The entry to register.
  134. * @param {boolean|string|number=} opt_defaultValue Default value.
  135. * @param {goog.tweak.ConfigParams=} opt_configParams Extra
  136. * configuration parameters.
  137. * @private
  138. */
  139. goog.tweak.doRegister_ = function(entry, opt_defaultValue, opt_configParams) {
  140. if (opt_configParams) {
  141. goog.tweak.applyConfigParams_(entry, opt_configParams);
  142. }
  143. if (opt_defaultValue != undefined) {
  144. entry.setDefaultValue(opt_defaultValue);
  145. }
  146. if (goog.tweak.activeBooleanGroup_) {
  147. goog.asserts.assertInstanceof(
  148. entry, goog.tweak.BooleanInGroupSetting,
  149. 'Forgot to end Boolean Group: %s',
  150. goog.tweak.activeBooleanGroup_.getId());
  151. goog.tweak.activeBooleanGroup_.addChild(
  152. /** @type {!goog.tweak.BooleanInGroupSetting} */ (entry));
  153. }
  154. goog.tweak.getRegistry().register(entry);
  155. };
  156. /**
  157. * Creates and registers a group of BooleanSettings that are all set by a
  158. * single query parameter. A call to goog.tweak.endBooleanGroup() must be used
  159. * to close this group. Only goog.tweak.registerBoolean() calls are allowed with
  160. * the beginBooleanGroup()/endBooleanGroup().
  161. * @param {string} id The unique ID for the setting.
  162. * @param {string} description A description of what the setting does.
  163. * @param {goog.tweak.ConfigParams=} opt_configParams Extra configuration
  164. * parameters.
  165. */
  166. goog.tweak.beginBooleanGroup = function(id, description, opt_configParams) {
  167. var entry = new goog.tweak.BooleanGroup(id, description);
  168. goog.tweak.doRegister_(entry, undefined, opt_configParams);
  169. goog.tweak.activeBooleanGroup_ = entry;
  170. };
  171. /**
  172. * Stops adding boolean entries to the active boolean group.
  173. */
  174. goog.tweak.endBooleanGroup = function() {
  175. goog.tweak.activeBooleanGroup_ = null;
  176. };
  177. /**
  178. * Creates and registers a BooleanSetting.
  179. * @param {string} id The unique ID for the setting.
  180. * @param {string} description A description of what the setting does.
  181. * @param {boolean=} opt_defaultValue The default value for the setting.
  182. * @param {goog.tweak.ConfigParams=} opt_configParams Extra configuration
  183. * parameters.
  184. */
  185. goog.tweak.registerBoolean = function(
  186. id, description, opt_defaultValue, opt_configParams) {
  187. // TODO(agrieve): There is a bug in the compiler that causes these calls not
  188. // to be stripped without this outer if. Might be Issue #90.
  189. if (goog.tweak.activeBooleanGroup_) {
  190. var entry = new goog.tweak.BooleanInGroupSetting(
  191. id, description, goog.tweak.activeBooleanGroup_);
  192. } else {
  193. entry = new goog.tweak.BooleanSetting(id, description);
  194. }
  195. goog.tweak.doRegister_(entry, opt_defaultValue, opt_configParams);
  196. };
  197. /**
  198. * Creates and registers a StringSetting.
  199. * @param {string} id The unique ID for the setting.
  200. * @param {string} description A description of what the setting does.
  201. * @param {string=} opt_defaultValue The default value for the setting.
  202. * @param {goog.tweak.ConfigParams=} opt_configParams Extra configuration
  203. * parameters.
  204. */
  205. goog.tweak.registerString = function(
  206. id, description, opt_defaultValue, opt_configParams) {
  207. goog.tweak.doRegister_(
  208. new goog.tweak.StringSetting(id, description), opt_defaultValue,
  209. opt_configParams);
  210. };
  211. /**
  212. * Creates and registers a NumericSetting.
  213. * @param {string} id The unique ID for the setting.
  214. * @param {string} description A description of what the setting does.
  215. * @param {number=} opt_defaultValue The default value for the setting.
  216. * @param {goog.tweak.ConfigParams=} opt_configParams Extra configuration
  217. * parameters.
  218. */
  219. goog.tweak.registerNumber = function(
  220. id, description, opt_defaultValue, opt_configParams) {
  221. goog.tweak.doRegister_(
  222. new goog.tweak.NumericSetting(id, description), opt_defaultValue,
  223. opt_configParams);
  224. };
  225. /**
  226. * Creates and registers a ButtonAction.
  227. * @param {string} id The unique ID for the setting.
  228. * @param {string} description A description of what the action does.
  229. * @param {!Function} callback Function to call when the button is clicked.
  230. * @param {string=} opt_label The button text (instead of the ID).
  231. */
  232. goog.tweak.registerButton = function(id, description, callback, opt_label) {
  233. var tweak = new goog.tweak.ButtonAction(id, description, callback);
  234. tweak.label = opt_label || tweak.label;
  235. goog.tweak.doRegister_(tweak);
  236. };
  237. /**
  238. * Sets a default value to use for the given tweak instead of the one passed
  239. * to the register* function. This function must be called before the tweak is
  240. * registered.
  241. * @param {string} id The unique string that identifies the entry.
  242. * @param {string|number|boolean} value The new default value for the tweak.
  243. */
  244. goog.tweak.overrideDefaultValue = function(id, value) {
  245. goog.tweak.getRegistry().overrideDefaultValue(id, value);
  246. };
  247. /**
  248. * Returns the value of the boolean setting with the given ID.
  249. * @param {string} id The unique string that identifies this entry.
  250. * @return {boolean} The value of the tweak.
  251. */
  252. goog.tweak.getBoolean = function(id) {
  253. return goog.tweak.getRegistry().getBooleanSetting(id).getValue();
  254. };
  255. /**
  256. * Returns the value of the string setting with the given ID,
  257. * @param {string} id The unique string that identifies this entry.
  258. * @return {string} The value of the tweak.
  259. */
  260. goog.tweak.getString = function(id) {
  261. return goog.tweak.getRegistry().getStringSetting(id).getValue();
  262. };
  263. /**
  264. * Returns the value of the numeric setting with the given ID.
  265. * @param {string} id The unique string that identifies this entry.
  266. * @return {number} The value of the tweak.
  267. */
  268. goog.tweak.getNumber = function(id) {
  269. return goog.tweak.getRegistry().getNumericSetting(id).getValue();
  270. };