diff --git a/shell/browser/electron_pdf_document_helper_client.cc b/shell/browser/electron_pdf_document_helper_client.cc index 6a66f6d067ed..6ee4576169c5 100644 --- a/shell/browser/electron_pdf_document_helper_client.cc +++ b/shell/browser/electron_pdf_document_helper_client.cc @@ -27,13 +27,23 @@ void ElectronPDFDocumentHelperClient::UpdateContentRestrictions( // allowed there won't be a printing restriction passed, so we can use this // second call to notify that the pdf document is ready to print. if (!(content_restrictions & chrome_pdf::kContentRestrictionPrint)) { - content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(render_frame_host); - electron::api::WebContents* api_web_contents = - electron::api::WebContents::From( - web_contents->GetOutermostWebContents()); - if (api_web_contents) { - api_web_contents->PDFReadyToPrint(); + // It's a WebView - emit the event on the WebView webContents. + auto* guest_view = extensions::MimeHandlerViewGuest::FromRenderFrameHost( + render_frame_host); + if (guest_view) { + auto* gv_api_wc = + electron::api::WebContents::From(guest_view->embedder_web_contents()); + if (gv_api_wc) + gv_api_wc->PDFReadyToPrint(); + return; + } + + auto* wc = content::WebContents::FromRenderFrameHost(render_frame_host); + if (wc) { + auto* api_wc = + electron::api::WebContents::From(wc->GetOuterWebContents()); + if (api_wc) + api_wc->PDFReadyToPrint(); } } } diff --git a/spec/api-web-contents-spec.ts b/spec/api-web-contents-spec.ts index e182e83a798c..601eee14a226 100644 --- a/spec/api-web-contents-spec.ts +++ b/spec/api-web-contents-spec.ts @@ -3,6 +3,7 @@ import { AddressInfo } from 'node:net'; import * as path from 'node:path'; import * as fs from 'node:fs'; import * as http from 'node:http'; +import * as url from 'node:url'; import { BrowserWindow, ipcMain, webContents, session, app, BrowserView, WebContents } from 'electron/main'; import { closeAllWindows } from './lib/window-helpers'; import { ifdescribe, defer, waitUntil, listen, ifit } from './lib/spec-helpers'; @@ -11,7 +12,6 @@ import { setTimeout } from 'node:timers/promises'; const pdfjs = require('pdfjs-dist'); const fixturesPath = path.resolve(__dirname, 'fixtures'); -const mainFixturesPath = path.resolve(__dirname, 'fixtures'); const features = process._linkedBinding('electron_common_features'); describe('webContents module', () => { @@ -1055,7 +1055,7 @@ describe('webContents module', () => { }).to.throw('\'icon\' parameter is required'); expect(() => { - w.webContents.startDrag({ file: __filename, icon: path.join(mainFixturesPath, 'blank.png') }); + w.webContents.startDrag({ file: __filename, icon: path.join(fixturesPath, 'blank.png') }); }).to.throw(/Failed to load image from path (.+)/); }); }); @@ -2353,6 +2353,45 @@ describe('webContents module', () => { const { items } = await page.getTextContent(); expect(containsText(items, /Cat: The Ideal Pet/)).to.be.true(); }); + + it('from an existing pdf document in a WebView', async () => { + const win = new BrowserWindow({ + show: false, + webPreferences: { + webviewTag: true + } + }); + + await win.loadURL('about:blank'); + const webContentsCreated = once(app, 'web-contents-created') as Promise<[any, WebContents]>; + + const src = url.format({ + pathname: `${fixturesPath.replaceAll('\\', '/')}/cat.pdf`, + protocol: 'file', + slashes: true + }); + await win.webContents.executeJavaScript(` + new Promise((resolve, reject) => { + const webview = new WebView() + webview.setAttribute('src', '${src}') + document.body.appendChild(webview) + webview.addEventListener('did-finish-load', () => { + resolve() + }) + }) + `); + + const [, webContents] = await webContentsCreated; + + await once(webContents, '-pdf-ready-to-print'); + + const data = await webContents.printToPDF({}); + const doc = await pdfjs.getDocument(data).promise; + expect(doc.numPages).to.equal(2); + const page = await doc.getPage(1); + const { items } = await page.getTextContent(); + expect(containsText(items, /Cat: The Ideal Pet/)).to.be.true(); + }); }); describe('PictureInPicture video', () => {