Bug 1394704 - Early return ManageRecords.loadRecords during the loading process. r=lchang,scottwu
authorSean Lee <selee@mozilla.com>
Tue, 29 Aug 2017 14:09:18 +0800
changeset 428237 94f3d2f692069f5970ffe47ac67fff472ec23d5e
parent 428236 b0599327dfdd1a49fe863c5473b7fb15590da3a3
child 428238 3dbc8ba3dc09376c7ead3579837254c9b8fb2339
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslchang, scottwu
bugs1394704
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1394704 - Early return ManageRecords.loadRecords during the loading process. r=lchang,scottwu MozReview-Commit-ID: 8yR6kDg67PL
browser/extensions/formautofill/content/manageDialog.js
--- a/browser/extensions/formautofill/content/manageDialog.js
+++ b/browser/extensions/formautofill/content/manageDialog.js
@@ -24,16 +24,18 @@ this.log = null;
 FormAutofillUtils.defineLazyLogGetter(this, "manageAddresses");
 
 class ManageRecords {
   constructor(subStorageName, elements) {
     this._storageInitPromise = profileStorage.initialize();
     this._subStorageName = subStorageName;
     this._elements = elements;
     this._records = [];
+    this._newRequest = false;
+    this._isLoadingRecords = false;
     this.prefWin = window.opener;
     this.localizeDocument();
     window.addEventListener("DOMContentLoaded", this, {once: true});
   }
 
   async init() {
     await this.loadRecords();
     this.attachEventListeners();
@@ -65,27 +67,50 @@ class ManageRecords {
    * @returns {object}
    */
   async getStorage() {
     await this._storageInitPromise;
     return profileStorage[this._subStorageName];
   }
 
   /**
-   * Load records and render them.
+   * Load records and render them. This function is a wrapper for _loadRecords
+   * to ensure any reentrant will be handled well.
    */
   async loadRecords() {
+    // This function can be early returned when there is any reentrant happends.
+    // "_newRequest" needs to be set to ensure all changes will be applied.
+    if (this._isLoadingRecords) {
+      this._newRequest = true;
+      return;
+    }
+    this._isLoadingRecords = true;
+
+    await this._loadRecords();
+
+    // _loadRecords should be invoked again if there is any multiple entrant
+    // during running _loadRecords(). This step ensures that the latest request
+    // still is applied.
+    while (this._newRequest) {
+      this._newRequest = false;
+      await this._loadRecords();
+    }
+    this._isLoadingRecords = false;
+
+    // For testing only: Notify when records are loaded
+    this._elements.records.dispatchEvent(new CustomEvent("RecordsLoaded"));
+  }
+
+  async _loadRecords() {
     let storage = await this.getStorage();
     let records = storage.getAll();
     // Sort by last modified time starting with most recent
     records.sort((a, b) => b.timeLastModified - a.timeLastModified);
     await this.renderRecordElements(records);
     this.updateButtonsStates(this._selectedOptions.length);
-    // For testing only: Notify when records are loaded
-    this._elements.records.dispatchEvent(new CustomEvent("RecordsLoaded"));
   }
 
   /**
    * Render the records onto the page while maintaining selected options if
    * they still exist.
    *
    * @param  {array<object>} records
    */