OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | |
5 /** | 4 /** |
6 * @constructor | 5 * @unrestricted |
7 * @extends {WebInspector.AccessibilitySubPane} | |
8 */ | 6 */ |
9 WebInspector.ARIAAttributesPane = function() | 7 WebInspector.ARIAAttributesPane = class extends WebInspector.AccessibilitySubPan
e { |
10 { | 8 constructor() { |
11 WebInspector.AccessibilitySubPane.call(this, WebInspector.UIString("ARIA Att
ributes")); | 9 super(WebInspector.UIString('ARIA Attributes')); |
12 | 10 |
13 this._noPropertiesInfo = this.createInfo(WebInspector.UIString("No ARIA attr
ibutes")); | 11 this._noPropertiesInfo = this.createInfo(WebInspector.UIString('No ARIA attr
ibutes')); |
14 this._treeOutline = this.createTreeOutline(); | 12 this._treeOutline = this.createTreeOutline(); |
| 13 } |
| 14 |
| 15 /** |
| 16 * @override |
| 17 * @param {?WebInspector.DOMNode} node |
| 18 */ |
| 19 setNode(node) { |
| 20 super.setNode(node); |
| 21 this._treeOutline.removeChildren(); |
| 22 if (!this.node()) |
| 23 return; |
| 24 var target = this.node().target(); |
| 25 var attributes = node.attributes(); |
| 26 for (var i = 0; i < attributes.length; ++i) { |
| 27 var attribute = attributes[i]; |
| 28 if (WebInspector.ARIAAttributesPane._attributes.indexOf(attribute.name) <
0) |
| 29 continue; |
| 30 this._treeOutline.appendChild(new WebInspector.ARIAAttributesTreeElement(t
his, attribute, target)); |
| 31 } |
| 32 |
| 33 var foundAttributes = (this._treeOutline.rootElement().childCount() !== 0); |
| 34 this._noPropertiesInfo.classList.toggle('hidden', foundAttributes); |
| 35 this._treeOutline.element.classList.toggle('hidden', !foundAttributes); |
| 36 } |
15 }; | 37 }; |
16 | 38 |
17 | |
18 WebInspector.ARIAAttributesPane.prototype = { | |
19 /** | |
20 * @override | |
21 * @param {?WebInspector.DOMNode} node | |
22 */ | |
23 setNode: function(node) | |
24 { | |
25 WebInspector.AccessibilitySubPane.prototype.setNode.call(this, node); | |
26 this._treeOutline.removeChildren(); | |
27 if (!this.node()) | |
28 return; | |
29 var target = this.node().target(); | |
30 var attributes = node.attributes(); | |
31 for (var i = 0; i < attributes.length; ++i) { | |
32 var attribute = attributes[i]; | |
33 if (WebInspector.ARIAAttributesPane._attributes.indexOf(attribute.na
me) < 0) | |
34 continue; | |
35 this._treeOutline.appendChild(new WebInspector.ARIAAttributesTreeEle
ment(this, attribute, target)); | |
36 } | |
37 | |
38 var foundAttributes = (this._treeOutline.rootElement().childCount() !==
0); | |
39 this._noPropertiesInfo.classList.toggle("hidden", foundAttributes); | |
40 this._treeOutline.element.classList.toggle("hidden", !foundAttributes); | |
41 }, | |
42 | |
43 __proto__: WebInspector.AccessibilitySubPane.prototype | |
44 }; | |
45 | |
46 | |
47 /** | 39 /** |
48 * @constructor | 40 * @unrestricted |
49 * @extends {TreeElement} | |
50 * @param {!WebInspector.ARIAAttributesPane} parentPane | |
51 * @param {!WebInspector.DOMNode.Attribute} attribute | |
52 * @param {!WebInspector.Target} target | |
53 */ | 41 */ |
54 WebInspector.ARIAAttributesTreeElement = function(parentPane, attribute, target) | 42 WebInspector.ARIAAttributesTreeElement = class extends TreeElement { |
55 { | 43 /** |
56 TreeElement.call(this, ""); | 44 * @param {!WebInspector.ARIAAttributesPane} parentPane |
| 45 * @param {!WebInspector.DOMNode.Attribute} attribute |
| 46 * @param {!WebInspector.Target} target |
| 47 */ |
| 48 constructor(parentPane, attribute, target) { |
| 49 super(''); |
57 | 50 |
58 this._parentPane = parentPane; | 51 this._parentPane = parentPane; |
59 this._attribute = attribute; | 52 this._attribute = attribute; |
60 | 53 |
61 this.selectable = false; | 54 this.selectable = false; |
62 }; | 55 } |
63 | 56 |
64 WebInspector.ARIAAttributesTreeElement.prototype = { | 57 /** |
65 /** | 58 * @param {string} value |
66 * @override | 59 * @return {!Element} |
67 */ | 60 */ |
68 onattach: function() | 61 static createARIAValueElement(value) { |
69 { | 62 var valueElement = createElementWithClass('span', 'monospace'); |
70 this._populateListItem(); | 63 // TODO(aboxhall): quotation marks? |
71 this.listItemElement.addEventListener("click", this._mouseClick.bind(thi
s)); | 64 valueElement.setTextContentTruncatedIfNeeded(value || ''); |
72 }, | 65 return valueElement; |
73 | 66 } |
74 _populateListItem: function() | 67 |
75 { | 68 /** |
76 this.listItemElement.removeChildren(); | 69 * @override |
77 this.appendNameElement(this._attribute.name); | 70 */ |
78 this.listItemElement.createChild("span", "separator").textContent = ":\u
00A0"; | 71 onattach() { |
79 this.appendAttributeValueElement(this._attribute.value); | 72 this._populateListItem(); |
80 }, | 73 this.listItemElement.addEventListener('click', this._mouseClick.bind(this)); |
81 | 74 } |
82 /** | 75 |
83 * @param {string} name | 76 _populateListItem() { |
84 */ | 77 this.listItemElement.removeChildren(); |
85 appendNameElement: function(name) | 78 this.appendNameElement(this._attribute.name); |
86 { | 79 this.listItemElement.createChild('span', 'separator').textContent = ':\u00A0
'; |
87 this._nameElement = createElement("span"); | 80 this.appendAttributeValueElement(this._attribute.value); |
88 this._nameElement.textContent = name; | 81 } |
89 this._nameElement.classList.add("ax-name"); | 82 |
90 this._nameElement.classList.add("monospace"); | 83 /** |
91 this.listItemElement.appendChild(this._nameElement); | 84 * @param {string} name |
92 }, | 85 */ |
93 | 86 appendNameElement(name) { |
94 /** | 87 this._nameElement = createElement('span'); |
95 * @param {string} value | 88 this._nameElement.textContent = name; |
96 */ | 89 this._nameElement.classList.add('ax-name'); |
97 appendAttributeValueElement: function(value) | 90 this._nameElement.classList.add('monospace'); |
98 { | 91 this.listItemElement.appendChild(this._nameElement); |
99 this._valueElement = WebInspector.ARIAAttributesTreeElement.createARIAVa
lueElement(value); | 92 } |
100 this.listItemElement.appendChild(this._valueElement); | 93 |
101 }, | 94 /** |
102 | 95 * @param {string} value |
103 /** | 96 */ |
104 * @param {!Event} event | 97 appendAttributeValueElement(value) { |
105 */ | 98 this._valueElement = WebInspector.ARIAAttributesTreeElement.createARIAValueE
lement(value); |
106 _mouseClick: function(event) | 99 this.listItemElement.appendChild(this._valueElement); |
107 { | 100 } |
108 if (event.target === this.listItemElement) | 101 |
109 return; | 102 /** |
110 | 103 * @param {!Event} event |
111 event.consume(true); | 104 */ |
112 | 105 _mouseClick(event) { |
113 this._startEditing(); | 106 if (event.target === this.listItemElement) |
114 }, | 107 return; |
115 | 108 |
116 _startEditing: function() | 109 event.consume(true); |
117 { | 110 |
118 var valueElement = this._valueElement; | 111 this._startEditing(); |
119 | 112 } |
120 if (WebInspector.isBeingEdited(valueElement)) | 113 |
121 return; | 114 _startEditing() { |
122 | 115 var valueElement = this._valueElement; |
123 var previousContent = valueElement.textContent; | 116 |
124 | 117 if (WebInspector.isBeingEdited(valueElement)) |
125 /** | 118 return; |
126 * @param {string} previousContent | 119 |
127 * @param {!Event} event | 120 var previousContent = valueElement.textContent; |
128 * @this {WebInspector.ARIAAttributesTreeElement} | |
129 */ | |
130 function blurListener(previousContent, event) | |
131 { | |
132 var text = event.target.textContent; | |
133 this._editingCommitted(text, previousContent); | |
134 } | |
135 | |
136 this._prompt = new WebInspector.ARIAAttributesPane.ARIAAttributePrompt(W
ebInspector.ariaMetadata().valuesForProperty(this._nameElement.textContent), thi
s); | |
137 this._prompt.setAutocompletionTimeout(0); | |
138 var proxyElement = this._prompt.attachAndStartEditing(valueElement, blur
Listener.bind(this, previousContent)); | |
139 | |
140 proxyElement.addEventListener("keydown", this._editingValueKeyDown.bind(
this, previousContent), false); | |
141 | |
142 valueElement.getComponentSelection().setBaseAndExtent(valueElement, 0, v
alueElement, 1); | |
143 }, | |
144 | |
145 _removePrompt: function() | |
146 { | |
147 if (!this._prompt) | |
148 return; | |
149 this._prompt.detach(); | |
150 delete this._prompt; | |
151 }, | |
152 | |
153 /** | |
154 * @param {string} userInput | |
155 * @param {string} previousContent | |
156 */ | |
157 _editingCommitted: function(userInput, previousContent) | |
158 { | |
159 this._removePrompt(); | |
160 | |
161 // Make the changes to the attribute | |
162 if (userInput !== previousContent) | |
163 this._parentPane.node().setAttributeValue(this._attribute.name, user
Input); | |
164 }, | |
165 | |
166 _editingCancelled: function() | |
167 { | |
168 this._removePrompt(); | |
169 this._populateListItem(); | |
170 }, | |
171 | 121 |
172 /** | 122 /** |
173 * @param {string} previousContent | 123 * @param {string} previousContent |
174 * @param {!Event} event | 124 * @param {!Event} event |
| 125 * @this {WebInspector.ARIAAttributesTreeElement} |
175 */ | 126 */ |
176 _editingValueKeyDown: function(previousContent, event) | 127 function blurListener(previousContent, event) { |
177 { | 128 var text = event.target.textContent; |
178 if (event.handled) | 129 this._editingCommitted(text, previousContent); |
179 return; | 130 } |
180 | 131 |
181 if (isEnterKey(event)) { | 132 this._prompt = new WebInspector.ARIAAttributesPane.ARIAAttributePrompt( |
182 this._editingCommitted(event.target.textContent, previousContent); | 133 WebInspector.ariaMetadata().valuesForProperty(this._nameElement.textCont
ent), this); |
183 event.consume(); | 134 this._prompt.setAutocompletionTimeout(0); |
184 return; | 135 var proxyElement = this._prompt.attachAndStartEditing(valueElement, blurList
ener.bind(this, previousContent)); |
185 } | 136 |
186 | 137 proxyElement.addEventListener('keydown', this._editingValueKeyDown.bind(this
, previousContent), false); |
187 if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || eve
nt.keyIdentifier === "U+001B") { | 138 |
188 this._editingCancelled(); | 139 valueElement.getComponentSelection().setBaseAndExtent(valueElement, 0, value
Element, 1); |
189 event.consume(); | 140 } |
190 return; | 141 |
191 } | 142 _removePrompt() { |
192 }, | 143 if (!this._prompt) |
193 | 144 return; |
194 __proto__: TreeElement.prototype | 145 this._prompt.detach(); |
| 146 delete this._prompt; |
| 147 } |
| 148 |
| 149 /** |
| 150 * @param {string} userInput |
| 151 * @param {string} previousContent |
| 152 */ |
| 153 _editingCommitted(userInput, previousContent) { |
| 154 this._removePrompt(); |
| 155 |
| 156 // Make the changes to the attribute |
| 157 if (userInput !== previousContent) |
| 158 this._parentPane.node().setAttributeValue(this._attribute.name, userInput)
; |
| 159 } |
| 160 |
| 161 _editingCancelled() { |
| 162 this._removePrompt(); |
| 163 this._populateListItem(); |
| 164 } |
| 165 |
| 166 /** |
| 167 * @param {string} previousContent |
| 168 * @param {!Event} event |
| 169 */ |
| 170 _editingValueKeyDown(previousContent, event) { |
| 171 if (event.handled) |
| 172 return; |
| 173 |
| 174 if (isEnterKey(event)) { |
| 175 this._editingCommitted(event.target.textContent, previousContent); |
| 176 event.consume(); |
| 177 return; |
| 178 } |
| 179 |
| 180 if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.k
eyIdentifier === 'U+001B') { |
| 181 this._editingCancelled(); |
| 182 event.consume(); |
| 183 return; |
| 184 } |
| 185 } |
195 }; | 186 }; |
196 | 187 |
| 188 |
197 /** | 189 /** |
198 * @param {string} value | 190 * @unrestricted |
199 * @return {!Element} | |
200 */ | 191 */ |
201 WebInspector.ARIAAttributesTreeElement.createARIAValueElement = function(value) | 192 WebInspector.ARIAAttributesPane.ARIAAttributePrompt = class extends WebInspector
.TextPrompt { |
202 { | 193 /** |
203 var valueElement = createElementWithClass("span", "monospace"); | 194 * @param {!Array<string>} ariaCompletions |
204 // TODO(aboxhall): quotation marks? | 195 * @param {!WebInspector.ARIAAttributesTreeElement} treeElement |
205 valueElement.setTextContentTruncatedIfNeeded(value || ""); | 196 */ |
206 return valueElement; | 197 constructor(ariaCompletions, treeElement) { |
207 }; | 198 super(); |
208 | |
209 /** | |
210 * @constructor | |
211 * @extends {WebInspector.TextPrompt} | |
212 * @param {!Array<string>} ariaCompletions | |
213 * @param {!WebInspector.ARIAAttributesTreeElement} treeElement | |
214 */ | |
215 WebInspector.ARIAAttributesPane.ARIAAttributePrompt = function(ariaCompletions,
treeElement) | |
216 { | |
217 WebInspector.TextPrompt.call(this); | |
218 this.initialize(this._buildPropertyCompletions.bind(this)); | 199 this.initialize(this._buildPropertyCompletions.bind(this)); |
219 | 200 |
220 this.setSuggestBoxEnabled(true); | 201 this.setSuggestBoxEnabled(true); |
221 | 202 |
222 this._ariaCompletions = ariaCompletions; | 203 this._ariaCompletions = ariaCompletions; |
223 this._treeElement = treeElement; | 204 this._treeElement = treeElement; |
| 205 } |
| 206 |
| 207 /** |
| 208 * @param {!Element} proxyElement |
| 209 * @param {!Range} wordRange |
| 210 * @param {boolean} force |
| 211 * @param {function(!Array.<string>, number=)} completionsReadyCallback |
| 212 */ |
| 213 _buildPropertyCompletions(proxyElement, wordRange, force, completionsReadyCall
back) { |
| 214 var prefix = wordRange.toString().toLowerCase(); |
| 215 if (!prefix && !force && (this._isEditingName || proxyElement.textContent.le
ngth)) { |
| 216 completionsReadyCallback([]); |
| 217 return; |
| 218 } |
| 219 |
| 220 var results = this._ariaCompletions.filter((value) => value.startsWith(prefi
x)); |
| 221 |
| 222 completionsReadyCallback(results, 0); |
| 223 } |
224 }; | 224 }; |
225 | 225 |
226 WebInspector.ARIAAttributesPane.ARIAAttributePrompt.prototype = { | |
227 /** | |
228 * @param {!Element} proxyElement | |
229 * @param {!Range} wordRange | |
230 * @param {boolean} force | |
231 * @param {function(!Array.<string>, number=)} completionsReadyCallback | |
232 */ | |
233 _buildPropertyCompletions: function(proxyElement, wordRange, force, completi
onsReadyCallback) | |
234 { | |
235 var prefix = wordRange.toString().toLowerCase(); | |
236 if (!prefix && !force && (this._isEditingName || proxyElement.textConten
t.length)) { | |
237 completionsReadyCallback([]); | |
238 return; | |
239 } | |
240 | |
241 var results = this._ariaCompletions.filter((value) => value.startsWith(p
refix)); | |
242 | |
243 completionsReadyCallback(results, 0); | |
244 }, | |
245 | |
246 __proto__: WebInspector.TextPrompt.prototype | |
247 }; | |
248 | |
249 | |
250 WebInspector.ARIAAttributesPane._attributes = [ | 226 WebInspector.ARIAAttributesPane._attributes = [ |
251 "role", | 227 'role', |
252 "aria-busy", | 228 'aria-busy', |
253 "aria-checked", | 229 'aria-checked', |
254 "aria-disabled", | 230 'aria-disabled', |
255 "aria-expanded", | 231 'aria-expanded', |
256 "aria-grabbed", | 232 'aria-grabbed', |
257 "aria-hidden", | 233 'aria-hidden', |
258 "aria-invalid", | 234 'aria-invalid', |
259 "aria-pressed", | 235 'aria-pressed', |
260 "aria-selected", | 236 'aria-selected', |
261 "aria-activedescendant", | 237 'aria-activedescendant', |
262 "aria-atomic", | 238 'aria-atomic', |
263 "aria-autocomplete", | 239 'aria-autocomplete', |
264 "aria-controls", | 240 'aria-controls', |
265 "aria-describedby", | 241 'aria-describedby', |
266 "aria-dropeffect", | 242 'aria-dropeffect', |
267 "aria-flowto", | 243 'aria-flowto', |
268 "aria-haspopup", | 244 'aria-haspopup', |
269 "aria-label", | 245 'aria-label', |
270 "aria-labelledby", | 246 'aria-labelledby', |
271 "aria-level", | 247 'aria-level', |
272 "aria-live", | 248 'aria-live', |
273 "aria-multiline", | 249 'aria-multiline', |
274 "aria-multiselectable", | 250 'aria-multiselectable', |
275 "aria-orientation", | 251 'aria-orientation', |
276 "aria-owns", | 252 'aria-owns', |
277 "aria-posinset", | 253 'aria-posinset', |
278 "aria-readonly", | 254 'aria-readonly', |
279 "aria-relevant", | 255 'aria-relevant', |
280 "aria-required", | 256 'aria-required', |
281 "aria-setsize", | 257 'aria-setsize', |
282 "aria-sort", | 258 'aria-sort', |
283 "aria-valuemax", | 259 'aria-valuemax', |
284 "aria-valuemin", | 260 'aria-valuemin', |
285 "aria-valuenow", | 261 'aria-valuenow', |
286 "aria-valuetext", | 262 'aria-valuetext', |
287 ]; | 263 ]; |
OLD | NEW |