Bug 1304306 - (Part 1) Add Form Autofill preference checkbox and button
MozReview-Commit-ID: I7O4l9aQ5JC
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1574,14 +1574,15 @@ pref("browser.crashReports.unsubmittedCh
#ifdef NIGHTLY_BUILD
// Enable the (fairly costly) client/server validation on nightly only. The other prefs
// controlling validation are located in /services/sync/services-sync.js
pref("services.sync.validation.enabled", true);
#endif
// Preferences for the form autofill system extension
pref("browser.formautofill.experimental", false);
+pref("browser.formautofill.enabled", false);
// Enable safebrowsing v4 tables (suffixed by "-proto") update.
#ifdef NIGHTLY_BUILD
pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,goog-malware-proto,goog-unwanted-proto,test-malware-simple,test-unwanted-simple");
pref("urlclassifier.phishTable", "goog-phish-shavar,goog-phish-proto,test-phish-simple");
#endif
--- a/browser/extensions/formautofill/FormAutofillParent.jsm
+++ b/browser/extensions/formautofill/FormAutofillParent.jsm
@@ -27,21 +27,24 @@
/* exported FormAutofillParent */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ProfileStorage",
"resource://formautofill/ProfileStorage.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillPreferences",
+ "resource://formautofill/FormAutofillPreferences.jsm");
const PROFILE_JSON_FILE_NAME = "autofill-profiles.json";
let FormAutofillParent = {
_profileStore: null,
/**
* Initializes ProfileStorage and registers the message handler.
@@ -52,16 +55,18 @@ let FormAutofillParent = {
this._profileStore = new ProfileStorage(storePath);
this._profileStore.initialize();
let mm = Cc["@mozilla.org/globalmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
mm.addMessageListener("FormAutofill:PopulateFieldValues", this);
mm.addMessageListener("FormAutofill:GetProfiles", this);
+
+ Services.obs.addObserver(this, "advanced-pane-loaded", false);
},
/**
* Handles the message coming from FormAutofillContent.
*
* @param {string} message.name The name of the message.
* @param {object} message.data The data of the message.
* @param {nsIFrameMessageManager} message.target Caller's message manager.
@@ -72,16 +77,30 @@ let FormAutofillParent = {
this._populateFieldValues(data, target);
break;
case "FormAutofill:GetProfiles":
this._getProfiles(data, target);
break;
}
},
+ observe: function(subject, topic, data) {
+ switch (topic) {
+ case "advanced-pane-loaded": {
+ let formAutofillPreferences = new FormAutofillPreferences();
+ let document = subject.document;
+ let prefGroup = formAutofillPreferences.init(document);
+ let parentNode = document.getElementById("mainPrefPane");
+ let insertBeforeNode = document.getElementById("locationBarGroup");
+ parentNode.insertBefore(prefGroup, insertBeforeNode);
+ break;
+ }
+ }
+ },
+
/**
* Returns the instance of ProfileStorage. To avoid syncing issues, anyone
* who needs to access the profile should request the instance by this instead
* of creating a new one.
*
* @returns {ProfileStorage}
*/
getProfileStore: function() {
@@ -98,16 +117,18 @@ let FormAutofillParent = {
this._profileStore._saveImmediately();
this._profileStore = null;
}
let mm = Cc["@mozilla.org/globalmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
mm.removeMessageListener("FormAutofill:PopulateFieldValues", this);
mm.removeMessageListener("FormAutofill:GetProfiles", this);
+
+ Services.obs.removeObserver(this, "advanced-pane-loaded");
},
/**
* Populates the field values and notifies content to fill in. Exception will
* be thrown if there's no matching profile.
*
* @private
* @param {string} data.guid
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/FormAutofillPreferences.jsm
@@ -0,0 +1,137 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Creates form autofill preferences group.
+ */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+const PREF_AUTOFILL_ENABLED = "browser.formautofill.enabled";
+
+function FormAutofillPreferences() {
+ this.bundle = Services.strings.createBundle(
+ "chrome://formautofill/locale/formautofill.properties");
+}
+
+FormAutofillPreferences.prototype = {
+ /**
+ * Check if Form Autofill feature is enabled.
+ *
+ * @returns {boolean}
+ */
+ get isAutofillEnabled() {
+ return Services.prefs.getBoolPref(PREF_AUTOFILL_ENABLED);
+ },
+
+ /**
+ * Check if the current page is Preferences/Privacy.
+ *
+ * @returns {boolean}
+ */
+ get isPrivacyPane() {
+ return this.refs.document.location.href == "about:preferences#privacy";
+ },
+
+ /**
+ * Create the Form Autofill preference group.
+ *
+ * @param {XULDocument} document
+ * @returns {XULElement}
+ */
+ init(document) {
+ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+ let formAutofillGroup = document.createElementNS(XUL_NS, "groupbox");
+ let caption = document.createElementNS(XUL_NS, "caption");
+ let captionLabel = document.createElementNS(XUL_NS, "label");
+ let hbox = document.createElementNS(XUL_NS, "hbox");
+ let enabledCheckbox = document.createElementNS(XUL_NS, "checkbox");
+ let spacer = document.createElementNS(XUL_NS, "spacer");
+ let savedProfilesBtn = document.createElementNS(XUL_NS, "button");
+
+ this.refs = {
+ document,
+ formAutofillGroup,
+ enabledCheckbox,
+ savedProfilesBtn,
+ };
+
+ formAutofillGroup.id = "formAutofillGroup";
+ formAutofillGroup.hidden = !this.isPrivacyPane;
+ // Use .setAttribute because HTMLElement.dataset is not available on XUL elements
+ formAutofillGroup.setAttribute("data-category", "panePrivacy");
+
+ captionLabel.textContent = this.bundle.GetStringFromName("preferenceGroupTitle");
+ savedProfilesBtn.setAttribute("label", this.bundle.GetStringFromName("savedProfiles"));
+ enabledCheckbox.setAttribute("label", this.bundle.GetStringFromName("enableProfileAutofill"));
+
+ // Manually set the checked state
+ if (this.isAutofillEnabled) {
+ enabledCheckbox.setAttribute("checked", true);
+ }
+
+ spacer.flex = 1;
+
+ formAutofillGroup.appendChild(caption);
+ caption.appendChild(captionLabel);
+ formAutofillGroup.appendChild(hbox);
+ hbox.appendChild(enabledCheckbox);
+ hbox.appendChild(spacer);
+ hbox.appendChild(savedProfilesBtn);
+
+ this.attachEventListeners();
+
+ return formAutofillGroup;
+ },
+
+ /**
+ * Remove event listeners and the preference group.
+ */
+ uninit() {
+ this.detachEventListeners();
+ this.refs.formAutofillGroup.remove();
+ },
+
+ /**
+ * Handle events
+ *
+ * @param {DOMEvent} event
+ */
+ handleEvent(event) {
+ switch (event.type) {
+ case "command": {
+ let target = event.target;
+
+ if (target == this.refs.enabledCheckbox) {
+ // Set preference directly instead of relying on <Preference>
+ Services.prefs.setBoolPref(PREF_AUTOFILL_ENABLED, target.checked);
+ } else if (target == this.refs.savedProfilesBtn) {
+ // TODO: Open Saved Profiles dialog
+ }
+ break;
+ }
+ }
+ },
+
+ /**
+ * Attach event listener
+ */
+ attachEventListeners() {
+ this.refs.formAutofillGroup.addEventListener("command", this);
+ },
+
+ /**
+ * Remove event listener
+ */
+ detachEventListeners() {
+ this.refs.formAutofillGroup.removeEventListener("command", this);
+ },
+};
+
+this.EXPORTED_SYMBOLS = ["FormAutofillPreferences"];
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/locale/en-US/formautofill.properties
@@ -0,0 +1,7 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+preferenceGroupTitle = Form Autofill
+enableProfileAutofill = Enable Profile Autofill
+savedProfiles = Saved Profiles…
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/locale/jar.mn
@@ -0,0 +1,8 @@
+#filter substitution
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+@AB_CD@.jar:
+% locale formautofill @AB_CD@ %locale/@AB_CD@/
+ locale/@AB_CD@/ (en-US/*)
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/locale/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+JAR_MANIFESTS += ['jar.mn']
--- a/browser/extensions/formautofill/moz.build
+++ b/browser/extensions/formautofill/moz.build
@@ -2,16 +2,18 @@
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
+DIRS += ['locale']
+
FINAL_TARGET_FILES.features['formautofill@mozilla.org'] += [
'bootstrap.js'
]
FINAL_TARGET_PP_FILES.features['formautofill@mozilla.org'] += [
'install.rdf.in'
]