OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 | 4 |
5 cr.define('options', function() { | 5 cr.define('options', function() { |
6 const DeletableItem = options.DeletableItem; | 6 const DeletableItem = options.DeletableItem; |
7 const DeletableItemList = options.DeletableItemList; | 7 const DeletableItemList = options.DeletableItemList; |
8 | 8 |
9 /** | 9 /** |
10 * Creates a new list item with support for inline editing. | 10 * Creates a new list item with support for inline editing. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // When this is called in response to the selectedChange event, | 83 // When this is called in response to the selectedChange event, |
84 // the list grabs focus immediately afterwards. Thus we must delay | 84 // the list grabs focus immediately afterwards. Thus we must delay |
85 // our focus grab. | 85 // our focus grab. |
86 if (focusElement) { | 86 if (focusElement) { |
87 window.setTimeout(function() { | 87 window.setTimeout(function() { |
88 focusElement.focus(); | 88 focusElement.focus(); |
89 focusElement.select(); | 89 focusElement.select(); |
90 }, 50); | 90 }, 50); |
91 } | 91 } |
92 } else { | 92 } else { |
93 if (!this.editCancelled_ && this.hasBeenEdited() && | 93 if (!this.editCancelled_ && this.hasBeenEdited && |
94 this.currentInputIsValid) { | 94 this.currentInputIsValid) { |
| 95 this.updateStaticValues_(); |
95 cr.dispatchSimpleEvent(this, 'commitedit', true); | 96 cr.dispatchSimpleEvent(this, 'commitedit', true); |
96 } else { | 97 } else { |
| 98 this.resetEditableValues_(); |
97 cr.dispatchSimpleEvent(this, 'canceledit', true); | 99 cr.dispatchSimpleEvent(this, 'canceledit', true); |
98 } | 100 } |
99 } | 101 } |
100 }, | 102 }, |
101 | 103 |
102 /** | 104 /** |
103 * Whether the item is editable. | 105 * Whether the item is editable. |
104 * @type {boolean} | 106 * @type {boolean} |
105 */ | 107 */ |
106 get editable() { | 108 get editable() { |
107 return this.editable_; | 109 return this.editable_; |
108 }, | 110 }, |
109 set editable(editable) { | 111 set editable(editable) { |
110 this.editable_ = editable; | 112 this.editable_ = editable; |
111 if (!editable) | 113 if (!editable) |
112 this.editing = false; | 114 this.editing = false; |
113 }, | 115 }, |
114 | 116 |
115 /** | 117 /** |
116 * The HTML element that should have focus initially when editing starts. | 118 * The HTML element that should have focus initially when editing starts. |
117 * Should be overriden by subclasses. | 119 * Defaults to the first <input> element; can be overriden by subclasses if |
| 120 * a different element should be focused. |
118 * @type {HTMLElement} | 121 * @type {HTMLElement} |
119 */ | 122 */ |
120 get initialFocusElement() { | 123 get initialFocusElement() { |
121 return null; | 124 return this.contentElement.querySelector('input'); |
122 }, | 125 }, |
123 | 126 |
124 /** | 127 /** |
125 * Whether the input in currently valid to submit. If this returns false | 128 * Whether the input in currently valid to submit. If this returns false |
126 * when editing would be submitted, either editing will not be ended, | 129 * when editing would be submitted, either editing will not be ended, |
127 * or it will be cancelled, depending on the context. | 130 * or it will be cancelled, depending on the context. |
128 * Can be overrided by subclasses to perform input validation. | 131 * Can be overrided by subclasses to perform input validation. |
| 132 * @type {boolean} |
129 */ | 133 */ |
130 get currentInputIsValid() { | 134 get currentInputIsValid() { |
131 return true; | 135 return true; |
132 }, | 136 }, |
133 | 137 |
134 /** | 138 /** |
135 * Returns true if the item has been changed by an edit. | 139 * Returns true if the item has been changed by an edit. |
136 * Can be overrided by subclasses to return false when nothing has changed | 140 * Can be overrided by subclasses to return false when nothing has changed |
137 * to avoid unnecessary commits. | 141 * to avoid unnecessary commits. |
| 142 * @type {boolean} |
138 */ | 143 */ |
139 hasBeenEdited: function() { | 144 get hasBeenEdited() { |
140 return true; | 145 return true; |
141 }, | 146 }, |
142 | 147 |
143 /** | 148 /** |
| 149 * Returns a div containing an <input>, as well as static text if |
| 150 * opt_alwaysEditable is not true. |
| 151 * @param {string} text The text of the cell. |
| 152 * @param {bool} opt_alwaysEditable True if the cell always shows the input. |
| 153 * @return {HTMLElement} The HTML element for the cell. |
| 154 * @private |
| 155 */ |
| 156 createEditableTextCell: function(text, opt_alwaysEditable) { |
| 157 var container = this.ownerDocument.createElement('div'); |
| 158 |
| 159 if (!opt_alwaysEditable) { |
| 160 var textEl = this.ownerDocument.createElement('div'); |
| 161 textEl.className = 'static-text'; |
| 162 textEl.textContent = text; |
| 163 textEl.setAttribute('editmode', false); |
| 164 container.appendChild(textEl); |
| 165 } |
| 166 |
| 167 var inputEl = this.ownerDocument.createElement('input'); |
| 168 inputEl.type = 'text'; |
| 169 inputEl.value = text; |
| 170 if (!opt_alwaysEditable) { |
| 171 inputEl.setAttribute('editmode', true); |
| 172 inputEl.staticVersion = textEl; |
| 173 } |
| 174 container.appendChild(inputEl); |
| 175 |
| 176 return container; |
| 177 }, |
| 178 |
| 179 /** |
| 180 * Resets the editable version of any controls created by createEditable* |
| 181 * to match the static text. |
| 182 * @private |
| 183 */ |
| 184 resetEditableValues_: function() { |
| 185 var editFields = this.querySelectorAll('[editmode=true]'); |
| 186 for (var i = 0; i < editFields.length; i++) { |
| 187 var staticLabel = editFields[i].staticVersion; |
| 188 if (!staticLabel) |
| 189 continue; |
| 190 if (editFields[i].tagName == 'INPUT') |
| 191 editFields[i].value = staticLabel.textContent; |
| 192 // Add more tag types here as new createEditable* methods are added. |
| 193 |
| 194 editFields[i].setCustomValidity(''); |
| 195 } |
| 196 }, |
| 197 |
| 198 /** |
| 199 * Sets the static version of any controls created by createEditable* |
| 200 * to match the current value of the editable version. Called on commit so |
| 201 * that there's no flicker of the old value before the model updates. |
| 202 * @private |
| 203 */ |
| 204 updateStaticValues_: function() { |
| 205 var editFields = this.querySelectorAll('[editmode=true]'); |
| 206 for (var i = 0; i < editFields.length; i++) { |
| 207 var staticLabel = editFields[i].staticVersion; |
| 208 if (!staticLabel) |
| 209 continue; |
| 210 if (editFields[i].tagName == 'INPUT') |
| 211 staticLabel.textContent = editFields[i].value; |
| 212 // Add more tag types here as new createEditable* methods are added. |
| 213 } |
| 214 }, |
| 215 |
| 216 /** |
144 * Called a key is pressed. Handles committing and cancelling edits. | 217 * Called a key is pressed. Handles committing and cancelling edits. |
145 * @param {Event} e The key down event. | 218 * @param {Event} e The key down event. |
146 * @private | 219 * @private |
147 */ | 220 */ |
148 handleKeyDown_: function(e) { | 221 handleKeyDown_: function(e) { |
149 if (!this.editing) | 222 if (!this.editing) |
150 return; | 223 return; |
151 | 224 |
152 var endEdit = false; | 225 var endEdit = false; |
153 switch (e.keyIdentifier) { | 226 switch (e.keyIdentifier) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 }, 50); | 274 }, 50); |
202 }, | 275 }, |
203 }; | 276 }; |
204 | 277 |
205 // Export | 278 // Export |
206 return { | 279 return { |
207 InlineEditableItem: InlineEditableItem, | 280 InlineEditableItem: InlineEditableItem, |
208 InlineEditableItemList: InlineEditableItemList, | 281 InlineEditableItemList: InlineEditableItemList, |
209 }; | 282 }; |
210 }); | 283 }); |
OLD | NEW |