Add an exponential backoff to rechecking the app list doodle.
[chromium-blink-merge.git] / third_party / polymer / components-chromium / core-focusable / core-focusable.js
blob6633b5f9443737c40f92f9fa8fa6dc33db1aed2c
1 /**
2  * @group Polymer Mixins
3  *
4  * `Polymer.CoreFocusable` is a mixin for elements that the user can interact with.
5  * Elements using this mixin will receive attributes reflecting the focus, pressed
6  * and disabled states.
7  *
8  * @element Polymer.CoreFocusable
9  * @status unstable
10  */
12 Polymer.CoreFocusable = {
14   mixinPublish: {
16     /**
17      * If true, the element is currently active either because the
18      * user is touching it, or the button is a toggle
19      * and is currently in the active state.
20      *
21      * @attribute active
22      * @type boolean
23      * @default false
24      */
25     active: {value: false, reflect: true},
27     /**
28      * If true, the element currently has focus due to keyboard
29      * navigation.
30      *
31      * @attribute focused
32      * @type boolean
33      * @default false
34      */
35     focused: {value: false, reflect: true},
37     /**
38      * If true, the user is currently holding down the button.
39      *
40      * @attribute pressed
41      * @type boolean
42      * @default false
43      */
44     pressed: {value: false, reflect: true},
46     /**
47      * If true, the user cannot interact with this element.
48      *
49      * @attribute disabled
50      * @type boolean
51      * @default false
52      */
53     disabled: {value: false, reflect: true},
55     /**
56      * If true, the button toggles the active state with each tap.
57      * Otherwise, the button becomes active when the user is holding
58      * it down.
59      *
60      * @attribute toggle
61      * @type boolean
62      * @default false
63      */
64     toggle: false
66   },
68   mixinDelegates: {
69     contextMenu: '_contextMenuAction',
70     down: '_downAction',
71     up: '_upAction',
72     focus: '_focusAction',
73     blur: '_blurAction'
74   },
76   mixinObserve: {
77     disabled: '_disabledChanged'
78   },
80   _disabledChanged: function() {
81     if (this.disabled) {
82       this.style.pointerEvents = 'none';
83       this.removeAttribute('tabindex');
84       this.setAttribute('aria-disabled', '');
85     } else {
86       this.style.pointerEvents = '';
87       this.setAttribute('tabindex', 0);
88       this.removeAttribute('aria-disabled');
89     }
90   },
92   _downAction: function() {
93     this.pressed = true;
95     if (this.toggle) {
96       this.active = !this.active;
97     } else {
98       this.active = true;
99     }
100   },
102   // Pulling up the context menu for an item should focus it; but we need to
103   // be careful about how we deal with down/up events surrounding context
104   // menus. The up event typically does not fire until the context menu
105   // closes: so we focus immediately.
106   //
107   // This fires _after_ downAction.
108   _contextMenuAction: function(e) {
109     // Note that upAction may fire _again_ on the actual up event.
110     this._upAction(e);
111     this._focusAction();
112   },
114   _upAction: function() {
115     this.pressed = false;
117     if (!this.toggle) {
118       this.active = false;
119     }
120   },
122   _focusAction: function() {
123     if (!this.pressed) {
124       // Only render the "focused" state if the element gains focus due to
125       // keyboard navigation.
126       this.focused = true;
127     }
128   },
130   _blurAction: function() {
131     this.focused = false;
132   }