button.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // Copyright 2007 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 A button control. This implementation extends {@link
  16. * goog.ui.Control}.
  17. *
  18. * @author attila@google.com (Attila Bodis)
  19. * @see ../demos/button.html
  20. */
  21. goog.provide('goog.ui.Button');
  22. goog.provide('goog.ui.Button.Side');
  23. goog.require('goog.events.EventType');
  24. goog.require('goog.events.KeyCodes');
  25. goog.require('goog.events.KeyHandler');
  26. goog.require('goog.ui.ButtonRenderer');
  27. goog.require('goog.ui.ButtonSide');
  28. goog.require('goog.ui.Component');
  29. goog.require('goog.ui.Control');
  30. goog.require('goog.ui.NativeButtonRenderer');
  31. goog.require('goog.ui.registry');
  32. /**
  33. * A button control, rendered as a native browser button by default.
  34. *
  35. * @param {goog.ui.ControlContent=} opt_content Text caption or existing DOM
  36. * structure to display as the button's caption (if any).
  37. * @param {goog.ui.ButtonRenderer=} opt_renderer Renderer used to render or
  38. * decorate the button; defaults to {@link goog.ui.NativeButtonRenderer}.
  39. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper, used for
  40. * document interaction.
  41. * @constructor
  42. * @extends {goog.ui.Control}
  43. */
  44. goog.ui.Button = function(opt_content, opt_renderer, opt_domHelper) {
  45. goog.ui.Control.call(
  46. this, opt_content,
  47. opt_renderer || goog.ui.NativeButtonRenderer.getInstance(),
  48. opt_domHelper);
  49. };
  50. goog.inherits(goog.ui.Button, goog.ui.Control);
  51. goog.tagUnsealableClass(goog.ui.Button);
  52. /**
  53. * Constants for button sides, see {@link goog.ui.Button.prototype.setCollapsed}
  54. * for details. Aliased from goog.ui.ButtonSide to support legacy users without
  55. * creating a circular dependency in {@link goog.ui.ButtonRenderer}.
  56. * @enum {number}
  57. * @deprecated use {@link goog.ui.ButtonSide} instead.
  58. */
  59. goog.ui.Button.Side = goog.ui.ButtonSide;
  60. /**
  61. * Value associated with the button.
  62. * @type {*}
  63. * @private
  64. */
  65. goog.ui.Button.prototype.value_;
  66. /**
  67. * Tooltip text for the button, displayed on hover.
  68. * @type {string|undefined}
  69. * @private
  70. */
  71. goog.ui.Button.prototype.tooltip_;
  72. // goog.ui.Button API implementation.
  73. /**
  74. * Returns the value associated with the button.
  75. * @return {*} Button value (undefined if none).
  76. */
  77. goog.ui.Button.prototype.getValue = function() {
  78. return this.value_;
  79. };
  80. /**
  81. * Sets the value associated with the button, and updates its DOM.
  82. * @param {*} value New button value.
  83. */
  84. goog.ui.Button.prototype.setValue = function(value) {
  85. this.value_ = value;
  86. var renderer = /** @type {!goog.ui.ButtonRenderer} */ (this.getRenderer());
  87. renderer.setValue(this.getElement(), /** @type {string} */ (value));
  88. };
  89. /**
  90. * Sets the value associated with the button. Unlike {@link #setValue},
  91. * doesn't update the button's DOM. Considered protected; to be called only
  92. * by renderer code during element decoration.
  93. * @param {*} value New button value.
  94. * @protected
  95. */
  96. goog.ui.Button.prototype.setValueInternal = function(value) {
  97. this.value_ = value;
  98. };
  99. /**
  100. * Returns the tooltip for the button.
  101. * @return {string|undefined} Tooltip text (undefined if none).
  102. */
  103. goog.ui.Button.prototype.getTooltip = function() {
  104. return this.tooltip_;
  105. };
  106. /**
  107. * Sets the tooltip for the button, and updates its DOM.
  108. * @param {string} tooltip New tooltip text.
  109. */
  110. goog.ui.Button.prototype.setTooltip = function(tooltip) {
  111. this.tooltip_ = tooltip;
  112. this.getRenderer().setTooltip(this.getElement(), tooltip);
  113. };
  114. /**
  115. * Sets the tooltip for the button. Unlike {@link #setTooltip}, doesn't update
  116. * the button's DOM. Considered protected; to be called only by renderer code
  117. * during element decoration.
  118. * @param {string} tooltip New tooltip text.
  119. * @protected
  120. */
  121. goog.ui.Button.prototype.setTooltipInternal = function(tooltip) {
  122. this.tooltip_ = tooltip;
  123. };
  124. /**
  125. * Collapses the border on one or both sides of the button, allowing it to be
  126. * combined with the adjancent button(s), forming a single UI componenet with
  127. * multiple targets.
  128. * @param {number} sides Bitmap of one or more {@link goog.ui.ButtonSide}s for
  129. * which borders should be collapsed.
  130. */
  131. goog.ui.Button.prototype.setCollapsed = function(sides) {
  132. this.getRenderer().setCollapsed(this, sides);
  133. };
  134. // goog.ui.Control & goog.ui.Component API implementation.
  135. /** @override */
  136. goog.ui.Button.prototype.disposeInternal = function() {
  137. goog.ui.Button.superClass_.disposeInternal.call(this);
  138. delete this.value_;
  139. delete this.tooltip_;
  140. };
  141. /** @override */
  142. goog.ui.Button.prototype.enterDocument = function() {
  143. goog.ui.Button.superClass_.enterDocument.call(this);
  144. if (this.isSupportedState(goog.ui.Component.State.FOCUSED)) {
  145. var keyTarget = this.getKeyEventTarget();
  146. if (keyTarget) {
  147. this.getHandler().listen(
  148. keyTarget, goog.events.EventType.KEYUP, this.handleKeyEventInternal);
  149. }
  150. }
  151. };
  152. /**
  153. * Attempts to handle a keyboard event; returns true if the event was handled,
  154. * false otherwise. If the button is enabled and the Enter/Space key was
  155. * pressed, handles the event by dispatching an {@code ACTION} event,
  156. * and returns true. Overrides {@link goog.ui.Control#handleKeyEventInternal}.
  157. * @param {goog.events.KeyEvent} e Key event to handle.
  158. * @return {boolean} Whether the key event was handled.
  159. * @protected
  160. * @override
  161. */
  162. goog.ui.Button.prototype.handleKeyEventInternal = function(e) {
  163. if (e.keyCode == goog.events.KeyCodes.ENTER &&
  164. e.type == goog.events.KeyHandler.EventType.KEY ||
  165. e.keyCode == goog.events.KeyCodes.SPACE &&
  166. e.type == goog.events.EventType.KEYUP) {
  167. return this.performActionInternal(e);
  168. }
  169. // Return true for space keypress (even though the event is handled on keyup)
  170. // as preventDefault needs to be called up keypress to take effect in IE and
  171. // WebKit.
  172. return e.keyCode == goog.events.KeyCodes.SPACE;
  173. };
  174. // Register a decorator factory function for goog.ui.Buttons.
  175. goog.ui.registry.setDecoratorByClassName(
  176. goog.ui.ButtonRenderer.CSS_CLASS,
  177. function() { return new goog.ui.Button(null); });