Bug 1449055 Convert formautofill to a webextension
MozReview-Commit-ID: Cpecuks22Dz
rename from browser/extensions/formautofill/bootstrap.js
rename to browser/extensions/formautofill/api.js
--- a/browser/extensions/formautofill/bootstrap.js
+++ b/browser/extensions/formautofill/api.js
@@ -1,25 +1,22 @@
/* 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/. */
"use strict";
-/* exported startup, shutdown, install, uninstall */
+/* globals ExtensionAPI */
const STYLESHEET_URI = "chrome://formautofill/content/formautofill.css";
const CACHED_STYLESHEETS = new WeakMap();
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
-ChromeUtils.defineModuleGetter(this, "AddonManagerPrivate",
- "resource://gre/modules/AddonManager.jsm");
ChromeUtils.defineModuleGetter(this, "FormAutofill",
"resource://formautofill/FormAutofill.jsm");
ChromeUtils.defineModuleGetter(this, "formAutofillParent",
"resource://formautofill/FormAutofillParent.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "resProto",
"@mozilla.org/network/protocol;1?name=resource",
"nsISubstitutingProtocolHandler");
@@ -45,23 +42,16 @@ function onMaybeOpenPopup(evt) {
if (CACHED_STYLESHEETS.has(domWindow)) {
// This window already has autofill stylesheets.
return;
}
insertStyleSheet(domWindow, STYLESHEET_URI);
}
-function addUpgradeListener(instanceID) {
- AddonManager.addUpgradeListener(instanceID, upgrade => {
- // don't install the upgrade by doing nothing here.
- // The upgrade will be installed upon next restart.
- });
-}
-
function isAvailable() {
let availablePref = Services.prefs.getCharPref("extensions.formautofill.available");
if (availablePref == "on") {
return true;
} else if (availablePref == "detect") {
let locale = Services.locale.getRequestedLocale();
let region = Services.prefs.getCharPref("browser.search.region", "");
let supportedCountries = Services.prefs.getCharPref("extensions.formautofill.supportedCountries")
@@ -70,90 +60,86 @@ function isAvailable() {
Services.locale.isAppLocaleRTL) {
return false;
}
return locale == "en-US" && supportedCountries.includes(region);
}
return false;
}
-function startup(data) {
- // We have to do this before actually determining if we're enabled, since
- // there are scripts inside of the core browser code that depend on the
- // FormAutofill JSMs being registered.
- resProto.setSubstitution(RESOURCE_HOST,
- Services.io.newURI("chrome/res/", null, data.resourceURI));
+this.formautofill = class extends ExtensionAPI {
+ onStartup() {
+ // We have to do this before actually determining if we're enabled, since
+ // there are scripts inside of the core browser code that depend on the
+ // FormAutofill JSMs being registered.
+ let uri = Services.io.newURI("chrome/res/", null, this.extension.rootURI);
+ resProto.setSubstitution(RESOURCE_HOST, uri);
+
+ let aomStartup = Cc["@mozilla.org/addons/addon-manager-startup;1"]
+ .getService(Ci.amIAddonManagerStartup);
+ const manifestURI = Services.io.newURI("manifest.json", null, this.extension.rootURI);
+ this.chromeHandle = aomStartup.registerChrome(manifestURI, [
+ ["content", "formautofill", "chrome/content/"],
+ ["locale", "formautofill", "en-US", "en-US/locale/en-US/"],
+ ]);
+
+ if (!isAvailable()) {
+ Services.prefs.clearUserPref("dom.forms.autocomplete.formautofill");
+ // reset the sync related prefs incase the feature was previously available
+ // but isn't now.
+ Services.prefs.clearUserPref("services.sync.engine.addresses.available");
+ Services.prefs.clearUserPref("services.sync.engine.creditcards.available");
+ Services.telemetry.scalarSet("formautofill.availability", false);
+ return;
+ }
- if (!isAvailable()) {
- Services.prefs.clearUserPref("dom.forms.autocomplete.formautofill");
- // reset the sync related prefs incase the feature was previously available
- // but isn't now.
- Services.prefs.clearUserPref("services.sync.engine.addresses.available");
- Services.prefs.clearUserPref("services.sync.engine.creditcards.available");
- Services.telemetry.scalarSet("formautofill.availability", false);
- return;
- }
+ // This pref is used for web contents to detect the autocomplete feature.
+ // When it's true, "element.autocomplete" will return tokens we currently
+ // support -- otherwise it'll return an empty string.
+ Services.prefs.setBoolPref("dom.forms.autocomplete.formautofill", true);
+ Services.telemetry.scalarSet("formautofill.availability", true);
- if (data.hasOwnProperty("instanceID") && data.instanceID) {
- if (AddonManagerPrivate.isDBLoaded()) {
- addUpgradeListener(data.instanceID);
+ // This pref determines whether the "addresses"/"creditcards" sync engine is
+ // available (ie, whether it is shown in any UI etc) - it *does not* determine
+ // whether the engine is actually enabled or not.
+ Services.prefs.setBoolPref("services.sync.engine.addresses.available", true);
+ if (FormAutofill.isAutofillCreditCardsAvailable) {
+ Services.prefs.setBoolPref("services.sync.engine.creditcards.available", true);
} else {
- // Wait for the extension database to be loaded so we don't cause its init.
- Services.obs.addObserver(function xpiDatabaseLoaded() {
- Services.obs.removeObserver(xpiDatabaseLoaded, "xpi-database-loaded");
- addUpgradeListener(data.instanceID);
- }, "xpi-database-loaded");
+ Services.prefs.clearUserPref("services.sync.engine.creditcards.available");
}
- } else {
- throw Error("no instanceID passed to bootstrap startup");
+
+ // Listen for the autocomplete popup message to lazily append our stylesheet related to the popup.
+ Services.mm.addMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
+
+ formAutofillParent.init().catch(Cu.reportError);
+ /* eslint-disable no-unused-vars */
+ Services.ppmm.loadProcessScript("data:,new " + function() {
+ ChromeUtils.import("resource://formautofill/FormAutofillContent.jsm");
+ }, true);
+ /* eslint-enable no-unused-vars */
+ Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillFrameScript.js", true);
}
- // This pref is used for web contents to detect the autocomplete feature.
- // When it's true, "element.autocomplete" will return tokens we currently
- // support -- otherwise it'll return an empty string.
- Services.prefs.setBoolPref("dom.forms.autocomplete.formautofill", true);
- Services.telemetry.scalarSet("formautofill.availability", true);
+ onShutdown() {
+ resProto.setSubstitution(RESOURCE_HOST, null);
- // This pref determines whether the "addresses"/"creditcards" sync engine is
- // available (ie, whether it is shown in any UI etc) - it *does not* determine
- // whether the engine is actually enabled or not.
- Services.prefs.setBoolPref("services.sync.engine.addresses.available", true);
- if (FormAutofill.isAutofillCreditCardsAvailable) {
- Services.prefs.setBoolPref("services.sync.engine.creditcards.available", true);
- } else {
- Services.prefs.clearUserPref("services.sync.engine.creditcards.available");
- }
+ this.chromeHandle.destruct();
+ this.chromeHandle = null;
- // Listen for the autocomplete popup message to lazily append our stylesheet related to the popup.
- Services.mm.addMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
+ Services.mm.removeMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
- formAutofillParent.init().catch(Cu.reportError);
- /* eslint-disable no-unused-vars */
- Services.ppmm.loadProcessScript("data:,new " + function() {
- ChromeUtils.import("resource://formautofill/FormAutofillContent.jsm");
- }, true);
- /* eslint-enable no-unused-vars */
- Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillFrameScript.js", true);
-}
-
-function shutdown() {
- resProto.setSubstitution(RESOURCE_HOST, null);
+ let enumerator = Services.wm.getEnumerator("navigator:browser");
+ while (enumerator.hasMoreElements()) {
+ let win = enumerator.getNext();
+ let domWindow = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
+ let cachedStyleSheets = CACHED_STYLESHEETS.get(domWindow);
- Services.mm.removeMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
+ if (!cachedStyleSheets) {
+ continue;
+ }
- let enumerator = Services.wm.getEnumerator("navigator:browser");
- while (enumerator.hasMoreElements()) {
- let win = enumerator.getNext();
- let domWindow = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
- let cachedStyleSheets = CACHED_STYLESHEETS.get(domWindow);
-
- if (!cachedStyleSheets) {
- continue;
- }
-
- while (cachedStyleSheets.length !== 0) {
- cachedStyleSheets.pop().remove();
+ while (cachedStyleSheets.length !== 0) {
+ cachedStyleSheets.pop().remove();
+ }
}
}
-}
-
-function install() {}
-function uninstall() {}
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/background.js
@@ -0,0 +1,8 @@
+/* eslint-env webextensions */
+
+"use strict";
+
+browser.runtime.onUpdateAvailable.addListener(details => {
+ // By listening to but ignoring this event, any updates will
+ // be delayed until the next browser restart.
+});
--- a/browser/extensions/formautofill/content/editAddress.xhtml
+++ b/browser/extensions/formautofill/content/editAddress.xhtml
@@ -4,19 +4,19 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title data-localization="addNewAddressTitle"/>
- <link rel="stylesheet" href="chrome://formautofill-shared/skin/editDialog.css"/>
- <link rel="stylesheet" href="chrome://formautofill-shared/skin/editAddress.css"/>
- <link rel="stylesheet" href="chrome://formautofill/skin/editDialog.css"/>
+ <link rel="stylesheet" href="resource://formautofill/editDialog-shared.css"/>
+ <link rel="stylesheet" href="resource://formautofill/editAddress.css"/>
+ <link rel="stylesheet" href="resource://formautofill/editDialog.css"/>
<script src="chrome://formautofill/content/l10n.js"></script>
<script src="chrome://formautofill/content/editDialog.js"></script>
<script src="chrome://formautofill/content/autofillEditForms.js"></script>
</head>
<body dir="&locale.dir;">
<form id="form" autocomplete="off">
<div>
<div id="name-container">
--- a/browser/extensions/formautofill/content/editCreditCard.xhtml
+++ b/browser/extensions/formautofill/content/editCreditCard.xhtml
@@ -4,19 +4,19 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title data-localization="addNewCreditCardTitle"/>
- <link rel="stylesheet" href="chrome://formautofill-shared/skin/editDialog.css"/>
- <link rel="stylesheet" href="chrome://formautofill-shared/skin/editCreditCard.css"/>
- <link rel="stylesheet" href="chrome://formautofill/skin/editDialog.css"/>
+ <link rel="stylesheet" href="resource://formautofill/editDialog-shared.css"/>
+ <link rel="stylesheet" href="resource://formautofill/editCreditCard.css"/>
+ <link rel="stylesheet" href="resource://formautofill/editDialog.css"/>
<script src="chrome://formautofill/content/l10n.js"></script>
<script src="chrome://formautofill/content/editDialog.js"></script>
<script src="chrome://formautofill/content/autofillEditForms.js"></script>
</head>
<body dir="&locale.dir;">
<form id="form" autocomplete="off">
<label>
<span data-localization="cardNumber"/>
--- a/browser/extensions/formautofill/jar.mn
+++ b/browser/extensions/formautofill/jar.mn
@@ -1,18 +1,11 @@
# 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/.
[features/formautofill@mozilla.org] chrome.jar:
-% resource formautofill %res/
res/ (*.jsm)
res/phonenumberutils/ (phonenumberutils/*.jsm)
res/addressmetadata/ (addressmetadata/*)
-
-% content formautofill %content/
- content/ (content/*)
+ res/ (skin/shared/*)
-% skin formautofill classic/1.0 %skin/linux/ os=LikeUnix
-% skin formautofill classic/1.0 %skin/osx/ os=Darwin
-% skin formautofill classic/1.0 %skin/windows/ os=WINNT
-% skin formautofill-shared classic/1.0 %skin/shared/
- skin/ (skin/*)
+ content/ (content/*)
rename from browser/extensions/formautofill/install.rdf.in
rename to browser/extensions/formautofill/manifest.json
--- a/browser/extensions/formautofill/install.rdf.in
+++ b/browser/extensions/formautofill/manifest.json
@@ -1,32 +1,26 @@
-<?xml version="1.0"?>
-<!-- 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/. -->
+{
+ "manifest_version": 2,
+ "name": "Form Autofill",
+ "version": "1.0",
-#filter substitution
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ "applications": {
+ "gecko": {
+ "id": "formautofill@mozilla.org"
+ }
+ },
- <Description about="urn:mozilla:install-manifest">
- <em:id>formautofill@mozilla.org</em:id>
- <em:version>1.0</em:version>
- <em:type>2</em:type>
- <em:bootstrap>true</em:bootstrap>
- <em:multiprocessCompatible>true</em:multiprocessCompatible>
+ "background": {
+ "scripts": ["background.js"]
+ },
- <!-- Target Application this extension can install into,
- with minimum and maximum supported versions. -->
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
- <em:maxVersion>@MOZ_APP_MAXVERSION@</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <!-- Front End MetaData -->
- <em:name>Form Autofill</em:name>
- <em:description>Autofill forms with saved profiles</em:description>
- </Description>
-</RDF>
+ "experiment_apis": {
+ "formautofill": {
+ "schema": "schema.json",
+ "parent": {
+ "scopes": ["addon_parent"],
+ "script": "api.js",
+ "events": ["startup"]
+ }
+ }
+ }
+}
--- a/browser/extensions/formautofill/moz.build
+++ b/browser/extensions/formautofill/moz.build
@@ -5,22 +5,37 @@
# 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 += ['locales']
FINAL_TARGET_FILES.features['formautofill@mozilla.org'] += [
- 'bootstrap.js'
+ 'api.js',
+ 'background.js',
+ 'manifest.json',
+ 'schema.json',
]
-FINAL_TARGET_PP_FILES.features['formautofill@mozilla.org'] += [
- 'install.rdf.in'
-]
+if CONFIG['OS_ARCH'] == 'Linux':
+ FINAL_TARGET_FILES.features['formautofill@mozilla.org'].chrome.res += [
+ 'skin/linux/autocomplete-item.css',
+ 'skin/linux/editDialog.css',
+ ]
+elif CONFIG['OS_ARCH'] == 'Darwin':
+ FINAL_TARGET_FILES.features['formautofill@mozilla.org'].chrome.res += [
+ 'skin/osx/autocomplete-item.css',
+ 'skin/osx/editDialog.css',
+ ]
+elif CONFIG['OS_ARCH'] == 'WINNT':
+ FINAL_TARGET_FILES.features['formautofill@mozilla.org'].chrome.res += [
+ 'skin/windows/autocomplete-item.css',
+ 'skin/windows/editDialog.css',
+ ]
BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']
JAR_MANIFESTS += ['jar.mn']
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/schema.json
@@ -0,0 +1,1 @@
+[]
rename from browser/extensions/formautofill/skin/shared/autocomplete-item.css
rename to browser/extensions/formautofill/skin/shared/autocomplete-item-shared.css
rename from browser/extensions/formautofill/skin/shared/editDialog.css
rename to browser/extensions/formautofill/skin/shared/editDialog-shared.css
--- a/toolkit/content/widgets.css
+++ b/toolkit/content/widgets.css
@@ -3,18 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* ===== widgets.css =====================================================
== Styles ported from XBL <resources>, loaded by "global.css".
======================================================================= */
@import url("chrome://global/content/autocomplete.css");
@import url("chrome://global/skin/autocomplete.css");
-@import url("chrome://formautofill-shared/skin/autocomplete-item.css");
-@import url("chrome://formautofill/skin/autocomplete-item.css");
+@import url("resource://formautofill/autocomplete-item-shared.css");
+@import url("resource://formautofill/autocomplete-item.css");
@import url("chrome://global/skin/dialog.css");
@import url("chrome://global/skin/dropmarker.css");
@import url("chrome://global/skin/groupbox.css");
@import url("chrome://global/skin/menu.css");
@import url("chrome://global/skin/menulist.css");
@import url("chrome://global/skin/notification.css");
@import url("chrome://global/skin/popup.css");
@import url("chrome://global/skin/progressmeter.css");