Files
sousa-gecko/browser/extensions/formautofill/api.js
T
Andrew McCreight ebcadf506b Bug 2041784 - Annotate the direct ChromeUtils.register*Actor calls. r=perftest-reviewers,geckoview-reviewers,extension-reviewers,credential-management-reviewers,devtools-reviewers,sync-reviewers,places-reviewers,layout-reviewers,jdescottes,nalexander,Gijs,rpl,skhamis,emilio,nchevobbe,sparky,dimi
This commit and commit message was mostly generated automatically by little_safefor.py.

* Actors that had the annotation added: AllowJavascript, AppTestDelegate,
BrowserTestUtils, Bug1622420, ColorPicker, ContentEventListener, ContentMeta,
DampLoad, DateTimePicker, DocShellHelpers, ForceRefresh, FormAutofill,
FullscreenFrame, Interactions, LayoutDebug, MarionetteCommands, MarionetteEvents,
MarionetteReftest, PageData, PictureInPicture, PictureInPictureLauncher,
PictureInPictureToggle, ReftestFission, Screenshot, Select, SpecialPowers,
SpecialPowersProcessActor, StartupContentSubframe, TPSFxAAutofill, TalosTabSwitch,
TestSupport, TestSupportProcess, TestWorkerWatcher, UserCharacteristicsWindowInfo,
UserCharacteristicsCanvasRendering, WPTEvents, WebDriverDocumentInserted,
WebDriverProcessData, WebDriverWorkerListener

* Actors that were seen that shouldn't have the annotation: AboutNewTab,
AboutTranslations, CodeMirrorTest, MigrationWizard, MozCachedOHTTP,
UserCharacteristics

Files that were skipped by the analysis:
browser/extensions/newtab/lib/ExternalComponentsFeed.sys.mjs
  This one does something weird, but I think it only registers ASRouterNewTabMessage,
  which is non-web.
devtools/server/actors/watcher/ParentProcessWatcherRegistry.sys.mjs
  This one does something weird so it is manually fixed separately.
dom/chrome-webidl/JSProcessActor.webidl
dom/chrome-webidl/JSWindowActor.webidl
  These two files define the register calls and aren't actually calling it.
dom/ipc/tests/JSProcessActor/browser_registerProcessActor.js
dom/ipc/tests/JSProcessActor/head.js
dom/ipc/tests/JSWindowActor/browser_registerWindowActor.js
dom/ipc/tests/JSWindowActor/head.js
  These four files do something weird and this is manually fixed up as part of
  the patch that adds the annotation.
mobile/shared/modules/geckoview/GeckoViewActorManager.sys.mjs
  This file handles the mass-registration of actors and is dealt with
  by the other automated patch. This is also the case for most of the
  registrations in ActorManagerParent.sys.mjs, but we also fix up some
  of the individual registrations in this patch.

Differential Revision: https://phabricator.services.mozilla.com/D304934
2026-06-18 22:10:05 +00:00

187 lines
5.9 KiB
JavaScript

