This repository was archived by the owner on Mar 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcore-focusable.js
134 lines (115 loc) · 2.99 KB
/
core-focusable.js
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
/**
* @group Polymer Mixins
*
* `Polymer.CoreFocusable` is a mixin for elements that the user can interact with.
* Elements using this mixin will receive attributes reflecting the focus, pressed
* and disabled states.
*
* @element Polymer.CoreFocusable
* @status unstable
*/
Polymer.CoreFocusable = {
mixinPublish: {
/**
* If true, the element is currently active either because the
* user is touching it, or the button is a toggle
* and is currently in the active state.
*
* @attribute active
* @type boolean
* @default false
*/
active: {value: false, reflect: true},
/**
* If true, the element currently has focus due to keyboard
* navigation.
*
* @attribute focused
* @type boolean
* @default false
*/
focused: {value: false, reflect: true},
/**
* If true, the user is currently holding down the button.
*
* @attribute pressed
* @type boolean
* @default false
*/
pressed: {value: false, reflect: true},
/**
* If true, the user cannot interact with this element.
*
* @attribute disabled
* @type boolean
* @default false
*/
disabled: {value: false, reflect: true},
/**
* If true, the button toggles the active state with each tap.
* Otherwise, the button becomes active when the user is holding
* it down.
*
* @attribute toggle
* @type boolean
* @default false
*/
toggle: false
},
mixinDelegates: {
contextMenu: '_contextMenuAction',
down: '_downAction',
up: '_upAction',
focus: '_focusAction',
blur: '_blurAction'
},
mixinObserve: {
disabled: '_disabledChanged'
},
_disabledChanged: function() {
if (this.disabled) {
this.style.pointerEvents = 'none';
this.removeAttribute('tabindex');
this.setAttribute('aria-disabled', '');
} else {
this.style.pointerEvents = '';
this.setAttribute('tabindex', 0);
this.removeAttribute('aria-disabled');
}
},
_downAction: function() {
this.pressed = true;
if (this.toggle) {
this.active = !this.active;
} else {
this.active = true;
}
},
// Pulling up the context menu for an item should focus it; but we need to
// be careful about how we deal with down/up events surrounding context
// menus. The up event typically does not fire until the context menu
// closes: so we focus immediately.
//
// This fires _after_ downAction.
_contextMenuAction: function(e) {
// Note that upAction may fire _again_ on the actual up event.
this._upAction(e);
this._focusAction();
},
_upAction: function() {
this.pressed = false;
if (!this.toggle) {
this.active = false;
}
},
_focusAction: function() {
if (!this.pressed) {
// Only render the "focused" state if the element gains focus due to
// keyboard navigation.
this.focused = true;
}
},
_blurAction: function() {
this.focused = false;
}
}