<commit_before>pageCache               = {}
cacheSize               = 10
transitionCacheEnabled  = false
progressBar             = null

currentState            = null
loadedAssets            = null

referer                 = null

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'

fetch = (url, options = {}) ->
  url = new ComponentUrl url

  rememberReferer()
  cacheCurrentPage()
  progressBar?.start()

  if transitionCacheEnabled and cachedPage = transitionCacheFor(url.absolute)
    fetchHistory cachedPage
    options.showProgressBar = false
    fetchReplacement url, options
  else
    options.onLoadFunction = resetScrollPosition
    fetchReplacement url, options

transitionCacheFor = (url) ->
  cachedPage = pageCache[url]
  cachedPage if cachedPage and !cachedPage.transitionCacheDisabled

enableTransitionCache = (enable = true) ->
  transitionCacheEnabled = enable

enableProgressBar = (enable = true) ->
  return unless browserSupportsTurbolinks
  if enable
    progressBar ?= new ProgressBar 'html'
  else
    progressBar?.uninstall()
    progressBar = null

fetchReplacement = (url, options) ->
  options.showProgressBar ?= true

  triggerEvent EVENTS.FETCH, url: url.absolute

  xhr?.abort()
  xhr = new XMLHttpRequest
  xhr.open 'GET', url.withoutHashForIE10compatibility(), true
  xhr.setRequestHeader 'Accept', 'text/html, application/xhtml+xml, application/xml'
  xhr.setRequestHeader 'X-XHR-Referer', referer

  xhr.onload = ->
    triggerEvent EVENTS.RECEIVE, url: url.absolute

    if doc = processResponse()
      reflectNewUrl url
      reflectRedirectedUrl()
      changePage doc, options
      if options.showProgressBar
        progressBar?.done()
      manuallyTriggerHashChangeForFirefox()
      options.onLoadFunction?()
      triggerEvent EVENTS.LOAD
    else
      progressBar?.done()
      document.location.href = crossOriginRedirect() or url.absolute

  if progressBar and options.showProgressBar
    xhr.onprogress = (event) =>
      percent = if event.lengthComputable
        event.loaded / event.total * 100
      else
        progressBar.value + (100 - progressBar.value) / 10
      progressBar.advanceTo(percent)

  xhr.onloadend = -> xhr = null
  xhr.onerror   = -> document.location.href = url.absolute

  xhr.send()

fetchHistory = (cachedPage) ->
  xhr?.abort()
  changePage createDocument(cachedPage.body.outerHTML), title: cachedPage.title
  progressBar?.done()
  recallScrollPosition cachedPage
  triggerEvent EVENTS.RESTORE

cacheCurrentPage = ->
  currentStateUrl = new ComponentUrl currentState.url

  pageCache[currentStateUrl.absolute] =
    url:                      currentStateUrl.relative,
    body:                     document.body,
    title:                    document.title,
    positionY:                window.pageYOffset,
    positionX:                window.pageXOffset,
    cachedAt:                 new Date().getTime(),
    transitionCacheDisabled:  document.querySelector('[data-no-transition-cache]')?

  constrainPageCacheTo cacheSize

pagesCached = (size = cacheSize) ->
  cacheSize = parseInt(size) if /^[\d]+$/.test size

constrainPageCacheTo = (limit) ->
  pageCacheKeys = Object.keys pageCache

  cacheTimesRecentFirst = pageCacheKeys.map (url) ->
    pageCache[url].cachedAt
  .sort (a, b) -> b - a

  for key in pageCacheKeys when pageCache[key].cachedAt <= cacheTimesRecentFirst[limit]
    triggerEvent EVENTS.EXPIRE, pageCache[key]
    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

  swapNodes(targetBody, findNodes(document.body, '[data-turbolinks-temporary]'), keep: false)
  if options.change
    swapNodes(targetBody, findNodesMatchingKeys(document.body, options.change), keep: false)
  else
    unless options.flush
      nodesToBeKept = findNodes(document.body, '[data-turbolinks-permanent]')
      nodesToBeKept.push(findNodesMatchingKeys(document.body, options.keep)...) if options.keep
      swapNodes(targetBody, nodesToBeKept, keep: true)

    document.documentElement.replaceChild targetBody, document.body
    CSRFToken.update csrfToken if csrfToken?
    setAutofocusElement()
    executeScriptTags() if runScripts
    currentState = window.history.state

  triggerEvent EVENTS.CHANGE
  triggerEvent EVENTS.UPDATE
<commit_msg>changePage should always change current_state<commit_after>pageCache               = {}
cacheSize               = 10
transitionCacheEnabled  = false
progressBar             = null

