gitlab-turbolinks-classic 2.5.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/turbolinks.rb ADDED
@@ -0,0 +1,39 @@
1
+ require 'turbolinks/version'
2
+ require 'turbolinks/xhr_headers'
3
+ require 'turbolinks/xhr_url_for'
4
+ require 'turbolinks/cookies'
5
+ require 'turbolinks/x_domain_blocker'
6
+ require 'turbolinks/redirection'
7
+
8
+ module Turbolinks
9
+ class Engine < ::Rails::Engine
10
+ initializer :turbolinks do |config|
11
+ ActiveSupport.on_load(:action_controller) do
12
+ ActionController::Base.class_eval do
13
+ include XHRHeaders, Cookies, XDomainBlocker, Redirection
14
+
15
+ if respond_to?(:before_action)
16
+ before_action :set_xhr_redirected_to, :set_request_method_cookie
17
+ after_action :abort_xdomain_redirect
18
+ else
19
+ before_filter :set_xhr_redirected_to, :set_request_method_cookie
20
+ after_filter :abort_xdomain_redirect
21
+ end
22
+ end
23
+
24
+ ActionDispatch::Request.class_eval do
25
+ def referer
26
+ self.headers['X-XHR-Referer'] || super
27
+ end
28
+ alias referrer referer
29
+ end
30
+ end
31
+
32
+ ActiveSupport.on_load(:action_view) do
33
+ (ActionView::RoutingUrlFor rescue ActionView::Helpers::UrlHelper).module_eval do
34
+ include XHRUrlFor
35
+ end
36
+ end unless RUBY_VERSION =~ /^1\.8/
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,15 @@
1
+ module Turbolinks
2
+ # For non-GET requests, sets a request_method cookie containing
3
+ # the request method of the current request. The Turbolinks script
4
+ # will not initialize if this cookie is set.
5
+ module Cookies
6
+ private
7
+ def set_request_method_cookie
8
+ if request.get?
9
+ cookies.delete(:request_method)
10
+ else
11
+ cookies[:request_method] = request.request_method
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Turbolinks
2
+ # Provides a means of using Turbolinks to perform redirects. The server
3
+ # will respond with a JavaScript call to Turbolinks.visit(url).
4
+ module Redirection
5
+ extend ActiveSupport::Concern
6
+
7
+ def redirect_via_turbolinks_to(url = {}, response_status = {})
8
+ redirect_to(url, response_status)
9
+
10
+ self.status = 200
11
+ self.response_body = "Turbolinks.visit('#{location}');"
12
+ response.content_type = Mime::JS
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Turbolinks
2
+ VERSION = '2.5.4'
3
+ end
@@ -0,0 +1,21 @@
1
+ module Turbolinks
2
+ # Changes the response status to 403 Forbidden if all of these conditions are true:
3
+ # - The current request originated from Turbolinks
4
+ # - The request is being redirected to a different domain
5
+ module XDomainBlocker
6
+ private
7
+ def same_origin?(a, b)
8
+ a = URI.parse URI.escape(a)
9
+ b = URI.parse URI.escape(b)
10
+ [a.scheme, a.host, a.port] == [b.scheme, b.host, b.port]
11
+ end
12
+
13
+ def abort_xdomain_redirect
14
+ to_uri = response.headers['Location'] || ""
15
+ current = request.headers['X-XHR-Referer'] || ""
16
+ unless to_uri.blank? || current.blank? || same_origin?(current, to_uri)
17
+ self.status = 403
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,46 @@
1
+ module Turbolinks
2
+ # Intercepts calls to _compute_redirect_to_location (used by redirect_to) for two purposes.
3
+ #
4
+ # 1. Corrects the behavior of redirect_to with the :back option by using the X-XHR-Referer
5
+ # request header instead of the standard Referer request header.
6
+ #
7
+ # 2. Stores the return value (the redirect target url) to persist through to the redirect
8
+ # request, where it will be used to set the X-XHR-Redirected-To response header. The
9
+ # Turbolinks script will detect the header and use replaceState to reflect the redirected
10
+ # url.
11
+ module XHRHeaders
12
+ extend ActiveSupport::Concern
13
+
14
+ def _compute_redirect_to_location(*args)
15
+ options, request = _normalize_redirect_params(args)
16
+
17
+ store_for_turbolinks begin
18
+ if options == :back && request.headers["X-XHR-Referer"]
19
+ super(*[(request if args.length == 2), request.headers["X-XHR-Referer"]].compact)
20
+ else
21
+ super(*args)
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+ def store_for_turbolinks(url)
28
+ session[:_turbolinks_redirect_to] = url if session && request.headers["X-XHR-Referer"]
29
+ url
30
+ end
31
+
32
+ def set_xhr_redirected_to
33
+ if session && session[:_turbolinks_redirect_to]
34
+ response.headers['X-XHR-Redirected-To'] = session.delete :_turbolinks_redirect_to
35
+ end
36
+ end
37
+
38
+ # Ensure backwards compatibility
39
+ # Rails < 4.2: _compute_redirect_to_location(options)
40
+ # Rails >= 4.2: _compute_redirect_to_location(request, options)
41
+ def _normalize_redirect_params(args)
42
+ options, req = args.reverse
43
+ [options, req || request]
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ module Turbolinks
2
+ # Corrects the behavior of url_for (and link_to, which uses url_for) with the :back
3
+ # option by using the X-XHR-Referer request header instead of the standard Referer
4
+ # request header.
5
+ module XHRUrlFor
6
+ def self.included(base)
7
+ base.alias_method_chain :url_for, :xhr_referer
8
+ end
9
+
10
+ def url_for_with_xhr_referer(options = {})
11
+ options = (controller.request.headers["X-XHR-Referer"] || options) if options == :back
12
+ url_for_without_xhr_referer options
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ <html>
2
+ <body>
3
+ <script language="javascript">alert("you shouldn't see this");</script>
4
+ </body>
5
+ </html>
data/test/config.ru ADDED
@@ -0,0 +1,63 @@
1
+ require 'sprockets'
2
+ require 'coffee-script'
3
+
4
+ Root = File.expand_path("../..", __FILE__)
5
+
6
+ Assets = Sprockets::Environment.new do |env|
7
+ env.append_path File.join(Root, "lib", "assets", "javascripts")
8
+ end
9
+
10
+ class SlowResponse
11
+ CHUNKS = ['<html><body>', '.'*50, '.'*20, '<a href="/index.html">Home</a></body></html>']
12
+
13
+ def call(env)
14
+ [200, headers, self]
15
+ end
16
+
17
+ def each
18
+ CHUNKS.each do |part|
19
+ sleep rand(0.3..0.8)
20
+ yield part
21
+ end
22
+ end
23
+
24
+ def length
25
+ CHUNKS.join.length
26
+ end
27
+
28
+ def headers
29
+ { "Content-Length" => length.to_s, "Content-Type" => "text/html", "Cache-Control" => "no-cache, no-store, must-revalidate" }
30
+ end
31
+ end
32
+
33
+ map "/js" do
34
+ run Assets
35
+ end
36
+
37
+ map "/500" do
38
+ # throw Internal Server Error (500)
39
+ end
40
+
41
+ map "/withoutextension" do
42
+ run Rack::File.new(File.join(Root, "test", "withoutextension"), "Content-Type" => "text/html")
43
+ end
44
+
45
+ map "/slow-response" do
46
+ run SlowResponse.new
47
+ end
48
+
49
+ map "/bounce" do
50
+ run Proc.new{ [200, { "X-XHR-Redirected-To" => "redirect1.html", "Content-Type" => "text/html" }, File.open( File.join( Root, "test", "redirect1.html" ) ) ] }
51
+ end
52
+
53
+ map "/" do
54
+ run Rack::Directory.new(File.join(Root, "test"))
55
+ end
56
+
57
+ map "/attachment.txt" do
58
+ run Rack::File.new(File.join(Root, "test", "attachment.html"), "Content-Type" => "text/plain")
59
+ end
60
+
61
+ map "/attachment.html" do
62
+ run Rack::File.new(File.join(Root, "test", "attachment.html"), "Content-Type" => "text/html", "Content-Disposition" => "attachment; filename=attachment.html")
63
+ end
data/test/dummy.gif ADDED
Binary file
data/test/index.html ADDED
@@ -0,0 +1,53 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Home</title>
6
+ <script type="text/javascript" src="/js/turbolinks.js"></script>
7
+ <script type="text/javascript">
8
+ Turbolinks.enableProgressBar();
9
+
10
+ document.addEventListener("page:change", function() {
11
+ console.log("page changed");
12
+ });
13
+
14
+ document.addEventListener("page:update", function() {
15
+ console.log("page updated");
16
+ });
17
+
18
+ document.addEventListener("page:restore", function() {
19
+ console.log("page restored");
20
+ });
21
+ </script>
22
+ </head>
23
+ <body class="page-index">
24
+ <ul style="margin-top:20px;">
25
+ <li><a href="/other.html">Other page</a></li>
26
+ <li><a href="/slow-response">Slow loading page for progress bar</a></li>
27
+ <li><a href="/other.html"><span>Wrapped link</span></a></li>
28
+ <li><a href="/withoutextension">Without extension</a></li>
29
+ <li><a href="/withoutextension?sort=user.name">Without extension with query params</a></li>
30
+ <li><a href="http://www.google.com/">Cross origin</a></li>
31
+ <li><a href="/other.html" onclick="if(!confirm('follow link?')) { return false}">Confirm Fire Order</a></li>
32
+ <li><a href="/reload.html"><span>New assets track </span></a></li>
33
+ <li><a href="/dummy.gif?12345">Query Param Image Link</a></li>
34
+ <li><a href="/bounce">Redirect</a></li>
35
+ <li><a href="#">Hash link</a></li>
36
+ <li><a href="/reload.html#foo">New assets track with hash link</a></li>
37
+ <li><a href="/attachment.txt">A text response should load normally</a></li>
38
+ <li><a href="/attachment.html">An html response with Content-Disposition: attachment should load normally</a></li>
39
+ <li><h5>If you stop the server or go into airplane/offline mode</h5></li>
40
+ <li><a href="/doesnotexist.html">A page with client error (4xx, rfc2616 sec. 10.4) should error out</a></li>
41
+ <li><a href="/500">Also server errors (5xx, rfc2616 sec. 10.5) should error out</a></li>
42
+ <li><a href="/fallback.html">A page that has a fallback in appcache should fallback</a></li>
43
+ </ul>
44
+
45
+ <div style="background:#ccc;height:5000px;width:200px;">
46
+ </div>
47
+ <iframe height='1' scrolling='no' src='/offline.html' style='display: none;' width='1'></iframe>
48
+
49
+ <script type="text/javascript" data-turbolinks-eval=false>
50
+ console.log("turbolinks-eval-false script fired. This should only happen on the initial page load.");
51
+ </script>
52
+ </body>
53
+ </html>
@@ -0,0 +1,10 @@
1
+ CACHE MANIFEST
2
+
3
+ CACHE:
4
+ /offline.html
5
+
6
+ NETWORK:
7
+ *
8
+
9
+ FALLBACK:
10
+ /fallback.html /offline.html
data/test/offline.html ADDED
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" manifest="/manifest.appcache">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Home</title>
6
+ <script type="text/javascript" src="/js/turbolinks.js"></script>
7
+ <script type="text/javascript">
8
+ document.addEventListener("page:change", function() {
9
+ console.log("page changed");
10
+ });
11
+ </script>
12
+ </head>
13
+ <body class="page-offline">
14
+ <h1>Offline Mode Fallback</h1>
15
+ <ul>
16
+ <li><a href="/index.html">Home</a></li>
17
+ </ul>
18
+ </body>
19
+ </html>
data/test/other.html ADDED
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Home</title>
6
+ <script type="text/javascript" src="/js/turbolinks.js"></script>
7
+ <script type="text/javascript">
8
+ document.addEventListener("page:change", function() {
9
+ console.log("page changed");
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
+ });
19
+ </script>
20
+ </head>
21
+ <body class="page-other">
22
+ <ul>
23
+ <li><a href="/index.html">Home</a></li>
24
+ </ul>
25
+ </body>
26
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Home</title>
6
+ <script type="text/javascript" src="/js/turbolinks.js"></script>
7
+ </head>
8
+ <body class="page-other">
9
+ Should show /redirect1.html as path
10
+ <ul>
11
+ <li>Click <a href="/redirect2.html">Redirect 2</a></li>
12
+ </ul>
13
+
14
+ </body>
15
+ </html>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Home</title>
6
+ <script type="text/javascript" src="/js/turbolinks.js"></script>
7
+ </head>
8
+ <body class="page-other">
9
+ Hit back button twice. It should go back to home page.
10
+ </body>
11
+ </html>
data/test/reload.html ADDED
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Home</title>
6
+ <script type="text/javascript" src="/js/turbolinks.js?1" data-turbolinks-track='true'></script>
7
+ <script type="text/javascript">
8
+ document.addEventListener("page:change", function() {
9
+ console.log("page changed");
10
+ });
11
+ </script>
12
+ </head>
13
+ <body class="page-reload">
14
+ <ul>
15
+ <li><a href="/index.html">Home</a></li>
16
+ </ul>
17
+ </body>
18
+ </html>
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Home</title>
6
+ <script type="text/javascript" src="/js/turbolinks.js"></script>
7
+ <script type="text/javascript">
8
+ document.addEventListener("page:change", function() {
9
+ console.log("page changed");
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
+ });
19
+ </script>
20
+ </head>
21
+ <body class="page-other">
22
+ <ul>
23
+ <li><a href="/index.html">Home</a></li>
24
+ </ul>
25
+ </body>
26
+ </html>
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gitlab-turbolinks-classic
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.5.4
5
+ platform: ruby
6
+ authors:
7
+ - David Heinemeier Hansson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: coffee-rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email: david@loudthinking.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - MIT-LICENSE
34
+ - README.md
35
+ - lib/assets/javascripts/turbolinks.js.coffee
36
+ - lib/turbolinks.rb
37
+ - lib/turbolinks/cookies.rb
38
+ - lib/turbolinks/redirection.rb
39
+ - lib/turbolinks/version.rb
40
+ - lib/turbolinks/x_domain_blocker.rb
41
+ - lib/turbolinks/xhr_headers.rb
42
+ - lib/turbolinks/xhr_url_for.rb
43
+ - test/attachment.html
44
+ - test/config.ru
45
+ - test/dummy.gif
46
+ - test/index.html
47
+ - test/manifest.appcache
48
+ - test/offline.html
49
+ - test/other.html
50
+ - test/redirect1.html
51
+ - test/redirect2.html
52
+ - test/reload.html
53
+ - test/withoutextension
54
+ homepage: https://gitlab.com/jamedjo/gitlab-turbolinks-classic/
55
+ licenses:
56
+ - MIT
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.5.1
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Turbolinks makes following links in your web application faster (use with
78
+ Rails Asset Pipeline)
79
+ test_files: []