import { InjectionToken } from '@angular/core'; /** * A shared seam for handing a generated `Blob` to the browser, WITHOUT the calling * command inlining `URL.createObjectURL`/`window.open`/`document.createElement('a')` * as its own last statement (TE-006) — those calls are unassertable in jsdom because * they are the end of the command, not a value the spec can intercept. A recording * fake satisfies this shape in specs; `realBlobPresenter` is the production default. */ export interface BlobPresenter { /** Open a blob in a new tab (e.g. a rendered letter preview). Never revokes the object URL — the tab outlives this call, and the POC treats the leak as cheap (see `BriefStore.previewLetter`'s original comment). */ open(blob: Blob): void; /** Trigger a browser download of a blob under the given file name, then revoke the object URL once the click has been dispatched. */ download(blob: Blob, filename: string): void; } const realBlobPresenter: BlobPresenter = { open(blob: Blob) { window.open(URL.createObjectURL(blob), '_blank'); }, download(blob: Blob, filename: string) { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); }, }; export const BLOB_PRESENTER = new InjectionToken('BLOB_PRESENTER', { providedIn: 'root', factory: () => realBlobPresenter, });