Source code
Revision control
Copy as Markdown
Other Tools
/* 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
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
XPCOMUtils.defineLazyServiceGetter(
lazy,
"serviceWorkerManager",
"@mozilla.org/serviceworkers/manager;1",
"nsIServiceWorkerManager"
);
if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
throw new Error(
"ServiceWorkerCleanUp.sys.mjs can only be used in the parent process"
);
}
function unregisterServiceWorker(aSW) {
return new Promise(resolve => {
let unregisterCallback = {
unregisterSucceeded: resolve,
unregisterFailed: resolve, // We don't care about failures.
QueryInterface: ChromeUtils.generateQI([
"nsIServiceWorkerUnregisterCallback",
]),
};
lazy.serviceWorkerManager.propagateUnregister(
aSW.principal,
unregisterCallback,
aSW.scope
);
});
}
function unregisterServiceWorkersMatching(filterFn) {
let promises = [];
let serviceWorkers = lazy.serviceWorkerManager.getAllRegistrations();
for (let i = 0; i < serviceWorkers.length; i++) {
let sw = serviceWorkers.queryElementAt(
i,
Ci.nsIServiceWorkerRegistrationInfo
);
if (filterFn(sw)) {
promises.push(unregisterServiceWorker(sw));
}
}
return Promise.all(promises);
}
export const ServiceWorkerCleanUp = {
removeFromHost(aHost) {
return unregisterServiceWorkersMatching(sw =>
Services.eTLD.hasRootDomain(sw.principal.host, aHost)
);
},
removeFromSite(aSchemelessSite, aOriginAttributesPattern) {
return unregisterServiceWorkersMatching(sw => {
let { principal } = sw;
let { originAttributes } = principal;
// Check service workers owned by aSchemelessSite.
if (
principal.baseDomain == aSchemelessSite &&
ChromeUtils.originAttributesMatchPattern(
originAttributes,
aOriginAttributesPattern
)
) {
return true;
}
// Check service workers partitioned under aSchemelessSite.
return ChromeUtils.originAttributesMatchPattern(originAttributes, {
partitionKeyPattern: { baseDomain: aSchemelessSite },
...aOriginAttributesPattern,
});
});
},
removeFromPrincipal(aPrincipal) {
return unregisterServiceWorkersMatching(sw =>
sw.principal.equals(aPrincipal)
);
},
removeFromOriginAttributes(aOriginAttributesString) {
lazy.serviceWorkerManager.removeRegistrationsByOriginAttributes(
aOriginAttributesString
);
return Promise.resolve();
},
removeAll() {
return unregisterServiceWorkersMatching(() => true);
},
};