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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { RemotePageChild } from "resource://gre/actors/RemotePageChild.sys.mjs";
const PDF_HEADER = "%PDF-";
export class AboutPDFChild extends RemotePageChild {
actorCreated() {
super.actorCreated();
this.exportFunctions([
"RPMCanSetDefaultPDFHandler",
"RPMOpenPDFFile",
"RPMSetDefaultPDFHandler",
]);
}
RPMCanSetDefaultPDFHandler() {
return this.wrapPromise(this.sendQuery("AboutPDF:CanSetDefaultPDFHandler"));
}
RPMOpenPDFFile(file) {
return this.wrapPromise(this.#openPDFFile(file));
}
RPMSetDefaultPDFHandler() {
if (!this.contentWindow.navigator.userActivation.isActive) {
throw new Error("User activation is required");
}
return this.wrapPromise(this.sendQuery("AboutPDF:SetDefaultPDFHandler"));
}
async #openPDFFile(file) {
if (
!file ||
ChromeUtils.getClassName(file) !== "File" ||
!file.name?.toLowerCase().endsWith(".pdf") ||
!file.mozFullPath ||
!(await this.#looksLikePDF(file))
) {
return false;
}
await this.sendQuery("AboutPDF:OpenFile", {
fileURL: PathUtils.toFileURI(file.mozFullPath),
});
return true;
}
// Cheap pre-filter so the page can flip to its error state instantly without
// a round-trip to the parent. The parent re-validates before navigating.
async #looksLikePDF(file) {
return (await file.slice(0, PDF_HEADER.length).text()) === PDF_HEADER;
}
}