117 lines
		
	
	
	
		
			3.4 KiB
			
		
	
	
	
		
			CoffeeScript
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
	
		
			3.4 KiB
			
		
	
	
	
		
			CoffeeScript
		
	
	
	
	
	
ipc = require 'ipc'
 | 
						|
 | 
						|
# The history operation in renderer is redirected to browser.
 | 
						|
ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
 | 
						|
  event.sender[method] args...
 | 
						|
 | 
						|
ipc.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) ->
 | 
						|
  event.returnValue = event.sender[method] args...
 | 
						|
 | 
						|
# 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) ->
 | 
						|
    @clearHistory()
 | 
						|
 | 
						|
    @webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) =>
 | 
						|
      if @inPageIndex > -1 and not inPage
 | 
						|
        # Navigated to a new page, clear in-page mark.
 | 
						|
        @inPageIndex = -1
 | 
						|
      else if @inPageIndex is -1 and inPage
 | 
						|
        # Started in-page navigations.
 | 
						|
        @inPageIndex = @currentIndex
 | 
						|
 | 
						|
      if @pendingIndex >= 0 # Go to index.
 | 
						|
        @currentIndex = @pendingIndex
 | 
						|
        @pendingIndex = -1
 | 
						|
        @history[@currentIndex] = url
 | 
						|
      else if replaceEntry # Non-user initialized navigation.
 | 
						|
        @history[@currentIndex] = url
 | 
						|
      else  # Normal navigation.
 | 
						|
        @history = @history.slice 0, @currentIndex + 1  # Clear history.
 | 
						|
        currentEntry = @history[@currentIndex]
 | 
						|
        if currentEntry?.url isnt url
 | 
						|
          @currentIndex++
 | 
						|
          @history.push url
 | 
						|
 | 
						|
  loadUrl: (url, options={}) ->
 | 
						|
    @pendingIndex = -1
 | 
						|
    @webContents._loadUrl url, options
 | 
						|
    @webContents.emit 'load-url', 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: ->
 | 
						|
    @getActiveIndex() > 0
 | 
						|
 | 
						|
  canGoForward: ->
 | 
						|
    @getActiveIndex() < @history.length - 1
 | 
						|
 | 
						|
  canGoToIndex: (index) ->
 | 
						|
    index >=0 and index < @history.length
 | 
						|
 | 
						|
  canGoToOffset: (offset) ->
 | 
						|
    @canGoToIndex @currentIndex + offset
 | 
						|
 | 
						|
  clearHistory: ->
 | 
						|
    @history = []
 | 
						|
    @currentIndex = -1
 | 
						|
    @pendingIndex = -1
 | 
						|
    @inPageIndex = -1
 | 
						|
 | 
						|
  goBack: ->
 | 
						|
    return unless @canGoBack()
 | 
						|
    @pendingIndex = @getActiveIndex() - 1
 | 
						|
    if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
 | 
						|
      @webContents._goBack()
 | 
						|
    else
 | 
						|
      @webContents._loadUrl @history[@pendingIndex], {}
 | 
						|
 | 
						|
  goForward: ->
 | 
						|
    return unless @canGoForward()
 | 
						|
    @pendingIndex = @getActiveIndex() + 1
 | 
						|
    if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
 | 
						|
      @webContents._goForward()
 | 
						|
    else
 | 
						|
      @webContents._loadUrl @history[@pendingIndex], {}
 | 
						|
 | 
						|
  goToIndex: (index) ->
 | 
						|
    return unless @canGoToIndex index
 | 
						|
    @pendingIndex = index
 | 
						|
    @webContents._loadUrl @history[@pendingIndex], {}
 | 
						|
 | 
						|
  goToOffset: (offset) ->
 | 
						|
    return unless @canGoToOffset offset
 | 
						|
    pendingIndex = @currentIndex + offset
 | 
						|
    if @inPageIndex > -1 and pendingIndex >= @inPageIndex
 | 
						|
      @pendingIndex = pendingIndex
 | 
						|
      @webContents._goToOffset offset
 | 
						|
    else
 | 
						|
      @goToIndex pendingIndex
 | 
						|
 | 
						|
  getActiveIndex: ->
 | 
						|
    if @pendingIndex is -1 then @currentIndex else @pendingIndex
 | 
						|
 | 
						|
  length: ->
 | 
						|
    @history.length
 | 
						|
 | 
						|
module.exports = NavigationController
 |