/* 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";
/* globals ExtensionAPI, Services, XPCOMUtils */
const CACHED_STYLESHEETS = new WeakMap();
ChromeUtils.defineESModuleGetters(this, {
AutofillDataTypes: "resource://gre/modules/shared/AutofillDataTypes.sys.mjs",
FormAutofill: "resource://autofill/FormAutofill.sys.mjs",
FormAutofillParent: "resource://autofill/FormAutofillParent.sys.mjs",
FormAutofillStatus: "resource://autofill/FormAutofillParent.sys.mjs",
AutoCompleteParent: "resource://gre/actors/AutoCompleteParent.sys.mjs",
});
XPCOMUtils.defineLazyServiceGetter(
this,
"resProto",
"@mozilla.org/network/protocol;1?name=resource",
Ci.nsISubstitutingProtocolHandler
);
const RESOURCE_HOST = "formautofill";
function insertStyleSheet(domWindow, url) {
let doc = domWindow.document;
let styleSheetAttr = `href="${url}" type="text/css"`;
let styleSheet = doc.createProcessingInstruction(
"xml-stylesheet",
styleSheetAttr
);
doc.insertBefore(styleSheet, doc.documentElement);
if (CACHED_STYLESHEETS.has(domWindow)) {
CACHED_STYLESHEETS.get(domWindow).push(styleSheet);
} else {
CACHED_STYLESHEETS.set(domWindow, [styleSheet]);
}
}
function ensureCssLoaded(domWindow) {
if (CACHED_STYLESHEETS.has(domWindow)) {
// This window already has autofill stylesheets.
return;
}
insertStyleSheet(domWindow, "chrome://formautofill/content/formautofill.css");
}
this.formautofill = class extends ExtensionAPI {
/**
* Adjusts and checks form autofill preferences during startup.
*/
adjustAndCheckFormAutofillPrefs() {
const addressAutofillAvailable = FormAutofill.isAutofillTypeAvailable(
AutofillDataTypes.ADDRESS
);
const creditCardAutofillAvailable = FormAutofill.isAutofillTypeAvailable(
AutofillDataTypes.CREDIT_CARD
);
// Reset the sync prefs in case the features were previously available
// but aren't now.
if (!creditCardAutofillAvailable) {
Services.prefs.clearUserPref(
"services.sync.engine.creditcards.available"
);
}
if (!addressAutofillAvailable) {
Services.prefs.clearUserPref("services.sync.engine.addresses.available");
}
if (!addressAutofillAvailable && !creditCardAutofillAvailable) {
Services.prefs.clearUserPref("dom.forms.autocomplete.formautofill");
Glean.formautofill.availability.set(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);
Glean.formautofill.availability.set(true);
// These "*.available" prefs 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.
if (addressAutofillAvailable) {
Services.prefs.setBoolPref(
"services.sync.engine.addresses.available",
true
);
} else {
Services.prefs.clearUserPref("services.sync.engine.addresses.available");
}
if (creditCardAutofillAvailable) {
Services.prefs.setBoolPref(
"services.sync.engine.creditcards.available",
true
);
} else {
Services.prefs.clearUserPref(
"services.sync.engine.creditcards.available"
);
}
}
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", "content/"],
]);
this.adjustAndCheckFormAutofillPrefs();
// Listen for the autocomplete popup message
// or the form submitted message (which may trigger a
// doorhanger) to lazily append our stylesheets related
// to the autocomplete feature.
AutoCompleteParent.addPopupStateListener(ensureCssLoaded);
FormAutofillParent.addMessageObserver(this);
this.onFormSubmitted = (data, window) => ensureCssLoaded(window);
FormAutofillStatus.init();
ChromeUtils.registerWindowActor("FormAutofill", {
parent: {
esModuleURI: "resource://autofill/FormAutofillParent.sys.mjs",
},
child: {
esModuleURI: "resource://autofill/FormAutofillChild.sys.mjs",
events: {
focusin: { capture: true },
"form-changed": { createActor: false },
"form-submission-detected": { createActor: false },
},
},
allFrames: true,
safeForUntrustedWebProcess: true,
});
}
onShutdown(isAppShutdown) {
if (isAppShutdown) {
return;
}
resProto.setSubstitution(RESOURCE_HOST, null);
this.chromeHandle.destruct();
this.chromeHandle = null;
ChromeUtils.unregisterWindowActor("FormAutofill");
AutoCompleteParent.removePopupStateListener(ensureCssLoaded);
FormAutofillParent.removeMessageObserver(this);
for (let win of Services.wm.getEnumerator("navigator:browser")) {
let cachedStyleSheets = CACHED_STYLESHEETS.get(win);
if (!cachedStyleSheets) {
continue;
}
while (cachedStyleSheets.length !== 0) {
cachedStyleSheets.pop().remove();
}
}
}
};