Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / iron-behaviors / iron-button-state-extracted.js
blobc1ea1ed6128a5b6393712c339a142187a4867782
3   /**
4    * @demo demo/index.html
5    * @polymerBehavior Polymer.IronButtonState
6    */
7   Polymer.IronButtonStateImpl = {
9     properties: {
11       /**
12        * If true, the user is currently holding down the button.
13        */
14       pressed: {
15         type: Boolean,
16         readOnly: true,
17         value: false,
18         reflectToAttribute: true,
19         observer: '_pressedChanged'
20       },
22       /**
23        * If true, the button toggles the active state with each tap or press
24        * of the spacebar.
25        */
26       toggles: {
27         type: Boolean,
28         value: false,
29         reflectToAttribute: true
30       },
32       /**
33        * If true, the button is a toggle and is currently in the active state.
34        */
35       active: {
36         type: Boolean,
37         value: false,
38         notify: true,
39         reflectToAttribute: true
40       },
42       /**
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
45        * keyboard input).
46        */
47       pointerDown: {
48         type: Boolean,
49         readOnly: true,
50         value: false
51       },
53       /**
54        * True if the input device that caused the element to receive focus
55        * was a keyboard.
56        */
57       receivedFocusFromKeyboard: {
58         type: Boolean,
59         readOnly: true
60       },
62       /**
63        * The aria attribute to be set if the button is a toggle and in the
64        * active state.
65        */
66       ariaActiveAttribute: {
67         type: String,
68         value: 'aria-pressed',
69         observer: '_ariaActiveAttributeChanged'
70       }
71     },
73     listeners: {
74       down: '_downHandler',
75       up: '_upHandler',
76       tap: '_tapHandler'
77     },
79     observers: [
80       '_detectKeyboardFocus(focused)',
81       '_activeChanged(active, ariaActiveAttribute)'
82     ],
84     keyBindings: {
85       'enter:keydown': '_asyncClick',
86       'space:keydown': '_spaceKeyDownHandler',
87       'space:keyup': '_spaceKeyUpHandler',
88     },
90     _mouseEventRe: /^mouse/,
92     _tapHandler: function() {
93       if (this.toggles) {
94        // a tap is needed to toggle the active state
95         this._userActivate(!this.active);
96       } else {
97         this.active = false;
98       }
99     },
101     _detectKeyboardFocus: function(focused) {
102       this._setReceivedFocusFromKeyboard(!this.pointerDown && focused);
103     },
105     // to emulate native checkbox, (de-)activations from a user interaction fire
106     // 'change' events
107     _userActivate: function(active) {
108       if (this.active !== active) {
109         this.active = active;
110         this.fire('change');
111       }
112     },
114     _eventSourceIsPrimaryInput: function(event) {
115       event = event.detail.sourceEvent || event;
117       // Always true for non-mouse events....
118       if (!this._mouseEventRe.test(event.type)) {
119         return true;
120       }
122       // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
123       if ('buttons' in event) {
124         return event.buttons === 1;
125       }
127       // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which
128       if (typeof event.which === 'number') {
129         return event.which < 2;
130       }
132       // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
133       return event.button < 1;
134     },
136     _downHandler: function(event) {
137       if (!this._eventSourceIsPrimaryInput(event)) {
138         return;
139       }
141       this._setPointerDown(true);
142       this._setPressed(true);
143       this._setReceivedFocusFromKeyboard(false);
144     },
146     _upHandler: function() {
147       this._setPointerDown(false);
148       this._setPressed(false);
149     },
151     _spaceKeyDownHandler: function(event) {
152       var keyboardEvent = event.detail.keyboardEvent;
153       keyboardEvent.preventDefault();
154       keyboardEvent.stopImmediatePropagation();
155       this._setPressed(true);
156     },
158     _spaceKeyUpHandler: function() {
159       if (this.pressed) {
160         this._asyncClick();
161       }
162       this._setPressed(false);
163     },
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() {
169         this.click();
170       }, 1);
171     },
173     // any of these changes are considered a change to button state
175     _pressedChanged: function(pressed) {
176       this._changedButtonState();
177     },
179     _ariaActiveAttributeChanged: function(value, oldValue) {
180       if (oldValue && oldValue != value && this.hasAttribute(oldValue)) {
181         this.removeAttribute(oldValue);
182       }
183     },
185     _activeChanged: function(active, ariaActiveAttribute) {
186       if (this.toggles) {
187         this.setAttribute(this.ariaActiveAttribute,
188                           active ? 'true' : 'false');
189       } else {
190         this.removeAttribute(this.ariaActiveAttribute);
191       }
192       this._changedButtonState();
193     },
195     _controlStateChanged: function() {
196       if (this.disabled) {
197         this._setPressed(false);
198       } else {
199         this._changedButtonState();
200       }
201     },
203     // provide hook for follow-on behaviors to react to button-state
205     _changedButtonState: function() {
206       if (this._buttonStateChanged) {
207         this._buttonStateChanged(); // abstract
208       }
209     }
211   };
213   /** @polymerBehavior */
214   Polymer.IronButtonState = [
215     Polymer.IronA11yKeysBehavior,
216     Polymer.IronButtonStateImpl
217   ];