Chromium Code Reviews| 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.search_engines', function() { | 5 cr.define('options.search_engines', function() { |
| 6 const InlineEditableItemList = options.InlineEditableItemList; | 6 const InlineEditableItemList = options.InlineEditableItemList; |
| 7 const InlineEditableItem = options.InlineEditableItem; | 7 const InlineEditableItem = options.InlineEditableItem; |
| 8 const ListInlineHeaderSelectionController = | 8 const ListInlineHeaderSelectionController = |
| 9 options.ListInlineHeaderSelectionController; | 9 options.ListInlineHeaderSelectionController; |
| 10 | 10 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 // For non-heading rows, start with a favicon. | 116 // For non-heading rows, start with a favicon. |
| 117 if (!engine['heading']) { | 117 if (!engine['heading']) { |
| 118 var faviconDivEl = this.ownerDocument.createElement('div'); | 118 var faviconDivEl = this.ownerDocument.createElement('div'); |
| 119 faviconDivEl.className = 'favicon'; | 119 faviconDivEl.className = 'favicon'; |
| 120 var imgEl = this.ownerDocument.createElement('img'); | 120 var imgEl = this.ownerDocument.createElement('img'); |
| 121 imgEl.src = 'chrome://favicon/iconurl/' + engine['iconURL']; | 121 imgEl.src = 'chrome://favicon/iconurl/' + engine['iconURL']; |
| 122 faviconDivEl.appendChild(imgEl); | 122 faviconDivEl.appendChild(imgEl); |
| 123 nameColEl.appendChild(faviconDivEl); | 123 nameColEl.appendChild(faviconDivEl); |
| 124 } | 124 } |
| 125 | 125 |
| 126 var nameEl = this.createEditableTextCell_(nameText); | 126 var nameEl = this.createEditableTextCell(nameText, this.isPlaceholder_); |
| 127 nameColEl.appendChild(nameEl); | 127 nameColEl.appendChild(nameEl); |
| 128 | 128 |
| 129 // Then the keyword column. | 129 // Then the keyword column. |
| 130 var keywordEl = this.createEditableTextCell_(keywordText); | 130 var keywordEl = this.createEditableTextCell(keywordText, |
| 131 this.isPlaceholder_); | |
| 131 keywordEl.className = 'keyword-column'; | 132 keywordEl.className = 'keyword-column'; |
| 132 this.contentElement.appendChild(keywordEl); | 133 this.contentElement.appendChild(keywordEl); |
| 133 | 134 |
| 134 // And the URL column. | 135 // And the URL column. |
| 135 var urlEl = this.createEditableTextCell_(urlText); | 136 var urlEl = this.createEditableTextCell(urlText, this.isPlaceholder_); |
| 136 urlEl.className = 'url-column'; | 137 urlEl.className = 'url-column'; |
| 137 this.contentElement.appendChild(urlEl); | 138 this.contentElement.appendChild(urlEl); |
| 138 | 139 |
| 139 // Do final adjustment to the input fields. | 140 // Do final adjustment to the input fields. |
| 140 if (!engine['heading']) { | 141 if (!engine['heading']) { |
| 141 this.nameField_ = nameEl.querySelector('input'); | 142 this.nameField_ = nameEl.querySelector('input'); |
| 142 this.keywordField_ = keywordEl.querySelector('input'); | 143 this.keywordField_ = keywordEl.querySelector('input'); |
| 143 this.urlField_ = urlEl.querySelector('input'); | 144 this.urlField_ = urlEl.querySelector('input'); |
| 144 | 145 |
| 145 if (engine['urlLocked']) | 146 if (engine['urlLocked']) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 159 fields[i].oninput = this.startFieldValidation_.bind(this); | 160 fields[i].oninput = this.startFieldValidation_.bind(this); |
| 160 } | 161 } |
| 161 } | 162 } |
| 162 | 163 |
| 163 // Listen for edit events. | 164 // Listen for edit events. |
| 164 this.addEventListener('edit', this.onEditStarted_.bind(this)); | 165 this.addEventListener('edit', this.onEditStarted_.bind(this)); |
| 165 this.addEventListener('canceledit', this.onEditCancelled_.bind(this)); | 166 this.addEventListener('canceledit', this.onEditCancelled_.bind(this)); |
| 166 this.addEventListener('commitedit', this.onEditCommitted_.bind(this)); | 167 this.addEventListener('commitedit', this.onEditCommitted_.bind(this)); |
| 167 }, | 168 }, |
| 168 | 169 |
| 169 /** | |
| 170 * Returns a div containing an <input>, as well as static text if needed. | |
| 171 * @param {string} text The text of the cell. | |
| 172 * @return {HTMLElement} The HTML element for the cell. | |
| 173 * @private | |
| 174 */ | |
| 175 createEditableTextCell_: function(text) { | |
| 176 var container = this.ownerDocument.createElement('div'); | |
| 177 | |
| 178 if (!this.isPlaceholder_) { | |
| 179 var textEl = this.ownerDocument.createElement('div'); | |
| 180 textEl.className = 'static-text'; | |
| 181 textEl.textContent = text; | |
| 182 textEl.setAttribute('editmode', false); | |
| 183 container.appendChild(textEl); | |
| 184 } | |
| 185 | |
| 186 var inputEl = this.ownerDocument.createElement('input'); | |
| 187 inputEl.type = 'text'; | |
| 188 inputEl.value = text; | |
| 189 if (!this.isPlaceholder_) { | |
| 190 inputEl.setAttribute('editmode', true); | |
| 191 inputEl.staticVersion = textEl; | |
| 192 } | |
| 193 container.appendChild(inputEl); | |
| 194 | |
| 195 return container; | |
| 196 }, | |
| 197 | |
| 198 /** @inheritDoc */ | |
| 199 get initialFocusElement() { | |
| 200 return this.nameField_; | |
| 201 }, | |
| 202 | |
| 203 /** @inheritDoc */ | 170 /** @inheritDoc */ |
| 204 get currentInputIsValid() { | 171 get currentInputIsValid() { |
| 205 return !this.waitingForValidation_ && this.currentlyValid_; | 172 return !this.waitingForValidation_ && this.currentlyValid_; |
| 206 }, | 173 }, |
| 207 | 174 |
| 208 /** @inheritDoc */ | 175 /** @inheritDoc */ |
| 209 hasBeenEdited: function(e) { | 176 get hasBeenEdited() { |
| 210 var engine = this.searchEngine_; | 177 var engine = this.searchEngine_; |
| 211 return this.nameField_.value != engine['name'] || | 178 return this.nameField_.value != engine['name'] || |
| 212 this.keywordField_.value != engine['keyword'] || | 179 this.keywordField_.value != engine['keyword'] || |
| 213 this.urlField_.value != engine['url']; | 180 this.urlField_.value != engine['url']; |
| 214 }, | 181 }, |
| 215 | 182 |
| 216 /** | 183 /** |
| 217 * Called when entering edit mode; starts an edit session in the model. | 184 * Called when entering edit mode; starts an edit session in the model. |
| 218 * @param {Event} e The edit event. | 185 * @param {Event} e The edit event. |
| 219 * @private | 186 * @private |
| 220 */ | 187 */ |
| 221 onEditStarted_: function(e) { | 188 onEditStarted_: function(e) { |
| 222 var editIndex = this.searchEngine_['modelIndex']; | 189 var editIndex = this.searchEngine_['modelIndex']; |
| 223 chrome.send('editSearchEngine', [String(editIndex)]); | 190 chrome.send('editSearchEngine', [String(editIndex)]); |
| 191 this.startFieldValidation_(); | |
| 224 }, | 192 }, |
| 225 | 193 |
| 226 /** | 194 /** |
| 227 * Called when committing an edit; updates the model. | 195 * Called when committing an edit; updates the model. |
| 228 * @param {Event} e The end event. | 196 * @param {Event} e The end event. |
| 229 * @private | 197 * @private |
| 230 */ | 198 */ |
| 231 onEditCommitted_: function(e) { | 199 onEditCommitted_: function(e) { |
| 232 chrome.send('searchEngineEditCompleted', this.getInputFieldValues_()); | 200 chrome.send('searchEngineEditCompleted', this.getInputFieldValues_()); |
| 233 // Update the static version immediately to prevent flickering before | |
| 234 // the model update callback updates the UI. | |
| 235 var editFields = [ this.nameField_, this.keywordField_, this.urlField_ ]; | |
| 236 for (var i = 0; i < editFields.length; i++) { | |
| 237 var staticLabel = editFields[i].staticVersion; | |
| 238 if (staticLabel) | |
| 239 staticLabel.textContent = editFields[i].value; | |
| 240 } | |
| 241 }, | 201 }, |
| 242 | 202 |
| 243 /** | 203 /** |
| 244 * Called when cancelling an edit; informs the model and resets the control | 204 * Called when cancelling an edit; informs the model and resets the control |
| 245 * states. | 205 * states. |
| 246 * @param {Event} e The cancel event. | 206 * @param {Event} e The cancel event. |
| 247 * @private | 207 * @private |
| 248 */ | 208 */ |
| 249 onEditCancelled_: function() { | 209 onEditCancelled_: function() { |
| 250 chrome.send('searchEngineEditCancelled'); | 210 chrome.send('searchEngineEditCancelled'); |
| 251 var engine = this.searchEngine_; | |
| 252 this.nameField_.value = engine['name']; | |
| 253 this.keywordField_.value = engine['keyword']; | |
| 254 this.urlField_.value = engine['url']; | |
| 255 | 211 |
| 256 var editFields = [ this.nameField_, this.keywordField_, this.urlField_ ]; | 212 if (this.isPlaceholder_) { |
| 257 for (var i = 0; i < editFields.length; i++) { | 213 var engine = this.searchEngine_; |
| 258 editFields[i].classList.remove('invalid'); | 214 this.nameField_.value = ''; |
| 215 this.keywordField_.value = ''; | |
| 216 this.urlField_.value = ''; | |
| 259 } | 217 } |
| 260 this.currentlyValid_ = !this.isPlaceholder_; | 218 this.currentlyValid_ = !this.isPlaceholder_; |
| 261 }, | 219 }, |
| 262 | 220 |
| 263 /** | 221 /** |
| 264 * Returns the input field values as an array suitable for passing to | 222 * Returns the input field values as an array suitable for passing to |
| 265 * chrome.send. The order of the array is important. | 223 * chrome.send. The order of the array is important. |
| 266 * @private | 224 * @private |
| 267 * @return {array} The current input field values. | 225 * @return {array} The current input field values. |
| 268 */ | 226 */ |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 283 chrome.send('checkSearchEngineInfoValidity', args); | 241 chrome.send('checkSearchEngineInfoValidity', args); |
| 284 }, | 242 }, |
| 285 | 243 |
| 286 /** | 244 /** |
| 287 * Callback for the completion of an input validition check. | 245 * Callback for the completion of an input validition check. |
| 288 * @param {Object} validity A dictionary of validitation results. | 246 * @param {Object} validity A dictionary of validitation results. |
| 289 */ | 247 */ |
| 290 validationComplete: function(validity) { | 248 validationComplete: function(validity) { |
| 291 this.waitingForValidation_ = false; | 249 this.waitingForValidation_ = false; |
| 292 // TODO(stuartmorgan): Implement the full validation UI with | 250 // TODO(stuartmorgan): Implement the full validation UI with |
| 293 // checkmark/exclamation mark icons and tooltips. | 251 // checkmark/exclamation mark icons and tooltips showing the errors. |
| 294 if (validity['name']) | 252 if (validity['name']) { |
| 295 this.nameField_.classList.remove('invalid'); | 253 this.nameField_.setCustomValidity(''); |
| 296 else | 254 } else { |
| 297 this.nameField_.classList.add('invalid'); | 255 this.nameField_.setCustomValidity( |
| 256 localStrings.getString('editSearchEngineInvalidTitleToolTip')); | |
|
Evan Stade
2011/01/13 23:12:46
templateData is shorter, i don't know what the dif
stuartmorgan
2011/01/13 23:35:37
templateData is fine here; Done.
| |
| 257 } | |
| 298 | 258 |
| 299 if (validity['keyword']) | 259 if (validity['keyword']) { |
| 300 this.keywordField_.classList.remove('invalid'); | 260 this.keywordField_.setCustomValidity(''); |
| 301 else | 261 } else { |
| 302 this.keywordField_.classList.add('invalid'); | 262 this.keywordField_.setCustomValidity( |
| 263 localStrings.getString('editSearchEngineInvalidKeywordToolTip')); | |
| 264 } | |
| 303 | 265 |
| 304 if (validity['url']) | 266 if (validity['url']) { |
| 305 this.urlField_.classList.remove('invalid'); | 267 this.urlField_.setCustomValidity(''); |
| 306 else | 268 } else { |
| 307 this.urlField_.classList.add('invalid'); | 269 this.urlField_.setCustomValidity( |
| 270 localStrings.getString('editSearchEngineInvalidURLToolTip')); | |
| 271 } | |
| 308 | 272 |
| 309 this.currentlyValid_ = validity['name'] && validity['keyword'] && | 273 this.currentlyValid_ = validity['name'] && validity['keyword'] && |
| 310 validity['url']; | 274 validity['url']; |
| 311 }, | 275 }, |
| 312 }; | 276 }; |
| 313 | 277 |
| 314 var SearchEngineList = cr.ui.define('list'); | 278 var SearchEngineList = cr.ui.define('list'); |
| 315 | 279 |
| 316 SearchEngineList.prototype = { | 280 SearchEngineList.prototype = { |
| 317 __proto__: InlineEditableItemList.prototype, | 281 __proto__: InlineEditableItemList.prototype, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 }, | 319 }, |
| 356 }; | 320 }; |
| 357 | 321 |
| 358 // Export | 322 // Export |
| 359 return { | 323 return { |
| 360 SearchEngineList: SearchEngineList | 324 SearchEngineList: SearchEngineList |
| 361 }; | 325 }; |
| 362 | 326 |
| 363 }); | 327 }); |
| 364 | 328 |
| OLD | NEW |