OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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.VBox} | |
8 * @param {!WebInspector.ListWidget.Delegate} delegate | |
9 */ | 6 */ |
10 WebInspector.ListWidget = function(delegate) | 7 WebInspector.ListWidget = class extends WebInspector.VBox { |
11 { | 8 /** |
12 WebInspector.VBox.call(this, true); | 9 * @param {!WebInspector.ListWidget.Delegate} delegate |
13 this.registerRequiredCSS("ui/listWidget.css"); | 10 */ |
| 11 constructor(delegate) { |
| 12 super(true); |
| 13 this.registerRequiredCSS('ui/listWidget.css'); |
14 this._delegate = delegate; | 14 this._delegate = delegate; |
15 | 15 |
16 this._list = this.contentElement.createChild("div", "list"); | 16 this._list = this.contentElement.createChild('div', 'list'); |
17 | 17 |
18 /** @type {?WebInspector.ListWidget.Editor} */ | 18 /** @type {?WebInspector.ListWidget.Editor} */ |
19 this._editor = null; | 19 this._editor = null; |
20 /** @type {*|null} */ | 20 /** @type {*|null} */ |
21 this._editItem = null; | 21 this._editItem = null; |
22 /** @type {?Element} */ | 22 /** @type {?Element} */ |
23 this._editElement = null; | 23 this._editElement = null; |
24 | 24 |
25 /** @type {?Element} */ | 25 /** @type {?Element} */ |
26 this._emptyPlaceholder = null; | 26 this._emptyPlaceholder = null; |
27 | 27 |
28 this.clear(); | 28 this.clear(); |
| 29 } |
| 30 |
| 31 clear() { |
| 32 this._items = []; |
| 33 this._editable = []; |
| 34 this._elements = []; |
| 35 this._lastSeparator = false; |
| 36 this._list.removeChildren(); |
| 37 this._updatePlaceholder(); |
| 38 this._stopEditing(); |
| 39 } |
| 40 |
| 41 /** |
| 42 * @param {*} item |
| 43 * @param {boolean} editable |
| 44 */ |
| 45 appendItem(item, editable) { |
| 46 if (this._lastSeparator && this._items.length) |
| 47 this._list.appendChild(createElementWithClass('div', 'list-separator')); |
| 48 this._lastSeparator = false; |
| 49 |
| 50 this._items.push(item); |
| 51 this._editable.push(editable); |
| 52 |
| 53 var element = this._list.createChild('div', 'list-item'); |
| 54 element.appendChild(this._delegate.renderItem(item, editable)); |
| 55 if (editable) { |
| 56 element.classList.add('editable'); |
| 57 element.appendChild(this._createControls(item, element)); |
| 58 } |
| 59 this._elements.push(element); |
| 60 this._updatePlaceholder(); |
| 61 } |
| 62 |
| 63 appendSeparator() { |
| 64 this._lastSeparator = true; |
| 65 } |
| 66 |
| 67 /** |
| 68 * @param {number} index |
| 69 */ |
| 70 removeItem(index) { |
| 71 if (this._editItem === this._items[index]) |
| 72 this._stopEditing(); |
| 73 |
| 74 var element = this._elements[index]; |
| 75 |
| 76 var previous = element.previousElementSibling; |
| 77 var previousIsSeparator = previous && previous.classList.contains('list-sepa
rator'); |
| 78 |
| 79 var next = element.nextElementSibling; |
| 80 var nextIsSeparator = next && next.classList.contains('list-separator'); |
| 81 |
| 82 if (previousIsSeparator && (nextIsSeparator || !next)) |
| 83 previous.remove(); |
| 84 if (nextIsSeparator && !previous) |
| 85 next.remove(); |
| 86 element.remove(); |
| 87 |
| 88 this._elements.splice(index, 1); |
| 89 this._items.splice(index, 1); |
| 90 this._editable.splice(index, 1); |
| 91 this._updatePlaceholder(); |
| 92 } |
| 93 |
| 94 /** |
| 95 * @param {number} index |
| 96 * @param {*} item |
| 97 */ |
| 98 addNewItem(index, item) { |
| 99 this._startEditing(item, null, this._elements[index] || null); |
| 100 } |
| 101 |
| 102 /** |
| 103 * @param {?Element} element |
| 104 */ |
| 105 setEmptyPlaceholder(element) { |
| 106 this._emptyPlaceholder = element; |
| 107 this._updatePlaceholder(); |
| 108 } |
| 109 |
| 110 /** |
| 111 * @param {*} item |
| 112 * @param {!Element} element |
| 113 * @return {!Element} |
| 114 */ |
| 115 _createControls(item, element) { |
| 116 var controls = createElementWithClass('div', 'controls-container fill'); |
| 117 var gradient = controls.createChild('div', 'controls-gradient'); |
| 118 var buttons = controls.createChild('div', 'controls-buttons'); |
| 119 |
| 120 var editButton = buttons.createChild('div', 'edit-button'); |
| 121 editButton.title = WebInspector.UIString('Edit'); |
| 122 editButton.addEventListener('click', onEditClicked.bind(this), false); |
| 123 |
| 124 var removeButton = buttons.createChild('div', 'remove-button'); |
| 125 removeButton.title = WebInspector.UIString('Remove'); |
| 126 removeButton.addEventListener('click', onRemoveClicked.bind(this), false); |
| 127 |
| 128 return controls; |
| 129 |
| 130 /** |
| 131 * @param {!Event} event |
| 132 * @this {WebInspector.ListWidget} |
| 133 */ |
| 134 function onEditClicked(event) { |
| 135 event.consume(); |
| 136 var index = this._elements.indexOf(element); |
| 137 var insertionPoint = this._elements[index + 1] || null; |
| 138 this._startEditing(item, element, insertionPoint); |
| 139 } |
| 140 |
| 141 /** |
| 142 * @param {!Event} event |
| 143 * @this {WebInspector.ListWidget} |
| 144 */ |
| 145 function onRemoveClicked(event) { |
| 146 event.consume(); |
| 147 var index = this._elements.indexOf(element); |
| 148 this._delegate.removeItemRequested(this._items[index], index); |
| 149 } |
| 150 } |
| 151 |
| 152 /** |
| 153 * @override |
| 154 */ |
| 155 wasShown() { |
| 156 super.wasShown(); |
| 157 this._stopEditing(); |
| 158 } |
| 159 |
| 160 _updatePlaceholder() { |
| 161 if (!this._emptyPlaceholder) |
| 162 return; |
| 163 |
| 164 if (!this._elements.length && !this._editor) |
| 165 this._list.appendChild(this._emptyPlaceholder); |
| 166 else |
| 167 this._emptyPlaceholder.remove(); |
| 168 } |
| 169 |
| 170 /** |
| 171 * @param {*} item |
| 172 * @param {?Element} element |
| 173 * @param {?Element} insertionPoint |
| 174 */ |
| 175 _startEditing(item, element, insertionPoint) { |
| 176 if (element && this._editElement === element) |
| 177 return; |
| 178 |
| 179 this._stopEditing(); |
| 180 |
| 181 this._list.classList.add('list-editing'); |
| 182 this._editItem = item; |
| 183 this._editElement = element; |
| 184 if (element) |
| 185 element.classList.add('hidden'); |
| 186 |
| 187 var index = element ? this._elements.indexOf(element) : -1; |
| 188 this._editor = this._delegate.beginEdit(item); |
| 189 this._updatePlaceholder(); |
| 190 this._list.insertBefore(this._editor.element, insertionPoint); |
| 191 this._editor.beginEdit( |
| 192 item, index, element ? WebInspector.UIString('Save') : WebInspector.UISt
ring('Add'), |
| 193 this._commitEditing.bind(this), this._stopEditing.bind(this)); |
| 194 } |
| 195 |
| 196 _commitEditing() { |
| 197 var editItem = this._editItem; |
| 198 var isNew = !this._editElement; |
| 199 var editor = /** @type {!WebInspector.ListWidget.Editor} */ (this._editor); |
| 200 this._stopEditing(); |
| 201 this._delegate.commitEdit(editItem, editor, isNew); |
| 202 } |
| 203 |
| 204 _stopEditing() { |
| 205 this._list.classList.remove('list-editing'); |
| 206 if (this._editElement) |
| 207 this._editElement.classList.remove('hidden'); |
| 208 if (this._editor && this._editor.element.parentElement) |
| 209 this._editor.element.remove(); |
| 210 |
| 211 this._editor = null; |
| 212 this._editItem = null; |
| 213 this._editElement = null; |
| 214 this._updatePlaceholder(); |
| 215 } |
29 }; | 216 }; |
30 | 217 |
31 /** | 218 /** |
32 * @interface | 219 * @interface |
33 */ | 220 */ |
34 WebInspector.ListWidget.Delegate = function() | 221 WebInspector.ListWidget.Delegate = function() {}; |
35 { | 222 |
| 223 WebInspector.ListWidget.Delegate.prototype = { |
| 224 /** |
| 225 * @param {*} item |
| 226 * @param {boolean} editable |
| 227 * @return {!Element} |
| 228 */ |
| 229 renderItem: function(item, editable) {}, |
| 230 |
| 231 /** |
| 232 * @param {*} item |
| 233 * @param {number} index |
| 234 */ |
| 235 removeItemRequested: function(item, index) {}, |
| 236 |
| 237 /** |
| 238 * @param {*} item |
| 239 * @return {!WebInspector.ListWidget.Editor} |
| 240 */ |
| 241 beginEdit: function(item) {}, |
| 242 |
| 243 /** |
| 244 * @param {*} item |
| 245 * @param {!WebInspector.ListWidget.Editor} editor |
| 246 * @param {boolean} isNew |
| 247 */ |
| 248 commitEdit: function(item, editor, isNew) {} |
36 }; | 249 }; |
37 | 250 |
38 WebInspector.ListWidget.Delegate.prototype = { | 251 /** |
| 252 * @unrestricted |
| 253 */ |
| 254 WebInspector.ListWidget.Editor = class { |
| 255 constructor() { |
| 256 this.element = createElementWithClass('div', 'editor-container'); |
| 257 this.element.addEventListener('keydown', onKeyDown.bind(null, isEscKey, this
._cancelClicked.bind(this)), false); |
| 258 this.element.addEventListener('keydown', onKeyDown.bind(null, isEnterKey, th
is._commitClicked.bind(this)), false); |
| 259 |
| 260 this._contentElement = this.element.createChild('div', 'editor-content'); |
| 261 |
| 262 var buttonsRow = this.element.createChild('div', 'editor-buttons'); |
| 263 this._commitButton = createTextButton('', this._commitClicked.bind(this)); |
| 264 buttonsRow.appendChild(this._commitButton); |
| 265 this._cancelButton = createTextButton(WebInspector.UIString('Cancel'), this.
_cancelClicked.bind(this)); |
| 266 this._cancelButton.addEventListener( |
| 267 'keydown', onKeyDown.bind(null, isEnterKey, this._cancelClicked.bind(thi
s)), false); |
| 268 buttonsRow.appendChild(this._cancelButton); |
| 269 |
39 /** | 270 /** |
40 * @param {*} item | |
41 * @param {boolean} editable | |
42 * @return {!Element} | |
43 */ | |
44 renderItem: function(item, editable) { }, | |
45 | |
46 /** | |
47 * @param {*} item | |
48 * @param {number} index | |
49 */ | |
50 removeItemRequested: function(item, index) { }, | |
51 | |
52 /** | |
53 * @param {*} item | |
54 * @return {!WebInspector.ListWidget.Editor} | |
55 */ | |
56 beginEdit: function(item) { }, | |
57 | |
58 /** | |
59 * @param {*} item | |
60 * @param {!WebInspector.ListWidget.Editor} editor | |
61 * @param {boolean} isNew | |
62 */ | |
63 commitEdit: function(item, editor, isNew) { } | |
64 }; | |
65 | |
66 WebInspector.ListWidget.prototype = { | |
67 clear: function() | |
68 { | |
69 this._items = []; | |
70 this._editable = []; | |
71 this._elements = []; | |
72 this._lastSeparator = false; | |
73 this._list.removeChildren(); | |
74 this._updatePlaceholder(); | |
75 this._stopEditing(); | |
76 }, | |
77 | |
78 /** | |
79 * @param {*} item | |
80 * @param {boolean} editable | |
81 */ | |
82 appendItem: function(item, editable) | |
83 { | |
84 if (this._lastSeparator && this._items.length) | |
85 this._list.appendChild(createElementWithClass("div", "list-separator
")); | |
86 this._lastSeparator = false; | |
87 | |
88 this._items.push(item); | |
89 this._editable.push(editable); | |
90 | |
91 var element = this._list.createChild("div", "list-item"); | |
92 element.appendChild(this._delegate.renderItem(item, editable)); | |
93 if (editable) { | |
94 element.classList.add("editable"); | |
95 element.appendChild(this._createControls(item, element)); | |
96 } | |
97 this._elements.push(element); | |
98 this._updatePlaceholder(); | |
99 }, | |
100 | |
101 appendSeparator: function() | |
102 { | |
103 this._lastSeparator = true; | |
104 }, | |
105 | |
106 /** | |
107 * @param {number} index | |
108 */ | |
109 removeItem: function(index) | |
110 { | |
111 if (this._editItem === this._items[index]) | |
112 this._stopEditing(); | |
113 | |
114 var element = this._elements[index]; | |
115 | |
116 var previous = element.previousElementSibling; | |
117 var previousIsSeparator = previous && previous.classList.contains("list-
separator"); | |
118 | |
119 var next = element.nextElementSibling; | |
120 var nextIsSeparator = next && next.classList.contains("list-separator"); | |
121 | |
122 if (previousIsSeparator && (nextIsSeparator || !next)) | |
123 previous.remove(); | |
124 if (nextIsSeparator && !previous) | |
125 next.remove(); | |
126 element.remove(); | |
127 | |
128 this._elements.splice(index, 1); | |
129 this._items.splice(index, 1); | |
130 this._editable.splice(index, 1); | |
131 this._updatePlaceholder(); | |
132 }, | |
133 | |
134 /** | |
135 * @param {number} index | |
136 * @param {*} item | |
137 */ | |
138 addNewItem: function(index, item) | |
139 { | |
140 this._startEditing(item, null, this._elements[index] || null); | |
141 }, | |
142 | |
143 /** | |
144 * @param {?Element} element | |
145 */ | |
146 setEmptyPlaceholder: function(element) | |
147 { | |
148 this._emptyPlaceholder = element; | |
149 this._updatePlaceholder(); | |
150 }, | |
151 | |
152 /** | |
153 * @param {*} item | |
154 * @param {!Element} element | |
155 * @return {!Element} | |
156 */ | |
157 _createControls: function(item, element) | |
158 { | |
159 var controls = createElementWithClass("div", "controls-container fill"); | |
160 var gradient = controls.createChild("div", "controls-gradient"); | |
161 var buttons = controls.createChild("div", "controls-buttons"); | |
162 | |
163 var editButton = buttons.createChild("div", "edit-button"); | |
164 editButton.title = WebInspector.UIString("Edit"); | |
165 editButton.addEventListener("click", onEditClicked.bind(this), false); | |
166 | |
167 var removeButton = buttons.createChild("div", "remove-button"); | |
168 removeButton.title = WebInspector.UIString("Remove"); | |
169 removeButton.addEventListener("click", onRemoveClicked.bind(this), false
); | |
170 | |
171 return controls; | |
172 | |
173 /** | |
174 * @param {!Event} event | |
175 * @this {WebInspector.ListWidget} | |
176 */ | |
177 function onEditClicked(event) | |
178 { | |
179 event.consume(); | |
180 var index = this._elements.indexOf(element); | |
181 var insertionPoint = this._elements[index + 1] || null; | |
182 this._startEditing(item, element, insertionPoint); | |
183 } | |
184 | |
185 /** | |
186 * @param {!Event} event | |
187 * @this {WebInspector.ListWidget} | |
188 */ | |
189 function onRemoveClicked(event) | |
190 { | |
191 event.consume(); | |
192 var index = this._elements.indexOf(element); | |
193 this._delegate.removeItemRequested(this._items[index], index); | |
194 } | |
195 }, | |
196 | |
197 wasShown: function() | |
198 { | |
199 WebInspector.VBox.prototype.wasShown.call(this); | |
200 this._stopEditing(); | |
201 }, | |
202 | |
203 _updatePlaceholder: function() | |
204 { | |
205 if (!this._emptyPlaceholder) | |
206 return; | |
207 | |
208 if (!this._elements.length && !this._editor) | |
209 this._list.appendChild(this._emptyPlaceholder); | |
210 else | |
211 this._emptyPlaceholder.remove(); | |
212 }, | |
213 | |
214 /** | |
215 * @param {*} item | |
216 * @param {?Element} element | |
217 * @param {?Element} insertionPoint | |
218 */ | |
219 _startEditing: function(item, element, insertionPoint) | |
220 { | |
221 if (element && this._editElement === element) | |
222 return; | |
223 | |
224 this._stopEditing(); | |
225 | |
226 this._list.classList.add("list-editing"); | |
227 this._editItem = item; | |
228 this._editElement = element; | |
229 if (element) | |
230 element.classList.add("hidden"); | |
231 | |
232 var index = element ? this._elements.indexOf(element) : -1; | |
233 this._editor = this._delegate.beginEdit(item); | |
234 this._updatePlaceholder(); | |
235 this._list.insertBefore(this._editor.element, insertionPoint); | |
236 this._editor.beginEdit(item, index, element ? WebInspector.UIString("Sav
e") : WebInspector.UIString("Add"), this._commitEditing.bind(this), this._stopEd
iting.bind(this)); | |
237 }, | |
238 | |
239 _commitEditing: function() | |
240 { | |
241 var editItem = this._editItem; | |
242 var isNew = !this._editElement; | |
243 var editor = /** @type {!WebInspector.ListWidget.Editor} */ (this._edito
r); | |
244 this._stopEditing(); | |
245 this._delegate.commitEdit(editItem, editor, isNew); | |
246 }, | |
247 | |
248 _stopEditing: function() | |
249 { | |
250 this._list.classList.remove("list-editing"); | |
251 if (this._editElement) | |
252 this._editElement.classList.remove("hidden"); | |
253 if (this._editor && this._editor.element.parentElement) | |
254 this._editor.element.remove(); | |
255 | |
256 this._editor = null; | |
257 this._editItem = null; | |
258 this._editElement = null; | |
259 this._updatePlaceholder(); | |
260 }, | |
261 | |
262 __proto__: WebInspector.VBox.prototype | |
263 }; | |
264 | |
265 /** | |
266 * @constructor | |
267 */ | |
268 WebInspector.ListWidget.Editor = function() | |
269 { | |
270 this.element = createElementWithClass("div", "editor-container"); | |
271 this.element.addEventListener("keydown", onKeyDown.bind(null, isEscKey, this
._cancelClicked.bind(this)), false); | |
272 this.element.addEventListener("keydown", onKeyDown.bind(null, isEnterKey, th
is._commitClicked.bind(this)), false); | |
273 | |
274 this._contentElement = this.element.createChild("div", "editor-content"); | |
275 | |
276 var buttonsRow = this.element.createChild("div", "editor-buttons"); | |
277 this._commitButton = createTextButton("", this._commitClicked.bind(this)); | |
278 buttonsRow.appendChild(this._commitButton); | |
279 this._cancelButton = createTextButton(WebInspector.UIString("Cancel"), this.
_cancelClicked.bind(this)); | |
280 this._cancelButton.addEventListener("keydown", onKeyDown.bind(null, isEnterK
ey, this._cancelClicked.bind(this)), false); | |
281 buttonsRow.appendChild(this._cancelButton); | |
282 | |
283 /** | |
284 * @param {function(!Event):boolean} predicate | 271 * @param {function(!Event):boolean} predicate |
285 * @param {function()} callback | 272 * @param {function()} callback |
286 * @param {!Event} event | 273 * @param {!Event} event |
287 */ | 274 */ |
288 function onKeyDown(predicate, callback, event) | 275 function onKeyDown(predicate, callback, event) { |
289 { | 276 if (predicate(event)) { |
290 if (predicate(event)) { | 277 event.consume(true); |
291 event.consume(true); | 278 callback(); |
292 callback(); | 279 } |
293 } | |
294 } | 280 } |
295 | 281 |
296 /** @type {!Array<!HTMLInputElement|!HTMLSelectElement>} */ | 282 /** @type {!Array<!HTMLInputElement|!HTMLSelectElement>} */ |
297 this._controls = []; | 283 this._controls = []; |
298 /** @type {!Map<string, !HTMLInputElement|!HTMLSelectElement>} */ | 284 /** @type {!Map<string, !HTMLInputElement|!HTMLSelectElement>} */ |
299 this._controlByName = new Map(); | 285 this._controlByName = new Map(); |
300 /** @type {!Array<function(*, number, (!HTMLInputElement|!HTMLSelectElement)
):boolean>} */ | 286 /** @type {!Array<function(*, number, (!HTMLInputElement|!HTMLSelectElement)
):boolean>} */ |
301 this._validators = []; | 287 this._validators = []; |
302 | 288 |
303 /** @type {?function()} */ | 289 /** @type {?function()} */ |
304 this._commit = null; | 290 this._commit = null; |
305 /** @type {?function()} */ | 291 /** @type {?function()} */ |
306 this._cancel = null; | 292 this._cancel = null; |
307 /** @type {*|null} */ | 293 /** @type {*|null} */ |
308 this._item = null; | 294 this._item = null; |
309 /** @type {number} */ | 295 /** @type {number} */ |
310 this._index = -1; | 296 this._index = -1; |
| 297 } |
| 298 |
| 299 /** |
| 300 * @return {!Element} |
| 301 */ |
| 302 contentElement() { |
| 303 return this._contentElement; |
| 304 } |
| 305 |
| 306 /** |
| 307 * @param {string} name |
| 308 * @param {string} type |
| 309 * @param {string} title |
| 310 * @param {function(*, number, (!HTMLInputElement|!HTMLSelectElement)):boolean
} validator |
| 311 * @return {!HTMLInputElement} |
| 312 */ |
| 313 createInput(name, type, title, validator) { |
| 314 var input = /** @type {!HTMLInputElement} */ (createElement('input')); |
| 315 input.type = type; |
| 316 input.placeholder = title; |
| 317 input.addEventListener('input', this._validateControls.bind(this, false), fa
lse); |
| 318 input.addEventListener('blur', this._validateControls.bind(this, false), fal
se); |
| 319 this._controlByName.set(name, input); |
| 320 this._controls.push(input); |
| 321 this._validators.push(validator); |
| 322 return input; |
| 323 } |
| 324 |
| 325 /** |
| 326 * @param {string} name |
| 327 * @param {!Array<string>} options |
| 328 * @param {function(*, number, (!HTMLInputElement|!HTMLSelectElement)):boolean
} validator |
| 329 * @return {!HTMLSelectElement} |
| 330 */ |
| 331 createSelect(name, options, validator) { |
| 332 var select = /** @type {!HTMLSelectElement} */ (createElementWithClass('sele
ct', 'chrome-select')); |
| 333 for (var index = 0; index < options.length; ++index) { |
| 334 var option = select.createChild('option'); |
| 335 option.value = options[index]; |
| 336 option.textContent = options[index]; |
| 337 } |
| 338 select.addEventListener('input', this._validateControls.bind(this, false), f
alse); |
| 339 select.addEventListener('blur', this._validateControls.bind(this, false), fa
lse); |
| 340 this._controlByName.set(name, select); |
| 341 this._controls.push(select); |
| 342 this._validators.push(validator); |
| 343 return select; |
| 344 } |
| 345 |
| 346 /** |
| 347 * @param {string} name |
| 348 * @return {!HTMLInputElement|!HTMLSelectElement} |
| 349 */ |
| 350 control(name) { |
| 351 return /** @type {!HTMLInputElement|!HTMLSelectElement} */ (this._controlByN
ame.get(name)); |
| 352 } |
| 353 |
| 354 /** |
| 355 * @param {boolean} forceValid |
| 356 */ |
| 357 _validateControls(forceValid) { |
| 358 var allValid = true; |
| 359 for (var index = 0; index < this._controls.length; ++index) { |
| 360 var input = this._controls[index]; |
| 361 var valid = this._validators[index].call(null, this._item, this._index, in
put); |
| 362 input.classList.toggle('error-input', !valid && !forceValid); |
| 363 allValid &= valid; |
| 364 } |
| 365 this._commitButton.disabled = !allValid; |
| 366 } |
| 367 |
| 368 /** |
| 369 * @param {*} item |
| 370 * @param {number} index |
| 371 * @param {string} commitButtonTitle |
| 372 * @param {function()} commit |
| 373 * @param {function()} cancel |
| 374 */ |
| 375 beginEdit(item, index, commitButtonTitle, commit, cancel) { |
| 376 this._commit = commit; |
| 377 this._cancel = cancel; |
| 378 this._item = item; |
| 379 this._index = index; |
| 380 |
| 381 this._commitButton.textContent = commitButtonTitle; |
| 382 this.element.scrollIntoViewIfNeeded(false); |
| 383 if (this._controls.length) |
| 384 this._controls[0].focus(); |
| 385 this._validateControls(true); |
| 386 } |
| 387 |
| 388 _commitClicked() { |
| 389 if (this._commitButton.disabled) |
| 390 return; |
| 391 |
| 392 var commit = this._commit; |
| 393 this._commit = null; |
| 394 this._cancel = null; |
| 395 this._item = null; |
| 396 this._index = -1; |
| 397 commit(); |
| 398 } |
| 399 |
| 400 _cancelClicked() { |
| 401 var cancel = this._cancel; |
| 402 this._commit = null; |
| 403 this._cancel = null; |
| 404 this._item = null; |
| 405 this._index = -1; |
| 406 cancel(); |
| 407 } |
311 }; | 408 }; |
312 | |
313 WebInspector.ListWidget.Editor.prototype = { | |
314 /** | |
315 * @return {!Element} | |
316 */ | |
317 contentElement: function() | |
318 { | |
319 return this._contentElement; | |
320 }, | |
321 | |
322 /** | |
323 * @param {string} name | |
324 * @param {string} type | |
325 * @param {string} title | |
326 * @param {function(*, number, (!HTMLInputElement|!HTMLSelectElement)):boole
an} validator | |
327 * @return {!HTMLInputElement} | |
328 */ | |
329 createInput: function(name, type, title, validator) | |
330 { | |
331 var input = /** @type {!HTMLInputElement} */ (createElement("input")); | |
332 input.type = type; | |
333 input.placeholder = title; | |
334 input.addEventListener("input", this._validateControls.bind(this, false)
, false); | |
335 input.addEventListener("blur", this._validateControls.bind(this, false),
false); | |
336 this._controlByName.set(name, input); | |
337 this._controls.push(input); | |
338 this._validators.push(validator); | |
339 return input; | |
340 }, | |
341 | |
342 /** | |
343 * @param {string} name | |
344 * @param {!Array<string>} options | |
345 * @param {function(*, number, (!HTMLInputElement|!HTMLSelectElement)):boole
an} validator | |
346 * @return {!HTMLSelectElement} | |
347 */ | |
348 createSelect: function(name, options, validator) | |
349 { | |
350 var select = /** @type {!HTMLSelectElement} */ (createElementWithClass("
select", "chrome-select")); | |
351 for (var index = 0; index < options.length; ++index) { | |
352 var option = select.createChild("option"); | |
353 option.value = options[index]; | |
354 option.textContent = options[index]; | |
355 } | |
356 select.addEventListener("input", this._validateControls.bind(this, false
), false); | |
357 select.addEventListener("blur", this._validateControls.bind(this, false)
, false); | |
358 this._controlByName.set(name, select); | |
359 this._controls.push(select); | |
360 this._validators.push(validator); | |
361 return select; | |
362 }, | |
363 | |
364 /** | |
365 * @param {string} name | |
366 * @return {!HTMLInputElement|!HTMLSelectElement} | |
367 */ | |
368 control: function(name) | |
369 { | |
370 return /** @type {!HTMLInputElement|!HTMLSelectElement} */ (this._contro
lByName.get(name)); | |
371 }, | |
372 | |
373 /** | |
374 * @param {boolean} forceValid | |
375 */ | |
376 _validateControls: function(forceValid) | |
377 { | |
378 var allValid = true; | |
379 for (var index = 0; index < this._controls.length; ++index) { | |
380 var input = this._controls[index]; | |
381 var valid = this._validators[index].call(null, this._item, this._ind
ex, input); | |
382 input.classList.toggle("error-input", !valid && !forceValid); | |
383 allValid &= valid; | |
384 } | |
385 this._commitButton.disabled = !allValid; | |
386 }, | |
387 | |
388 /** | |
389 * @param {*} item | |
390 * @param {number} index | |
391 * @param {string} commitButtonTitle | |
392 * @param {function()} commit | |
393 * @param {function()} cancel | |
394 */ | |
395 beginEdit: function(item, index, commitButtonTitle, commit, cancel) | |
396 { | |
397 this._commit = commit; | |
398 this._cancel = cancel; | |
399 this._item = item; | |
400 this._index = index; | |
401 | |
402 this._commitButton.textContent = commitButtonTitle; | |
403 this.element.scrollIntoViewIfNeeded(false); | |
404 if (this._controls.length) | |
405 this._controls[0].focus(); | |
406 this._validateControls(true); | |
407 }, | |
408 | |
409 _commitClicked: function() | |
410 { | |
411 if (this._commitButton.disabled) | |
412 return; | |
413 | |
414 var commit = this._commit; | |
415 this._commit = null; | |
416 this._cancel = null; | |
417 this._item = null; | |
418 this._index = -1; | |
419 commit(); | |
420 }, | |
421 | |
422 _cancelClicked: function() | |
423 { | |
424 var cancel = this._cancel; | |
425 this._commit = null; | |
426 this._cancel = null; | |
427 this._item = null; | |
428 this._index = -1; | |
429 cancel(); | |
430 } | |
431 }; | |
OLD | NEW |