Skip to content

Commit 9667b83

Browse files
Cheng Zhaocodebytere
authored andcommitted
fix: create WebContents for webview on request (electron#13714)
1 parent 58295a3 commit 9667b83

File tree

5 files changed

+43
-23
lines changed

5 files changed

+43
-23
lines changed

lib/browser/guest-view-manager.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,10 @@ ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', function (event, params,
331331
event.sender.send(`ELECTRON_RESPONSE_${requestId}`, createGuest(event.sender, params))
332332
})
333333

334+
ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', function (event, params) {
335+
event.returnValue = createGuest(event.sender, params)
336+
})
337+
334338
ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, elementInstanceId, guestInstanceId, params) {
335339
attachGuest(event, elementInstanceId, guestInstanceId, params)
336340
})

lib/renderer/web-view/guest-view-internal.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ module.exports = {
100100
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params, requestId)
101101
ipcRenderer.once(`ELECTRON_RESPONSE_${requestId}`, callback)
102102
},
103+
createGuestSync: function (params) {
104+
return ipcRenderer.sendSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', params)
105+
},
103106
attachGuest: function (elementInstanceId, guestInstanceId, params) {
104107
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', elementInstanceId, guestInstanceId, params)
105108
webFrame.attachGuest(elementInstanceId)

lib/renderer/web-view/web-view-attributes.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class SrcAttribute extends WebViewAttribute {
230230
}
231231

232232
parse () {
233-
if (!this.webViewImpl.elementAttached || !this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId) {
233+
if (!this.webViewImpl.elementAttached || !this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId || !this.getValue()) {
234234
return
235235
}
236236
if (this.webViewImpl.guestInstanceId == null) {
@@ -240,9 +240,6 @@ class SrcAttribute extends WebViewAttribute {
240240
}
241241
return
242242
}
243-
if (!this.getValue()) {
244-
return
245-
}
246243

247244
// Navigate to |this.src|.
248245
const opts = {}

lib/renderer/web-view/web-view.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ class WebViewImpl {
171171
})
172172
}
173173

174+
createGuestSync () {
175+
this.attachGuestInstance(guestViewInternal.createGuestSync(this.buildParams()))
176+
}
177+
174178
dispatchEvent (webViewEvent) {
175179
this.webviewNode.dispatchEvent(webViewEvent)
176180
}
@@ -418,7 +422,11 @@ const registerWebViewElement = function () {
418422

419423
// WebContents associated with this webview.
420424
proto.getWebContents = function () {
421-
return v8Util.getHiddenValue(this, 'internal').webContents
425+
const internal = v8Util.getHiddenValue(this, 'internal')
426+
if (!internal.webContents) {
427+
internal.createGuestSync()
428+
}
429+
return internal.webContents
422430
}
423431

424432
window.WebView = webFrame.registerEmbedderCustomElement('webview', {

spec/webview-spec.js

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -646,24 +646,22 @@ describe('<webview> tag', function () {
646646
describe('setDevToolsWebCotnents() API', () => {
647647
it('sets webContents of webview as devtools', (done) => {
648648
const webview2 = new WebView()
649-
webview2.addEventListener('did-attach', () => {
650-
webview2.addEventListener('dom-ready', () => {
651-
const devtools = webview2.getWebContents()
652-
assert.ok(devtools.getURL().startsWith('chrome-devtools://devtools'))
653-
devtools.executeJavaScript('InspectorFrontendHost.constructor.name', (name) => {
654-
assert.ok(name, 'InspectorFrontendHostImpl')
655-
document.body.removeChild(webview2)
656-
done()
657-
})
658-
})
659-
webview.addEventListener('dom-ready', () => {
660-
webview.getWebContents().setDevToolsWebContents(webview2.getWebContents())
661-
webview.getWebContents().openDevTools()
649+
document.body.appendChild(webview2)
650+
webview2.addEventListener('dom-ready', () => {
651+
const devtools = webview2.getWebContents()
652+
assert.ok(devtools.getURL().startsWith('chrome-devtools://devtools'))
653+
devtools.executeJavaScript('InspectorFrontendHost.constructor.name', (name) => {
654+
assert.ok(name, 'InspectorFrontendHostImpl')
655+
document.body.removeChild(webview2)
656+
done()
662657
})
663-
webview.src = 'about:blank'
664-
document.body.appendChild(webview)
665658
})
666-
document.body.appendChild(webview2)
659+
webview.addEventListener('dom-ready', () => {
660+
webview.getWebContents().setDevToolsWebContents(webview2.getWebContents())
661+
webview.getWebContents().openDevTools()
662+
})
663+
webview.src = 'about:blank'
664+
document.body.appendChild(webview)
667665
})
668666
})
669667

@@ -1153,6 +1151,16 @@ describe('<webview> tag', function () {
11531151
})
11541152

11551153
describe('will-attach-webview event', () => {
1154+
it('does not emit when src is not changed', (done) => {
1155+
document.body.appendChild(webview)
1156+
setTimeout(() => {
1157+
assert.throws(() => {
1158+
webview.stop()
1159+
}, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.')
1160+
done()
1161+
})
1162+
})
1163+
11561164
it('supports changing the web preferences', (done) => {
11571165
ipcRenderer.send('disable-node-on-next-will-attach-webview')
11581166
webview.addEventListener('console-message', (event) => {
@@ -1350,12 +1358,12 @@ describe('<webview> tag', function () {
13501358
const destroy1Listener = () => {
13511359
webview.removeEventListener('destroyed', destroy1Listener, false)
13521360
assert.equal(webContents, webview2.getWebContents())
1353-
assert.equal(null, webview.getWebContents())
1361+
assert.notStrictEqual(webContents, webview.getWebContents())
13541362

13551363
const destroy2Listener = () => {
13561364
webview2.removeEventListener('destroyed', destroy2Listener, false)
13571365
assert.equal(webContents, webview.getWebContents())
1358-
assert.equal(null, webview2.getWebContents())
1366+
assert.notStrictEqual(webContents, webview2.getWebContents())
13591367

13601368
// Make sure that events are hooked up to the right webview now
13611369
webview.addEventListener('console-message', (e) => {

0 commit comments

Comments
 (0)