{"action":"created","comment":{"url":"https://api.github.com/repos/Shopify/turbograft/pulls/comments/82831499","pull_request_review_id":3711042,"id":82831499,"diff_hunk":"@@ -136,39 +136,48 @@ class window.Turbolinks\n \n   @loadPage: (url, xhr, options = {}) ->\n     triggerEvent 'page:receive'\n+    response = new TurboGraft.Response(xhr)\n+    options.onlyKeys ?= []\n+    options.exceptKeys ?= []\n     options.updatePushState ?= true\n-    if upstreamDocument = new TurboGraft.Response(xhr).document()\n-      if options.partialReplace\n-        reflectNewUrl url if options.updatePushState\n-        updateBody(upstreamDocument, xhr, options)\n-      else\n-        turbohead = new TurboGraft.TurboHead(activeDocument, upstreamDocument)\n-        if turbohead.hasAssetConflicts()\n-          return Turbolinks.fullPageNavigate(url)\n-        reflectNewUrl url if options.updatePushState\n-        turbohead.waitForAssets().then((result) ->\n-          updateBody(upstreamDocument, xhr, options) unless result?.isCanceled\n-        )\n-    else\n+    options.partialReplace = isPartialReplace(options, response)\n+\n+    unless upstreamDocument = response.document()\n       triggerEvent 'page:error', xhr\n       Turbolinks.fullPageNavigate(url)\n+      return\n+\n+    if options.partialReplace\n+      reflectNewUrl url if options.updatePushState\n+      updateBody(upstreamDocument, response, options)\n+      return\n \n-  updateBody = (upstreamDocument, xhr, options) ->\n+    turbohead = new TurboGraft.TurboHead(activeDocument, upstreamDocument)\n+    if turbohead.hasAssetConflicts()\n+      return Turbolinks.fullPageNavigate(url)\n+\n+    reflectNewUrl url if options.updatePushState","path":"lib/assets/javascripts/turbograft/turbolinks.coffee","position":59,"original_position":59,"commit_id":"85af075751896667419074f54300907a343b2939","original_commit_id":"85af075751896667419074f54300907a343b2939","user":{"login":"qq99","id":150352,"avatar_url":"https://avatars.githubusercontent.com/u/150352?v=3","gravatar_id":"","url":"https://api.github.com/users/qq99","html_url":"https://github.com/qq99","followers_url":"https://api.github.com/users/qq99/followers","following_url":"https://api.github.com/users/qq99/following{/other_user}","gists_url":"https://api.github.com/users/qq99/gists{/gist_id}","starred_url":"https://api.github.com/users/qq99/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qq99/subscriptions","organizations_url":"https://api.github.com/users/qq99/orgs","repos_url":"https://api.github.com/users/qq99/repos","events_url":"https://api.github.com/users/qq99/events{/privacy}","received_events_url":"https://api.github.com/users/qq99/received_events","type":"User","site_admin":false},"body":"is it cool that `reflectNewUrl` and `reflectRedirectedUrl` can both fire? this here, and then `reflectRedirectedUrl` in the `updateBody` call?","created_at":"2016-10-11T16:20:18Z","updated_at":"2016-10-11T16:20:18Z","html_url":"https://github.com/Shopify/turbograft/pull/162#discussion_r82831499","pull_request_url":"https://api.github.com/repos/Shopify/turbograft/pulls/162","_links":{"self":{"href":"https://api.github.com/repos/Shopify/turbograft/pulls/comments/82831499"},"html":{"href":"https://github.com/Shopify/turbograft/pull/162#discussion_r82831499"},"pull_request":{"href":"https://api.github.com/repos/Shopify/turbograft/pulls/162"}}},"pull_request":{"url":"https://api.github.com/repos/Shopify/turbograft/pulls/162","id":87200538,"html_url":"https://github.com/Shopify/turbograft/pull/162","diff_url":"https://github.com/Shopify/turbograft/pull/162.diff","patch_url":"https://github.com/Shopify/turbograft/pull/162.patch","issue_url":"https://api.github.com/repos/Shopify/turbograft/issues/162","number":162,"state":"open","locked":false,"title":"Fix remote redirects being all wonky","user":{"login":"TheMallen","id":4889856,"avatar_url":"https://avatars.githubusercontent.com/u/4889856?v=3","gravatar_id":"","url":"https://api.github.com/users/TheMallen","html_url":"https://github.com/TheMallen","followers_url":"https://api.github.com/users/TheMallen/followers","following_url":"https://api.github.com/users/TheMallen/following{/other_user}","gists_url":"https://api.github.com/users/TheMallen/gists{/gist_id}","starred_url":"https://api.github.com/users/TheMallen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TheMallen/subscriptions","organizations_url":"https://api.github.com/users/TheMallen/orgs","repos_url":"https://api.github.com/users/TheMallen/repos","events_url":"https://api.github.com/users/TheMallen/events{/privacy}","received_events_url":"https://api.github.com/users/TheMallen/received_events","type":"User","site_admin":false},"body":"## Summary\r\nThis PR fixes the two main issues (#157 and #149) with remotes that result in redirects ~~on an opt-in  basis~~, and also refactors some of `Turbolinks` to make it a bit easier to maintain (and to add these changes). \r\n\r\n## Details\r\nAs we can see with #157 and #149, remotes that result in redirects can be pretty sketchy in the current release of TG. In most cases, a remote resulting in a redirect is due to submitting a form and then being redirected to the html generating endpoint afterwards. This means that we want scroll position to not be affected, and we don't want to bother waiting on head asset tracking. However, some cases (see home card navigation) actually are page navigations in disguise. In these (exceptional) cases there is no elegant solution with the current build of TG and we are currently just forcing full page refreshes on them. \r\n\r\n## How?\r\n- Adds a check for whether the `X-XHR-Redirect` header is pointing elsewhere, and considers the visit to be a non-partial replace if so. (This causes a scroll reset and triggers turbohead tracking)\r\n- ~~Adds `tg-force-scroll-reset` as an optional attribute on remotes. `tg-force-scroll-reset='true'` will cause a scroll reset when the redirect navigation concludes.~~\r\n- ~~Adds `tg-force-head-asset-insertion` as an optional attribute on remotes. `tg-force-head-asset-insertion='true'` will cause TG to perform head asset tracking just like a regular navigation, while still respecting partial replace rules that may have been set.~~\r\n- Adds tests for scroll reset behaviour so that future contributors can better understand how it is intended to behave.\r\n- Refactors with an emphasis on simplifying unnecessary forking and currying and iteratively rolling out proper sinon assertions (`assert @spy.called` => `assert.called @spy`)\r\n- Leaves behaviour unchanged for other redirects \r\n\r\n## Reviewers: \r\n@edward \r\n@GoodForOneFare \r\n@qq99 \r\n@Shopify/tnt \r\n\r\n**Edit**\r\nRedid this from the ground up with a much simpler convention of simply counting redirects to another url to be non-partial replaces. No new syntax.\r\n","created_at":"2016-09-28T21:01:57Z","updated_at":"2016-10-11T16:20:18Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4de241cf88e97b84e2d953b12d7ee473ceff3f0d","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Shopify/turbograft/pulls/162/commits","review_comments_url":"https://api.github.com/repos/Shopify/turbograft/pulls/162/comments","review_comment_url":"https://api.github.com/repos/Shopify/turbograft/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Shopify/turbograft/issues/162/comments","statuses_url":"https://api.github.com/repos/Shopify/turbograft/statuses/85af075751896667419074f54300907a343b2939","head":{"label":"Shopify:fix/scroll-reset","ref":"fix/scroll-reset","sha":"85af075751896667419074f54300907a343b2939","user":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"repo":{"id":23920094,"name":"turbograft","full_name":"Shopify/turbograft","owner":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Shopify/turbograft","description":"Hard fork of turbolinks, adding partial page replacement strategies, and utilities.","fork":false,"url":"https://api.github.com/repos/Shopify/turbograft","forks_url":"https://api.github.com/repos/Shopify/turbograft/forks","keys_url":"https://api.github.com/repos/Shopify/turbograft/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Shopify/turbograft/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Shopify/turbograft/teams","hooks_url":"https://api.github.com/repos/Shopify/turbograft/hooks","issue_events_url":"https://api.github.com/repos/Shopify/turbograft/issues/events{/number}","events_url":"https://api.github.com/repos/Shopify/turbograft/events","assignees_url":"https://api.github.com/repos/Shopify/turbograft/assignees{/user}","branches_url":"https://api.github.com/repos/Shopify/turbograft/branches{/branch}","tags_url":"https://api.github.com/repos/Shopify/turbograft/tags","blobs_url":"https://api.github.com/repos/Shopify/turbograft/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Shopify/turbograft/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Shopify/turbograft/git/refs{/sha}","trees_url":"https://api.github.com/repos/Shopify/turbograft/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Shopify/turbograft/statuses/{sha}","languages_url":"https://api.github.com/repos/Shopify/turbograft/languages","stargazers_url":"https://api.github.com/repos/Shopify/turbograft/stargazers","contributors_url":"https://api.github.com/repos/Shopify/turbograft/contributors","subscribers_url":"https://api.github.com/repos/Shopify/turbograft/subscribers","subscription_url":"https://api.github.com/repos/Shopify/turbograft/subscription","commits_url":"https://api.github.com/repos/Shopify/turbograft/commits{/sha}","git_commits_url":"https://api.github.com/repos/Shopify/turbograft/git/commits{/sha}","comments_url":"https://api.github.com/repos/Shopify/turbograft/comments{/number}","issue_comment_url":"https://api.github.com/repos/Shopify/turbograft/issues/comments{/number}","contents_url":"https://api.github.com/repos/Shopify/turbograft/contents/{+path}","compare_url":"https://api.github.com/repos/Shopify/turbograft/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Shopify/turbograft/merges","archive_url":"https://api.github.com/repos/Shopify/turbograft/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Shopify/turbograft/downloads","issues_url":"https://api.github.com/repos/Shopify/turbograft/issues{/number}","pulls_url":"https://api.github.com/repos/Shopify/turbograft/pulls{/number}","milestones_url":"https://api.github.com/repos/Shopify/turbograft/milestones{/number}","notifications_url":"https://api.github.com/repos/Shopify/turbograft/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Shopify/turbograft/labels{/name}","releases_url":"https://api.github.com/repos/Shopify/turbograft/releases{/id}","deployments_url":"https://api.github.com/repos/Shopify/turbograft/deployments","created_at":"2014-09-11T13:47:46Z","updated_at":"2016-10-05T19:09:57Z","pushed_at":"2016-10-07T19:02:56Z","git_url":"git://github.com/Shopify/turbograft.git","ssh_url":"git@github.com:Shopify/turbograft.git","clone_url":"https://github.com/Shopify/turbograft.git","svn_url":"https://github.com/Shopify/turbograft","homepage":"","size":660,"stargazers_count":162,"watchers_count":162,"language":"CoffeeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":15,"mirror_url":null,"open_issues_count":22,"forks":15,"open_issues":22,"watchers":162,"default_branch":"master"}},"base":{"label":"Shopify:master","ref":"master","sha":"a5453e64828fda2ea17c9cbfa41ddf344ce7ce85","user":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"repo":{"id":23920094,"name":"turbograft","full_name":"Shopify/turbograft","owner":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Shopify/turbograft","description":"Hard fork of turbolinks, adding partial page replacement strategies, and utilities.","fork":false,"url":"https://api.github.com/repos/Shopify/turbograft","forks_url":"https://api.github.com/repos/Shopify/turbograft/forks","keys_url":"https://api.github.com/repos/Shopify/turbograft/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Shopify/turbograft/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Shopify/turbograft/teams","hooks_url":"https://api.github.com/repos/Shopify/turbograft/hooks","issue_events_url":"https://api.github.com/repos/Shopify/turbograft/issues/events{/number}","events_url":"https://api.github.com/repos/Shopify/turbograft/events","assignees_url":"https://api.github.com/repos/Shopify/turbograft/assignees{/user}","branches_url":"https://api.github.com/repos/Shopify/turbograft/branches{/branch}","tags_url":"https://api.github.com/repos/Shopify/turbograft/tags","blobs_url":"https://api.github.com/repos/Shopify/turbograft/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Shopify/turbograft/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Shopify/turbograft/git/refs{/sha}","trees_url":"https://api.github.com/repos/Shopify/turbograft/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Shopify/turbograft/statuses/{sha}","languages_url":"https://api.github.com/repos/Shopify/turbograft/languages","stargazers_url":"https://api.github.com/repos/Shopify/turbograft/stargazers","contributors_url":"https://api.github.com/repos/Shopify/turbograft/contributors","subscribers_url":"https://api.github.com/repos/Shopify/turbograft/subscribers","subscription_url":"https://api.github.com/repos/Shopify/turbograft/subscription","commits_url":"https://api.github.com/repos/Shopify/turbograft/commits{/sha}","git_commits_url":"https://api.github.com/repos/Shopify/turbograft/git/commits{/sha}","comments_url":"https://api.github.com/repos/Shopify/turbograft/comments{/number}","issue_comment_url":"https://api.github.com/repos/Shopify/turbograft/issues/comments{/number}","contents_url":"https://api.github.com/repos/Shopify/turbograft/contents/{+path}","compare_url":"https://api.github.com/repos/Shopify/turbograft/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Shopify/turbograft/merges","archive_url":"https://api.github.com/repos/Shopify/turbograft/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Shopify/turbograft/downloads","issues_url":"https://api.github.com/repos/Shopify/turbograft/issues{/number}","pulls_url":"https://api.github.com/repos/Shopify/turbograft/pulls{/number}","milestones_url":"https://api.github.com/repos/Shopify/turbograft/milestones{/number}","notifications_url":"https://api.github.com/repos/Shopify/turbograft/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Shopify/turbograft/labels{/name}","releases_url":"https://api.github.com/repos/Shopify/turbograft/releases{/id}","deployments_url":"https://api.github.com/repos/Shopify/turbograft/deployments","created_at":"2014-09-11T13:47:46Z","updated_at":"2016-10-05T19:09:57Z","pushed_at":"2016-10-07T19:02:56Z","git_url":"git://github.com/Shopify/turbograft.git","ssh_url":"git@github.com:Shopify/turbograft.git","clone_url":"https://github.com/Shopify/turbograft.git","svn_url":"https://github.com/Shopify/turbograft","homepage":"","size":660,"stargazers_count":162,"watchers_count":162,"language":"CoffeeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":15,"mirror_url":null,"open_issues_count":22,"forks":15,"open_issues":22,"watchers":162,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Shopify/turbograft/pulls/162"},"html":{"href":"https://github.com/Shopify/turbograft/pull/162"},"issue":{"href":"https://api.github.com/repos/Shopify/turbograft/issues/162"},"comments":{"href":"https://api.github.com/repos/Shopify/turbograft/issues/162/comments"},"review_comments":{"href":"https://api.github.com/repos/Shopify/turbograft/pulls/162/comments"},"review_comment":{"href":"https://api.github.com/repos/Shopify/turbograft/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Shopify/turbograft/pulls/162/commits"},"statuses":{"href":"https://api.github.com/repos/Shopify/turbograft/statuses/85af075751896667419074f54300907a343b2939"}}}}
{"actor":{"display_login":"qq99"}}