diff --git a/browser/extensions/formautofill/FormAutofillParent.jsm b/browser/extensions/formautofill/FormAutofillParent.jsm index 373795fcb83e..a8830be3c1f7 100644 --- a/browser/extensions/formautofill/FormAutofillParent.jsm +++ b/browser/extensions/formautofill/FormAutofillParent.jsm @@ -77,8 +77,9 @@ FormAutofillParent.prototype = { Services.obs.addObserver(this, "advanced-pane-loaded", false); - // Observing the pref (and storage) changes + // Observing the pref and storage changes Services.prefs.addObserver(ENABLED_PREF, this, false); + Services.obs.addObserver(this, "formautofill-storage-changed", false); this._enabled = this._getStatus(); // Force to trigger the onStatusChanged function for setting listeners properly // while initizlization @@ -109,6 +110,20 @@ FormAutofillParent.prototype = { break; } + case "formautofill-storage-changed": { + // Early exit if the action is not "add" nor "remove" + if (data != "add" && data != "remove") { + break; + } + + let currentStatus = this._getStatus(); + if (currentStatus !== this._enabled) { + this._enabled = currentStatus; + this._onStatusChanged(); + } + break; + } + default: { throw new Error(`FormAutofillParent: Unexpected topic observed: ${topic}`); } @@ -131,13 +146,17 @@ FormAutofillParent.prototype = { }, /** - * Query pref (and storage) status to determine the overall status for + * Query pref and storage status to determine the overall status for * form autofill feature. * * @returns {boolean} status of form autofill feature */ _getStatus() { - return Services.prefs.getBoolPref(ENABLED_PREF); + if (!Services.prefs.getBoolPref(ENABLED_PREF)) { + return false; + } + + return this._profileStore.getAll().length > 0; }, /** diff --git a/browser/extensions/formautofill/ProfileStorage.jsm b/browser/extensions/formautofill/ProfileStorage.jsm index 6dab52b99b13..5e604b4859b4 100644 --- a/browser/extensions/formautofill/ProfileStorage.jsm +++ b/browser/extensions/formautofill/ProfileStorage.jsm @@ -132,6 +132,7 @@ ProfileStorage.prototype = { this._store.data.profiles.push(profileToSave); this._store.saveSoon(); + Services.obs.notifyObservers(null, "formautofill-storage-changed", "add"); }, /** @@ -163,6 +164,7 @@ ProfileStorage.prototype = { profileFound.timeLastModified = Date.now(); this._store.saveSoon(); + Services.obs.notifyObservers(null, "formautofill-storage-changed", "update"); }, /** @@ -184,6 +186,7 @@ ProfileStorage.prototype = { profileFound.timeLastUsed = Date.now(); this._store.saveSoon(); + Services.obs.notifyObservers(null, "formautofill-storage-changed", "notifyUsed"); }, /** @@ -199,6 +202,7 @@ ProfileStorage.prototype = { this._store.data.profiles = this._store.data.profiles.filter(profile => profile.guid != guid); this._store.saveSoon(); + Services.obs.notifyObservers(null, "formautofill-storage-changed", "remove"); }, /** @@ -261,7 +265,7 @@ ProfileStorage.prototype = { }, _findByFilter({info, searchString}) { - let profiles = MOCK_MODE ? MOCK_STORAGE : this._store.data.profiles; + let profiles = this._store.data.profiles; let lcSearchString = searchString.toLowerCase(); return profiles.filter(profile => { @@ -296,7 +300,7 @@ ProfileStorage.prototype = { _dataPostProcessor(data) { data.version = SCHEMA_VERSION; if (!data.profiles) { - data.profiles = []; + data.profiles = MOCK_MODE ? MOCK_STORAGE : []; } return data; }, diff --git a/browser/extensions/formautofill/test/unit/head.js b/browser/extensions/formautofill/test/unit/head.js index 0d83e032af88..a49757a340ba 100644 --- a/browser/extensions/formautofill/test/unit/head.js +++ b/browser/extensions/formautofill/test/unit/head.js @@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://testing-common/MockDocument.jsm"); +Cu.import("resource://testing-common/TestUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths", "resource://gre/modules/DownloadPaths.jsm"); diff --git a/browser/extensions/formautofill/test/unit/test_enabledStatus.js b/browser/extensions/formautofill/test/unit/test_enabledStatus.js index 75479d524c25..31ccdf20299f 100644 --- a/browser/extensions/formautofill/test/unit/test_enabledStatus.js +++ b/browser/extensions/formautofill/test/unit/test_enabledStatus.js @@ -34,6 +34,24 @@ add_task(function* test_enabledStatus_observe() { formAutofillParent._getStatus.returns(false); formAutofillParent.observe(null, "nsPref:changed", "browser.formautofill.enabled"); do_check_eq(formAutofillParent._onStatusChanged.called, true); + + // profile added => Need to trigger onStatusChanged + formAutofillParent._getStatus.returns(!formAutofillParent._enabled); + formAutofillParent._onStatusChanged.reset(); + formAutofillParent.observe(null, "formautofill-storage-changed", "add"); + do_check_eq(formAutofillParent._onStatusChanged.called, true); + + // profile removed => Need to trigger onStatusChanged + formAutofillParent._getStatus.returns(!formAutofillParent._enabled); + formAutofillParent._onStatusChanged.reset(); + formAutofillParent.observe(null, "formautofill-storage-changed", "remove"); + do_check_eq(formAutofillParent._onStatusChanged.called, true); + + // profile updated => no need to trigger onStatusChanged + formAutofillParent._getStatus.returns(!formAutofillParent._enabled); + formAutofillParent._onStatusChanged.reset(); + formAutofillParent.observe(null, "formautofill-storage-changed", "update"); + do_check_eq(formAutofillParent._onStatusChanged.called, false); }); add_task(function* test_enabledStatus_getStatus() { @@ -42,9 +60,25 @@ add_task(function* test_enabledStatus_getStatus() { Services.prefs.clearUserPref("browser.formautofill.enabled"); }); + let fakeStorage = []; + formAutofillParent._profileStore = { + getAll: () => fakeStorage, + }; + + // pref is enabled and profile is empty. + Services.prefs.setBoolPref("browser.formautofill.enabled", true); + do_check_eq(formAutofillParent._getStatus(), false); + + // pref is disabled and profile is empty. + Services.prefs.setBoolPref("browser.formautofill.enabled", false); + do_check_eq(formAutofillParent._getStatus(), false); + + fakeStorage = ["test-profile"]; + // pref is enabled and profile is not empty. Services.prefs.setBoolPref("browser.formautofill.enabled", true); do_check_eq(formAutofillParent._getStatus(), true); + // pref is disabled and profile is not empty. Services.prefs.setBoolPref("browser.formautofill.enabled", false); do_check_eq(formAutofillParent._getStatus(), false); }); diff --git a/browser/extensions/formautofill/test/unit/test_profileStorage.js b/browser/extensions/formautofill/test/unit/test_profileStorage.js index eb04fb25564c..d7b0daef00ee 100644 --- a/browser/extensions/formautofill/test/unit/test_profileStorage.js +++ b/browser/extensions/formautofill/test/unit/test_profileStorage.js @@ -39,7 +39,10 @@ let prepareTestProfiles = Task.async(function* (path) { let profileStorage = new ProfileStorage(path); yield profileStorage.initialize(); + let onChanged = TestUtils.topicObserved("formautofill-storage-changed", + (subject, data) => data == "add"); profileStorage.add(TEST_PROFILE_1); + yield onChanged; profileStorage.add(TEST_PROFILE_2); yield profileStorage._saveImmediately(); }); @@ -174,9 +177,13 @@ add_task(function* test_update() { let guid = profiles[1].guid; let timeLastModified = profiles[1].timeLastModified; + let onChanged = TestUtils.topicObserved("formautofill-storage-changed", + (subject, data) => data == "update"); + do_check_neq(profiles[1].country, undefined); profileStorage.update(guid, TEST_PROFILE_3); + yield onChanged; yield profileStorage._saveImmediately(); profileStorage = new ProfileStorage(path); @@ -211,7 +218,11 @@ add_task(function* test_notifyUsed() { let timeLastUsed = profiles[1].timeLastUsed; let timesUsed = profiles[1].timesUsed; + let onChanged = TestUtils.topicObserved("formautofill-storage-changed", + (subject, data) => data == "notifyUsed"); + profileStorage.notifyUsed(guid); + yield onChanged; yield profileStorage._saveImmediately(); profileStorage = new ProfileStorage(path); @@ -236,9 +247,13 @@ add_task(function* test_remove() { let profiles = profileStorage.getAll(); let guid = profiles[1].guid; + let onChanged = TestUtils.topicObserved("formautofill-storage-changed", + (subject, data) => data == "remove"); + do_check_eq(profiles.length, 2); profileStorage.remove(guid); + yield onChanged; yield profileStorage._saveImmediately(); profileStorage = new ProfileStorage(path);