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

Unified Diff: chrome/browser/resources/options2/autofill_options_list.js

Issue 8895023: Options2: Pull the trigger. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: DIAF. Created 9 years 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/options2/autofill_options_list.js
diff --git a/chrome/browser/resources/options2/autofill_options_list.js b/chrome/browser/resources/options2/autofill_options_list.js
new file mode 100644
index 0000000000000000000000000000000000000000..c9ed67ce9ff07d3aa0aaa37fa7ba5d20b3c142fd
--- /dev/null
+++ b/chrome/browser/resources/options2/autofill_options_list.js
@@ -0,0 +1,506 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('options.autofillOptions', function() {
+ const DeletableItem = options.DeletableItem;
+ const DeletableItemList = options.DeletableItemList;
+ const InlineEditableItem = options.InlineEditableItem;
+ const InlineEditableItemList = options.InlineEditableItemList;
+
+ function AutofillEditProfileButton(guid, edit) {
+ var editButtonEl = document.createElement('button');
+ editButtonEl.className = 'raw-button custom-appearance';
+ editButtonEl.textContent =
+ templateData.autofillEditProfileButton;
+ editButtonEl.onclick = function(e) { edit(guid); };
+
+ // Don't select the row when clicking the button.
+ editButtonEl.onmousedown = function(e) {
+ e.stopPropagation();
+ };
+
+ return editButtonEl;
+ }
+
+ /**
+ * Creates a new address list item.
+ * @param {Array} entry An array of the form [guid, label].
+ * @constructor
+ * @extends {options.DeletableItem}
+ */
+ function AddressListItem(entry) {
+ var el = cr.doc.createElement('div');
+ el.guid = entry[0];
+ el.label = entry[1];
+ el.__proto__ = AddressListItem.prototype;
+ el.decorate();
+
+ return el;
+ }
+
+ AddressListItem.prototype = {
+ __proto__: DeletableItem.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ DeletableItem.prototype.decorate.call(this);
+
+ // The stored label.
+ var label = this.ownerDocument.createElement('div');
+ label.className = 'autofill-list-item';
+ label.textContent = this.label;
+ this.contentElement.appendChild(label);
+
+ // The 'Edit' button.
+ var editButtonEl = new AutofillEditProfileButton(
+ this.guid,
+ AutofillOptions.loadAddressEditor);
+ this.contentElement.appendChild(editButtonEl);
+ },
+ };
+
+ /**
+ * Creates a new credit card list item.
+ * @param {Array} entry An array of the form [guid, label, icon].
+ * @constructor
+ * @extends {options.DeletableItem}
+ */
+ function CreditCardListItem(entry) {
+ var el = cr.doc.createElement('div');
+ el.guid = entry[0];
+ el.label = entry[1];
+ el.icon = entry[2];
+ el.description = entry[3];
+ el.__proto__ = CreditCardListItem.prototype;
+ el.decorate();
+
+ return el;
+ }
+
+ CreditCardListItem.prototype = {
+ __proto__: DeletableItem.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ DeletableItem.prototype.decorate.call(this);
+
+ // The stored label.
+ var label = this.ownerDocument.createElement('div');
+ label.className = 'autofill-list-item';
+ label.textContent = this.label;
+ this.contentElement.appendChild(label);
+
+ // The credit card icon.
+ var icon = this.ownerDocument.createElement('image');
+ icon.src = this.icon;
+ icon.alt = this.description;
+ this.contentElement.appendChild(icon);
+
+ // The 'Edit' button.
+ var editButtonEl = new AutofillEditProfileButton(
+ this.guid,
+ AutofillOptions.loadCreditCardEditor);
+ this.contentElement.appendChild(editButtonEl);
+ },
+ };
+
+ /**
+ * Creates a new value list item.
+ * @param {AutofillValuesList} list The parent list of this item.
+ * @param {String} entry A string value.
+ * @constructor
+ * @extends {options.InlineEditableItem}
+ */
+ function ValuesListItem(list, entry) {
+ var el = cr.doc.createElement('div');
+ el.list = list;
+ el.value = entry ? entry : '';
+ el.__proto__ = ValuesListItem.prototype;
+ el.decorate();
+
+ return el;
+ }
+
+ ValuesListItem.prototype = {
+ __proto__: InlineEditableItem.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ InlineEditableItem.prototype.decorate.call(this);
+
+ // Note: This must be set prior to calling |createEditableTextCell|.
+ this.isPlaceholder = !this.value;
+
+ // The stored value.
+ var cell = this.createEditableTextCell(this.value);
+ this.contentElement.appendChild(cell);
+ this.input = cell.querySelector('input');
+
+ if (this.isPlaceholder) {
+ this.input.placeholder = this.list.getAttribute('placeholder');
+ this.deletable = false;
+ }
+
+ this.addEventListener('commitedit', this.onEditCommitted_);
+ },
+
+ /**
+ * @return This item's value.
+ * @protected
+ */
+ value_: function() {
+ return this.input.value;
+ },
+
+ /**
+ * @param {Object} value The value to test.
+ * @return true if the given value is non-empty.
+ * @protected
+ */
+ valueIsNonEmpty_: function(value) {
+ return !!value;
+ },
+
+ /**
+ * @return true if value1 is logically equal to value2.
+ */
+ valuesAreEqual_: function(value1, value2) {
+ return value1 === value2;
+ },
+
+ /**
+ * Clears the item's value.
+ * @protected
+ */
+ clearValue_: function() {
+ this.input.value = '';
+ },
+
+ /**
+ * Called when committing an edit.
+ * If this is an "Add ..." item, committing a non-empty value adds that
+ * value to the end of the values list, but also leaves this "Add ..." item
+ * in place.
+ * @param {Event} e The end event.
+ * @private
+ */
+ onEditCommitted_: function(e) {
+ var value = this.value_();
+ var i = this.list.items.indexOf(this);
+ if (i < this.list.dataModel.length &&
+ this.valuesAreEqual_(value, this.list.dataModel.item(i))) {
+ return;
+ }
+
+ var entries = this.list.dataModel.slice();
+ if (this.valueIsNonEmpty_(value) &&
+ !entries.some(this.valuesAreEqual_.bind(this, value))) {
+ // Update with new value.
+ if (this.isPlaceholder) {
+ // It is important that updateIndex is done before validateAndSave.
+ // Otherwise we can not be sure about AddRow index.
+ this.list.dataModel.updateIndex(i);
+ this.list.validateAndSave(i, 0, value);
+ } else {
+ this.list.validateAndSave(i, 1, value);
+ }
+ } else {
+ // Reject empty values and duplicates.
+ if (!this.isPlaceholder)
+ this.list.dataModel.splice(i, 1);
+ else
+ this.clearValue_();
+ }
+ },
+ };
+
+ /**
+ * Creates a new name value list item.
+ * @param {AutofillNameValuesList} list The parent list of this item.
+ * @param {array} entry An array of [first, middle, last] names.
+ * @constructor
+ * @extends {options.ValuesListItem}
+ */
+ function NameListItem(list, entry) {
+ var el = cr.doc.createElement('div');
+ el.list = list;
+ el.first = entry ? entry[0] : '';
+ el.middle = entry ? entry[1] : '';
+ el.last = entry ? entry[2] : '';
+ el.__proto__ = NameListItem.prototype;
+ el.decorate();
+
+ return el;
+ }
+
+ NameListItem.prototype = {
+ __proto__: ValuesListItem.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ InlineEditableItem.prototype.decorate.call(this);
+
+ // Note: This must be set prior to calling |createEditableTextCell|.
+ this.isPlaceholder = !this.first && !this.middle && !this.last;
+
+ // The stored value.
+ // For the simulated static "input element" to display correctly, the
+ // value must not be empty. We use a space to force the UI to render
+ // correctly when the value is logically empty.
+ var cell = this.createEditableTextCell(this.first);
+ this.contentElement.appendChild(cell);
+ this.firstNameInput = cell.querySelector('input');
+
+ cell = this.createEditableTextCell(this.middle);
+ this.contentElement.appendChild(cell);
+ this.middleNameInput = cell.querySelector('input');
+
+ cell = this.createEditableTextCell(this.last);
+ this.contentElement.appendChild(cell);
+ this.lastNameInput = cell.querySelector('input');
+
+ if (this.isPlaceholder) {
+ this.firstNameInput.placeholder =
+ templateData.autofillAddFirstNamePlaceholder;
+ this.middleNameInput.placeholder =
+ templateData.autofillAddMiddleNamePlaceholder;
+ this.lastNameInput.placeholder =
+ templateData.autofillAddLastNamePlaceholder;
+ this.deletable = false;
+ }
+
+ this.addEventListener('commitedit', this.onEditCommitted_);
+ },
+
+ /** @inheritDoc */
+ value_: function() {
+ return [ this.firstNameInput.value,
+ this.middleNameInput.value,
+ this.lastNameInput.value ];
+ },
+
+ /** @inheritDoc */
+ valueIsNonEmpty_: function(value) {
+ return value[0] || value[1] || value[2];
+ },
+
+ /** @inheritDoc */
+ valuesAreEqual_: function(value1, value2) {
+ // First, check for null values.
+ if (!value1 || !value2)
+ return value1 == value2;
+
+ return value1[0] === value2[0] &&
+ value1[1] === value2[1] &&
+ value1[2] === value2[2];
+ },
+
+ /** @inheritDoc */
+ clearValue_: function() {
+ this.firstNameInput.value = '';
+ this.middleNameInput.value = '';
+ this.lastNameInput.value = '';
+ },
+ };
+
+ /**
+ * Base class for shared implementation between address and credit card lists.
+ * @constructor
+ * @extends {options.DeletableItemList}
+ */
+ var AutofillProfileList = cr.ui.define('list');
+
+ AutofillProfileList.prototype = {
+ __proto__: DeletableItemList.prototype,
+
+ decorate: function() {
+ DeletableItemList.prototype.decorate.call(this);
+
+ this.addEventListener('blur', this.onBlur_);
+ },
+
+ /**
+ * When the list loses focus, unselect all items in the list.
+ * @private
+ */
+ onBlur_: function() {
+ this.selectionModel.unselectAll();
+ },
+ };
+
+ /**
+ * Create a new address list.
+ * @constructor
+ * @extends {options.AutofillProfileList}
+ */
+ var AutofillAddressList = cr.ui.define('list');
+
+ AutofillAddressList.prototype = {
+ __proto__: AutofillProfileList.prototype,
+
+ decorate: function() {
+ AutofillProfileList.prototype.decorate.call(this);
+ },
+
+ /** @inheritDoc */
+ activateItemAtIndex: function(index) {
+ AutofillOptions.loadAddressEditor(this.dataModel.item(index)[0]);
+ },
+
+ /** @inheritDoc */
+ createItem: function(entry) {
+ return new AddressListItem(entry);
+ },
+
+ /** @inheritDoc */
+ deleteItemAtIndex: function(index) {
+ AutofillOptions.removeAddress(this.dataModel.item(index)[0]);
+ },
+ };
+
+ /**
+ * Create a new credit card list.
+ * @constructor
+ * @extends {options.DeletableItemList}
+ */
+ var AutofillCreditCardList = cr.ui.define('list');
+
+ AutofillCreditCardList.prototype = {
+ __proto__: AutofillProfileList.prototype,
+
+ decorate: function() {
+ AutofillProfileList.prototype.decorate.call(this);
+ },
+
+ /** @inheritDoc */
+ activateItemAtIndex: function(index) {
+ AutofillOptions.loadCreditCardEditor(this.dataModel.item(index)[0]);
+ },
+
+ /** @inheritDoc */
+ createItem: function(entry) {
+ return new CreditCardListItem(entry);
+ },
+
+ /** @inheritDoc */
+ deleteItemAtIndex: function(index) {
+ AutofillOptions.removeCreditCard(this.dataModel.item(index)[0]);
+ },
+ };
+
+ /**
+ * Create a new value list.
+ * @constructor
+ * @extends {options.InlineEditableItemList}
+ */
+ var AutofillValuesList = cr.ui.define('list');
+
+ AutofillValuesList.prototype = {
+ __proto__: InlineEditableItemList.prototype,
+
+ /** @inheritDoc */
+ createItem: function(entry) {
+ return new ValuesListItem(this, entry);
+ },
+
+ /** @inheritDoc */
+ deleteItemAtIndex: function(index) {
+ this.dataModel.splice(index, 1);
+ },
+
+ /** @inheritDoc */
+ shouldFocusPlaceholder: function() {
+ return false;
+ },
+
+ /**
+ * Called when the list hierarchy as a whole loses or gains focus.
+ * If the list was focused in response to a mouse click, call into the
+ * superclass's implementation. If the list was focused in response to a
+ * keyboard navigation, focus the first item.
+ * If the list loses focus, unselect all the elements.
+ * @param {Event} e The change event.
+ * @private
+ */
+ handleListFocusChange_: function(e) {
+ // We check to see whether there is a selected item as a proxy for
+ // distinguishing between mouse- and keyboard-originated focus events.
+ var selectedItem = this.selectedItem;
+ if (selectedItem)
+ InlineEditableItemList.prototype.handleListFocusChange_.call(this, e);
+
+ if (!e.newValue) {
+ // When the list loses focus, unselect all the elements.
+ this.selectionModel.unselectAll();
+ } else {
+ // When the list gains focus, select the first item if nothing else is
+ // selected.
+ var firstItem = this.getListItemByIndex(0);
+ if (!selectedItem && firstItem && e.newValue)
+ firstItem.handleFocus_();
+ }
+ },
+
+ /**
+ * Called when a new list item should be validated; subclasses are
+ * responsible for implementing if validation is required.
+ * @param {number} index The index of the item that was inserted or changed.
+ * @param {number} remove The number items to remove.
+ * @param {string} value The value of the item to insert.
+ */
+ validateAndSave: function(index, remove, value) {
+ this.dataModel.splice(index, remove, value);
+ },
+ };
+
+ /**
+ * Create a new value list for phone number validation.
+ * @constructor
+ * @extends {options.AutofillValuesList}
+ */
+ var AutofillNameValuesList = cr.ui.define('list');
+
+ AutofillNameValuesList.prototype = {
+ __proto__: AutofillValuesList.prototype,
+
+ /** @inheritDoc */
+ createItem: function(entry) {
+ return new NameListItem(this, entry);
+ },
+ };
+
+ /**
+ * Create a new value list for phone number validation.
+ * @constructor
+ * @extends {options.AutofillValuesList}
+ */
+ var AutofillPhoneValuesList = cr.ui.define('list');
+
+ AutofillPhoneValuesList.prototype = {
+ __proto__: AutofillValuesList.prototype,
+
+ /** @inheritDoc */
+ validateAndSave: function(index, remove, value) {
+ var numbers = this.dataModel.slice(0, this.dataModel.length - 1);
+ numbers.splice(index, remove, value);
+ var info = new Array();
+ info[0] = index;
+ info[1] = numbers;
+ info[2] = $('country').value;
+ chrome.send('validatePhoneNumbers', info);
+ },
+ };
+
+ return {
+ AddressListItem: AddressListItem,
+ CreditCardListItem: CreditCardListItem,
+ ValuesListItem: ValuesListItem,
+ NameListItem: NameListItem,
+ AutofillAddressList: AutofillAddressList,
+ AutofillCreditCardList: AutofillCreditCardList,
+ AutofillValuesList: AutofillValuesList,
+ AutofillNameValuesList: AutofillNameValuesList,
+ AutofillPhoneValuesList: AutofillPhoneValuesList,
+ };
+});
« no previous file with comments | « chrome/browser/resources/options2/autofill_options.js ('k') | chrome/browser/resources/options2/autofill_overlay.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698