// ==UserScript==
// @name SBI DOWNLOAD PDF FINAL WORKING 13072026
// @namespace http://tampermonkey.net/
// @version 8.0
// @description Safely add Export as PDF beside SBI Download button
// @match https://yonoretail.sbi.bank.in/*
// @require https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js
// @grant GM_xmlhttpRequest
// @connect *
// @run-at document-idle
// ==/UserScript==
(function(){
'use strict';
/* =====================================================
IMAGE URL LOADER
Supports PNG, JPG, JPEG, WEBP and Base64 images.
===================================================== */
function loadImageForPDF(url) {
return new Promise(function(resolve, reject) {
if (!url || !String(url).trim()) {
resolve(null);
return;
}
const cleanUrl = String(url).trim();
if (cleanUrl.startsWith("data:image/")) {
const match = cleanUrl.match(/^data:image\/(png|jpe?g|webp)/i);
const format = match ? match[1].toUpperCase().replace("JPEG", "JPG") : "PNG";
resolve({
data: cleanUrl,
format: format
});
return;
}
GM_xmlhttpRequest({
method: "GET",
url: cleanUrl,
responseType: "arraybuffer",
timeout: 30000,
onload: function(response) {
try {
if (response.status < 200 || response.status >= 300) {
throw new Error("Image request failed with HTTP " + response.status);
}
const contentType =
response.responseHeaders.match(/content-type:\s*([^\r\n;]+)/i)?.[1] ||
"";
let mimeType = contentType.toLowerCase();
if (!mimeType.startsWith("image/")) {
const lowerUrl = cleanUrl.toLowerCase();
if (lowerUrl.includes(".jpg") || lowerUrl.includes(".jpeg")) {
mimeType = "image/jpeg";
} else if (lowerUrl.includes(".webp")) {
mimeType = "image/webp";
} else {
mimeType = "image/png";
}
}
const bytes = new Uint8Array(response.response);
let binary = "";
for (let i = 0; i < bytes.length; i += 0x8000) {
binary += String.fromCharCode.apply(
null,
bytes.subarray(i, i + 0x8000)
);
}
const dataUrl = "data:" + mimeType + ";base64," + btoa(binary);
let format = "PNG";
if (mimeType.includes("jpeg") || mimeType.includes("jpg")) {
format = "JPEG";
} else if (mimeType.includes("webp")) {
format = "WEBP";
}
resolve({
data: dataUrl,
format: format
});
} catch (error) {
reject(error);
}
},
onerror: function() {
reject(new Error("Could not download image: " + cleanUrl));
},
ontimeout: function() {
reject(new Error("Image loading timed out: " + cleanUrl));
}
});
});
}
async function safeAddImage(doc, url, x, y, width, height, imageName) {
if (!url || !String(url).trim()) {
console.log("[SBI PDF] " + imageName + " URL is empty.");
return;
}
try {
const image = await loadImageForPDF(url);
if (!image) return;
doc.addImage(
image.data,
image.format,
x,
y,
width,
height
);
console.log("[SBI PDF] Added image:", imageName, image.format);
} catch (error) {
console.error("[SBI PDF] Failed to add " + imageName + ":", error);
}
}
/* =====================================================
HELPER: Parse "DD/MM/YYYY" or "DD-MM-YYYY" → Date
===================================================== */
function parseDate(str) {
if (!str || str === "dd-mm-yyyy" || str.trim() === "") return null;
const parts = str.includes("/") ? str.split("/") : str.split("-");
if (parts.length !== 3) return null;
const [d, m, y] = parts;
return new Date(Number(y), Number(m) - 1, Number(d));
}
/* =====================================================
HELPER: Check if a row's Value Date is within range
===================================================== */
function isInRange(rowDateStr, from, to) {
const rowDate = parseDate(rowDateStr);
if (!rowDate) return false;
if (!from && !to) return true;
if (from && rowDate < from) return false;
if (to && rowDate > to) return false;
return true;
}
/* =====================================================
HELPER: Format balance number → "1,490.00CR" style
- If balance is positive → add "CR" suffix
- If balance is negative → add "DR" suffix
- toLocaleString adds commas: 24500 → "24,500"
- toFixed(2) ensures always 2 decimal places
===================================================== */
function formatBalance(balance) {
if (balance === "" || balance === null || balance === undefined) return "0.00";
const num = parseFloat(String(balance).replace(/,/g, "")); // remove existing commas if any
if (isNaN(num)) return "0.00";
// toLocaleString with minimumFractionDigits=2 → "24,500.00"
const formatted = Math.abs(num).toLocaleString('en-IN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
// Positive = Credit balance, Negative = Debit balance
return num >= 0 ? formatted + "CR" : formatted + "DR";
}
/* =====================================================
MAIN PDF GENERATOR
===================================================== */
async function generatePDF(){
/* UPDATED: classic jsPDF is loaded directly by Tampermonkey @require */
const JsPDF =
(typeof jsPDF === "function" && jsPDF) ||
(typeof window.jsPDF === "function" && window.jsPDF);
if (typeof JsPDF !== "function") {
console.error("[SBI PDF] jsPDF library is not available.");
alert("PDF library is not loaded. Disable all older SBI PDF scripts, save this script, and reload the SBI page using Ctrl + F5.");
return;
}
const doc = new JsPDF('p','mm','a4');
const w = doc.internal.pageSize.getWidth();
const h = doc.internal.pageSize.getHeight();
const cx = w/2;
/* --------------------------------------------------
STEP 1: READ SELECTED DATE RANGE FROM THE PAGE
-------------------------------------------------- */
const dateInputs = document.querySelectorAll('.mat-datepicker-input');
let fromDateStr = "dd-mm-yyyy";
let toDateStr = "dd-mm-yyyy";
if (dateInputs.length >= 2) {
fromDateStr = dateInputs[0].value || "dd-mm-yyyy";
toDateStr = dateInputs[1].value || "dd-mm-yyyy";
}
const fromDateObj = parseDate(fromDateStr);
const toDateObj = parseDate(toDateStr);
/* --------------------------------------------------
STEP 2: ALL TRANSACTION DATA
-------------------------------------------------- */
const statementdata =[];
/* --------------------------------------------------
STEP 3: FILTER DATA BASED ON DATE RANGE
-------------------------------------------------- */
const filteredData = statementdata.filter(row =>
isInRange(row["Value Date"], fromDateObj, toDateObj)
);
const hasData = filteredData.length > 0;
/* --------------------------------------------------
STEP 4: COMPUTE CLEAR BALANCE FROM FILTERED DATA
✅ KEY LOGIC:
- filteredData is already sorted by date (as it comes from bank)
- Last element = last transaction in the selected period
- That transaction's "Balance" = closing/clear balance for this period
- If no data in range → fallback to "0.00"
Example:
filteredData = [ {Balance: 24500}, {Balance: 20000} ]
filteredData[filteredData.length - 1] → {Balance: 20000}
clearBalance → "20,000.00CR"
-------------------------------------------------- */
const lastRow = hasData ? filteredData[filteredData.length - 1] : null;
const clearBalance = lastRow ? formatBalance(lastRow["Balance"]) : "0.00";
/* ==================================================
PDF CONTENT STARTS BELOW
================================================== */
/* HEADER BACKGROUND */
doc.setFillColor(88,83,171);
doc.rect(0,0,w,20,'F');
const leftImg ="data:image/png;base64,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";
if(leftImg.startsWith("data:image")) doc.addImage(leftImg,"PNG",9,1,39,17);
/* DATE BOX */
const d = new Date();
const date = `As On ${String(d.getDate()).padStart(2,'0')}-${String(d.getMonth()+1).padStart(2,'0')}-${d.getFullYear()}`;
doc.setFont("helvetica","normal");
doc.setFontSize(10);
const textW = doc.getTextWidth(date);
const boxX = cx - textW/2 - 10;
doc.setDrawColor(255);
doc.rect(boxX,6,textW+13,8);
const centerImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAZCAYAAADaILXQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKzSURBVEhLtZXdSxRRGIefGXV0nVVz101bLYnQMkKIPrywz4uILBVcLaIEoS76EouioJsoCoKQiCgLEcm0yD9ACspS6iqNNjH1Ri0y01yl3U3ddd3tYnXcGZ0y0QfOxfs77/nNmfedOUcostUHmANBhIBfq87mb3miVgDYuSuVx3UFJCbJ2qlZ3KvYj60wQyuDnrnJZCA8XCQuNko7NQuTyUC8yaCVARCmy5KyMhZbYQYWi0y8KQqzOZr29kHcbq92jYqsrBQGB37T0zuCZ2ySxlc9dHYOwbR5RITIg8oDyLKkXfvfjI/5KD3TgMvpJZypV5NlideNPVQ+/KDNnzcFtgwKD67Hao2hy+mYqrkQnPR6J/H7AwseHq8PAFEMGs7Z0MVCKLLVBxKTZO7c3YfT6WFkeEybM29i4yKJjzdw9cobOj4PqXcuRYQhG6UFD0kKC7ULNnSapqZeqqs+hkr/RW5+OkeOZirxktZc17yyKpeq6jwl3rxlBU+e2Th2fKOi3SrfQ+3TAiIj57aZWwVko0S0HIEw9Zmuy0hAFAVWr1mm5CxPlAkLE5Ai1bWeRlXzUC5fesmEb5LA1JlZW9NGZ8cQra39Ss65sudYEmRczomZhSHo7ry39xd939wqreV9v+p4HXaM09XlCE1RoWteXJJJcclM541GiWvXd2NNNipaXn46pWVblViLrnlOTho5OWlKzU+e2kT6WjMXLmYrOYcObyB72ypMOkeurrnd/oNP9gGl5nV1bTgco9Q8sis5b5u/0t09zLDOX63b0Js33qni731uTp9oUGkV91tUsRYRYNIX3F5cXBTJyTELHmZzNAB+f9BPKLLVBwQRym/vxWqNCX3wgnA6PZw/+wKXyztzzVks0WzfkUqUQbdS/8Qz7qO5+Qs/B0ch9A5dCnS/lsXgD/lu+SLKMOsRAAAAAElFTkSuQmCC";
await safeAddImage(
doc,
centerImg,
boxX + 2,
7,
5,
5,
"centerImg"
);
doc.setTextColor(255);
doc.text(date,cx,11,{align:"center"});
doc.text(["Welcome:","Mr. BARLA HARISH KUMAR"],w-10,8,{align:"right"});
/* TITLE */
doc.setTextColor(0);
doc.setFontSize(12);
doc.text("STATEMENT OF ACCOUNT",cx,25,{align:"center"});
doc.setDrawColor(180,180,180);
doc.line(10,30,w-10,30);
const belowLineImg ="data:image/png;base64,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ObQ+Dxqi/KY3Mti3OhcaonxtpLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwopLwo/jflK8oMlBVX+OxTUWZQb8Jr6ryB/fyZy3z6/A9kJFveU+ZLOvRqwYOvjKRxizB1yGVmt95JlyGRPLq0V92S/+zFLddEHODkkRy+mLtNnewxNiVvrDIyo997AEx6eiA3DGhbO69XZCTn8fmcrQAs3v+kOuwydkveZLpagyKbh9K8baTPPi3aRdbelE+oU20aEj6RrygzcO7URc6ddPA5dVG9mNfY1HlDZRVP3PI+AI++Poret3Wqnbde9v3wK8vm7aC8pFIdssvwuN5MmDUARVHUIafYrfPuUnK5nM/nbnVLHGDrlwdJTcxWJ7uNVyX/64EzvPnYWrQ6DfN/eBi9v1adxQazGRb96RsyknMZ++f+jHqwrzqLU3xW8jW/W6PTENwoAL8AvcOPf6CegBA/y7K1jmye4pV8fVSWV7FyYTzvzFzH9q8Pq8M+xefyK97YxY6vD3N8TxarFsazd1OqOovP8Ll8Vkq+zffstPM2332Jz+U79W5l871jTEub777E5/KTnhrI2Bn9ufnOrjz06h3EDO2gzuIzfC6v0WoYNb0v018aQd+RndVhn+KVfE0LaawykZtZwMWcKw4/F85dobiwzLKsxv3WVY1XjVR5SSV/G/UJFaXu95L++skkOvRyf3/wWSMVEOzHo6/fSXjTEHXIIeOfGOCRuBqvSr4Gk9FEyZVybDuUtpw+nsd7T30L16oz4ikarYbQiCDCIu1/QiOC1It5jU/kRaHqw5qY0e8/AIx+9Ga69I2undcrslLyWfVmAopG4YPEJ9Rhl6ldbepc+nh75jpS9mTVTvIpPQa1Y8ZbY9TJLuOwzk+bM5weg9qh02vRaBWffXR6Lb2GtOf+f92m3qTH1Cn53zsOS74hIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVFIeVF0eDkY8Y0pcPN4dAQp3CvTYMr+dpIeVFIeVFIeVFIeVFIeVFIeVFIeVE0GPmET86w5OEkjAaTNa3ByGcevMyRjecxGa/2nTyWP3fyIqeO5mCsMqpDvxluyZvNZlL2ZvHGI6t56Q/LmP/gKp4f+zk/rjyCoaJKnf2a41If1mw2c+zn03z3UaL11fKKAn6BeuurJsOighj5QCyDJtyAX4BetQbvWTrjGAfW5LEgcwj6AMu7lx3Km81mjuw6xfef7LO+tFajVeg/uhsjp/UhLDKI+DVJbF16kKICyws8QyMCuT2uN0Mm9yAgyPL+Y1/gsrzJZObQjnQ2fbKPMycuAKDTaxkwtjsjpsbSuEWYTf7KcgM/rTvGls8PUHi+BICgMH9uv+9Gbv1DLwJD/G3ye4JTeZPRxP6tJ9j0yT5yMi4BoA/QMXhiD4bH3Uh4E8cv9DRUVrFnYyqbl+zjYk4RAIEhfgybEsOwe2MIbhSgXsRlHMon785k5cJ48rMKrQs0axvBbVNiCIkIvLoWFzBWmUjcnEZSQoY1zT9Iz/D7ezP6kZtt8rqKQ/l5ccvJSrV9GfO1YMHWhz166adD+S1fHODgjnT1Mj6lSXQjps8dgUbr1hEanMn/3qlP3v0i+B1hV764sIyfvz1OZXn97zvOTjvP0fhT6mQrR+NPXfN9yK78hsV7+GLuNhLWJqtDACz+63e8/8xGcjMth9Ta5GRc4v1nNvLfZ79Xh3yKXfmaEq8sr/+cpeZcpqKsbrxmGXv/mq+wK98QkPKikPKikPKisCvfol1jAJq2ttzzVNO8bQQBwX6ENwlWhwhvEkxAsB/N2kSoQ77FbAeTyWQuLixTJ1sxVFaZy4or1MlWyoorzIbKKnWyx3zx52TzrGbbzZVlV9dpt+QVRXHY89HptQQE2++jBgT7odNbzv6uFdZTYpPJTMllSyf6WhEQ5IfeX6dOdon6Tomt8p8+/wOJm9PUy/iU8CbBvLxuqkc/oD55a7UJCLFfBXyFX6AeFHWq59j0pIxVVy9iXgs0WgVF8czeYckDaHWaa/rxVNwedo82DYEGLf9/tZ8+WMHcqzYAAAAASUVORK5CYII=";
await safeAddImage(
doc,
belowLineImg,
12,
34,
10,
120,
"belowLineImg"
);
const rightSideImage = "data:image/png;base64,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";
await safeAddImage(
doc,
rightSideImage,
120,
48,
9,
110,
"rightSideImage"
);
/* BANK NAME */
doc.setFont("helvetica","bold");
doc.setFontSize(14);
doc.setTextColor(0,191,255);
doc.text("State Bank of India",128,39);
doc.setFont("helvetica","normal");
doc.setFontSize(10);
doc.setTextColor(0,0,0);
const rx = 132, ry = 52, rg = 3;
doc.text("H.NO.1-1-130,MUNICIPAL COMMERCIAL",rx,ry);
doc.text("JANGAON,WARANGAL DIST",rx,ry+rg*1.5);
doc.text("Branch Code : 21371",rx,ry+rg*4.5);
doc.text("Branch Name : ACB MUNICIPAL",rx,ry+rg*6.5);
doc.text("Branch Email : [email protected]",rx,ry+rg*8.5);
doc.text("Branch Phone : 9063179841",rx,ry+rg*10.5);
doc.text("CIF Number : 72265407076",rx,ry+rg*15);
doc.text("Account Number : 62510603394",rx,ry+rg*17.5);
doc.text("IFSC Code : SBIN0021371",rx,ry+rg*20.5);
doc.text("Currency : INR ",rx,ry+rg*23.5);
doc.text("Account Status : OPEN ",rx,ry+rg*26.5);
doc.text("CKYCR Number : 60050134633336",rx,ry+rg*28.5);
doc.text("MICR Code : 506002205 ",rx,ry+rg*30.5);
doc.text("Nominee Name : XXXXXXXXX",rx,ry+rg*35);
/* CUSTOMER DETAILS */
doc.setFontSize(12);
doc.text("Mr. BARLA HARISH KUMAR",24,40);
doc.setFontSize(10);
doc.text("Not Available",24,46);
doc.text("2-6-89/2 KURMAWADA",24,56);
doc.text("JANGAON,WARANGAL",24,62);
/* FIELD FUNCTION */
function field(label,value,x,y){
doc.text(label,x,y);
doc.text(":",x+45,y);
doc.text(value,x+50,y);
}
/* --------------------------------------------------
TODAY'S DATE for "Date of Statement" field
-------------------------------------------------- */
const today = new Date();
const todayStr = `${String(today.getDate()).padStart(2,'0')}-${String(today.getMonth()+1).padStart(2,'0')}-${today.getFullYear()}`;
const startX = 24;
field("Date of Statement", todayStr, startX, 76);
/* ✅ clearBalance is now DYNAMIC based on filtered last row */
field("Clear Balance", clearBalance, startX, 86);
field("Uncleared Amount", "0.00", startX, 93);
field("+MOD Bal", "0.00", startX, 101);
field("Lien", "0.00", startX, 109);
field("Limit", "0.00", startX, 117);
field("Monthly Avg Balance","0.00", startX, 125);
field("Interest Rate", "0.00", startX, 133);
field("Drawing Power", "0.00", startX, 140);
field("Account open Date", "24/05/2017", startX, 152);
/* STATEMENT RANGE */
doc.setFontSize(10);
doc.text("Statement From : " + fromDateStr + " to " + toDateStr, 72, 168);
/* =====================================================
TABLE SETUP
===================================================== */
const statementheader = [
"Value Date","Post Date","Details","Cheq No","Debit","Credit","Balance"
];
const tableStartX = 12;
const tableStartY = 175;
const headerHeight = 14;
const colWidth = {
"Value Date": 22,
"Post Date": 22,
"Details": 70,
"Cheq No": 18,
"Debit": 18,
"Credit": 18,
"Balance": 22
};
function drawTableHeader(yPos){
let hx = tableStartX;
doc.setFont("helvetica","bold");
doc.setFontSize(9);
doc.setTextColor(255,255,255);
statementheader.forEach(col => {
doc.setFillColor(88,83,171);
doc.rect(hx, yPos, colWidth[col], headerHeight, "F");
doc.text(col, hx+2, yPos+5);
hx += colWidth[col];
});
doc.setFont("helvetica","normal");
doc.setTextColor(0,0,0);
return yPos + headerHeight;
}
let rowY = drawTableHeader(tableStartY);
/* NO DATA MESSAGE */
if (!hasData) {
doc.setFontSize(10);
doc.setTextColor(180, 0, 0);
doc.text(
"No transactions found for the selected date range: " + fromDateStr + " to " + toDateStr,
tableStartX + 2,
rowY + 8
);
doc.setTextColor(0,0,0);
}
/* ROW RENDERING LOOP */
filteredData.forEach(row => {
let maxHeight = 6;
statementheader.forEach(col => {
const wrapped = doc.splitTextToSize(String(row[col] || ""), colWidth[col] - 4);
const needed = wrapped.length * 4 + 2;
if (needed > maxHeight) maxHeight = needed;
});
if (rowY + maxHeight > 285) {
doc.addPage();
rowY = 20;
rowY = drawTableHeader(rowY);
}
let cellX = tableStartX;
statementheader.forEach(col => {
const wrapped = doc.splitTextToSize(String(row[col] || ""), colWidth[col] - 4);
doc.rect(cellX, rowY, colWidth[col], maxHeight);
doc.text(wrapped, cellX + 2, rowY + 4);
cellX += colWidth[col];
});
rowY += maxHeight;
});
/* FOOTER: PAGE NUMBERS */
const totalPages = doc.internal.getNumberOfPages();
doc.setFontSize(9);
doc.setTextColor(120,120,120);
for (let i = 1; i <= totalPages; i++) {
doc.setPage(i);
doc.text(`Page no. ${i}`, cx, h - 7, {align:"center"});
}
/* =====================================================
DYNAMIC FILENAME: AccountStatement_DDMMYYYY_HHMMSS.pdf
===================================================== */
const now = new Date();
const dd = String(now.getDate()).padStart(2,'0');
const mm = String(now.getMonth() + 1).padStart(2,'0');
const yyyy = now.getFullYear();
const hh = String(now.getHours()).padStart(2,'0');
const min = String(now.getMinutes()).padStart(2,'0');
const ss = String(now.getSeconds()).padStart(2,'0');
const filename = `AccountStatement_${dd}${mm}${yyyy}_${hh}${min}${ss}.pdf`;
doc.save(filename);
}
/* =====================================================
UPDATED BUTTON:
- Do NOT remove SBI's original button or dff-button
- Keep SBI DOM intact to prevent classList/null errors
- Hide original button visually and overlay our button
===================================================== */
const NEW_BUTTON_ID = "sbi-own-download-btn";
function installOwnDownloadButton() {
if (document.getElementById(NEW_BUTTON_ID)) return;
const oldButton = document.querySelector(
'button.custom-download-btn, button[data-pdf="1"]'
);
if (!oldButton) return;
const buttonContainer = oldButton.parentElement;
if (!buttonContainer) return;
/*
* Keep the original button in the DOM because SBI's scripts may hold
* references to it. Only make it invisible and non-clickable.
*/
oldButton.style.visibility = "hidden";
oldButton.style.pointerEvents = "none";
oldButton.setAttribute("aria-hidden", "true");
oldButton.tabIndex = -1;
const computedContainerStyle = window.getComputedStyle(buttonContainer);
if (computedContainerStyle.position === "static") {
buttonContainer.style.position = "relative";
}
const newButton = document.createElement("button");
newButton.id = NEW_BUTTON_ID;
newButton.type = "button";
newButton.textContent = "Download";
/* Exact styles copied from your original button */
newButton.style.borderRadius = "40px";
newButton.style.border = "2px solid rgb(82, 74, 151)";
newButton.style.padding = "10px 60px";
newButton.style.color = "rgb(82, 74, 151)";
newButton.style.backgroundColor = "rgba(82, 74, 151, 0.12)";
newButton.style.cursor = "pointer";
newButton.style.boxShadow = "rgba(82, 74, 151, 0.4) 0px 0px 8px";
newButton.style.transition = "0.3s";
newButton.style.position = "absolute";
newButton.style.inset = "0";
newButton.style.width = "100%";
newButton.style.height = "100%";
newButton.style.zIndex = "10";
newButton.style.whiteSpace = "nowrap";
newButton.addEventListener("mouseenter", function() {
newButton.style.backgroundColor = "rgb(82, 74, 151)";
newButton.style.color = "#ffffff";
});
newButton.addEventListener("mouseleave", function() {
newButton.style.backgroundColor = "rgba(82, 74, 151, 0.12)";
newButton.style.color = "rgb(82, 74, 151)";
});
newButton.addEventListener("click", function(event) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
const normalText = "Download";
newButton.disabled = true;
newButton.textContent = "Generating...";
window.setTimeout(async function() {
try {
await generatePDF();
} catch (pdfError) {
console.error("[SBI PDF] PDF generation failed:", pdfError);
alert("PDF generation failed: " + (pdfError.message || pdfError));
} finally {
newButton.disabled = false;
newButton.textContent = normalText;
}
}, 100);
}, true);
buttonContainer.appendChild(newButton);
}
function initializeDownloadButton() {
installOwnDownloadButton();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initializeDownloadButton, {
once: true
});
} else {
initializeDownloadButton();
}
let buttonUpdateScheduled = false;
new MutationObserver(function() {
if (buttonUpdateScheduled) return;
buttonUpdateScheduled = true;
window.requestAnimationFrame(function() {
buttonUpdateScheduled = false;
installOwnDownloadButton();
});
}).observe(document.body, {
childList: true,
subtree: true
});
})();2 views