fix: use blob URL for Firefox downloads (data: URLs are access-denied)
build-extension / build (pull_request) Successful in 33s
build-extension / build (pull_request) Successful in 33s
Firefox rejects data: URLs in browser.downloads.download with "Access denied for URL data:...", breaking the PDF export. Build the download URL per-browser: a blob: object URL where URL.createObjectURL exists (Firefox background page), falling back to the base64 data: URL for Chrome MV3 service workers (no createObjectURL). Bump version to 1.3.0.
This commit is contained in:
+16
-8
@@ -10,11 +10,19 @@ function errMsg(err) {
|
|||||||
return String((err && err.message) || err);
|
return String((err && err.message) || err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a download URL from PDF bytes. Chrome MV3 runs the background as a
|
// Build a download URL from PDF bytes. Firefox's background is a real page
|
||||||
// service worker, where URL.createObjectURL is NOT available, so we use a
|
// (URL.createObjectURL available) and supports blob: URLs in downloads.
|
||||||
// base64 data URL (works in both Firefox and Chrome). PDFs here are small
|
// Chrome MV3 runs the background as a service worker where URL.createObjectURL
|
||||||
// (~150KB), well within data-URL length limits.
|
// is NOT available, but its downloads API accepts base64 data: URLs.
|
||||||
function pdfDataUrl(bytes) {
|
// Firefox rejects data: URLs in browser.downloads.download with
|
||||||
|
// "Access denied for URL data:...", so pick per-browser.
|
||||||
|
function buildDownloadUrl(bytes) {
|
||||||
|
if (typeof URL !== 'undefined' && typeof URL.createObjectURL === 'function') {
|
||||||
|
const blob = new Blob([bytes], { type: 'application/pdf' });
|
||||||
|
return URL.createObjectURL(blob);
|
||||||
|
}
|
||||||
|
// Fallback: Chrome MV3 service worker. PDFs here are small (~150KB), well
|
||||||
|
// within data-URL length limits.
|
||||||
let binary = '';
|
let binary = '';
|
||||||
const chunk = 0x8000;
|
const chunk = 0x8000;
|
||||||
for (let i = 0; i < bytes.length; i += chunk) {
|
for (let i = 0; i < bytes.length; i += chunk) {
|
||||||
@@ -45,9 +53,9 @@ function formatPeriod(period) {
|
|||||||
|
|
||||||
async function generatePdf(data) {
|
async function generatePdf(data) {
|
||||||
const bytes = await ISMIStools.buildStudyLoadPdf(data);
|
const bytes = await ISMIStools.buildStudyLoadPdf(data);
|
||||||
// Chrome MV3 background is a service worker (no URL.createObjectURL), so we
|
// Firefox accepts blob: object URLs; Chrome MV3 service worker has no
|
||||||
// use a base64 data URL that works in both browsers.
|
// URL.createObjectURL, so it falls back to a base64 data: URL there.
|
||||||
const url = pdfDataUrl(bytes);
|
const url = buildDownloadUrl(bytes);
|
||||||
const header = data.header || {};
|
const header = data.header || {};
|
||||||
const year = parseInt(data.year, 10);
|
const year = parseInt(data.year, 10);
|
||||||
const period = formatPeriod(data.period || header.semester || '');
|
const period = formatPeriod(data.period || header.semester || '');
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "ISMIS Helper",
|
"name": "ISMIS Helper",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"description": "Auto-login, auto-accept privacy policy, and Study Load PDF for the USC ISMIS portal.",
|
"description": "Auto-login, auto-accept privacy policy, and Study Load PDF for the USC ISMIS portal.",
|
||||||
"permissions": ["storage", "downloads"],
|
"permissions": ["storage", "downloads"],
|
||||||
"host_permissions": ["https://ismis.usc.edu.ph/*"],
|
"host_permissions": ["https://ismis.usc.edu.ph/*"],
|
||||||
|
|||||||
Reference in New Issue
Block a user