// ============================================================================= // MyCard Statement Download Helper (mycard.com.au) // ============================================================================= // PASTE + ENTER, then click statement rows normally. // The blob tab still opens (just close it), BUT you also get a properly // named PDF saved automatically. // // TO STOP: just refresh the page (F5) // ============================================================================= (function () { 'use strict'; if (window._mcStatementHelper) { if (window._mcOrigWindowOpen) window.open = window._mcOrigWindowOpen; console.log('🔄 Restarting MyCard helper...'); } window._mcStatementHelper = true; let downloadCount = 0; let lastClickedDate = null; const downloadedSet = new Set(); const monthNames = ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; function extractDate(text) { const m = text.match(/(\d{1,2})\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+(\d{4})/); if (!m) return null; const monthNum = new Date(`${m[2]} 1, 2000`).getMonth() + 1; return { year: m[3], monthNum: String(monthNum).padStart(2, '0'), monthName: m[2] }; } // Click events compose through shadow DOM — use composedPath() to read inner elements document.addEventListener('click', function (e) { const path = e.composedPath(); for (const el of path) { if (!(el instanceof HTMLElement)) continue; // Search this element and its children for

with a date const paragraphs = el.querySelectorAll ? el.querySelectorAll('p') : []; for (const p of paragraphs) { const date = extractDate(p.textContent.trim()); if (date) { lastClickedDate = date; console.log(`⏳ MyCard-Statement-${date.year}-${date.monthNum}-${date.monthName}.pdf...`); return; } } } }, true); // Also try mousedown with composedPath document.addEventListener('mousedown', function (e) { const path = e.composedPath(); for (const el of path) { if (!(el instanceof HTMLElement)) continue; const paragraphs = el.querySelectorAll ? el.querySelectorAll('p') : []; for (const p of paragraphs) { const date = extractDate(p.textContent.trim()); if (date) { lastClickedDate = date; return; } } } }, true); // Search all shadow roots for dates (fallback) function findDateInShadowDom() { function searchNode(node) { if (node.shadowRoot) { const ps = node.shadowRoot.querySelectorAll('p'); for (const p of ps) { const date = extractDate(p.textContent.trim()); if (date) return date; } for (const child of node.shadowRoot.querySelectorAll('*')) { const result = searchNode(child); if (result) return result; } } return null; } for (const el of document.querySelectorAll('*')) { const result = searchNode(el); if (result) return result; } return null; } function savePdf(blob, filename) { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(() => URL.revokeObjectURL(url), 2000); } // Intercept window.open — fetch blob URL and save as named PDF const origWindowOpen = window._mcOrigWindowOpen || window.open; window._mcOrigWindowOpen = origWindowOpen; window.open = function (url, ...rest) { const win = origWindowOpen.call(this, url, ...rest); if (typeof url === 'string' && url.startsWith('blob:')) { if (downloadedSet.has(url)) return win; downloadedSet.add(url); setTimeout(() => downloadedSet.delete(url), 5000); // Try click-tracked date, then shadow DOM scan const date = lastClickedDate || findDateInShadowDom(); fetch(url) .then(r => r.blob()) .then(blob => { return blob.slice(0, 5).text().then(h => { if (h !== '%PDF-') return; let fn; if (date) { fn = `MyCard-Statement-${date.year}-${date.monthNum}-${date.monthName}.pdf`; } else { fn = `MyCard-Statement-${Date.now()}.pdf`; } savePdf(blob, fn); downloadCount++; console.log(`✅ #${downloadCount} ${fn} (${(blob.size / 1024).toFixed(0)} KB)`); console.log(` Close the blob tab, then click next statement.`); }); }) .catch(err => console.error('❌ Failed:', err)); } return win; }; console.log(''); console.log('✅ MyCard download helper active!'); console.log('👆 Click statement rows normally.'); console.log(' Each click: PDF saves as file + blob tab opens (close it).'); console.log(' To stop: refresh (F5)'); console.log(''); })();