turbolinks 1.3.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa1a853f7bfa398507ab56f01f6f60e701e5d610
4
- data.tar.gz: 1b905b7d3b6d6d536766371fecada3d7c8e033e3
3
+ metadata.gz: 42e6215f4902695d105228b3ee98d24219a2d690
4
+ data.tar.gz: 57aa487dbbb45d7cd209b295cc0006e6c602c853
5
5
  SHA512:
6
- metadata.gz: 4e41529e84e22f5c3ca8bcf57587888efb44b670bd28e1c1cb1712e8c46fe4dc4576b0caf7287ebcea260970885d02dbb76fc3c2930785d6dcd845f21ad08f2b
7
- data.tar.gz: 734e50ff840b75516f8645985e20c47419a74a3ec378a3d08396935eac562b3afebba6d7680d14a3ecf3195ad474b433e26ae7d40caf82c4507c7d77ed705e92
6
+ metadata.gz: d0619a0efb53282613f6e745e89d2eb3bf21673b8b460e9aba14f4bbf6f41df1dd59fb2d555c43ad399a3600f2de8d647764c9af1a32755a693faaf805becefc
7
+ data.tar.gz: 0e983e4382e1ec55236bc832c4c0021b5fb5766fa3b78e51a5d6d637329eff87a5329c76d281d7c31cb84f0bbd2cf39f913d21077cfecfb5690398879672644d
data/README.md CHANGED
@@ -18,10 +18,10 @@ In any case, the benefit can be up to [twice as fast](https://github.com/stevekl
18
18
  The best way to find out just how fast it is? Try it on your own application. It hardly takes any effort at all.
19
19
 
20
20
 
21
- No jQuery or any other framework
21
+ No jQuery or any other library
22
22
  --------------------------------
23
23
 
24
- Turbolinks is designed to be as light-weight as possible (so you won't think twice about using it even for mobile stuff). It does not require jQuery or any other framework to work. But it works great _with_ jQuery or Prototype or whatever else have you.
24
+ Turbolinks is designed to be as light-weight as possible (so you won't think twice about using it even for mobile stuff). It does not require jQuery or any other library to work. But it works great _with_ the jQuery or Prototype framework, or whatever else have you.
25
25
 
26
26
 
27
27
  Events
@@ -33,10 +33,11 @@ With Turbolinks pages will change without a full reload, so you can't rely on `D
33
33
  * `page:before-change` a Turbolinks-enabled link has been clicked *(see below for more details)*
34
34
  * `page:fetch` starting to fetch a new target page
35
35
  * `page:receive` the page has been fetched from the server, but not yet parsed
36
- * `page:change` the page has been parsed and changed to the new version
36
+ * `page:change` the page has been parsed and changed to the new version and on DOMContentLoaded
37
+ * `page:update` is triggered whenever page:change is PLUS on jQuery's ajaxSucess, if jQuery is available (otherwise you can manually trigger it when calling XMLHttpRequest in your own code)
37
38
  * `page:load` is fired at the end of the loading process.
38
39
 
39
- Handlers bound to the `page:before-change` event may return `false`, which will cancel the Turbolinks process.
40
+ Handlers bound to the `page:before-change` event may return `false`, which will cancel the Turbolinks process.
40
41
 
41
42
  By default, Turbolinks caches 10 of these page loads. It listens to the [popstate](https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history#The_popstate_event) event and attempts to restore page state from the cache when it's triggered. When `popstate` is fired the following process happens:
42
43
 
@@ -58,7 +59,7 @@ To implement a client-side spinner, you could listen for `page:fetch` to start i
58
59
 
59
60
  document.addEventListener("page:fetch", startSpinner);
60
61
  document.addEventListener("page:receive", stopSpinner);
61
-
62
+
62
63
  DOM transformations that are idempotent are best. If you have transformations that are not, hook them to happen only on `page:load` instead of `page:change` (as that would run them again on the cached pages).
63
64
 
64
65
  Initialization
@@ -88,7 +89,7 @@ By default, all internal HTML links will be funneled through Turbolinks, but you
88
89
  </div>
89
90
  ```
90
91
 
91
- Note that internal links to files not ending in .html, or having no extension, will automatically be opted out of Turbolinks. So links to /images/panda.gif will just work as expected.
92
+ Note that internal links to files containing a file extension other than **.html** will automatically be opted out of Turbolinks. So links to /images/panda.gif will just work as expected.
92
93
 
93
94
  Also, Turbolinks is installed as the last click handler for links. So if you install another handler that calls event.preventDefault(), Turbolinks will not run. This ensures that you can safely use Turbolinks with stuff like `data-method`, `data-remote`, or `data-confirm` from Rails.
94
95
 
@@ -139,6 +140,8 @@ Triggering a Turbolinks visit manually
139
140
 
140
141
  You can use `Turbolinks.visit(path)` to go to a URL through Turbolinks.
141
142
 
143
+ You can also use `redirect_via_turbolinks_to` in Rails to perform a redirect via Turbolinks.
144
+
142
145
 
143
146
  Full speed for pushState browsers, graceful fallback for everything else
144
147
  ------------------------------------------------------------------------
@@ -165,7 +168,10 @@ Installation
165
168
  Language Ports
166
169
  --------------
167
170
 
171
+ *These projects are not affiliated with or endorsed by the Rails Turbolinks team.*
172
+
168
173
  * [Flask Turbolinks](https://github.com/lepture/flask-turbolinks) (Python Flask)
174
+ * [ASP.NET MVC Turbolinks](https://github.com/kazimanzurrashid/aspnetmvcturbolinks)
169
175
 
170
176
  Credits
171
177
  -------
@@ -1,22 +1,22 @@
1
+ pageCache = {}
1
2
  cacheSize = 10
2
3
  currentState = null
3
- referer = null
4
4
  loadedAssets = null
5
- pageCache = {}
5
+
6
+ referer = null
7
+
6
8
  createDocument = null
7
- requestMethod = document.cookie.match(/request_method=(\w+)/)?[1].toUpperCase() or ''
8
9
  xhr = null
9
10
 
10
11
 
11
- fetchReplacement = (url) ->
12
- triggerEvent 'page:fetch'
13
-
14
- # Remove hash from url to ensure IE 10 compatibility
15
- safeUrl = removeHash url
12
+ fetchReplacement = (url) ->
13
+ rememberReferer()
14
+ cacheCurrentPage()
15
+ triggerEvent 'page:fetch', url: url
16
16
 
17
17
  xhr?.abort()
18
18
  xhr = new XMLHttpRequest
19
- xhr.open 'GET', safeUrl, true
19
+ xhr.open 'GET', removeHashForIE10compatiblity(url), true
20
20
  xhr.setRequestHeader 'Accept', 'text/html, application/xhtml+xml, application/xml'
21
21
  xhr.setRequestHeader 'X-XHR-Referer', referer
22
22
 
@@ -27,10 +27,7 @@ fetchReplacement = (url) ->
27
27
  reflectNewUrl url
28
28
  changePage extractTitleAndBody(doc)...
29
29
  reflectRedirectedUrl()
30
- if document.location.hash
31
- document.location.href = document.location.href
32
- else
33
- resetScrollPosition()
30
+ resetScrollPosition()
34
31
  triggerEvent 'page:load'
35
32
  else
36
33
  document.location.href = url
@@ -41,12 +38,11 @@ fetchReplacement = (url) ->
41
38
 
42
39
  xhr.send()
43
40
 
44
- fetchHistory = (position) ->
41
+ fetchHistory = (cachedPage) ->
45
42
  cacheCurrentPage()
46
- page = pageCache[position]
47
43
  xhr?.abort()
48
- changePage page.title, page.body
49
- recallScrollPosition page
44
+ changePage cachedPage.title, cachedPage.body
45
+ recallScrollPosition cachedPage
50
46
  triggerEvent 'page:restore'
51
47
 
52
48
 
@@ -76,6 +72,7 @@ changePage = (title, body, csrfToken, runScripts) ->
76
72
  executeScriptTags() if runScripts
77
73
  currentState = window.history.state
78
74
  triggerEvent 'page:change'
75
+ triggerEvent 'page:update'
79
76
 
80
77
  executeScriptTags = ->
81
78
  scripts = Array::slice.call document.body.querySelectorAll 'script:not([data-turbolinks-eval="false"])'
@@ -102,6 +99,9 @@ reflectRedirectedUrl = ->
102
99
  preservedHash = if removeHash(location) is location then document.location.hash else ''
103
100
  window.history.replaceState currentState, '', location + preservedHash
104
101
 
102
+ rememberReferer = ->
103
+ referer = document.location.href
104
+
105
105
  rememberCurrentUrl = ->
106
106
  window.history.replaceState { turbolinks: true, position: Date.now() }, '', document.location.href
107
107
 
@@ -112,7 +112,15 @@ recallScrollPosition = (page) ->
112
112
  window.scrollTo page.positionX, page.positionY
113
113
 
114
114
  resetScrollPosition = ->
115
- window.scrollTo 0, 0
115
+ if document.location.hash
116
+ document.location.href = document.location.href
117
+ else
118
+ window.scrollTo 0, 0
119
+
120
+
121
+ # Intention revealing function alias
122
+ removeHashForIE10compatiblity = (url) ->
123
+ removeHash url
116
124
 
117
125
  removeHash = (url) ->
118
126
  link = url
@@ -121,8 +129,14 @@ removeHash = (url) ->
121
129
  link.href = url
122
130
  link.href.replace link.hash, ''
123
131
 
124
- triggerEvent = (name) ->
132
+ popCookie = (name) ->
133
+ value = document.cookie.match(new RegExp(name+"=(\\w+)"))?[1].toUpperCase() or ''
134
+ document.cookie = name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/'
135
+ value
136
+
137
+ triggerEvent = (name, data) ->
125
138
  event = document.createEvent 'Events'
139
+ event.data = data if data
126
140
  event.initEvent name, true, true
127
141
  document.dispatchEvent event
128
142
 
@@ -250,20 +264,33 @@ nonStandardClick = (event) ->
250
264
  ignoreClick = (event, link) ->
251
265
  crossOriginLink(link) or anchoredLink(link) or nonHtmlLink(link) or noTurbolink(link) or targetLink(link) or nonStandardClick(event)
252
266
 
267
+
268
+ installDocumentReadyPageEventTriggers = ->
269
+ document.addEventListener 'DOMContentLoaded', ( ->
270
+ triggerEvent 'page:change'
271
+ triggerEvent 'page:update'
272
+ ), true
273
+
274
+ installJqueryAjaxSuccessPageUpdateTrigger = ->
275
+ if typeof jQuery isnt 'undefined'
276
+ jQuery(document).on 'ajaxSuccess', (event, xhr, settings) ->
277
+ return unless jQuery.trim xhr.responseText
278
+ triggerEvent 'page:update'
279
+
280
+ installHistoryChangeHandler = (event) ->
281
+ if event.state?.turbolinks
282
+ if cachedPage = pageCache[event.state.position]
283
+ fetchHistory cachedPage
284
+ else
285
+ visit event.target.location.href
286
+
253
287
  initializeTurbolinks = ->
254
288
  rememberCurrentUrl()
255
289
  rememberCurrentState()
256
290
  createDocument = browserCompatibleDocumentParser()
257
- document.addEventListener 'click', installClickHandlerLast, true
258
- window.addEventListener 'popstate', (event) ->
259
- state = event.state
260
291
 
261
- if state?.turbolinks
262
- if pageCache[state.position]
263
- fetchHistory state.position
264
- else
265
- visit event.target.location.href
266
- , false
292
+ document.addEventListener 'click', installClickHandlerLast, true
293
+ window.addEventListener 'popstate', installHistoryChangeHandler, false
267
294
 
268
295
  browserSupportsPushState =
269
296
  window.history and window.history.pushState and window.history.replaceState and window.history.state != undefined
@@ -272,21 +299,22 @@ browserIsntBuggy =
272
299
  !navigator.userAgent.match /CriOS\//
273
300
 
274
301
  requestMethodIsSafe =
275
- requestMethod in ['GET','']
302
+ popCookie('request_method') in ['GET','']
303
+
304
+ browserSupportsTurbolinks = browserSupportsPushState and browserIsntBuggy and requestMethodIsSafe
276
305
 
277
- if browserSupportsPushState and browserIsntBuggy and requestMethodIsSafe
278
- visit = (url) ->
279
- referer = document.location.href
280
- cacheCurrentPage()
281
- fetchReplacement url
306
+ installDocumentReadyPageEventTriggers()
307
+ installJqueryAjaxSuccessPageUpdateTrigger()
282
308
 
309
+ if browserSupportsTurbolinks
310
+ visit = fetchReplacement
283
311
  initializeTurbolinks()
284
312
  else
285
- visit = (url) ->
286
- document.location.href = url
313
+ visit = (url) -> document.location.href = url
287
314
 
288
315
  # Public API
289
316
  # Turbolinks.visit(url)
290
- # Turbolinks.pagesCached()
317
+ # Turbolinks.pagesCached()
291
318
  # Turbolinks.pagesCached(20)
292
- @Turbolinks = { visit, pagesCached }
319
+ # Turbolinks.supported
320
+ @Turbolinks = { visit, pagesCached, supported: browserSupportsTurbolinks }
data/lib/turbolinks.rb CHANGED
@@ -47,10 +47,22 @@ module Turbolinks
47
47
  end
48
48
  end
49
49
 
50
+ module Redirection
51
+ extend ActiveSupport::Concern
52
+
53
+ def redirect_via_turbolinks_to(url = {}, response_status = {})
54
+ redirect_to(url, response_status)
55
+
56
+ self.status = 200
57
+ self.response_body = "Turbolinks.visit('#{location}');"
58
+ response.content_type = Mime::JS
59
+ end
60
+ end
61
+
50
62
  class Engine < ::Rails::Engine
51
63
  initializer :turbolinks_xhr_headers do |config|
52
64
  ActionController::Base.class_eval do
53
- include XHRHeaders, Cookies, XDomainBlocker
65
+ include XHRHeaders, Cookies, XDomainBlocker, Redirection
54
66
  before_filter :set_xhr_redirected_to, :set_request_method_cookie
55
67
  after_filter :abort_xdomain_redirect
56
68
  end
data/test/index.html CHANGED
@@ -8,6 +8,14 @@
8
8
  document.addEventListener("page:change", function() {
9
9
  console.log("page changed");
10
10
  });
11
+
12
+ document.addEventListener("page:update", function() {
13
+ console.log("page updated");
14
+ });
15
+
16
+ document.addEventListener("page:restore", function() {
17
+ console.log("page restored");
18
+ });
11
19
  </script>
12
20
  </head>
13
21
  <body class="page-index">
data/test/other.html CHANGED
@@ -8,6 +8,14 @@
8
8
  document.addEventListener("page:change", function() {
9
9
  console.log("page changed");
10
10
  });
11
+
12
+ document.addEventListener("page:update", function() {
13
+ console.log("page updated");
14
+ });
15
+
16
+ document.addEventListener("page:restore", function() {
17
+ console.log("page restored");
18
+ });
11
19
  </script>
12
20
  </head>
13
21
  <body class="page-other">
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbolinks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-14 00:00:00.000000000 Z
11
+ date: 2013-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coffee-rails
@@ -61,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
61
  version: '0'
62
62
  requirements: []
63
63
  rubyforge_project:
64
- rubygems_version: 2.0.5
64
+ rubygems_version: 2.0.3
65
65
  signing_key:
66
66
  specification_version: 4
67
67
  summary: Turbolinks makes following links in your web application faster (use with