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 { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
const PDF_HEADER = "%PDF-";
let ShellService = null;
try {
({ ShellService } = ChromeUtils.importESModule(
// eslint-disable-next-line mozilla/no-browser-refs-in-toolkit
"moz-src:///browser/components/shell/ShellService.sys.mjs"
));
} catch {}
export class AboutPDFParent extends JSWindowActorParent {
receiveMessage(message) {
switch (message.name) {
case "AboutPDF:CanSetDefaultPDFHandler":
return this.#canSetDefaultPDFHandler();
case "AboutPDF:OpenFile":
return this.#openFile(message.data?.fileURL);
case "AboutPDF:SetDefaultPDFHandler":
return this.#setDefaultPDFHandler();
}
return undefined;
}
#canSetDefaultPDFHandler() {
if (!ShellService || AppConstants.platform != "win") {
return false;
}
try {
return !ShellService.isDefaultHandlerFor(".pdf");
} catch {
return false;
}
}
async #openFile(fileURL) {
if (typeof fileURL !== "string") {
throw new Error("Expected a file URL");
}
let uri = Services.io.newURI(fileURL);
if (!uri.schemeIs("file")) {
throw new Error("Expected a file URL");
}
let nsFile = uri.QueryInterface(Ci.nsIFileURL).file;
if (!nsFile.leafName.toLowerCase().endsWith(".pdf")) {
throw new Error("Expected a PDF file URL");
}
if (!nsFile.exists() || !nsFile.isFile()) {
throw new Error("Expected an existing PDF file");
}
let file = await File.createFromNsIFile(nsFile);
if (!(await this.#looksLikePDF(file))) {
throw new Error("Expected PDF content");
}
this.browsingContext.top.loadURI(uri, {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
}
async #setDefaultPDFHandler() {
if (!this.#canSetDefaultPDFHandler()) {
return;
}
await ShellService.setAsDefaultPDFHandler();
}
async #looksLikePDF(file) {
return (await file.slice(0, PDF_HEADER.length).text()) === PDF_HEADER;
}
}