 xhr                     = null
 
 EVENTS =
-  BEFORE_CHANGE:          'page:before-change'
-  FETCH:                  'page:fetch'
-  RECEIVE:                'page:receive'
-  CHANGE:                 'page:change'
-  UPDATE:                 'page:update'
-  LOAD:                   'page:load'
-  RESTORE:                'page:restore'
-  BEFORE_UNLOAD:          'page:before-unload'
-  EXPIRE:                 'page:expire'
+  BEFORE_CHANGE:  'page:before-change'
+  FETCH:          'page:fetch'
+  RECEIVE:        'page:receive'
+  CHANGE:         'page:change'
+  UPDATE:         'page:update'
+  LOAD:           'page:load'
+  RESTORE:        'page:restore'
+  BEFORE_UNLOAD:  'page:before-unload'
+  EXPIRE:         'page:expire'
 
 fetch = (url, options = {}) ->
   url = new ComponentUrl url


  return matchingNodes

keepNodes = (body, allNodesToKeep) ->
  for existingNode in allNodesToKeep
    unless nodeId = existingNode.getAttribute('id')
      throw new Error("Turbolinks partial replace: Kept nodes must have an id.")

    if remoteNode = body.querySelector('[id="'+nodeId+'"]')
      remoteNode.parentNode.replaceChild(existingNode, remoteNode)

changeNodes = (body, allNodesToBeChanged) ->
  parentIsRefreshing = (node) ->
    for potentialParent in allNodesToBeChanged when node != potentialParent
      return true if potentialParent.contains(node)
    false

  refreshedNodes = []
  for existingNode in allNodesToBeChanged
    continue if parentIsRefreshing(existingNode)

    unless nodeId = existingNode.getAttribute('id')
      throw new Error "Turbolinks partial replacement: change key elements must have an id."

    if newNode = body.querySelector('[id="'+nodeId+'"]')
      newNode = newNode.cloneNode(true)
      existingNode.parentNode.replaceChild(newNode, existingNode)


    delete pageCache[key]

replace = (html, options = {}) ->
  changePage createDocument(html), options

changePage = (doc, options = {}) ->
  [title, targetBody, csrfToken, runScripts] = extractTitleAndBody(doc)
  title ?= options.title

  triggerEvent EVENTS.BEFORE_UNLOAD
  document.title = title

  changeNodes(targetBody, findNodes(document.body, '[data-turbolinks-temporary]'))

