fix: webContents.printToPDF()
with cross-process subframes (#46218)
fix: webContents.printToPDF() with cross-process subframes
This commit is contained in:
parent
8e856dfdb8
commit
1d6cb348b4
5 changed files with 63 additions and 1 deletions
|
@ -176,6 +176,7 @@
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_PRINTING)
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
#include "chrome/browser/printing/print_view_manager_base.h"
|
#include "chrome/browser/printing/print_view_manager_base.h"
|
||||||
|
#include "components/printing/browser/print_composite_client.h"
|
||||||
#include "components/printing/browser/print_manager_utils.h"
|
#include "components/printing/browser/print_manager_utils.h"
|
||||||
#include "components/printing/browser/print_to_pdf/pdf_print_result.h"
|
#include "components/printing/browser/print_to_pdf/pdf_print_result.h"
|
||||||
#include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
|
#include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
|
||||||
|
@ -1023,6 +1024,7 @@ void WebContents::InitWithWebContents(
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_PRINTING)
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
PrintViewManagerElectron::CreateForWebContents(web_contents.get());
|
PrintViewManagerElectron::CreateForWebContents(web_contents.get());
|
||||||
|
printing::CreateCompositeClientIfNeeded(web_contents.get(), GetUserAgent());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Determine whether the WebContents is offscreen.
|
// Determine whether the WebContents is offscreen.
|
||||||
|
@ -1983,6 +1985,17 @@ void WebContents::DraggableRegionsChanged(
|
||||||
draggable_region_ = DraggableRegionsToSkRegion(regions);
|
draggable_region_ = DraggableRegionsToSkRegion(regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContents::PrintCrossProcessSubframe(
|
||||||
|
content::WebContents* web_contents,
|
||||||
|
const gfx::Rect& rect,
|
||||||
|
int document_cookie,
|
||||||
|
content::RenderFrameHost* subframe_host) const {
|
||||||
|
if (auto* client =
|
||||||
|
printing::PrintCompositeClient::FromWebContents(web_contents)) {
|
||||||
|
client->PrintCrossProcessSubframe(rect, document_cookie, subframe_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SkRegion* WebContents::draggable_region() {
|
SkRegion* WebContents::draggable_region() {
|
||||||
return g_disable_draggable_regions ? nullptr : draggable_region_.get();
|
return g_disable_draggable_regions ? nullptr : draggable_region_.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -585,6 +585,11 @@ class WebContents final : public ExclusiveAccessContext,
|
||||||
void DraggableRegionsChanged(
|
void DraggableRegionsChanged(
|
||||||
const std::vector<blink::mojom::DraggableRegionPtr>& regions,
|
const std::vector<blink::mojom::DraggableRegionPtr>& regions,
|
||||||
content::WebContents* contents) override;
|
content::WebContents* contents) override;
|
||||||
|
void PrintCrossProcessSubframe(
|
||||||
|
content::WebContents* web_contents,
|
||||||
|
const gfx::Rect& rect,
|
||||||
|
int document_cookie,
|
||||||
|
content::RenderFrameHost* subframe_host) const override;
|
||||||
|
|
||||||
// content::WebContentsObserver:
|
// content::WebContentsObserver:
|
||||||
void BeforeUnloadFired(bool proceed) override;
|
void BeforeUnloadFired(bool proceed) override;
|
||||||
|
|
|
@ -90,6 +90,7 @@ void ElectronExtensionsAPIClient::AttachWebContentsHelpers(
|
||||||
content::WebContents* web_contents) const {
|
content::WebContents* web_contents) const {
|
||||||
#if BUILDFLAG(ENABLE_PRINTING)
|
#if BUILDFLAG(ENABLE_PRINTING)
|
||||||
electron::PrintViewManagerElectron::CreateForWebContents(web_contents);
|
electron::PrintViewManagerElectron::CreateForWebContents(web_contents);
|
||||||
|
printing::CreateCompositeClientIfNeeded(web_contents, std::string());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extensions::ElectronExtensionWebContentsObserver::CreateForWebContents(
|
extensions::ElectronExtensionWebContentsObserver::CreateForWebContents(
|
||||||
|
|
|
@ -2440,6 +2440,7 @@ describe('webContents module', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
ifdescribe(features.isPrintingEnabled())('printToPDF()', () => {
|
ifdescribe(features.isPrintingEnabled())('printToPDF()', () => {
|
||||||
|
let server: http.Server | null;
|
||||||
const readPDF = async (data: any) => {
|
const readPDF = async (data: any) => {
|
||||||
const tmpDir = await fs.promises.mkdtemp(path.resolve(os.tmpdir(), 'e-spec-printtopdf-'));
|
const tmpDir = await fs.promises.mkdtemp(path.resolve(os.tmpdir(), 'e-spec-printtopdf-'));
|
||||||
const pdfPath = path.resolve(tmpDir, 'test.pdf');
|
const pdfPath = path.resolve(tmpDir, 'test.pdf');
|
||||||
|
@ -2483,7 +2484,12 @@ describe('webContents module', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(closeAllWindows);
|
afterEach(() => {
|
||||||
|
closeAllWindows();
|
||||||
|
if (server) {
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('rejects on incorrectly typed parameters', async () => {
|
it('rejects on incorrectly typed parameters', async () => {
|
||||||
const badTypes = {
|
const badTypes = {
|
||||||
|
@ -2644,6 +2650,32 @@ describe('webContents module', () => {
|
||||||
expect(pdfInfo.markInfo).to.be.null();
|
expect(pdfInfo.markInfo).to.be.null();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can print same-origin iframes', async () => {
|
||||||
|
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-same-origin.html'));
|
||||||
|
|
||||||
|
const data = await w.webContents.printToPDF({});
|
||||||
|
const pdfInfo = await readPDF(data);
|
||||||
|
expect(containsText(pdfInfo.textContent, /Virtual member functions/)).to.be.true();
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO(codebytere): OOPIF printing is disabled on Linux at the moment due to crashes.
|
||||||
|
ifit(process.platform !== 'linux')('can print cross-origin iframes', async () => {
|
||||||
|
server = http.createServer((_, res) => {
|
||||||
|
res.writeHead(200);
|
||||||
|
res.end(`
|
||||||
|
<title>cross-origin iframe</title>
|
||||||
|
<p>This page is displayed in an iframe.</p>
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
const { port } = await listen(server);
|
||||||
|
|
||||||
|
await w.loadURL(`data:text/html,<iframe src="http://localhost:${port}"></iframe>`);
|
||||||
|
|
||||||
|
const data = await w.webContents.printToPDF({});
|
||||||
|
const pdfInfo = await readPDF(data);
|
||||||
|
expect(containsText(pdfInfo.textContent, /This page is displayed in an iframe./)).to.be.true();
|
||||||
|
});
|
||||||
|
|
||||||
it('can generate tag data for PDFs', async () => {
|
it('can generate tag data for PDFs', async () => {
|
||||||
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-small.html'));
|
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-small.html'));
|
||||||
|
|
||||||
|
|
11
spec/fixtures/api/print-to-pdf-same-origin.html
vendored
Normal file
11
spec/fixtures/api/print-to-pdf-same-origin.html
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Your Title Here</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="background: green;">
|
||||||
|
<iframe src="../pages/content.html"</iframe>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue