Implement our own NavigationController

This commit is contained in:
Cheng Zhao 2015-04-26 21:28:30 +08:00
parent 2f1683445b
commit 0143a45488
5 changed files with 89 additions and 73 deletions

View file

@ -0,0 +1,76 @@
# 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) =>
if @pendingIndex >= 0 # Go to index.
@currentIndex = @pendingIndex
@pendingIndex = -1
@history[@currentIndex] = url
else # Normal navigation.
@history = @history.slice 0, @currentIndex + 1 # Clear history.
if @history[@currentIndex] isnt url
@currentIndex++
@history.push url
loadUrl: (url, options={}) ->
@pendingIndex = -1
@webContents._loadUrl url, options
getUrl: ->
if @currentIndex is -1
''
else
@history[@currentIndex]
stop: ->
@pendingIndex = -1
@webContents._stop()
reload: ->
@pendingIndex = @currentIndex
@webContents._loadUrl @getUrl(), {}
reloadIgnoringCache: ->
@webContents._reloadIgnoringCache() # Rely on WebContents to clear cache.
@reload()
canGoBack: ->
@currentIndex > 0
canGoForward: ->
@currentIndex < @history.length
canGoToIndex: (index) ->
index >=0 and index < @history.length
canGoToOffset: (offset) ->
@canGoToIndex @currentIndex + offset
goBack: ->
return unless @canGoBack()
@pendingIndex = @currentIndex - 1
@webContents._loadUrl @history[@pendingIndex], {}
goForward: ->
return unless @canGoForward()
@pendingIndex = @currentIndex + 1
@webContents._loadUrl @history[@pendingIndex], {}
goToIndex: (index) ->
return unless @canGoToIndex index
@pendingIndex = index
@webContents._loadUrl @history[@pendingIndex], {}
goToOffset: (offset) ->
return unless @canGoToOffset offset
@goToIndex @currentIndex + offset
module.exports = NavigationController

View file

@ -1,4 +1,5 @@
EventEmitter = require('events').EventEmitter
NavigationController = require './navigation-controller'
binding = process.atomBinding 'web_contents'
ipc = require 'ipc'
@ -26,10 +27,12 @@ module.exports.wrap = (webContents) ->
webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}"
webContents.equal = (other) -> @getId() is other.getId()
# Provide a default parameter for |urlOptions|.
webContents.loadUrl = (url, urlOptions={}) -> @_loadUrl url, urlOptions
webContents.reload = (urlOptions={}) -> @_reload urlOptions
webContents.reloadIgnoringCache = (urlOptions={}) -> @_reloadIgnoringCache urlOptions
# The navigation controller.
controller = new NavigationController(webContents)
webContents.controller = controller
for name, method of NavigationController.prototype when method instanceof Function
do (name, method) ->
webContents[name] = -> method.apply controller, arguments
# Translate |disposition| to string for 'new-window' event.
webContents.on '-new-window', (args..., disposition) ->