currentState            = null
loadedAssets            = null

referer                 = null

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'

fetch = (url, options = {}) ->
  url = new ComponentUrl url

  rememberReferer()
  cacheCurrentPage()
  progressBar?.start()

  if transitionCacheEnabled and cachedPage = transitionCacheFor(url.absolute)
    fetchHistory cachedPage
    options.showProgressBar = false
    fetchReplacement url, options
  else
    options.onLoadFunction = resetScrollPosition
    fetchReplacement url, options

transitionCacheFor = (url) ->
  cachedPage = pageCache[url]
  cachedPage if cachedPage and !cachedPage.transitionCacheDisabled

enableTransitionCache = (enable = true) ->
  transitionCacheEnabled = enable

enableProgressBar = (enable = true) ->
  return unless browserSupportsTurbolinks
  if enable
    progressBar ?= new ProgressBar 'html'
  else
    progressBar?.uninstall()
    progressBar = null

fetchReplacement = (url, options) ->
  options.showProgressBar ?= true

  triggerEvent EVENTS.FETCH, url: url.absolute

  xhr?.abort()
  xhr = new XMLHttpRequest
  xhr.open 'GET', url.withoutHashForIE10compatibility(), true
  xhr.setRequestHeader 'Accept', 'text/html, application/xhtml+xml, application/xml'
  xhr.setRequestHeader 'X-XHR-Referer', referer

  xhr.onload = ->
    triggerEvent EVENTS.RECEIVE, url: url.absolute

    if doc = processResponse()
      reflectNewUrl url
      reflectRedirectedUrl()
      changePage doc, options
      if options.showProgressBar
        progressBar?.done()
      manuallyTriggerHashChangeForFirefox()
      options.onLoadFunction?()
      triggerEvent EVENTS.LOAD
    else
      progressBar?.done()
      document.location.href = crossOriginRedirect() or url.absolute

  if progressBar and options.showProgressBar
    xhr.onprogress = (event) =>
      percent = if event.lengthComputable
        event.loaded / event.total * 100
      else
        progressBar.value + (100 - progressBar.value) / 10
      progressBar.advanceTo(percent)

  xhr.onloadend = -> xhr = null
  xhr.onerror   = -> document.location.href = url.absolute

  xhr.send()

fetchHistory = (cachedPage) ->
  xhr?.abort()
  changePage createDocument(cachedPage.body.outerHTML), title: cachedPage.title
  progressBar?.done()
  recallScrollPosition cachedPage
  triggerEvent EVENTS.RESTORE

cacheCurrentPage = ->
  currentStateUrl = new ComponentUrl currentState.url

  pageCache[currentStateUrl.absolute] =
    url:                      currentStateUrl.relative,
    body:                     document.body,
    title:                    document.title,
    positionY:                window.pageYOffset,
    positionX:                window.pageXOffset,
    cachedAt:                 new Date().getTime(),
    transitionCacheDisabled:  document.querySelector('[data-no-transition-cache]')?

  constrainPageCacheTo cacheSize

pagesCached = (size = cacheSize) ->
  cacheSize = parseInt(size) if /^[\d]+$/.test size

constrainPageCacheTo = (limit) ->
  pageCacheKeys = Object.keys pageCache

  cacheTimesRecentFirst = pageCacheKeys.map (url) ->
    pageCache[url].cachedAt
  .sort (a, b) -> b - a

  for key in pageCacheKeys when pageCache[key].cachedAt <= cacheTimesRecentFirst[limit]
    triggerEvent EVENTS.EXPIRE, pageCache[key]
    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

  swapNodes(targetBody, findNodes(document.body, '[data-turbolinks-temporary]'), keep: false)
  if options.change
    swapNodes(targetBody, findNodesMatchingKeys(document.body, options.change), keep: false)
  else
    unless options.flush
      nodesToBeKept = findNodes(document.body, '[data-turbolinks-permanent]')
      nodesToBeKept.push(findNodesMatchingKeys(document.body, options.keep)...) if options.keep
      swapNodes(targetBody, nodesToBeKept, keep: true)

    document.documentElement.replaceChild targetBody, document.body
    CSRFToken.update csrfToken if csrfToken?
    setAutofocusElement()
    executeScriptTags() if runScripts

  currentState = window.history.state

  triggerEvent EVENTS.CHANGE
  triggerEvent EVENTS.UPDATE

{'fraction_non_alphanumeric': 0.09436133486766399, 'fraction_numerical': 0.0025107228789622345, 'mean_word_length': 3.167393199651264, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7380975', 'n_tokens_mistral': 2855, 'n_tokens_neox': 2791, 'n_words': 606}