| 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 |