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
	
	 Shelley Vohr
				Shelley Vohr