OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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.<Object>}} input Info | |
please use gerrit instead
2014/05/07 05:10:14
"components" is an array of array of objects. Exam
Dan Beam
2014/05/07 20:28:23
i think in general this is different from how the
| |
337 * 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.<{{field: string, value: string, placeholder: string=}}>} | |
please use gerrit instead
2014/05/07 05:10:14
An array of arrays of objects with elements "field
Dan Beam
2014/05/07 20:28:23
Done.
| |
353 * components A list of information about 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 Loading... | |
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 }); |
OLD | NEW |