turbolinks 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +40 -0
- data/lib/assets/javascripts/turbolinks.js.coffee +82 -0
- metadata +47 -0
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
Turbolinks
|
2
|
+
===========
|
3
|
+
|
4
|
+
Turbolinks makes following links in your web application faster. Instead of letting the browser reload the JavaScript and CSS between each page change, and spend extra HTTP requests checking if the assets are up-to-date, we keep the current instance alive and replace only the body and the title in the head.
|
5
|
+
|
6
|
+
This is similar to pjax, but instead of worrying about what element on the page to replace, and tailoring the server-side response to fit, we replace the entire body. This means that you get the bulk of the speed benefits from pjax (no recompiling of the JavaScript or CSS) without having to tailor the server-side response. It just works.
|
7
|
+
|
8
|
+
By default, all internal links will be funneled through Turbolinks, but you can opt out by marking links with data-no-turbolink.
|
9
|
+
|
10
|
+
|
11
|
+
No jQuery or any other framework
|
12
|
+
--------------------------------
|
13
|
+
|
14
|
+
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.
|
15
|
+
|
16
|
+
|
17
|
+
The page:update event
|
18
|
+
---------------------
|
19
|
+
|
20
|
+
Since pages will change without a full reload with Turbolinks, you can't by default rely on dom:loaded to trigger your JavaScript code. Instead, Turbolinks uses the page:update event.
|
21
|
+
|
22
|
+
|
23
|
+
Triggering a Turbolinks visit manually
|
24
|
+
---------------------------------------
|
25
|
+
|
26
|
+
You can use `Turbolinks.visit(path)` to go to a URL through Turbolinks.
|
27
|
+
|
28
|
+
|
29
|
+
Available only for pushState browsers
|
30
|
+
-------------------------------------
|
31
|
+
|
32
|
+
Like pjax, this naturally only works with browsers capable of pushState. But of course we fall back gracefully to full page reloads for browsers that do not support it.
|
33
|
+
|
34
|
+
|
35
|
+
Work left to do
|
36
|
+
---------------
|
37
|
+
|
38
|
+
* CSS/JS asset change detection and reload
|
39
|
+
* Add a DOM cache for faster back button
|
40
|
+
* Remember scroll position when using back button
|
@@ -0,0 +1,82 @@
|
|
1
|
+
visit = (url) ->
|
2
|
+
if browserSupportsPushState
|
3
|
+
reflectNewUrl url
|
4
|
+
fetchReplacement url
|
5
|
+
else
|
6
|
+
document.location.href = url
|
7
|
+
|
8
|
+
|
9
|
+
fetchReplacement = (url) ->
|
10
|
+
xhr = new XMLHttpRequest
|
11
|
+
xhr.open 'GET', url, true
|
12
|
+
xhr.onload = -> fullReplacement xhr.responseText, url
|
13
|
+
xhr.send()
|
14
|
+
|
15
|
+
fullReplacement = (html, url) ->
|
16
|
+
replaceHTML html
|
17
|
+
triggerPageChange()
|
18
|
+
|
19
|
+
reflectNewUrl = (url) ->
|
20
|
+
window.history.pushState { turbolinks: true }, "", url
|
21
|
+
|
22
|
+
triggerPageChange = ->
|
23
|
+
event = document.createEvent 'Events'
|
24
|
+
event.initEvent 'page:change', true, true
|
25
|
+
document.dispatchEvent event
|
26
|
+
|
27
|
+
replaceHTML = (html) ->
|
28
|
+
doc = document.implementation.createHTMLDocument ""
|
29
|
+
doc.open "replace"
|
30
|
+
doc.write html
|
31
|
+
doc.close()
|
32
|
+
|
33
|
+
originalBody = document.body
|
34
|
+
document.documentElement.appendChild doc.body, originalBody
|
35
|
+
document.documentElement.removeChild originalBody
|
36
|
+
document.title = title.textContent if title = doc.querySelector "title"
|
37
|
+
|
38
|
+
|
39
|
+
extractLink = (event) ->
|
40
|
+
link = event.target
|
41
|
+
until link is this or link.nodeName is 'A'
|
42
|
+
link = link.parentNode
|
43
|
+
link
|
44
|
+
|
45
|
+
crossOriginLink = (link) ->
|
46
|
+
location.protocol isnt link.protocol || location.host isnt link.host
|
47
|
+
|
48
|
+
anchoredLink = (link) ->
|
49
|
+
((link.hash && link.href.replace(link.hash, '')) is location.href.replace(location.hash, '')) ||
|
50
|
+
(link.href is location.href + '#')
|
51
|
+
|
52
|
+
noTurbolink = (link) ->
|
53
|
+
link.getAttribute('data-no-turbolink')?
|
54
|
+
|
55
|
+
newTabClick = (event) ->
|
56
|
+
event.which > 1 || event.metaKey || event.ctrlKey
|
57
|
+
|
58
|
+
ignoreClick = (event, link) ->
|
59
|
+
crossOriginLink(link) || anchoredLink(link) || noTurbolink(link) || newTabClick(event)
|
60
|
+
|
61
|
+
handleClick = (event) ->
|
62
|
+
link = extractLink event
|
63
|
+
|
64
|
+
if link.nodeName is 'A' and !ignoreClick(event, link)
|
65
|
+
visit link.href
|
66
|
+
event.preventDefault()
|
67
|
+
|
68
|
+
|
69
|
+
browserSupportsPushState =
|
70
|
+
window.history && window.history.pushState && window.history.replaceState
|
71
|
+
|
72
|
+
|
73
|
+
if browserSupportsPushState
|
74
|
+
window.addEventListener 'popstate', (event) ->
|
75
|
+
if event.state?.turbolinks
|
76
|
+
fetchReplacement document.location.href
|
77
|
+
|
78
|
+
document.addEventListener 'click', (event) ->
|
79
|
+
handleClick event
|
80
|
+
|
81
|
+
# Call Turbolinks.visit(url) from client code
|
82
|
+
@Turbolinks = { visit: visit }
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: turbolinks
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Heinemeier Hansson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-26 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email: david@loudthinking.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/assets/javascripts/turbolinks.js.coffee
|
21
|
+
- README.md
|
22
|
+
homepage:
|
23
|
+
licenses: []
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 1.8.7
|
43
|
+
signing_key:
|
44
|
+
specification_version: 3
|
45
|
+
summary: Turbolinks makes following links in your web application faster (use with
|
46
|
+
Rails Asset Pipeline)
|
47
|
+
test_files: []
|