Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: chrome/browser/resources/options/autofill_edit_address_overlay.js

Issue 273533003: autofill/options: address some nits I had on one of rouslan@'s CLs[1]. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: asdf Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/ui/webui/options/autofill_options_browsertest.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 */ var OptionsPage = options.OptionsPage; 6 /** @const */ var OptionsPage = options.OptionsPage;
7 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; 7 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
8 8
9 // The GUID of the loaded address.
10 var guid;
11
12 // The BCP 47 language code for the layout of input fields.
13 var languageCode;
14
15 /** 9 /**
16 * AutofillEditAddressOverlay class 10 * AutofillEditAddressOverlay class
17 * Encapsulated handling of the 'Add Page' overlay page. 11 * Encapsulated handling of the 'Add Page' overlay page.
18 * @class 12 * @class
19 */ 13 */
20 function AutofillEditAddressOverlay() { 14 function AutofillEditAddressOverlay() {
21 OptionsPage.call(this, 'autofillEditAddress', 15 OptionsPage.call(this, 'autofillEditAddress',
22 loadTimeData.getString('autofillEditAddressTitle'), 16 loadTimeData.getString('autofillEditAddressTitle'),
23 'autofill-edit-address-overlay'); 17 'autofill-edit-address-overlay');
24 } 18 }
25 19
26 cr.addSingletonGetter(AutofillEditAddressOverlay); 20 cr.addSingletonGetter(AutofillEditAddressOverlay);
27 21
28 AutofillEditAddressOverlay.prototype = { 22 AutofillEditAddressOverlay.prototype = {
29 __proto__: OptionsPage.prototype, 23 __proto__: OptionsPage.prototype,
30 24
31 /** 25 /**
26 * The GUID of the loaded address.
27 * @type {string}
28 */
29 guid_: '',
30
31 /**
32 * The BCP 47 language code for the layout of input fields.
33 * @type {string}
34 */
35 languageCode_: '',
36
37 /**
32 * Initializes the page. 38 * Initializes the page.
33 */ 39 */
34 initializePage: function() { 40 initializePage: function() {
35 OptionsPage.prototype.initializePage.call(this); 41 OptionsPage.prototype.initializePage.call(this);
36 42
37 this.createMultiValueLists_(); 43 this.createMultiValueLists_();
38 44
39 var self = this; 45 var self = this;
40 $('autofill-edit-address-cancel-button').onclick = function(event) { 46 $('autofill-edit-address-cancel-button').onclick = function(event) {
41 self.dismissOverlay_(); 47 self.dismissOverlay_();
(...skipping 19 matching lines...) Expand all
61 // insertion of new placeholder elements. The addition of placeholders 67 // insertion of new placeholder elements. The addition of placeholders
62 // affects layout, which interferes with being able to click on the 68 // affects layout, which interferes with being able to click on the
63 // buttons. 69 // buttons.
64 $('autofill-edit-address-apply-button').onmousedown = function(event) { 70 $('autofill-edit-address-apply-button').onmousedown = function(event) {
65 event.preventDefault(); 71 event.preventDefault();
66 }; 72 };
67 $('autofill-edit-address-cancel-button').onmousedown = function(event) { 73 $('autofill-edit-address-cancel-button').onmousedown = function(event) {
68 event.preventDefault(); 74 event.preventDefault();
69 }; 75 };
70 76
71 this.guid = ''; 77 this.guid_ = '';
72 this.populateCountryList_(); 78 this.populateCountryList_();
73 this.rebuildInputFields_( 79 this.rebuildInputFields_(
74 loadTimeData.getValue('autofillDefaultCountryComponents')); 80 loadTimeData.getValue('autofillDefaultCountryComponents'));
75 this.languageCode = 81 this.languageCode_ =
76 loadTimeData.getString('autofillDefaultCountryLanguageCode'); 82 loadTimeData.getString('autofillDefaultCountryLanguageCode');
77 this.connectInputEvents_(); 83 this.connectInputEvents_();
78 this.setInputFields_({}); 84 this.setInputFields_({});
79 this.getCountrySelector_().onchange = function(event) { 85 this.getCountrySwitcher_().onchange = function(event) {
80 self.countryChanged_(); 86 self.countryChanged_();
81 }; 87 };
82 }, 88 },
83 89
84 /** 90 /**
85 * Specifically catch the situations in which the overlay is cancelled 91 * Specifically catch the situations in which the overlay is cancelled
86 * externally (e.g. by pressing <Esc>), so that the input fields and 92 * externally (e.g. by pressing <Esc>), so that the input fields and
87 * GUID can be properly cleared. 93 * GUID can be properly cleared.
88 * @override 94 * @override
89 */ 95 */
(...skipping 11 matching lines...) Expand all
101 options.autofillOptions.AutofillPhoneValuesList.decorate(list); 107 options.autofillOptions.AutofillPhoneValuesList.decorate(list);
102 list.autoExpands = true; 108 list.autoExpands = true;
103 109
104 list = this.pageDiv.querySelector('[field=email]'); 110 list = this.pageDiv.querySelector('[field=email]');
105 options.autofillOptions.AutofillValuesList.decorate(list); 111 options.autofillOptions.AutofillValuesList.decorate(list);
106 list.autoExpands = true; 112 list.autoExpands = true;
107 }, 113 },
108 114
109 /** 115 /**
110 * Updates the data model for the |list| with the values from |entries|. 116 * Updates the data model for the |list| with the values from |entries|.
111 * @param {element} list The list to update. 117 * @param {cr.ui.List} list The list to update.
112 * @param {Array} entries The list of items to be added to the list. 118 * @param {Array} entries The list of items to be added to the list.
113 * @private 119 * @private
114 */ 120 */
115 setMultiValueList_: function(list, entries) { 121 setMultiValueList_: function(list, entries) {
116 // Add special entry for adding new values. 122 // Add special entry for adding new values.
117 var augmentedList = entries.slice(); 123 var augmentedList = entries.slice();
118 augmentedList.push(null); 124 augmentedList.push(null);
119 list.dataModel = new ArrayDataModel(augmentedList); 125 list.dataModel = new ArrayDataModel(augmentedList);
120 126
121 // Update the status of the 'OK' button. 127 // Update the status of the 'OK' button.
122 this.inputFieldChanged_(); 128 this.inputFieldChanged_();
123 129
124 list.dataModel.addEventListener('splice', 130 list.dataModel.addEventListener('splice',
125 this.inputFieldChanged_.bind(this)); 131 this.inputFieldChanged_.bind(this));
126 list.dataModel.addEventListener('change', 132 list.dataModel.addEventListener('change',
127 this.inputFieldChanged_.bind(this)); 133 this.inputFieldChanged_.bind(this));
128 }, 134 },
129 135
130 /** 136 /**
131 * Clears any uncommitted input, resets the stored GUID and dismisses the 137 * Clears any uncommitted input, resets the stored GUID and dismisses the
132 * overlay. 138 * overlay.
133 * @private 139 * @private
134 */ 140 */
135 dismissOverlay_: function() { 141 dismissOverlay_: function() {
136 this.setInputFields_({}); 142 this.setInputFields_({});
137 this.inputFieldChanged_(); 143 this.inputFieldChanged_();
138 this.guid = ''; 144 this.guid_ = '';
139 this.languageCode = ''; 145 this.languageCode_ = '';
140 OptionsPage.closeOverlay(); 146 OptionsPage.closeOverlay();
141 }, 147 },
142 148
143 /** 149 /**
144 * Returns the country selector element. 150 * @return {Element} The element used to switch countries.
145 * @return {element} The country selector.
146 * @private 151 * @private
147 */ 152 */
148 getCountrySelector_: function() { 153 getCountrySwitcher_: function() {
149 return this.pageDiv.querySelector('[field=country]'); 154 return this.pageDiv.querySelector('[field=country]');
150 }, 155 },
151 156
152 /** 157 /**
153 * Returns all list elements. 158 * Returns all list elements.
154 * @return {NodeList} The list elements. 159 * @return {!NodeList} The list elements.
155 * @private 160 * @private
156 */ 161 */
157 getLists_: function() { 162 getLists_: function() {
158 return this.pageDiv.querySelectorAll('list[field]'); 163 return this.pageDiv.querySelectorAll('list[field]');
159 }, 164 },
160 165
161 /** 166 /**
162 * Returns all text input elements. 167 * Returns all text input elements.
163 * @return {NodeList} The text input elements. 168 * @return {!NodeList} The text input elements.
164 * @private 169 * @private
165 */ 170 */
166 getTextFields_: function() { 171 getTextFields_: function() {
167 return this.pageDiv.querySelectorAll( 172 return this.pageDiv.querySelectorAll('textarea[field], input[field]');
168 ':-webkit-any(textarea, input)[field]');
169 }, 173 },
170 174
171 /** 175 /**
172 * Aggregates the values in the input fields into an object. 176 * Creates a map from type => value for all text fields.
173 * @return {object} The mapping from field names to values. 177 * @return {Object} The mapping from field names to values.
174 * @private 178 * @private
175 */ 179 */
176 getInputFields_: function() { 180 getInputFields_: function() {
177 var address = {}; 181 var address = {country: this.getCountrySwitcher_().value};
178 address['country'] = this.getCountrySelector_().value;
179 182
180 var lists = this.getLists_(); 183 var lists = this.getLists_();
181 for (var i = 0; i < lists.length; i++) { 184 for (var i = 0; i < lists.length; i++) {
182 address[lists[i].getAttribute('field')] = 185 address[lists[i].getAttribute('field')] =
183 lists[i].dataModel.slice(0, lists[i].dataModel.length - 1); 186 lists[i].dataModel.slice(0, lists[i].dataModel.length - 1);
184 } 187 }
185 188
186 var fields = this.getTextFields_(); 189 var fields = this.getTextFields_();
187 for (var i = 0; i < fields.length; i++) { 190 for (var i = 0; i < fields.length; i++) {
188 address[fields[i].getAttribute('field')] = fields[i].value; 191 address[fields[i].getAttribute('field')] = fields[i].value;
189 } 192 }
190 193
191 return address; 194 return address;
192 }, 195 },
193 196
194 /** 197 /**
195 * Sets the value of each input field according to |address|. 198 * Sets the value of each input field according to |address|.
196 * @param {object} address The object with values to use. 199 * @param {object} address The object with values to use.
197 * @private 200 * @private
198 */ 201 */
199 setInputFields_: function(address) { 202 setInputFields_: function(address) {
200 this.getCountrySelector_().value = address['country'] || ''; 203 this.getCountrySwitcher_().value = address.country || '';
201 204
202 var lists = this.getLists_(); 205 var lists = this.getLists_();
203 for (var i = 0; i < lists.length; i++) { 206 for (var i = 0; i < lists.length; i++) {
204 this.setMultiValueList_( 207 this.setMultiValueList_(
205 lists[i], address[lists[i].getAttribute('field')] || []); 208 lists[i], address[lists[i].getAttribute('field')] || []);
206 } 209 }
207 210
208 var fields = this.getTextFields_(); 211 var fields = this.getTextFields_();
209 for (var i = 0; i < fields.length; i++) { 212 for (var i = 0; i < fields.length; i++) {
210 fields[i].value = address[fields[i].getAttribute('field')] || ''; 213 fields[i].value = address[fields[i].getAttribute('field')] || '';
211 } 214 }
212 }, 215 },
213 216
214 /** 217 /**
215 * Aggregates the values in the input fields into an array and sends the 218 * Aggregates the values in the input fields into an array and sends the
216 * array to the Autofill handler. 219 * array to the Autofill handler.
217 * @private 220 * @private
218 */ 221 */
219 saveAddress_: function() { 222 saveAddress_: function() {
220 var inputFields = this.getInputFields_(); 223 var inputFields = this.getInputFields_();
221 var address = new Array(); 224 var address = [
222 var argCounter = 0; 225 this.guid_,
223 address[argCounter++] = this.guid; 226 inputFields.fullName || [],
224 address[argCounter++] = inputFields['fullName'] || []; 227 inputFields.companyName || '',
225 address[argCounter++] = inputFields['companyName'] || ''; 228 inputFields.addrLines || '',
226 address[argCounter++] = inputFields['addrLines'] || ''; 229 inputFields.dependentLocality || '',
227 address[argCounter++] = inputFields['dependentLocality'] || ''; 230 inputFields.city || '',
228 address[argCounter++] = inputFields['city'] || ''; 231 inputFields.state || '',
229 address[argCounter++] = inputFields['state'] || ''; 232 inputFields.postalCode || '',
230 address[argCounter++] = inputFields['postalCode'] || ''; 233 inputFields.sortingCode || '',
231 address[argCounter++] = inputFields['sortingCode'] || ''; 234 inputFields.country || '',
232 address[argCounter++] = inputFields['country'] || ''; 235 inputFields.phone || [],
233 address[argCounter++] = inputFields['phone'] || []; 236 inputFields.email || [],
234 address[argCounter++] = inputFields['email'] || []; 237 this.languageCode_,
235 address[argCounter++] = this.languageCode; 238 ];
236
237 chrome.send('setAddress', address); 239 chrome.send('setAddress', address);
238 }, 240 },
239 241
240 /** 242 /**
241 * Connects each input field to the inputFieldChanged_() method that enables 243 * Connects each input field to the inputFieldChanged_() method that enables
242 * or disables the 'Ok' button based on whether all the fields are empty or 244 * or disables the 'Ok' button based on whether all the fields are empty or
243 * not. 245 * not.
244 * @private 246 * @private
245 */ 247 */
246 connectInputEvents_: function() { 248 connectInputEvents_: function() {
247 var self = this;
248 var fields = this.getTextFields_(); 249 var fields = this.getTextFields_();
249 for (var i = 0; i < fields.length; i++) { 250 for (var i = 0; i < fields.length; i++) {
250 fields[i].oninput = function(event) { self.inputFieldChanged_(); }; 251 fields[i].oninput = this.inputFieldChanged_.bind(this);
251 } 252 }
252 }, 253 },
253 254
254 /** 255 /**
255 * Disables the 'Ok' button if all of the fields are empty. 256 * Disables the 'Ok' button if all of the fields are empty.
256 * @private 257 * @private
257 */ 258 */
258 inputFieldChanged_: function() { 259 inputFieldChanged_: function() {
259 var disabled = true; 260 var disabled = !this.getCountrySwitcher_().value;
260 if (this.getCountrySelector_().value)
261 disabled = false;
262
263 if (disabled) { 261 if (disabled) {
264 // Length of lists are tested for > 1 due to the "add" placeholder item 262 // Length of lists are tested for > 1 due to the "add" placeholder item
265 // in the list. 263 // in the list.
266 var lists = this.getLists_(); 264 var lists = this.getLists_();
267 for (var i = 0; i < lists.length; i++) { 265 for (var i = 0; i < lists.length; i++) {
268 if (lists[i].items.length > 1) { 266 if (lists[i].items.length > 1) {
269 disabled = false; 267 disabled = false;
270 break; 268 break;
271 } 269 }
272 } 270 }
(...skipping 10 matching lines...) Expand all
283 } 281 }
284 282
285 $('autofill-edit-address-apply-button').disabled = disabled; 283 $('autofill-edit-address-apply-button').disabled = disabled;
286 }, 284 },
287 285
288 /** 286 /**
289 * Updates the address fields appropriately for the selected country. 287 * Updates the address fields appropriately for the selected country.
290 * @private 288 * @private
291 */ 289 */
292 countryChanged_: function() { 290 countryChanged_: function() {
293 var countryCode = this.getCountrySelector_().value; 291 var countryCode = this.getCountrySwitcher_().value;
294 if (countryCode) 292 if (countryCode)
295 chrome.send('loadAddressEditorComponents', [countryCode]); 293 chrome.send('loadAddressEditorComponents', [countryCode]);
296 else 294 else
297 this.inputFieldChanged_(); 295 this.inputFieldChanged_();
298 }, 296 },
299 297
300 /** 298 /**
301 * Populates the country <select> list. 299 * Populates the country <select> list.
302 * @private 300 * @private
303 */ 301 */
304 populateCountryList_: function() { 302 populateCountryList_: function() {
305 var countryList = loadTimeData.getValue('autofillCountrySelectList'); 303 var countryList = loadTimeData.getValue('autofillCountrySelectList');
306 304
307 // Add the countries to the country <select> list. 305 // Add the countries to the country <select> list.
308 var countrySelect = this.getCountrySelector_(); 306 var countrySelect = this.getCountrySwitcher_();
309 // Add an empty option. 307 // Add an empty option.
310 countrySelect.appendChild(new Option('', '')); 308 countrySelect.appendChild(new Option('', ''));
311 for (var i = 0; i < countryList.length; i++) { 309 for (var i = 0; i < countryList.length; i++) {
312 var option = new Option(countryList[i].name, 310 var option = new Option(countryList[i].name,
313 countryList[i].value); 311 countryList[i].value);
314 option.disabled = countryList[i].value == 'separator'; 312 option.disabled = countryList[i].value == 'separator';
315 countrySelect.appendChild(option); 313 countrySelect.appendChild(option);
316 } 314 }
317 }, 315 },
318 316
319 /** 317 /**
320 * Loads the address data from |address|, sets the input fields based on 318 * Loads the address data from |address|, sets the input fields based on
321 * this data, and stores the GUID and language code of the address. 319 * this data, and stores the GUID and language code of the address.
320 * @param {!Object} address Lots of info about an address from the browser.
322 * @private 321 * @private
323 */ 322 */
324 loadAddress_: function(address) { 323 loadAddress_: function(address) {
325 this.rebuildInputFields_(address.components); 324 this.rebuildInputFields_(address.components);
326 this.setInputFields_(address); 325 this.setInputFields_(address);
327 this.inputFieldChanged_(); 326 this.inputFieldChanged_();
328 this.connectInputEvents_(); 327 this.connectInputEvents_();
329 this.guid = address.guid; 328 this.guid_ = address.guid;
330 this.languageCode = address.languageCode; 329 this.languageCode_ = address.languageCode;
331 }, 330 },
332 331
333 /** 332 /**
334 * Takes a snapshot of the input values, clears the input values, loads the 333 * Takes a snapshot of the input values, clears the input values, loads the
335 * address input layout from |input.components|, restores the input values 334 * address input layout from |input.components|, restores the input values
336 * from snapshot, and stores the |input.languageCode| for the address. 335 * from snapshot, and stores the |input.languageCode| for the address.
336 * @param {{languageCode: string, components: Array.<Array.<Object>>}} input
337 * Info about how to layout inputs fields in this dialog.
337 * @private 338 * @private
338 */ 339 */
339 loadAddressComponents_: function(input) { 340 loadAddressComponents_: function(input) {
340 var address = this.getInputFields_(); 341 var inputFields = this.getInputFields_();
341 this.rebuildInputFields_(input.components); 342 this.rebuildInputFields_(input.components);
342 this.setInputFields_(address); 343 this.setInputFields_(inputFields);
343 this.inputFieldChanged_(); 344 this.inputFieldChanged_();
344 this.connectInputEvents_(); 345 this.connectInputEvents_();
345 this.languageCode = input.languageCode; 346 this.languageCode_ = input.languageCode;
346 }, 347 },
347 348
348 /** 349 /**
349 * Clears address inputs and rebuilds the input fields according to 350 * Clears address inputs and rebuilds the input fields according to
350 * |components|. 351 * |components|.
352 * @param {Array.<Array.<Object>>} components A list of information about
353 * each input field.
351 * @private 354 * @private
352 */ 355 */
353 rebuildInputFields_: function(components) { 356 rebuildInputFields_: function(components) {
354 var content = $('autofill-edit-address-fields'); 357 var content = $('autofill-edit-address-fields');
355 while (content.firstChild) { 358 content.innerHTML = '';
356 content.removeChild(content.firstChild);
357 }
358 359
359 var customContainerElements = {'fullName': 'div'}; 360 var customContainerElements = {fullName: 'div'};
360 var customInputElements = {'fullName': 'list', 'addrLines': 'textarea'}; 361 var customInputElements = {fullName: 'list', addrLines: 'textarea'};
361 362
362 for (var i in components) { 363 for (var i in components) {
363 var row = document.createElement('div'); 364 var row = document.createElement('div');
364 row.classList.add('input-group', 'settings-row'); 365 row.classList.add('input-group', 'settings-row');
365 content.appendChild(row); 366 content.appendChild(row);
366 367
367 for (var j in components[i]) { 368 for (var j in components[i]) {
368 if (components[i][j].field == 'country') 369 if (components[i][j].field == 'country')
369 continue; 370 continue;
370 371
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 var phoneList = instance.pageDiv.querySelector('[field=phone]'); 410 var phoneList = instance.pageDiv.querySelector('[field=phone]');
410 instance.setMultiValueList_(phoneList, numbers); 411 instance.setMultiValueList_(phoneList, numbers);
411 phoneList.didReceiveValidationResult(); 412 phoneList.didReceiveValidationResult();
412 }; 413 };
413 414
414 // Export 415 // Export
415 return { 416 return {
416 AutofillEditAddressOverlay: AutofillEditAddressOverlay 417 AutofillEditAddressOverlay: AutofillEditAddressOverlay
417 }; 418 };
418 }); 419 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/webui/options/autofill_options_browsertest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698