| Index: chrome/browser/resources/options/autofill_options.js | 
| diff --git a/chrome/browser/resources/options/autofill_options.js b/chrome/browser/resources/options/autofill_options.js | 
| index 0c630fd06e2b5fbc39f7eca2c6c21689d7536737..a3637c44f87f9638dcf8bfeb03d81bee824304cc 100644 | 
| --- a/chrome/browser/resources/options/autofill_options.js | 
| +++ b/chrome/browser/resources/options/autofill_options.js | 
| @@ -3,28 +3,18 @@ | 
| // found in the LICENSE file. | 
|  | 
| cr.define('options', function() { | 
| -  var OptionsPage = options.OptionsPage; | 
| - | 
| -  // The offset of the first profile in either the address list or the credit | 
| -  // card list. Consists of the header and the horizontal rule. | 
| -  const addressOffset = 2; | 
| -  const creditCardOffset = 3; | 
| +  const OptionsPage = options.OptionsPage; | 
| +  const ArrayDataModel = cr.ui.ArrayDataModel; | 
| +  const ListSingleSelectionModel = cr.ui.ListSingleSelectionModel; | 
|  | 
| ///////////////////////////////////////////////////////////////////////////// | 
| // AutoFillOptions class: | 
| -  // | 
| -  // TODO(jhawkins): Replace <select> with a DOMUI List. | 
|  | 
| /** | 
| * Encapsulated handling of AutoFill options page. | 
| * @constructor | 
| */ | 
| function AutoFillOptions() { | 
| -    this.numAddresses = 0; | 
| -    this.numCreditCards = 0; | 
| -    this.activeNavTab = null; | 
| -    this.addressGUIDs = null; | 
| -    this.creditCardGUIDs = null; | 
| OptionsPage.call(this, | 
| 'autoFillOptions', | 
| templateData.autoFillOptionsTitle, | 
| @@ -36,32 +26,58 @@ cr.define('options', function() { | 
| AutoFillOptions.prototype = { | 
| __proto__: OptionsPage.prototype, | 
|  | 
| +    /** | 
| +     * The address list. | 
| +     * @type {DeletableItemList} | 
| +     * @private | 
| +     */ | 
| +    addressList_: null, | 
| + | 
| +    /** | 
| +     * The credit card list. | 
| +     * @type {DeletableItemList} | 
| +     * @private | 
| +     */ | 
| +    creditCardList_: null, | 
| + | 
| initializePage: function() { | 
| OptionsPage.prototype.initializePage.call(this); | 
|  | 
| +      this.createAddressList_(); | 
| +      this.createCreditCardList_(); | 
| + | 
| var self = this; | 
| -      $('profile-list').onchange = function(event) { | 
| -        self.updateButtonState_(); | 
| -      }; | 
| -      $('profile-list').addEventListener('dblclick', function(event) { | 
| -        if ($('autoFillEnabled').checked) | 
| -          self.editProfile_(); | 
| -      }); | 
| -      $('add-address-button').onclick = function(event) { | 
| +      $('autofill-add-address').onclick = function(event) { | 
| self.showAddAddressOverlay_(); | 
| }; | 
| -      $('add-credit-card-button').onclick = function(event) { | 
| +      $('autofill-add-creditcard').onclick = function(event) { | 
| self.showAddCreditCardOverlay_(); | 
| }; | 
| -      $('autofill-edit-button').onclick = function(event) { | 
| -        self.editProfile_(); | 
| -      }; | 
| -      $('autofill-remove-button').onclick = function(event) { | 
| -        self.removeProfile_(); | 
| -      }; | 
|  | 
| -      Preferences.getInstance().addEventListener('autofill.enabled', | 
| -          this.updateButtonState_.bind(this)); | 
| +      // TODO(jhawkins): What happens when AutoFill is disabled whilst on the | 
| +      // AutoFill options page? | 
| +    }, | 
| + | 
| +    /** | 
| +     * Creates, decorates and initializes the address list. | 
| +     * @private | 
| +     */ | 
| +    createAddressList_: function() { | 
| +      this.addressList_ = $('address-list'); | 
| +      options.autoFillOptions.AutoFillList.decorate(this.addressList_); | 
| +      this.addressList_.selectionModel = new ListSingleSelectionModel; | 
| +      this.addressList_.autoExpands = true; | 
| +    }, | 
| + | 
| +    /** | 
| +     * Creates, decorates and initializes the credit card list. | 
| +     * @private | 
| +     */ | 
| +    createCreditCardList_: function() { | 
| +      this.creditCardList_ = $('creditcard-list'); | 
| +      options.autoFillOptions.AutoFillList.decorate(this.creditCardList_); | 
| +      this.creditCardList_.selectionModel = new ListSingleSelectionModel; | 
| +      this.creditCardList_.autoExpands = true; | 
| }, | 
|  | 
| /** | 
| @@ -78,19 +94,6 @@ cr.define('options', function() { | 
| }, | 
|  | 
| /** | 
| -     * Shows the 'Edit address' overlay, using the data in |address| to fill the | 
| -     * input fields. |address| is a list with one item, an associative array | 
| -     * that contains the address data. | 
| -     * @private | 
| -     */ | 
| -    showEditAddressOverlay_: function(address) { | 
| -      var title = localStrings.getString('editAddressTitle'); | 
| -      AutoFillEditAddressOverlay.setTitle(title); | 
| -      AutoFillEditAddressOverlay.loadAddress(address[0]); | 
| -      OptionsPage.showOverlay('autoFillEditAddressOverlay'); | 
| -    }, | 
| - | 
| -    /** | 
| * Shows the 'Add credit card' overlay, specifically by loading the | 
| * 'Edit credit card' overlay, emptying the input fields and modifying the | 
| * overlay title. | 
| @@ -104,177 +107,91 @@ cr.define('options', function() { | 
| }, | 
|  | 
| /** | 
| -     * Shows the 'Edit credit card' overlay, using the data in |credit_card| to | 
| -     * fill the input fields. |address| is a list with one item, an associative | 
| -     * array that contains the credit card data. | 
| -     * @private | 
| +     * Updates the data model for the address list with the values from | 
| +     * |entries|. | 
| +     * @param {Array} entries The list of addresses. | 
| */ | 
| -    showEditCreditCardOverlay_: function(creditCard) { | 
| -      var title = localStrings.getString('editCreditCardTitle'); | 
| -      AutoFillEditCreditCardOverlay.setTitle(title); | 
| -      AutoFillEditCreditCardOverlay.loadCreditCard(creditCard[0]); | 
| -      OptionsPage.showOverlay('autoFillEditCreditCardOverlay'); | 
| +    setAddressList_: function(entries) { | 
| +      this.addressList_.dataModel = new ArrayDataModel(entries); | 
| }, | 
|  | 
| /** | 
| -     * Resets the address list. This method leaves the header and horizontal | 
| -     * rule unchanged. | 
| -     * @private | 
| +     * Updates the data model for the credit card list with the values from | 
| +     * |entries|. | 
| +     * @param {Array} entries The list of credit cards. | 
| */ | 
| -    resetAddresses_: function() { | 
| -      var profiles = $('profile-list'); | 
| -      for (var i = 0; i <  this.numAddresses; ++i) | 
| -        profiles.remove(addressOffset); | 
| -      this.numAddresses = 0; | 
| +    setCreditCardList_: function(entries) { | 
| +      this.creditCardList_.dataModel = new ArrayDataModel(entries); | 
| }, | 
|  | 
| /** | 
| -     * Resets the credit card list. This method leaves the header and horizontal | 
| -     * rule unchanged. | 
| +     * Removes the AutoFill profile represented by |guid|. | 
| +     * @param {String} guid The GUID of the profile to remove. | 
| * @private | 
| */ | 
| -    resetCreditCards_: function() { | 
| -      var profiles = $('profile-list'); | 
| -      var offset = this.numAddresses + addressOffset + creditCardOffset; | 
| -      for (var i = 0; i <  this.numCreditCards; ++i) | 
| -        profiles.remove(offset); | 
| -      this.numCreditCards = 0; | 
| +    removeAutoFillProfile_: function(guid) { | 
| +      chrome.send('removeAutoFillProfile', [guid]); | 
| }, | 
|  | 
| /** | 
| -     * Updates the address list with the given entries. | 
| +     * Requests profile data for the profile represented by |guid| from the | 
| +     * PersonalDataManager. Once the data is loaded, the AutoFillOptionsHandler | 
| +     * calls showEdit[Address,CreditCard]Overlay(), depending on the type of the | 
| +     * profile. | 
| +     * @param {String} guid The GUID of the profile to edit. | 
| * @private | 
| -     * @param {Array} address List of addresses. | 
| */ | 
| -    updateAddresses_: function(addresses) { | 
| -      this.resetAddresses_(); | 
| -      var profileList = $('profile-list'); | 
| -      var blankAddress = profileList.options[addressOffset]; | 
| -      this.numAddresses = addresses.length; | 
| -      this.addressGUIDs = new Array(this.numAddresses); | 
| -      for (var i = 0; i < this.numAddresses; i++) { | 
| -        var address = addresses[i]; | 
| -        var option = new Option(address['label']); | 
| -        this.addressGUIDs[i] = address['guid']; | 
| -        profileList.add(option, blankAddress); | 
| -      } | 
| - | 
| -      this.updateButtonState_(); | 
| +    loadProfileEditor_: function(guid) { | 
| +      chrome.send('loadProfileEditor', [guid]); | 
| }, | 
|  | 
| /** | 
| -     * Updates the credit card list with the given entries. | 
| -     * @private | 
| -     * @param {Array} creditCards List of credit cards. | 
| -     */ | 
| -    updateCreditCards_: function(creditCards) { | 
| -      this.resetCreditCards_(); | 
| -      var profileList = $('profile-list'); | 
| -      this.numCreditCards = creditCards.length; | 
| -      this.creditCardGUIDs = new Array(this.numCreditCards); | 
| -      for (var i = 0; i < this.numCreditCards; i++) { | 
| -        var creditCard = creditCards[i]; | 
| -        var option = new Option(creditCard['label']); | 
| -        this.creditCardGUIDs[i] = creditCard['guid']; | 
| -        profileList.add(option, null); | 
| -      } | 
| - | 
| -      this.updateButtonState_(); | 
| -    }, | 
| - | 
| -    /** | 
| -     * Sets the enabled state of the AutoFill Add Address and Credit Card | 
| -     * buttons on the current state of the |autoFillEnabled| checkbox. | 
| -     * Sets the enabled state of the AutoFill Edit and Remove buttons based on | 
| -     * the current selection in the profile list. | 
| -     * @private | 
| -     */ | 
| -    updateButtonState_: function() { | 
| -      var disabled = !$('autoFillEnabled').checked; | 
| -      $('add-address-button').disabled = disabled; | 
| -      $('add-credit-card-button').disabled = disabled; | 
| - | 
| -      disabled = disabled || ($('profile-list').selectedIndex == -1); | 
| -      $('autofill-remove-button').disabled = disabled; | 
| -      $('autofill-edit-button').disabled = disabled; | 
| -    }, | 
| - | 
| -    /** | 
| -     * Calls into the browser to load either an address or a credit card, | 
| -     * depending on the selected index.  The browser calls back into either | 
| -     * editAddress() or editCreditCard() which show their respective editors. | 
| -     * @private | 
| -     */ | 
| -    editProfile_: function() { | 
| -      var idx = $('profile-list').selectedIndex; | 
| -      if ((profileIndex = this.getAddressIndex_(idx)) != -1) { | 
| -        chrome.send('editAddress', [this.addressGUIDs[profileIndex]]); | 
| -      } else if ((profileIndex = this.getCreditCardIndex_(idx)) != -1) { | 
| -        chrome.send('editCreditCard', [this.creditCardGUIDs[profileIndex]]); | 
| -      } | 
| -    }, | 
| - | 
| -    /** | 
| -     * Removes the currently selected profile, whether it's an address or a | 
| -     * credit card. | 
| +     * Shows the 'Edit address' overlay, using the data in |address| to fill the | 
| +     * input fields. |address| is a list with one item, an associative array | 
| +     * that contains the address data. | 
| * @private | 
| */ | 
| -    removeProfile_: function() { | 
| -      var idx = $('profile-list').selectedIndex; | 
| -      if ((profileIndex = this.getAddressIndex_(idx)) != -1) | 
| -        chrome.send('removeAddress', [this.addressGUIDs[profileIndex]]); | 
| -      else if ((profileIndex = this.getCreditCardIndex_(idx)) != -1) | 
| -        chrome.send('removeCreditCard', [this.creditCardGUIDs[profileIndex]]); | 
| +    showEditAddressOverlay_: function(address) { | 
| +      var title = localStrings.getString('editAddressTitle'); | 
| +      AutoFillEditAddressOverlay.setTitle(title); | 
| +      AutoFillEditAddressOverlay.loadAddress(address[0]); | 
| +      OptionsPage.showOverlay('autoFillEditAddressOverlay'); | 
| }, | 
|  | 
| /** | 
| -     * Returns the index into the address list based on |index|, the index into | 
| -     * the select control. Returns -1 if this is not an address index. | 
| +     * Shows the 'Edit credit card' overlay, using the data in |credit_card| to | 
| +     * fill the input fields. |address| is a list with one item, an associative | 
| +     * array that contains the credit card data. | 
| * @private | 
| */ | 
| -    getAddressIndex_: function(index) { | 
| -      index -= addressOffset; | 
| -      if (index >= 0 && index < this.numAddresses) | 
| -        return index; | 
| - | 
| -      return -1; | 
| +    showEditCreditCardOverlay_: function(creditCard) { | 
| +      var title = localStrings.getString('editCreditCardTitle'); | 
| +      AutoFillEditCreditCardOverlay.setTitle(title); | 
| +      AutoFillEditCreditCardOverlay.loadCreditCard(creditCard[0]); | 
| +      OptionsPage.showOverlay('autoFillEditCreditCardOverlay'); | 
| }, | 
| +  }; | 
|  | 
| -    /** | 
| -     * Returns the index into the credit card list based on |index|, the index | 
| -     * into the select control. Returns -1 if this is not a credit card index. | 
| -     * @private | 
| -     */ | 
| -    getCreditCardIndex_: function(index) { | 
| -      index -= addressOffset + this.numAddresses + creditCardOffset; | 
| -      if (index >= 0 && index < this.numCreditCards) | 
| -        return index; | 
| +  AutoFillOptions.setAddressList = function(entries) { | 
| +    AutoFillOptions.getInstance().setAddressList_(entries); | 
| +  }; | 
|  | 
| -      return -1; | 
| -    }, | 
| +  AutoFillOptions.setCreditCardList = function(entries) { | 
| +    AutoFillOptions.getInstance().setCreditCardList_(entries); | 
| +  }; | 
|  | 
| -    /** | 
| -     * Returns true if |index| points to a credit card profile. | 
| -     * @private | 
| -     */ | 
| -    profileIndexIsCreditCard_: function(index) { | 
| -      index -= addressOffset + this.numAddresses + creditCardOffset; | 
| -      return (index >= 0 && index < this.numCreditCards); | 
| -    } | 
| +  AutoFillOptions.removeAutoFillProfile = function(guid) { | 
| +    AutoFillOptions.getInstance().removeAutoFillProfile_(guid); | 
| }; | 
|  | 
| -  AutoFillOptions.updateAddresses = function(addresses) { | 
| -    AutoFillOptions.getInstance().updateAddresses_(addresses); | 
| +  AutoFillOptions.loadProfileEditor = function(guid) { | 
| +    AutoFillOptions.getInstance().loadProfileEditor_(guid); | 
| }; | 
|  | 
| AutoFillOptions.editAddress = function(address) { | 
| AutoFillOptions.getInstance().showEditAddressOverlay_(address); | 
| }; | 
|  | 
| -  AutoFillOptions.updateCreditCards = function(creditCards) { | 
| -    AutoFillOptions.getInstance().updateCreditCards_(creditCards); | 
| -  }; | 
| - | 
| AutoFillOptions.editCreditCard = function(creditCard) { | 
| AutoFillOptions.getInstance().showEditCreditCardOverlay_(creditCard); | 
| }; | 
|  |