Skip to content

Commit

Permalink
[Screenshotting] Added workaround for webgl driven canvases (elastic#…
Browse files Browse the repository at this point in the history
…131907)

* added workaround for webgl driven canvases

* expand comment with link to origin of idea

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
2 people authored and Esteban Beltran committed May 12, 2022
1 parent ebf636d commit 60476d1
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,41 @@ export class HeadlessChromiumDriver {
return !this.page.isClosed();
}

/**
* Despite having "preserveDrawingBuffer": "true" for WebGL driven canvas elements
* we may still get a blank canvas in PDFs. As a further mitigation
* we convert WebGL backed canvases to images and inline replace the canvas element.
* The visual result is identical.
*
* The drawback is that we are mutating the page and so if anything were to interact
* with it after we ran this function it may lead to issues. Ideally, once Chromium
* fixes how PDFs are generated we can remove this code. See:
*
* https://bugs.chromium.org/p/chromium/issues/detail?id=809065
* https://bugs.chromium.org/p/chromium/issues/detail?id=137576
*
* Idea adapted from: https://github.com/puppeteer/puppeteer/issues/1731#issuecomment-864345938
*/
private async workaroundWebGLDrivenCanvases() {
const canvases = await this.page.$$('canvas');
for (const canvas of canvases) {
await canvas.evaluate((thisCanvas: Element) => {
if (
(thisCanvas as HTMLCanvasElement).getContext('webgl') ||
(thisCanvas as HTMLCanvasElement).getContext('webgl2')
) {
const newDiv = document.createElement('div');
const img = document.createElement('img');
img.src = (thisCanvas as HTMLCanvasElement).toDataURL('image/png');
newDiv.appendChild(img);
thisCanvas.parentNode!.replaceChild(newDiv, thisCanvas);
}
});
}
}

async printA4Pdf({ title, logo }: { title: string; logo?: string }): Promise<Buffer> {
await this.workaroundWebGLDrivenCanvases();
return this.page.pdf({
format: 'a4',
preferCSSPageSize: true,
Expand Down

0 comments on commit 60476d1

Please sign in to comment.