diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index 766ed326237..e2a386fbeb0 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -176,6 +176,7 @@ #if BUILDFLAG(ENABLE_PRINTING) #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_to_pdf/pdf_print_result.h" #include "components/printing/browser/print_to_pdf/pdf_print_utils.h" @@ -1023,6 +1024,7 @@ void WebContents::InitWithWebContents( #if BUILDFLAG(ENABLE_PRINTING) PrintViewManagerElectron::CreateForWebContents(web_contents.get()); + printing::CreateCompositeClientIfNeeded(web_contents.get(), GetUserAgent()); #endif // Determine whether the WebContents is offscreen. @@ -2074,6 +2076,17 @@ void WebContents::DraggableRegionsChanged( 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() { return g_disable_draggable_regions ? nullptr : draggable_region_.get(); } diff --git a/shell/browser/api/electron_api_web_contents.h b/shell/browser/api/electron_api_web_contents.h index a8b4ffa8e94..a17cbb29f84 100644 --- a/shell/browser/api/electron_api_web_contents.h +++ b/shell/browser/api/electron_api_web_contents.h @@ -630,6 +630,11 @@ class WebContents final : public ExclusiveAccessContext, void DraggableRegionsChanged( const std::vector& regions, 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: void BeforeUnloadFired(bool proceed) override; diff --git a/shell/browser/extensions/electron_extensions_api_client.cc b/shell/browser/extensions/electron_extensions_api_client.cc index d2bb0c88791..d00066c10f2 100644 --- a/shell/browser/extensions/electron_extensions_api_client.cc +++ b/shell/browser/extensions/electron_extensions_api_client.cc @@ -90,6 +90,7 @@ void ElectronExtensionsAPIClient::AttachWebContentsHelpers( content::WebContents* web_contents) const { #if BUILDFLAG(ENABLE_PRINTING) electron::PrintViewManagerElectron::CreateForWebContents(web_contents); + printing::CreateCompositeClientIfNeeded(web_contents, std::string()); #endif extensions::ElectronExtensionWebContentsObserver::CreateForWebContents( diff --git a/spec/api-web-contents-spec.ts b/spec/api-web-contents-spec.ts index d7993c93789..879217e37b0 100644 --- a/spec/api-web-contents-spec.ts +++ b/spec/api-web-contents-spec.ts @@ -2408,6 +2408,7 @@ describe('webContents module', () => { }); ifdescribe(features.isPrintingEnabled())('printToPDF()', () => { + let server: http.Server | null; const readPDF = async (data: any) => { const tmpDir = await fs.promises.mkdtemp(path.resolve(os.tmpdir(), 'e-spec-printtopdf-')); const pdfPath = path.resolve(tmpDir, 'test.pdf'); @@ -2451,7 +2452,12 @@ describe('webContents module', () => { }); }); - afterEach(closeAllWindows); + afterEach(() => { + closeAllWindows(); + if (server) { + server.close(); + } + }); it('rejects on incorrectly typed parameters', async () => { const badTypes = { @@ -2612,6 +2618,32 @@ describe('webContents module', () => { 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(` + cross-origin iframe +

This page is displayed in an iframe.

+ `); + }); + const { port } = await listen(server); + + await w.loadURL(`data:text/html,`); + + 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 () => { await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-small.html')); diff --git a/spec/fixtures/api/print-to-pdf-same-origin.html b/spec/fixtures/api/print-to-pdf-same-origin.html new file mode 100644 index 00000000000..838ae1e281f --- /dev/null +++ b/spec/fixtures/api/print-to-pdf-same-origin.html @@ -0,0 +1,11 @@ + + + + Your Title Here + + + +