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

Side by Side Diff: chrome/browser/resources/options2/autofill_options_list.js

Issue 10809005: Options: Rename chrome/browser/resources/options2 -> chrome/browser/resources/options. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix. Created 8 years, 4 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 cr.define('options.autofillOptions', function() {
6 /** @const */ var DeletableItem = options.DeletableItem;
7 /** @const */ var DeletableItemList = options.DeletableItemList;
8 /** @const */ var InlineEditableItem = options.InlineEditableItem;
9 /** @const */ var InlineEditableItemList = options.InlineEditableItemList;
10
11 function AutofillEditProfileButton(guid, edit) {
12 var editButtonEl = document.createElement('button');
13 editButtonEl.className = 'list-inline-button custom-appearance';
14 editButtonEl.textContent =
15 loadTimeData.getString('autofillEditProfileButton');
16 editButtonEl.onclick = function(e) { edit(guid); };
17
18 // Don't select the row when clicking the button.
19 editButtonEl.onmousedown = function(e) {
20 e.stopPropagation();
21 };
22
23 return editButtonEl;
24 }
25
26 /**
27 * Creates a new address list item.
28 * @param {Array} entry An array of the form [guid, label].
29 * @constructor
30 * @extends {options.DeletableItem}
31 */
32 function AddressListItem(entry) {
33 var el = cr.doc.createElement('div');
34 el.guid = entry[0];
35 el.label = entry[1];
36 el.__proto__ = AddressListItem.prototype;
37 el.decorate();
38
39 return el;
40 }
41
42 AddressListItem.prototype = {
43 __proto__: DeletableItem.prototype,
44
45 /** @inheritDoc */
46 decorate: function() {
47 DeletableItem.prototype.decorate.call(this);
48
49 // The stored label.
50 var label = this.ownerDocument.createElement('div');
51 label.className = 'autofill-list-item';
52 label.textContent = this.label;
53 this.contentElement.appendChild(label);
54
55 // The 'Edit' button.
56 var editButtonEl = new AutofillEditProfileButton(
57 this.guid,
58 AutofillOptions.loadAddressEditor);
59 this.contentElement.appendChild(editButtonEl);
60 },
61 };
62
63 /**
64 * Creates a new credit card list item.
65 * @param {Array} entry An array of the form [guid, label, icon].
66 * @constructor
67 * @extends {options.DeletableItem}
68 */
69 function CreditCardListItem(entry) {
70 var el = cr.doc.createElement('div');
71 el.guid = entry[0];
72 el.label = entry[1];
73 el.icon = entry[2];
74 el.description = entry[3];
75 el.__proto__ = CreditCardListItem.prototype;
76 el.decorate();
77
78 return el;
79 }
80
81 CreditCardListItem.prototype = {
82 __proto__: DeletableItem.prototype,
83
84 /** @inheritDoc */
85 decorate: function() {
86 DeletableItem.prototype.decorate.call(this);
87
88 // The stored label.
89 var label = this.ownerDocument.createElement('div');
90 label.className = 'autofill-list-item';
91 label.textContent = this.label;
92 this.contentElement.appendChild(label);
93
94 // The credit card icon.
95 var icon = this.ownerDocument.createElement('image');
96 icon.src = this.icon;
97 icon.alt = this.description;
98 this.contentElement.appendChild(icon);
99
100 // The 'Edit' button.
101 var editButtonEl = new AutofillEditProfileButton(
102 this.guid,
103 AutofillOptions.loadCreditCardEditor);
104 this.contentElement.appendChild(editButtonEl);
105 },
106 };
107
108 /**
109 * Creates a new value list item.
110 * @param {AutofillValuesList} list The parent list of this item.
111 * @param {String} entry A string value.
112 * @constructor
113 * @extends {options.InlineEditableItem}
114 */
115 function ValuesListItem(list, entry) {
116 var el = cr.doc.createElement('div');
117 el.list = list;
118 el.value = entry ? entry : '';
119 el.__proto__ = ValuesListItem.prototype;
120 el.decorate();
121
122 return el;
123 }
124
125 ValuesListItem.prototype = {
126 __proto__: InlineEditableItem.prototype,
127
128 /** @inheritDoc */
129 decorate: function() {
130 InlineEditableItem.prototype.decorate.call(this);
131
132 // Note: This must be set prior to calling |createEditableTextCell|.
133 this.isPlaceholder = !this.value;
134
135 // The stored value.
136 var cell = this.createEditableTextCell(this.value);
137 this.contentElement.appendChild(cell);
138 this.input = cell.querySelector('input');
139
140 if (this.isPlaceholder) {
141 this.input.placeholder = this.list.getAttribute('placeholder');
142 this.deletable = false;
143 }
144
145 this.addEventListener('commitedit', this.onEditCommitted_);
146 },
147
148 /**
149 * @return {string} This item's value.
150 * @protected
151 */
152 value_: function() {
153 return this.input.value;
154 },
155
156 /**
157 * @param {Object} value The value to test.
158 * @return {boolean} True if the given value is non-empty.
159 * @protected
160 */
161 valueIsNonEmpty_: function(value) {
162 return !!value;
163 },
164
165 /**
166 * @return {boolean} True if value1 is logically equal to value2.
167 */
168 valuesAreEqual_: function(value1, value2) {
169 return value1 === value2;
170 },
171
172 /**
173 * Clears the item's value.
174 * @protected
175 */
176 clearValue_: function() {
177 this.input.value = '';
178 },
179
180 /**
181 * Called when committing an edit.
182 * If this is an "Add ..." item, committing a non-empty value adds that
183 * value to the end of the values list, but also leaves this "Add ..." item
184 * in place.
185 * @param {Event} e The end event.
186 * @private
187 */
188 onEditCommitted_: function(e) {
189 var value = this.value_();
190 var i = this.list.items.indexOf(this);
191 if (i < this.list.dataModel.length &&
192 this.valuesAreEqual_(value, this.list.dataModel.item(i))) {
193 return;
194 }
195
196 var entries = this.list.dataModel.slice();
197 if (this.valueIsNonEmpty_(value) &&
198 !entries.some(this.valuesAreEqual_.bind(this, value))) {
199 // Update with new value.
200 if (this.isPlaceholder) {
201 // It is important that updateIndex is done before validateAndSave.
202 // Otherwise we can not be sure about AddRow index.
203 this.list.dataModel.updateIndex(i);
204 this.list.validateAndSave(i, 0, value);
205 } else {
206 this.list.validateAndSave(i, 1, value);
207 }
208 } else {
209 // Reject empty values and duplicates.
210 if (!this.isPlaceholder)
211 this.list.dataModel.splice(i, 1);
212 else
213 this.clearValue_();
214 }
215 },
216 };
217
218 /**
219 * Creates a new name value list item.
220 * @param {AutofillNameValuesList} list The parent list of this item.
221 * @param {array} entry An array of [first, middle, last] names.
222 * @constructor
223 * @extends {options.ValuesListItem}
224 */
225 function NameListItem(list, entry) {
226 var el = cr.doc.createElement('div');
227 el.list = list;
228 el.first = entry ? entry[0] : '';
229 el.middle = entry ? entry[1] : '';
230 el.last = entry ? entry[2] : '';
231 el.__proto__ = NameListItem.prototype;
232 el.decorate();
233
234 return el;
235 }
236
237 NameListItem.prototype = {
238 __proto__: ValuesListItem.prototype,
239
240 /** @inheritDoc */
241 decorate: function() {
242 InlineEditableItem.prototype.decorate.call(this);
243
244 // Note: This must be set prior to calling |createEditableTextCell|.
245 this.isPlaceholder = !this.first && !this.middle && !this.last;
246
247 // The stored value.
248 // For the simulated static "input element" to display correctly, the
249 // value must not be empty. We use a space to force the UI to render
250 // correctly when the value is logically empty.
251 var cell = this.createEditableTextCell(this.first);
252 this.contentElement.appendChild(cell);
253 this.firstNameInput = cell.querySelector('input');
254
255 cell = this.createEditableTextCell(this.middle);
256 this.contentElement.appendChild(cell);
257 this.middleNameInput = cell.querySelector('input');
258
259 cell = this.createEditableTextCell(this.last);
260 this.contentElement.appendChild(cell);
261 this.lastNameInput = cell.querySelector('input');
262
263 if (this.isPlaceholder) {
264 this.firstNameInput.placeholder =
265 loadTimeData.getString('autofillAddFirstNamePlaceholder');
266 this.middleNameInput.placeholder =
267 loadTimeData.getString('autofillAddMiddleNamePlaceholder');
268 this.lastNameInput.placeholder =
269 loadTimeData.getString('autofillAddLastNamePlaceholder');
270 this.deletable = false;
271 }
272
273 this.addEventListener('commitedit', this.onEditCommitted_);
274 },
275
276 /** @inheritDoc */
277 value_: function() {
278 return [this.firstNameInput.value,
279 this.middleNameInput.value,
280 this.lastNameInput.value];
281 },
282
283 /** @inheritDoc */
284 valueIsNonEmpty_: function(value) {
285 return value[0] || value[1] || value[2];
286 },
287
288 /** @inheritDoc */
289 valuesAreEqual_: function(value1, value2) {
290 // First, check for null values.
291 if (!value1 || !value2)
292 return value1 == value2;
293
294 return value1[0] === value2[0] &&
295 value1[1] === value2[1] &&
296 value1[2] === value2[2];
297 },
298
299 /** @inheritDoc */
300 clearValue_: function() {
301 this.firstNameInput.value = '';
302 this.middleNameInput.value = '';
303 this.lastNameInput.value = '';
304 },
305 };
306
307 /**
308 * Base class for shared implementation between address and credit card lists.
309 * @constructor
310 * @extends {options.DeletableItemList}
311 */
312 var AutofillProfileList = cr.ui.define('list');
313
314 AutofillProfileList.prototype = {
315 __proto__: DeletableItemList.prototype,
316
317 decorate: function() {
318 DeletableItemList.prototype.decorate.call(this);
319
320 this.addEventListener('blur', this.onBlur_);
321 },
322
323 /**
324 * When the list loses focus, unselect all items in the list.
325 * @private
326 */
327 onBlur_: function() {
328 this.selectionModel.unselectAll();
329 },
330 };
331
332 /**
333 * Create a new address list.
334 * @constructor
335 * @extends {options.AutofillProfileList}
336 */
337 var AutofillAddressList = cr.ui.define('list');
338
339 AutofillAddressList.prototype = {
340 __proto__: AutofillProfileList.prototype,
341
342 decorate: function() {
343 AutofillProfileList.prototype.decorate.call(this);
344 },
345
346 /** @inheritDoc */
347 activateItemAtIndex: function(index) {
348 AutofillOptions.loadAddressEditor(this.dataModel.item(index)[0]);
349 },
350
351 /** @inheritDoc */
352 createItem: function(entry) {
353 return new AddressListItem(entry);
354 },
355
356 /** @inheritDoc */
357 deleteItemAtIndex: function(index) {
358 AutofillOptions.removeAddress(this.dataModel.item(index)[0]);
359 },
360 };
361
362 /**
363 * Create a new credit card list.
364 * @constructor
365 * @extends {options.DeletableItemList}
366 */
367 var AutofillCreditCardList = cr.ui.define('list');
368
369 AutofillCreditCardList.prototype = {
370 __proto__: AutofillProfileList.prototype,
371
372 decorate: function() {
373 AutofillProfileList.prototype.decorate.call(this);
374 },
375
376 /** @inheritDoc */
377 activateItemAtIndex: function(index) {
378 AutofillOptions.loadCreditCardEditor(this.dataModel.item(index)[0]);
379 },
380
381 /** @inheritDoc */
382 createItem: function(entry) {
383 return new CreditCardListItem(entry);
384 },
385
386 /** @inheritDoc */
387 deleteItemAtIndex: function(index) {
388 AutofillOptions.removeCreditCard(this.dataModel.item(index)[0]);
389 },
390 };
391
392 /**
393 * Create a new value list.
394 * @constructor
395 * @extends {options.InlineEditableItemList}
396 */
397 var AutofillValuesList = cr.ui.define('list');
398
399 AutofillValuesList.prototype = {
400 __proto__: InlineEditableItemList.prototype,
401
402 /** @inheritDoc */
403 createItem: function(entry) {
404 return new ValuesListItem(this, entry);
405 },
406
407 /** @inheritDoc */
408 deleteItemAtIndex: function(index) {
409 this.dataModel.splice(index, 1);
410 },
411
412 /** @inheritDoc */
413 shouldFocusPlaceholder: function() {
414 return false;
415 },
416
417 /**
418 * Called when the list hierarchy as a whole loses or gains focus.
419 * If the list was focused in response to a mouse click, call into the
420 * superclass's implementation. If the list was focused in response to a
421 * keyboard navigation, focus the first item.
422 * If the list loses focus, unselect all the elements.
423 * @param {Event} e The change event.
424 * @private
425 */
426 handleListFocusChange_: function(e) {
427 // We check to see whether there is a selected item as a proxy for
428 // distinguishing between mouse- and keyboard-originated focus events.
429 var selectedItem = this.selectedItem;
430 if (selectedItem)
431 InlineEditableItemList.prototype.handleListFocusChange_.call(this, e);
432
433 if (!e.newValue) {
434 // When the list loses focus, unselect all the elements.
435 this.selectionModel.unselectAll();
436 } else {
437 // When the list gains focus, select the first item if nothing else is
438 // selected.
439 var firstItem = this.getListItemByIndex(0);
440 if (!selectedItem && firstItem && e.newValue)
441 firstItem.handleFocus_();
442 }
443 },
444
445 /**
446 * Called when a new list item should be validated; subclasses are
447 * responsible for implementing if validation is required.
448 * @param {number} index The index of the item that was inserted or changed.
449 * @param {number} remove The number items to remove.
450 * @param {string} value The value of the item to insert.
451 */
452 validateAndSave: function(index, remove, value) {
453 this.dataModel.splice(index, remove, value);
454 },
455 };
456
457 /**
458 * Create a new value list for phone number validation.
459 * @constructor
460 * @extends {options.AutofillValuesList}
461 */
462 var AutofillNameValuesList = cr.ui.define('list');
463
464 AutofillNameValuesList.prototype = {
465 __proto__: AutofillValuesList.prototype,
466
467 /** @inheritDoc */
468 createItem: function(entry) {
469 return new NameListItem(this, entry);
470 },
471 };
472
473 /**
474 * Create a new value list for phone number validation.
475 * @constructor
476 * @extends {options.AutofillValuesList}
477 */
478 var AutofillPhoneValuesList = cr.ui.define('list');
479
480 AutofillPhoneValuesList.prototype = {
481 __proto__: AutofillValuesList.prototype,
482
483 /** @inheritDoc */
484 validateAndSave: function(index, remove, value) {
485 var numbers = this.dataModel.slice(0, this.dataModel.length - 1);
486 numbers.splice(index, remove, value);
487 var info = new Array();
488 info[0] = index;
489 info[1] = numbers;
490 info[2] = $('country').value;
491 chrome.send('validatePhoneNumbers', info);
492 },
493 };
494
495 return {
496 AddressListItem: AddressListItem,
497 CreditCardListItem: CreditCardListItem,
498 ValuesListItem: ValuesListItem,
499 NameListItem: NameListItem,
500 AutofillAddressList: AutofillAddressList,
501 AutofillCreditCardList: AutofillCreditCardList,
502 AutofillValuesList: AutofillValuesList,
503 AutofillNameValuesList: AutofillNameValuesList,
504 AutofillPhoneValuesList: AutofillPhoneValuesList,
505 };
506 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/options2/autofill_options.js ('k') | chrome/browser/resources/options2/browser_options.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698