feat: webContents.loadURL returns a promise (#15855)

This commit is contained in:
Jeremy Apthorp 2018-12-06 12:16:19 -08:00 committed by GitHub
parent 1b8c11121f
commit 442c1b22e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 180 additions and 13 deletions

View file

@ -63,9 +63,66 @@ const NavigationController = (function () {
if (options == null) {
options = {}
}
const p = new Promise((resolve, reject) => {
const resolveAndCleanup = () => {
removeListeners()
resolve()
}
const rejectAndCleanup = (errorCode, errorDescription, url) => {
const err = new Error(`${errorDescription} (${errorCode}) loading '${url}'`)
Object.assign(err, { errno: errorCode, code: errorDescription, url })
removeListeners()
reject(err)
}
const finishListener = () => {
resolveAndCleanup()
}
const failListener = (event, errorCode, errorDescription, validatedURL, isMainFrame, frameProcessId, frameRoutingId) => {
if (isMainFrame) {
rejectAndCleanup(errorCode, errorDescription, validatedURL)
}
}
let navigationStarted = false
const navigationListener = (event, url, isSameDocument, isMainFrame, frameProcessId, frameRoutingId, navigationId) => {
if (isMainFrame) {
if (navigationStarted) {
// the webcontents has started another unrelated navigation in the
// main frame (probably from the app calling `loadURL` again); reject
// the promise
return rejectAndCleanup(-3, 'ERR_ABORTED', url)
}
navigationStarted = true
}
}
const stopLoadingListener = () => {
// By the time we get here, either 'finish' or 'fail' should have fired
// if the navigation occurred. However, in some situations (e.g. when
// attempting to load a page with a bad scheme), loading will stop
// without emitting finish or fail. In this case, we reject the promise
// with a generic failure.
// TODO(jeremy): enumerate all the cases in which this can happen. If
// the only one is with a bad scheme, perhaps ERR_INVALID_ARGUMENT
// would be more appropriate.
rejectAndCleanup(-2, 'ERR_FAILED', url)
}
const removeListeners = () => {
this.webContents.removeListener('did-finish-load', finishListener)
this.webContents.removeListener('did-fail-load', failListener)
this.webContents.removeListener('did-start-navigation', navigationListener)
this.webContents.removeListener('did-stop-loading', stopLoadingListener)
}
this.webContents.on('did-finish-load', finishListener)
this.webContents.on('did-fail-load', failListener)
this.webContents.on('did-start-navigation', navigationListener)
this.webContents.on('did-stop-loading', stopLoadingListener)
})
// Add a no-op rejection handler to silence the unhandled rejection error.
p.catch(() => {})
this.pendingIndex = -1
this.webContents._loadURL(url, options)
return this.webContents.emit('load-url', url, options)
this.webContents.emit('load-url', url, options)
return p
}
NavigationController.prototype.getURL = function () {