aboutsummaryrefslogtreecommitdiff
path: root/contexts/data/lib/closure-library/closure/goog/ui/nativebuttonrenderer.js
blob: fb2229bb6217e0a3f0117106f507e8c79658d84b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// Copyright 2008 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 Native browser button renderer for {@link goog.ui.Button}s.
 *
 * @author attila@google.com (Attila Bodis)
 */

goog.provide('goog.ui.NativeButtonRenderer');

goog.require('goog.dom.classes');
goog.require('goog.events.EventType');
goog.require('goog.ui.ButtonRenderer');
goog.require('goog.ui.Component.State');



/**
 * Renderer for {@link goog.ui.Button}s.  Renders and decorates native HTML
 * button elements.  Since native HTML buttons have built-in support for many
 * features, overrides many expensive (and redundant) superclass methods to
 * be no-ops.
 * @constructor
 * @extends {goog.ui.ButtonRenderer}
 */
goog.ui.NativeButtonRenderer = function() {
  goog.ui.ButtonRenderer.call(this);
};
goog.inherits(goog.ui.NativeButtonRenderer, goog.ui.ButtonRenderer);
goog.addSingletonGetter(goog.ui.NativeButtonRenderer);


/** @override */
goog.ui.NativeButtonRenderer.prototype.getAriaRole = function() {
  // Native buttons don't need ARIA roles to be recognized by screen readers.
  return undefined;
};


/**
 * Returns the button's contents wrapped in a native HTML button element.  Sets
 * the button's disabled attribute as needed.
 * @param {goog.ui.Control} button Button to render.
 * @return {Element} Root element for the button (a native HTML button element).
 * @override
 */
goog.ui.NativeButtonRenderer.prototype.createDom = function(button) {
  this.setUpNativeButton_(button);
  return button.getDomHelper().createDom('button', {
    'class': this.getClassNames(button).join(' '),
    'disabled': !button.isEnabled(),
    'title': button.getTooltip() || '',
    'value': button.getValue() || ''
  }, button.getCaption() || '');
};


/**
 * Overrides {@link goog.ui.ButtonRenderer#canDecorate} by returning true only
 * if the element is an HTML button.
 * @param {Element} element Element to decorate.
 * @return {boolean} Whether the renderer can decorate the element.
 * @override
 */
goog.ui.NativeButtonRenderer.prototype.canDecorate = function(element) {
  return element.tagName == 'BUTTON' ||
      (element.tagName == 'INPUT' && (element.type == 'button' ||
          element.type == 'submit' || element.type == 'reset'));
};


/** @override */
goog.ui.NativeButtonRenderer.prototype.decorate = function(button, element) {
  this.setUpNativeButton_(button);
  if (element.disabled) {
    // Add the marker class for the DISABLED state before letting the superclass
    // implementation decorate the element, so its state will be correct.
    goog.dom.classes.add(element,
        this.getClassForState(goog.ui.Component.State.DISABLED));
  }
  return goog.ui.NativeButtonRenderer.superClass_.decorate.call(this, button,
      element);
};


/**
 * Native buttons natively support BiDi and keyboard focus.
 * @suppress {visibility} getHandler and performActionInternal
 * @override
 */
goog.ui.NativeButtonRenderer.prototype.initializeDom = function(button) {
  // WARNING:  This is a hack, and it is only applicable to native buttons,
  // which are special because they do natively what most goog.ui.Controls
  // do programmatically.  Do not use your renderer's initializeDom method
  // to hook up event handlers!
  button.getHandler().listen(button.getElement(), goog.events.EventType.CLICK,
      button.performActionInternal);
};


/**
 * @override
 * Native buttons don't support text selection.
 */
goog.ui.NativeButtonRenderer.prototype.setAllowTextSelection =
    goog.nullFunction;


/**
 * @override
 * Native buttons natively support right-to-left rendering.
 */
goog.ui.NativeButtonRenderer.prototype.setRightToLeft = goog.nullFunction;


/**
 * @override
 * Native buttons are always focusable as long as they are enabled.
 */
goog.ui.NativeButtonRenderer.prototype.isFocusable = function(button) {
  return button.isEnabled();
};


/**
 * @override
 * Native buttons natively support keyboard focus.
 */
goog.ui.NativeButtonRenderer.prototype.setFocusable = goog.nullFunction;


/**
 * @override
 * Native buttons also expose the DISABLED state in the HTML button's
 * {@code disabled} attribute.
 */
goog.ui.NativeButtonRenderer.prototype.setState = function(button, state,
    enable) {
  goog.ui.NativeButtonRenderer.superClass_.setState.call(this, button, state,
      enable);
  var element = button.getElement();
  if (element && state == goog.ui.Component.State.DISABLED) {
    element.disabled = enable;
  }
};


/**
 * @override
 * Native buttons store their value in the HTML button's {@code value}
 * attribute.
 */
goog.ui.NativeButtonRenderer.prototype.getValue = function(element) {
  // TODO(attila): Make this work on IE!  This never worked...
  // See http://www.fourmilab.ch/fourmilog/archives/2007-03/000824.html
  // for a description of the problem.
  return element.value;
};


/**
 * @override
 * Native buttons also expose their value in the HTML button's {@code value}
 * attribute.
 */
goog.ui.NativeButtonRenderer.prototype.setValue = function(element, value) {
  if (element) {
    // TODO(attila): Make this work on IE!  This never worked...
    // See http://www.fourmilab.ch/fourmilog/archives/2007-03/000824.html
    // for a description of the problem.
    element.value = value;
  }
};


/**
 * @override
 * Native buttons don't need ARIA states to support accessibility, so this is
 * a no-op.
 */
goog.ui.NativeButtonRenderer.prototype.updateAriaState = goog.nullFunction;


/**
 * Sets up the button control such that it doesn't waste time adding
 * functionality that is already natively supported by native browser
 * buttons.
 * @param {goog.ui.Control} button Button control to configure.
 * @private
 */
goog.ui.NativeButtonRenderer.prototype.setUpNativeButton_ = function(button) {
  button.setHandleMouseEvents(false);
  button.setAutoStates(goog.ui.Component.State.ALL, false);
  button.setSupportedState(goog.ui.Component.State.FOCUSED, false);
};