ajax 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,7 +10,7 @@ As of the end of April, 2010, Ajax is being used live in production on altnet.co
10
10
 
11
11
  == Install
12
12
 
13
- === Rails 3
13
+ === Rails 3 (untested)
14
14
 
15
15
  1. Add the gem to your <tt>Gemspec</tt>
16
16
 
@@ -60,16 +60,24 @@ As of the end of April, 2010, Ajax is being used live in production on altnet.co
60
60
  skipped: app/views/ajax/framework.html.erb exists!
61
61
  ...
62
62
 
63
- === Post Install
63
+ == Getting Started
64
64
 
65
- 1. Create layouts in <tt>app/views/layouts/ajax/</tt> that mimic your existing layouts. See <b>Request Handling -> Layouts</b>.
66
- 2. Instantiate an instance of the Ajax class in <tt>application.js</tt>. For example:
65
+ 1. Ajax looks for an alternative layout to use with AJAX requests in <tt>app/views/layouts/ajax/</tt>. Copy existing layouts into this directory and get them ready for AJAX by removing any HTML HEAD elements, everything but the inner BODY content.
67
66
 
68
- window.ajax = new Ajax({
69
- default_container: '#main',
70
- enabled: true,
71
- lazy_load_assets: false
72
- });
67
+ Your main layout should contain a container element that will receive page content. Typically this would be the container below the page header. If you don't have a static header, you can make the whole BODY element the container.
68
+
69
+ Here is an {example of converting our <tt>layouts/application.html.haml</tt> to <tt>layouts/ajax/application.html.haml</tt>}[http://gist.github.com/373133/5a80a63ef69a883ed3c5630b68330b1036ad01ec].
70
+
71
+ 2. Instantiate an instance of the Ajax class in <tt>public/javascripts/application.js</tt>. For example:
72
+
73
+ // public/javascripts/application.js
74
+ if (typeof(Ajax) != 'undefined') {
75
+ window.ajax = new Ajax({
76
+ default_container: '#main', // jQuery selector of your container element
77
+ enabled: true, // Enable/disable the plugin
78
+ lazy_load_assets: false // YMMV
79
+ });
80
+ }
73
81
 
74
82
  == Introduction
75
83
 
@@ -183,15 +191,32 @@ If you need to, you can check the state of the plugin with:
183
191
 
184
192
  Other onfiguration goes in <tt>config/initializers/ajax.rb</tt> such as indicating which links to except from the request processing. See <b>Excepted Links</b>.
185
193
 
194
+ <b>Our <tt>config/initializers/ajax.rb</tt> file:</b>
195
+
196
+ # config/initializers/ajax.rb
197
+ Ajax.enabled = true
198
+ Ajax.lazy_load_assets = false
199
+
200
+ # Excepted paths: allow these paths to pass through unmodified.
201
+ Ajax.exclude_paths %w[ /login /logout /signup /altnet-pro /my-account/edit /user-session/new /facebook_signup /facebook_login /facebook_link_account /health_check /reset-password/new]
202
+ Ajax.exclude_paths [%r[\/my-account\/.*]]
203
+ Ajax.exclude_paths [%r[\/admin.*]]
204
+ Ajax.exclude_paths [%r[\/newrelic.*]]
205
+
186
206
  == Ajax Layouts
187
207
 
188
208
  Typically AJAX content does not render a layout because we just want to update a fragment of a page. Automatically turning off layouts when rendering AJAX is one option, but what about when we do want to use a layout?
189
209
 
190
- My solution is to first look in <tt>app/views/layouts/ajax/</tt> for a layout with the same name as the default layout for the current action. If a layout is found, we use it, otherwise the default layout is used.
210
+ Ajax looks for an alternative layout to use with AJAX requests in <tt>app/views/layouts/ajax/</tt>. If a layout is found, we use it, otherwise the default layout is used. Copy existing layouts into this directory and get them ready for AJAX by removing any HTML HEAD elements, everything but the inner BODY content.
211
+
212
+ Your main layout should contain a container element that will receive page content. Typically this would be the container below the page header. If you don't have a static header, you can make the whole BODY element the container.
213
+
214
+ In your Ajax layouts you can define callbacks, tabs to activate or the container to receive content. Using the <tt>ajax_header</tt> method:
191
215
 
192
- In your Ajax layouts you can define callbacks, tabs to activate or the container to receive content.
216
+ # layouts/ajax/two_column.html.haml
217
+ ajax_header :container, '#column2'
193
218
 
194
- For example, our layouts:
219
+ Our layouts:
195
220
 
196
221
  layouts/
197
222
  _assets.html.haml
@@ -203,9 +228,7 @@ For example, our layouts:
203
228
  single_column.html.haml
204
229
  two_column.html.haml
205
230
 
206
- Gists
207
- * {ajax/application.html.haml}[http://gist.github.com/373133#file_application.html.haml]
208
- * {ajax/two_column.html.haml}[http://gist.github.com/373133#file_two_column.html.haml]
231
+ {Converting our <tt>layouts/application.html.haml</tt> to <tt>layouts/ajax/application.html.haml</tt>}[http://gist.github.com/373133/5a80a63ef69a883ed3c5630b68330b1036ad01ec].
209
232
 
210
233
  == Link Handling
211
234
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
@@ -0,0 +1,19 @@
1
+ <%# Locals: url %>
2
+ <script type="text/javascript">
3
+ var url = <%= url.to_json %>;
4
+ var hash = document.location.hash;
5
+
6
+ // Remove leading # from the fragment
7
+ if (hash.charAt(0) == '#') {
8
+ hash = hash.substr(1);
9
+ }
10
+
11
+ // Remove leading / from the fragment if the URL already ends in a /
12
+ // This prevents double-slashes. Note we can't just replace all
13
+ // double-slashes because the protocol includes //.
14
+ if (url.charAt(url.length - 1) == '/' && hash.charAt(0) == '/') {
15
+ hash = hash.substr(1);
16
+ }
17
+
18
+ document.location.href = url + hash;
19
+ </script>
@@ -2,6 +2,8 @@ module Ajax
2
2
  module ActionController
3
3
  def self.included(klass)
4
4
  klass.class_eval do
5
+ include ClassMethods
6
+
5
7
  alias_method_chain :render, :ajax
6
8
  alias_method_chain :redirect_to_full_url, :ajax
7
9
 
@@ -26,7 +28,7 @@ module Ajax
26
28
  key, value = args.shift, args.shift
27
29
  value = block_given? ? Proc.new : value
28
30
 
29
- prepend_after_filter(options) do |controller|
31
+ (self.is_a?(Class) ? self : self.class).prepend_after_filter(options) do |controller|
30
32
  if controller.request.xhr?
31
33
  value = value.is_a?(Proc) ? controller.instance_eval(&value) : value
32
34
  Ajax.set_header(controller.response, key, value)
@@ -63,15 +65,30 @@ module Ajax
63
65
  return redirect_to_full_url_without_ajax(url, status) unless Ajax.is_enabled?
64
66
  raise DoubleRenderError if performed?
65
67
 
68
+ special_redirect = false
66
69
  original_url = url
70
+
71
+ # If we have the full referrer in Ajax-Info, use that because it
72
+ # includes the fragment.
67
73
  if url == request.headers["Referer"] && !request.headers['Ajax-Info'].blank?
68
74
  url = request.headers['Ajax-Info']['referer']
69
75
  Ajax.logger.debug("[ajax] using referer #{url} from Ajax-Info")
70
76
  end
71
77
 
72
78
  if !Ajax.exclude_path?(url)
79
+ # Never redirect to the Ajax framework path, redirect to /
73
80
  if url =~ %r[#{Ajax.framework_path}]
74
81
  url = url.sub(%r[#{Ajax.framework_path}], '/')
82
+
83
+ # Special case:
84
+ #
85
+ # Changing protocol forces a redirect from root to root.
86
+ # The full request URL (including the hashed part) is
87
+ # in the browser. So return JS to do the redirect and
88
+ # have it include the hashed part in the redirect URL.
89
+ if !request.xhr? && URI.parse(url).scheme != URI.parse(request.url).scheme
90
+ special_redirect = true
91
+ end
75
92
  end
76
93
 
77
94
  if !Ajax.is_hashed_url?(url)
@@ -80,11 +97,20 @@ module Ajax
80
97
  end
81
98
  Ajax.logger.info("[ajax] rewrote redirect from #{original_url} to #{url}")
82
99
 
83
- session[:redirected_to] = url
84
- if request.xhr?
85
- render(:update) { |page| page.redirect_to(url) }
100
+ # Don't store session[:redirected_to] if doing a special redirect otherwise
101
+ # when the next request for root comes in it will think we really want
102
+ # to display the home page.
103
+ if special_redirect
104
+ session[:redirected_to] = nil
105
+ Ajax.logger.info("[ajax] returning special redirect JS")
106
+ render :partial => '/ajax/redirect_with_fragment', :locals => { :url => url }
86
107
  else
87
- redirect_to_full_url_without_ajax(url, status)
108
+ session[:redirected_to] = url
109
+ if request.xhr?
110
+ render(:update) { |page| page.redirect_to(url) }
111
+ else
112
+ redirect_to_full_url_without_ajax(url, status)
113
+ end
88
114
  end
89
115
  end
90
116
 
@@ -38,13 +38,21 @@ module Ajax
38
38
 
39
39
  # Insert the deep link unless the URL is traditional
40
40
  if !html_options.has_key?('data-deep-link') && !html_options.delete('traditional')
41
- path = url_for(options)
41
+ case options
42
+ when Hash
43
+ options[:only_path] = true
44
+ path = url_for(options)
45
+ else
46
+ path = url_for(options)
42
47
 
43
- # Is this path to be excluded?
44
- unless Ajax.exclude_path?(path)
45
- if path.match(%r[^(http:\/\/[^\/]*)(\/?.*)])
46
- path = $2
48
+ # Strip out the protocol and host from the URL
49
+ if path =~ %r[#{root_url}]
50
+ path.sub!(%r[#{root_url}], '/')
47
51
  end
52
+ end
53
+
54
+ # Don't store a data-deep-link attribute if the path is excluded
55
+ unless Ajax.exclude_path?(path)
48
56
  html_options['data-deep-link'] = path
49
57
  end
50
58
  end
@@ -36,7 +36,7 @@ module Ajax
36
36
  protected
37
37
 
38
38
  def encode_and_parse_url(url)
39
- URI.parse(URI.encode(url).gsub("%23", "#"))
39
+ URI.parse(URI.encode(url).gsub("%23", "#")) rescue URI.parse('/')
40
40
  end
41
41
 
42
42
  def url_host(url)
@@ -8,6 +8,33 @@ namespace :ajax do
8
8
  INSTALL_FILES.map do |file|
9
9
  show_result(file) { |file| copy_unless_exists(file) }
10
10
  end
11
+ puts <<-END
12
+ \nWelcome to Ajax!
13
+
14
+ 1. Ajax looks for an alternative layout to use with AJAX requests in
15
+ <tt>app/views/layouts/ajax/</tt>. Copy existing layouts into this directory and get them
16
+ ready for AJAX by removing any HTML HEAD elements, everything but the inner BODY content.
17
+
18
+ Your main layout should contain a container element that will receive page content.
19
+ Typically this would be the container below the page header. If you don't have a static
20
+ header, you can make the whole BODY element the container.
21
+
22
+ Here is an example of converting our layouts/application.html.haml to
23
+ layouts/ajax/application.html.haml:
24
+ http://gist.github.com/373133/5a80a63ef69a883ed3c5630b68330b1036ad01ec.
25
+
26
+ 2. Instantiate an instance of the Ajax class in public/javascripts/application.js. For
27
+ example:
28
+
29
+ // public/javascripts/application.js
30
+ if (typeof(Ajax) != 'undefined') {
31
+ window.ajax = new Ajax({
32
+ default_container: '#main', // jQuery selector of your container element
33
+ enabled: true, // Enable/disable the plugin
34
+ lazy_load_assets: false // YMMV
35
+ });
36
+ }
37
+ END
11
38
  end
12
39
 
13
40
  namespace :install do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 5
9
- version: 0.1.5
8
+ - 6
9
+ version: 0.1.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Karl Varga
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-27 00:00:00 -07:00
17
+ date: 2010-05-13 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -43,6 +43,7 @@ files:
43
43
  - Rakefile
44
44
  - VERSION
45
45
  - app/controllers/ajax_controller.rb
46
+ - app/views/ajax/_redirect_with_fragment.html.erb
46
47
  - app/views/ajax/framework.html.erb
47
48
  - config/initializers/ajax.rb
48
49
  - lib/ajax.rb