ajaxify_rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .idea
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ajaxify_rails.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Nico
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # Nested Form Fields
2
+
3
+ Rails gem for automatically turning internal links into ajax links that load content without a full page reload.
4
+
5
+ Uses the html5 history interface for changing the url and making the browser's back and forward buttons working with ajax.
6
+ Falls back to a hash based approach for browsers without the history interface (like Internet Explorer).
7
+ Transparently handles redirects and supports flash messages and page titles. Requires Ruby 1.9 and the asset pipeline.
8
+
9
+ Inspired by the pjax_rails gem (https://github.com/rails/pjax_rails)
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'ajaxify_rails'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ In your application.js file add:
22
+
23
+ //= require ajaxify_rails
24
+
25
+ ## Usage
26
+
27
+
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/ajaxify_rails/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Nico Ritsche"]
6
+ gem.email = ["ncrdevmail@gmail.com"]
7
+ gem.description = %q{Rails gem for automatically turning internal links into ajax links that load content without a full page reload.
8
+ Uses the html5 history interface for changing the url and making the browser's back and forward buttons working with ajax.
9
+ Falls back to a hash based approach for browsers without the history interface (like Internet Explorer).
10
+ Transparently handles redirects and supports flash messages and page titles. Requires Ruby 1.9 and the asset pipeline.}
11
+ gem.summary = %q{Rails gem for automatically turning internal links into ajax links that load content without a full page reload.}
12
+ gem.homepage = "https://github.com/ncri/ajaxify_rails"
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.name = "ajaxify_rails"
18
+ gem.require_paths = ["lib"]
19
+ gem.version = AjaxifyRails::VERSION
20
+
21
+ gem.add_dependency 'rails', '>= 3.1.0'
22
+ end
@@ -0,0 +1,77 @@
1
+ require "ajaxify_rails/version"
2
+
3
+ module AjaxifyRails
4
+
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+
10
+ ActiveSupport.on_load(:action_controller) do
11
+ include ActionControllerAdditions
12
+ end
13
+
14
+ module ActionControllerAdditions
15
+
16
+ def self.included(controller)
17
+ controller.class_eval do
18
+
19
+ private
20
+
21
+ def ajaxified?
22
+ request.xhr? and params[:ajaxified]
23
+ end
24
+
25
+
26
+ def render *args, &block
27
+ if ajaxified?
28
+ args = _normalize_args(*args, &block)
29
+ layout = args[:layout] || current_layout
30
+ layout = (layout == 'application' or layout == true) ? false : layout
31
+ args[:layout] = layout
32
+ cookies[:flash_notice] = flash[:notice] # make customizable
33
+ flash[:notice] = nil
34
+ extra_content = (respond_to?(:ajaxify_extra_content) ? ajaxify_extra_content : '')
35
+ super args
36
+
37
+ # Store current path for redirect url changes. Also used to remove the ajaxify parameter that gets added to some auto generated urls
38
+ # like e.g. pagination links see (ajaxify.js -> on_ajaxify_success())
39
+ #
40
+ current_url_tag = view_context.content_tag(:span, request.fullpath.sub(/\?ajaxified=true&(.*)/, '?\1').sub(/(&|\?)ajaxified=true/, ''),
41
+ id: 'ajaxify_location')
42
+ response_body[0] += view_context.content_tag(:div, current_url_tag + extra_content,
43
+ id: 'ajaxify_content', style: 'display:none', data: { page_title: try(:page_title) })
44
+ response.body = self.response_body[0]
45
+ return
46
+ end
47
+ super
48
+ end
49
+
50
+
51
+ def current_layout
52
+ return @current_layout if @current_layout
53
+ @current_layout = _layout
54
+ @current_layout = File.basename(@current_layout.identifier).split('.').first unless @current_layout.instance_of? String
55
+ @current_layout
56
+ end
57
+
58
+
59
+ def redirect_to(options = {}, response_status = {})
60
+ request.referer.sub!('#/', '') if request.referer # make redirect to back work for browsers without history api
61
+
62
+ super
63
+
64
+ ajaxify_params = "ajaxified=true&ajaxify_redirect=true"
65
+ self.location += "#{self.location =~ /\?/ ? '&' : '?'}#{ajaxify_params}" if request.xhr? # to avoid the full layout from being rendered
66
+ end
67
+
68
+
69
+ def ajaxify_redirect_to url
70
+ render inline: "<%= javascript_tag(\"Ajaxify.load({url: '#{url}'});\") %>", layout: true
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,3 @@
1
+ module AjaxifyRails
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,229 @@
1
+ @Ajaxify =
2
+
3
+ content_container: 'main'
4
+ on_before_load: null
5
+ on_success: null
6
+ on_success_once: null
7
+ hash_changed: null
8
+ ignore_hash_change: null
9
+ load_page_from_hash: null
10
+ handle_extra_content: null
11
+ base_path_regexp: null
12
+
13
+ flash_types: ['notice']
14
+ flash_effect: null
15
+ clear_flash_effect: null
16
+
17
+ initial_history_state:
18
+ url: window.location.href
19
+ data:
20
+ ajaxified: true
21
+
22
+
23
+ init: ->
24
+
25
+ if this.load_page_from_hash
26
+ this.load_page_from_hash = false
27
+ this.on_hash_change()
28
+
29
+ self = this
30
+
31
+ protocol_and_hostname = "#{window.location.protocol}//#{window.location.hostname}"
32
+
33
+ $('body').on 'click', "a[href^='/']:not(.no_ajaxify), a[href^='#{protocol_and_hostname}']:not(.no_ajaxify)", ->
34
+
35
+ $this = $(this)
36
+ self.load
37
+ url: $this.attr('href')
38
+ type: $this.data('method')
39
+ confirm: $this.data('confirm')
40
+
41
+ false
42
+
43
+ exclude_selector = ":not(.no_ajaxify):not([enctype='multipart/form-data'])"
44
+ $('body').on 'submit', "form[action^='/']#{exclude_selector},
45
+ form[action^='#{protocol_and_hostname}']#{exclude_selector}", ->
46
+
47
+ $this = $(this)
48
+ form_params = $(this).serialize()
49
+ form_params += '&ajaxified=true'
50
+
51
+ self.load
52
+ url: $this.attr('action')
53
+ data: form_params
54
+ type: $this.attr('method')
55
+ confirm: $this.data('confirm')
56
+
57
+ false
58
+
59
+
60
+ window.onpopstate = (e) ->
61
+ if e.state
62
+ e.state.cache = false
63
+ self.load e.state, true
64
+
65
+
66
+ window.onhashchange = ->
67
+ self.hash_changed = true
68
+ if window.location.hash.indexOf('#/') == 0 # only react to hash changes if hash starts with '/'
69
+ unless self.ignore_hash_change
70
+ self.on_hash_change()
71
+ else
72
+ self.ignore_hash_change = false
73
+
74
+
75
+ on_hash_change: ->
76
+ url = window.location.hash.replace(/#/, "")
77
+ if url == ''
78
+ url = '/'
79
+ this.load
80
+ url: url
81
+ self.hash_changed = false
82
+
83
+
84
+ load: (options, pop_state = false) ->
85
+
86
+ unless this.load_page_from_hash
87
+ self = this
88
+
89
+ data = options.data || { ajaxified: true }
90
+
91
+ if options.type and options.type == 'delete'
92
+ type = 'post'
93
+ if self.is_string(data)
94
+ data += '&_method=delete'
95
+ else
96
+ data._method = 'delete'
97
+ else
98
+ type = options.type or 'get'
99
+
100
+ if options.confirm
101
+ return false unless confirm options.confirm
102
+
103
+ if self.on_before_load
104
+ self.on_before_load options.url
105
+
106
+ $.ajax
107
+ url: options.url
108
+ dataType: 'html'
109
+ data: data
110
+ type: type
111
+ cache: true
112
+ beforeSend: (xhr) ->
113
+ $("##{self.content_container}").html( "<div class='ajaxify_loader'></div>" )
114
+ $('html, body').animate
115
+ scrollTop:0
116
+ , 500
117
+
118
+ success: (data, status, jqXHR) ->
119
+ self.on_ajaxify_success data, status, jqXHR, pop_state, options
120
+
121
+
122
+ show_flash: () ->
123
+ self = this
124
+ $.each this.flash_types, ->
125
+ cookie_name = "flash_#{this}"
126
+ if $.cookie cookie_name
127
+ $("##{this}").html $.cookie(cookie_name)
128
+ $.cookie cookie_name, null
129
+ $("##{this}").show()
130
+ if self.flash_effect
131
+ self.flash_effect this
132
+ else
133
+ if self.clear_flash_effect
134
+ self.clear_flash_effect this
135
+ $("##{this}").hide()
136
+
137
+
138
+ on_ajaxify_success: (data, status, jqXHR, pop_state, options) ->
139
+
140
+ $("##{this.content_container}").html data
141
+
142
+ title = $('#ajaxify_content').data('page-title')
143
+
144
+ # Correct the url after a redirect and when it has the ajaxify param in it.
145
+ # The latter can happen e.g. for pagination links that are auto generated.
146
+ current_url = $('#ajaxify_content #ajaxify_location').text()
147
+ if options.url != current_url
148
+ options.url = current_url.replace(/(&|\?)ajaxify_redirect=true/,'')
149
+ options.type = 'GET'
150
+
151
+ this.update_url options, pop_state
152
+
153
+ if this.handle_extra_content
154
+ this.handle_extra_content()
155
+
156
+ $("##{this.content_container} #ajaxify_content").remove()
157
+
158
+ if title != ''
159
+ document.title = title.replace /&amp;/, '&' # Todo: need to figure out what else needs to be unescaped
160
+
161
+ this.show_flash()
162
+
163
+ if this.on_success
164
+ this.on_success( data, status, jqXHR, options.url )
165
+
166
+ if this.on_success_once
167
+ this.on_success_once( data, status, jqXHR )
168
+ this.on_success_once = null
169
+
170
+
171
+ update_url: (options, pop_state = false) ->
172
+
173
+ get_request = (!options.type or options.type.toLowerCase() == 'get')
174
+
175
+ # unless back/forward arrowing or request method is not 'get'
176
+ if !pop_state and get_request
177
+
178
+ if window.history.pushState
179
+
180
+ if this.initial_history_state != ''
181
+ window.history.replaceState this.initial_history_state, ''
182
+ this.initial_history_state = ''
183
+
184
+ window.history.pushState
185
+ url: options.url
186
+ data: options.data
187
+ type: options.type
188
+ ,'', options.url
189
+
190
+ else
191
+ this.ignore_hash_change = true # avoids loading the page for hash changes caused by link clicks
192
+ hash = "#{options.url.replace(new RegExp(this.protocol_with_host()), '')}"
193
+ if this.base_path_regexp
194
+ hash = hash.replace(this.base_path_regexp, '')
195
+ window.location.hash = hash
196
+
197
+
198
+
199
+ protocol_with_host: ->
200
+ loc = window.location
201
+ "#{loc.protocol}//#{loc.host}"
202
+
203
+
204
+ correct_url: ->
205
+ if window.location.hash.indexOf('#/') == 0
206
+ if !window.history.pushState
207
+ Ajaxify.load_page_from_hash = true # notify Ajaxify that a hash will be loaded and ignore all other calls to load until hash url is loaded
208
+ else
209
+ path = window.location.pathname + window.location.hash.replace(/#\//, "") # load proper url in case url contains #/ and browser supports history api
210
+ window.location.href = "#{this.protocol_with_host()}#{path}"
211
+
212
+ else if !window.history.pushState and window.location.pathname != '/'
213
+ if this.base_path_regexp and (match = window.location.pathname.match(this.base_path_regexp))
214
+ path = "#{match[0]}/##{window.location.pathname}"
215
+ if match[0] == window.location.pathname then return
216
+ else
217
+ path = "/##{window.location.pathname}"
218
+
219
+ window.location.href = "#{this.protocol_with_host()}#{path}#{window.location.search}" # move path behind # for browsers without history api if not at site root
220
+
221
+
222
+ is_string: (variable) ->
223
+ Object.prototype.toString.call(variable) == '[object String]'
224
+
225
+
226
+ Ajaxify.correct_url()
227
+
228
+ jQuery ->
229
+ Ajaxify.init()
@@ -0,0 +1,2 @@
1
+ //= require ./jquery_cookie
2
+ //= require ./ajaxify_rails
@@ -0,0 +1,61 @@
1
+ /*jshint eqnull:true */
2
+ /*!
3
+ * jQuery Cookie Plugin v1.1
4
+ * https://github.com/carhartl/jquery-cookie
5
+ *
6
+ * Copyright 2011, Klaus Hartl
7
+ * Dual licensed under the MIT or GPL Version 2 licenses.
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ * http://www.opensource.org/licenses/GPL-2.0
10
+ */
11
+ (function($, document) {
12
+
13
+ var pluses = /\+/g;
14
+ function raw(s) {
15
+ return s;
16
+ }
17
+ function decoded(s) {
18
+ return decodeURIComponent(s.replace(pluses, ' '));
19
+ }
20
+
21
+ $.cookie = function(key, value, options) {
22
+
23
+ // key and at least value given, set cookie...
24
+ if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value == null)) {
25
+ options = $.extend({}, $.cookie.defaults, options);
26
+
27
+ if (value == null) {
28
+ options.expires = -1;
29
+ }
30
+
31
+ if (typeof options.expires === 'number') {
32
+ var days = options.expires, t = options.expires = new Date();
33
+ t.setDate(t.getDate() + days);
34
+ }
35
+
36
+ value = String(value);
37
+
38
+ return (document.cookie = [
39
+ encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
40
+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
41
+ options.path ? '; path=' + options.path : '',
42
+ options.domain ? '; domain=' + options.domain : '',
43
+ options.secure ? '; secure' : ''
44
+ ].join(''));
45
+ }
46
+
47
+ // key and possibly options given, get cookie...
48
+ options = value || $.cookie.defaults || {};
49
+ var decode = options.raw ? raw : decoded;
50
+ var cookies = document.cookie.split('; ');
51
+ for (var i = 0, parts; (parts = cookies[i] && cookies[i].split('=')); i++) {
52
+ if (decode(parts.shift()) === key) {
53
+ return decode(parts.join('='));
54
+ }
55
+ }
56
+ return null;
57
+ };
58
+
59
+ $.cookie.defaults = {};
60
+
61
+ })(jQuery, document);
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ajaxify_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nico Ritsche
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.1.0
30
+ description: ! "Rails gem for automatically turning internal links into ajax links
31
+ that load content without a full page reload.\n Uses the
32
+ html5 history interface for changing the url and making the browser's back and forward
33
+ buttons working with ajax.\n Falls back to a hash based
34
+ approach for browsers without the history interface (like Internet Explorer).\n
35
+ \ Transparently handles redirects and supports flash messages
36
+ and page titles. Requires Ruby 1.9 and the asset pipeline."
37
+ email:
38
+ - ncrdevmail@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - LICENSE
46
+ - README.md
47
+ - Rakefile
48
+ - ajaxify_rails.gemspec
49
+ - lib/ajaxify_rails.rb
50
+ - lib/ajaxify_rails/version.rb
51
+ - vendor/assets/javascripts/ajaxify_rails/ajaxify_rails.js.coffee
52
+ - vendor/assets/javascripts/ajaxify_rails/index.js
53
+ - vendor/assets/javascripts/ajaxify_rails/jquery_cookie.js
54
+ homepage: https://github.com/ncri/ajaxify_rails
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ segments:
67
+ - 0
68
+ hash: -44075291166774192
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ segments:
76
+ - 0
77
+ hash: -44075291166774192
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 1.8.24
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Rails gem for automatically turning internal links into ajax links that load
84
+ content without a full page reload.
85
+ test_files: []