Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>10.0.21</Version>
<Version>10.0.22</Version>
</PropertyGroup>

<PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/components/BootstrapBlazor.PdfReader/PdfReader.razor
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@
</div>
</div>
</div>
<div class="bb-view-pdf-backdrop invisible"></div>
<div class="bb-view-pdf-info invisible">
<div class="bb-view-pdf-backdrop"></div>
<div class="bb-view-pdf-dialog">
<div class="bb-view-pdf-dialog-title mb-3">@Localizer["DocumentProperties"]</div>
<div class="bb-view-pdf-dialog-item">
Expand Down
43 changes: 27 additions & 16 deletions src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ const addToolbarEventHandlers = (el, pdfViewer, invoke, options) => {
rotateView(pdfViewer, 90);
});
EventHandler.on(toolbar, "click", ".bb-view-print", async e => {
await printPdf(el, options);
printPdf(el, options);
await invoke.invokeMethodAsync("Printing");
})
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid automated semicolon insertion (95% of all statements in the enclosing function have an explicit semicolon).

Copilot uses AI. Check for mistakes.
EventHandler.on(toolbar, "click", ".dropdown-item-pages", async e => {
Expand All @@ -540,15 +540,15 @@ const addToolbarEventHandlers = (el, pdfViewer, invoke, options) => {
pdfViewer.spreadMode = 0;
}
});
EventHandler.on(toolbar, "click", ".bb-view-download", async e => {
EventHandler.on(toolbar, "click", ".bb-view-download", e => {
let fileName = el.getAttribute('data-bb-download');
if (fileName === null) {
const docTitle = el.querySelector('.bb-view-subject');
if (docTitle) {
fileName = docTitle.textContent;
}
}
await downloadPdf(options, fileName);
downloadPdf(options, fileName);
});

EventHandler.on(toolbar, "click", ".dropdown-item-presentation", async e => {
Expand All @@ -562,6 +562,8 @@ const addToolbarEventHandlers = (el, pdfViewer, invoke, options) => {
//}
});
EventHandler.on(toolbar, "click", ".dropdown-item-doc", e => {
showBackdrop(el);

const dialog = el.querySelector(".bb-view-pdf-info");
if (dialog) {
dialog.classList.add("show");
Expand All @@ -574,25 +576,23 @@ const addToolbarEventHandlers = (el, pdfViewer, invoke, options) => {
if (dialog) {
dialog.classList.remove("show");
}

hideBackdrop(el);
});
}

const downloadPdf = async (options, fileName) => {
const downloadPdf = (options, fileName) => {
if (fileName === null) {
fileName = "download.pdf";
}

await getPdfUrl(options, url => {
getPdfUrl(options, url => {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName;
document.body.appendChild(anchorElement);
anchorElement.click();
document.body.removeChild(anchorElement);

return new Promise((resolve, reject) => {
resolve();
});
});
}

Expand Down Expand Up @@ -761,7 +761,7 @@ const makeThumb = async page => {
return canvas;
}

const printPdf = async (el, options) => {
const printPdf = (el, options) => {
let iframe = el.querySelector(".bb-view-print-iframe");
if (iframe === null) {
iframe = document.createElement("iframe");
Expand All @@ -772,26 +772,37 @@ const printPdf = async (el, options) => {
el.appendChild(iframe);
}

await getPdfUrl(options, url => {
getPdfUrl(options, url => {
iframe.src = url;
iframe.onload = () => {
iframe.contentWindow.focus();
iframe.contentWindow.print();
};
return new Promise((resolve, reject) => {
resolve();
});
});
}

const getPdfUrl = async (options, callback) => {
const showBackdrop = el => {
const backdrop = el.querySelector('.bb-view-pdf-backdrop');
if (backdrop) {
backdrop.classList.add('show');
}
}

const hideBackdrop = el => {
const backdrop = el.querySelector('.bb-view-pdf-backdrop');
if (backdrop) {
backdrop.classList.remove('show');
}
}

const getPdfUrl = (options, callback) => {
if (options.url) {
callback(options.url);
}
else if (options.data) {
const blob = new Blob([options.data], { type: 'application/pdf' });
var url = window.URL.createObjectURL(blob);
await callback(url);
callback(url);
window.URL.revokeObjectURL(url);
Comment on lines +805 to 806
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback is invoked synchronously, but the URL is immediately revoked on the next line. This creates a race condition where the URL may be revoked before it's fully used by the callback (e.g., before the download anchor is clicked or the iframe loads). Consider making the callback asynchronous or using a timeout/event listener to ensure the URL is used before being revoked.

Copilot uses AI. Check for mistakes.
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@
inset: 0;
}

.bb-view-pdf-backdrop {
position: absolute;
inset: 0;
background-color: #000;
opacity: 0.6;
z-index: 1;
}

.bb-view-pdf-backdrop:not(.show) {
display: none;
}

.bb-view-pdf-info {
position: absolute;
inset: 0;
Expand All @@ -250,14 +262,6 @@
display: none;
}

.bb-view-pdf-backdrop {
position: absolute;
inset: 0;
background-color: #000;
opacity: 0.6;
z-index: 1;
}

.bb-view-pdf-dialog {
background-color: #fff;
padding: 1rem;
Expand Down
Loading