electron/atom/browser/api/lib/navigation-controller.coffee

92 lines
2.7 KiB
CoffeeScript

# JavaScript implementation of Chromium's NavigationController.
# Instead of relying on Chromium for history control, we compeletely do history
# control on user land, and only rely on WebContents.loadUrl for navigation.
# This helps us avoid Chromium's various optimizations so we can ensure renderer
# process is restarted everytime.
class NavigationController
constructor: (@webContents) ->
@history = []
@currentIndex = -1
@pendingIndex = -1
@webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) =>
console.log 'navigation-entry-commited', url, inPage, replaceEntry
if @pendingIndex >= 0 # Go to index.
@currentIndex = @pendingIndex
@pendingIndex = -1
@history[@currentIndex] = {url, inPage}
else if replaceEntry # Non-user initialized navigation.
@history[@currentIndex] = {url, inPage}
else # Normal navigation.
@history = @history.slice 0, @currentIndex + 1 # Clear history.
currentEntry = @history[@currentIndex]
if currentEntry?.url isnt url or currentEntry?.inPage isnt inPage
@currentIndex++
@history.push {url, inPage}
loadUrl: (url, options={}) ->
@pendingIndex = -1
@webContents._loadUrl url, options
getUrl: ->
if @currentIndex is -1
''
else
@history[@currentIndex].url
stop: ->
@pendingIndex = -1
@webContents._stop()
reload: ->
@pendingIndex = @currentIndex
@webContents._loadUrl @getUrl(), {}
reloadIgnoringCache: ->
@webContents._reloadIgnoringCache() # Rely on WebContents to clear cache.
@reload()
canGoBack: ->
@getActiveIndex() > 0
canGoForward: ->
@getActiveIndex() < @history.length - 1
canGoToIndex: (index) ->
index >=0 and index < @history.length
canGoToOffset: (offset) ->
@canGoToIndex @currentIndex + offset
goBack: ->
return unless @canGoBack()
@pendingIndex = @getActiveIndex() - 1
pendingEntry = @history[@pendingIndex]
if pendingEntry.inPage
@webContents._goBack()
else
@webContents._loadUrl pendingEntry.url, {}
goForward: ->
return unless @canGoForward()
@pendingIndex = @getActiveIndex() + 1
pendingEntry = @history[@pendingIndex]
if pendingEntry.inPage
@webContents._goForward()
else
@webContents._loadUrl pendingEntry.url, {}
goToIndex: (index) ->
return unless @canGoToIndex index
@pendingIndex = index
@webContents._loadUrl @history[@pendingIndex].url, {}
goToOffset: (offset) ->
return unless @canGoToOffset offset
@goToIndex @currentIndex + offset
getActiveIndex: ->
if @pendingIndex is -1 then @currentIndex else @pendingIndex
module.exports = NavigationController