Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: do not mark navigations interupted with same-document navigations as aborted #18142

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/browser/navigation-controller.js
Expand Up @@ -86,10 +86,16 @@ const NavigationController = (function () {
let navigationStarted = false
const navigationListener = (event, url, isSameDocument, isMainFrame, frameProcessId, frameRoutingId, navigationId) => {
if (isMainFrame) {
if (navigationStarted) {
if (navigationStarted && !isSameDocument) {
// the webcontents has started another unrelated navigation in the
// main frame (probably from the app calling `loadURL` again); reject
// the promise
// We should only consider the request aborted if the "navigation" is
// actually navigating and not simply transitioning URL state in the
// current context. E.g. pushState and `location.hash` changes are
// considered navigation events but are triggered with isSameDocument.
// We can ignore these to allow virtual routing on page load as long
// as the routing does not leave the document
return rejectAndCleanup(-3, 'ERR_ABORTED', url)
}
navigationStarted = true
Expand Down
21 changes: 21 additions & 0 deletions spec/api-browser-window-spec.js
Expand Up @@ -290,6 +290,27 @@ describe('BrowserWindow module', () => {
w.loadURL(`data:image/png;base64,${data}`)
})

it('should return a promise', () => {
const p = w.loadURL('about:blank')
expect(p).to.have.property('then')
})

it('should return a promise that resolves', async () => {
expect(w.loadURL('about:blank')).to.eventually.be.fulfilled()
})

it('should return a promise that rejects on a load failure', async () => {
const data = Buffer.alloc(2 * 1024 * 1024).toString('base64')
const p = w.loadURL(`data:image/png;base64,${data}`)
await expect(p).to.eventually.be.rejected()
})

it('should return a promise that resolves even if pushState occurs during navigation', async () => {
const data = Buffer.alloc(2 * 1024 * 1024).toString('base64')
const p = w.loadURL('data:text/html,<script>window.history.pushState({}, "/foo")</script>')
await expect(p).to.eventually.be.fulfilled()
})

describe('POST navigations', () => {
afterEach(() => { w.webContents.session.webRequest.onBeforeSendHeaders(null) })

Expand Down