4 * @demo demo/index.html
5 * @polymerBehavior Polymer.IronButtonState
7 Polymer.IronButtonStateImpl = {
12 * If true, the user is currently holding down the button.
18 reflectToAttribute: true,
19 observer: '_pressedChanged'
23 * If true, the button toggles the active state with each tap or press
29 reflectToAttribute: true
33 * If true, the button is a toggle and is currently in the active state.
39 reflectToAttribute: true
43 * True if the element is currently being pressed by a "pointer," which
44 * is loosely defined as mouse or touch input (but specifically excluding
54 * True if the input device that caused the element to receive focus
57 receivedFocusFromKeyboard: {
63 * The aria attribute to be set if the button is a toggle and in the
66 ariaActiveAttribute: {
68 value: 'aria-pressed',
69 observer: '_ariaActiveAttributeChanged'
80 '_detectKeyboardFocus(focused)',
81 '_activeChanged(active, ariaActiveAttribute)'
85 'enter:keydown': '_asyncClick',
86 'space:keydown': '_spaceKeyDownHandler',
87 'space:keyup': '_spaceKeyUpHandler',
90 _mouseEventRe: /^mouse/,
92 _tapHandler: function() {
94 // a tap is needed to toggle the active state
95 this._userActivate(!this.active);
101 _detectKeyboardFocus: function(focused) {
102 this._setReceivedFocusFromKeyboard(!this.pointerDown && focused);
105 // to emulate native checkbox, (de-)activations from a user interaction fire
107 _userActivate: function(active) {
108 if (this.active !== active) {
109 this.active = active;
114 _eventSourceIsPrimaryInput: function(event) {
115 event = event.detail.sourceEvent || event;
117 // Always true for non-mouse events....
118 if (!this._mouseEventRe.test(event.type)) {
122 // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
123 if ('buttons' in event) {
124 return event.buttons === 1;
127 // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which
128 if (typeof event.which === 'number') {
129 return event.which < 2;
132 // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
133 return event.button < 1;
136 _downHandler: function(event) {
137 if (!this._eventSourceIsPrimaryInput(event)) {
141 this._setPointerDown(true);
142 this._setPressed(true);
143 this._setReceivedFocusFromKeyboard(false);
146 _upHandler: function() {
147 this._setPointerDown(false);
148 this._setPressed(false);
151 _spaceKeyDownHandler: function(event) {
152 var keyboardEvent = event.detail.keyboardEvent;
153 keyboardEvent.preventDefault();
154 keyboardEvent.stopImmediatePropagation();
155 this._setPressed(true);
158 _spaceKeyUpHandler: function() {
162 this._setPressed(false);
165 // trigger click asynchronously, the asynchrony is useful to allow one
166 // event handler to unwind before triggering another event
167 _asyncClick: function() {
168 this.async(function() {
173 // any of these changes are considered a change to button state
175 _pressedChanged: function(pressed) {
176 this._changedButtonState();
179 _ariaActiveAttributeChanged: function(value, oldValue) {
180 if (oldValue && oldValue != value && this.hasAttribute(oldValue)) {
181 this.removeAttribute(oldValue);
185 _activeChanged: function(active, ariaActiveAttribute) {
187 this.setAttribute(this.ariaActiveAttribute,
188 active ? 'true' : 'false');
190 this.removeAttribute(this.ariaActiveAttribute);
192 this._changedButtonState();
195 _controlStateChanged: function() {
197 this._setPressed(false);
199 this._changedButtonState();
203 // provide hook for follow-on behaviors to react to button-state
205 _changedButtonState: function() {
206 if (this._buttonStateChanged) {
207 this._buttonStateChanged(); // abstract
213 /** @polymerBehavior */
214 Polymer.IronButtonState = [
215 Polymer.IronA11yKeysBehavior,
216 Polymer.IronButtonStateImpl