rails-ajax 0.1.0.20120706
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +3 -0
- data/ChangeLog +5 -0
- data/Credits +15 -0
- data/Gemfile +36 -0
- data/Gemfile.lock +153 -0
- data/LICENSE +31 -0
- data/README +15 -0
- data/Rakefile +35 -0
- data/ReleaseInfo +8 -0
- data/assets/javascripts/jquery.history.js +1 -0
- data/assets/javascripts/jquery.rails-ajax.js.erb +256 -0
- data/gen/app/assets/javascripts/RailsAjax-Config.js.erb +46 -0
- data/gen/config/initializers/rails-ajax-config.rb +31 -0
- data/lib/rails-ajax.rb +18 -0
- data/lib/rails-ajax/action_controller/base.rb +15 -0
- data/lib/rails-ajax/action_view/base.rb +15 -0
- data/lib/rails-ajax/configuration.rb +74 -0
- data/lib/rails-ajax/controller.rb +155 -0
- data/lib/rails-ajax/form_tag_helper.rb +33 -0
- data/lib/rails-ajax/rails-ajax.rb +28 -0
- data/lib/rails-ajax/railtie.rb +31 -0
- data/lib/rails-ajax/url_helper.rb +44 -0
- data/tasks/rails-ajax_tasks.rake +29 -0
- metadata +86 -0
data/AUTHORS
ADDED
data/ChangeLog
ADDED
data/Credits
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
= Projects used by Rails-Ajax
|
2
|
+
|
3
|
+
== Ruby
|
4
|
+
* Yukihiro « matz » Matsumoto (http://www.rubyist.net/~matz/)
|
5
|
+
* http://www.ruby-lang.org/
|
6
|
+
* Thanks a lot Matz for this truly wonderful language !
|
7
|
+
|
8
|
+
== Ruby on Rails
|
9
|
+
* David Heinemeier Hansson (http://david.heinemeierhansson.com/)
|
10
|
+
* http://rubyonrails.org/
|
11
|
+
* Used for testing.
|
12
|
+
|
13
|
+
= People that helped a lot in developing Rails-Ajax
|
14
|
+
|
15
|
+
* Mattahan (http://www.iconarchive.com/artist/mattahan.html) for his wonderful icon sets.
|
data/Gemfile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# Declare your gem's dependencies in rails-ajax.gemspec.
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
5
|
+
# development dependencies will be added by default to the :development group.
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
# jquery-rails is used by the dummy application
|
9
|
+
gem "jquery-rails"
|
10
|
+
|
11
|
+
# Declare any dependencies that are still in development here instead of in
|
12
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
13
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
14
|
+
# your gem to rubygems.org.
|
15
|
+
|
16
|
+
# To use debugger
|
17
|
+
# gem 'debugger'
|
18
|
+
|
19
|
+
group :test do
|
20
|
+
|
21
|
+
# Rails itself
|
22
|
+
gem 'rails', '~>3.2.1'
|
23
|
+
|
24
|
+
# RSpec
|
25
|
+
gem 'rspec'
|
26
|
+
gem 'rspec-rails'
|
27
|
+
|
28
|
+
# Cucumber
|
29
|
+
gem 'cucumber-rails', :require => false
|
30
|
+
gem 'sqlite3'
|
31
|
+
gem 'database_cleaner'
|
32
|
+
|
33
|
+
# Capybara-webkit
|
34
|
+
gem 'capybara-webkit'
|
35
|
+
|
36
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
dummy_gem (0.0.1)
|
5
|
+
rails (~> 3.2.6)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
actionmailer (3.2.6)
|
11
|
+
actionpack (= 3.2.6)
|
12
|
+
mail (~> 2.4.4)
|
13
|
+
actionpack (3.2.6)
|
14
|
+
activemodel (= 3.2.6)
|
15
|
+
activesupport (= 3.2.6)
|
16
|
+
builder (~> 3.0.0)
|
17
|
+
erubis (~> 2.7.0)
|
18
|
+
journey (~> 1.0.1)
|
19
|
+
rack (~> 1.4.0)
|
20
|
+
rack-cache (~> 1.2)
|
21
|
+
rack-test (~> 0.6.1)
|
22
|
+
sprockets (~> 2.1.3)
|
23
|
+
activemodel (3.2.6)
|
24
|
+
activesupport (= 3.2.6)
|
25
|
+
builder (~> 3.0.0)
|
26
|
+
activerecord (3.2.6)
|
27
|
+
activemodel (= 3.2.6)
|
28
|
+
activesupport (= 3.2.6)
|
29
|
+
arel (~> 3.0.2)
|
30
|
+
tzinfo (~> 0.3.29)
|
31
|
+
activeresource (3.2.6)
|
32
|
+
activemodel (= 3.2.6)
|
33
|
+
activesupport (= 3.2.6)
|
34
|
+
activesupport (3.2.6)
|
35
|
+
i18n (~> 0.6)
|
36
|
+
multi_json (~> 1.0)
|
37
|
+
addressable (2.2.8)
|
38
|
+
arel (3.0.2)
|
39
|
+
builder (3.0.0)
|
40
|
+
capybara (1.1.2)
|
41
|
+
mime-types (>= 1.16)
|
42
|
+
nokogiri (>= 1.3.3)
|
43
|
+
rack (>= 1.0.0)
|
44
|
+
rack-test (>= 0.5.4)
|
45
|
+
selenium-webdriver (~> 2.0)
|
46
|
+
xpath (~> 0.1.4)
|
47
|
+
capybara-webkit (0.12.1)
|
48
|
+
capybara (>= 1.0.0, < 1.2)
|
49
|
+
json
|
50
|
+
childprocess (0.3.3)
|
51
|
+
ffi (~> 1.0.6)
|
52
|
+
cucumber (1.2.1)
|
53
|
+
builder (>= 2.1.2)
|
54
|
+
diff-lcs (>= 1.1.3)
|
55
|
+
gherkin (~> 2.11.0)
|
56
|
+
json (>= 1.4.6)
|
57
|
+
cucumber-rails (1.3.0)
|
58
|
+
capybara (>= 1.1.2)
|
59
|
+
cucumber (>= 1.1.8)
|
60
|
+
nokogiri (>= 1.5.0)
|
61
|
+
database_cleaner (0.8.0)
|
62
|
+
diff-lcs (1.1.3)
|
63
|
+
erubis (2.7.0)
|
64
|
+
ffi (1.0.11)
|
65
|
+
gherkin (2.11.1-x86-mingw32)
|
66
|
+
json (>= 1.4.6)
|
67
|
+
hike (1.2.1)
|
68
|
+
i18n (0.6.0)
|
69
|
+
journey (1.0.4)
|
70
|
+
jquery-rails (2.0.2)
|
71
|
+
railties (>= 3.2.0, < 5.0)
|
72
|
+
thor (~> 0.14)
|
73
|
+
json (1.7.3)
|
74
|
+
libwebsocket (0.1.3)
|
75
|
+
addressable
|
76
|
+
mail (2.4.4)
|
77
|
+
i18n (>= 0.4.0)
|
78
|
+
mime-types (~> 1.16)
|
79
|
+
treetop (~> 1.4.8)
|
80
|
+
mime-types (1.19)
|
81
|
+
multi_json (1.3.6)
|
82
|
+
nokogiri (1.5.5-x86-mingw32)
|
83
|
+
polyglot (0.3.3)
|
84
|
+
rack (1.4.1)
|
85
|
+
rack-cache (1.2)
|
86
|
+
rack (>= 0.4)
|
87
|
+
rack-ssl (1.3.2)
|
88
|
+
rack
|
89
|
+
rack-test (0.6.1)
|
90
|
+
rack (>= 1.0)
|
91
|
+
rails (3.2.6)
|
92
|
+
actionmailer (= 3.2.6)
|
93
|
+
actionpack (= 3.2.6)
|
94
|
+
activerecord (= 3.2.6)
|
95
|
+
activeresource (= 3.2.6)
|
96
|
+
activesupport (= 3.2.6)
|
97
|
+
bundler (~> 1.0)
|
98
|
+
railties (= 3.2.6)
|
99
|
+
railties (3.2.6)
|
100
|
+
actionpack (= 3.2.6)
|
101
|
+
activesupport (= 3.2.6)
|
102
|
+
rack-ssl (~> 1.3.2)
|
103
|
+
rake (>= 0.8.7)
|
104
|
+
rdoc (~> 3.4)
|
105
|
+
thor (>= 0.14.6, < 2.0)
|
106
|
+
rake (0.9.2.2)
|
107
|
+
rdoc (3.12)
|
108
|
+
json (~> 1.4)
|
109
|
+
rspec (2.10.0)
|
110
|
+
rspec-core (~> 2.10.0)
|
111
|
+
rspec-expectations (~> 2.10.0)
|
112
|
+
rspec-mocks (~> 2.10.0)
|
113
|
+
rspec-core (2.10.1)
|
114
|
+
rspec-expectations (2.10.0)
|
115
|
+
diff-lcs (~> 1.1.3)
|
116
|
+
rspec-mocks (2.10.1)
|
117
|
+
rspec-rails (2.10.1)
|
118
|
+
actionpack (>= 3.0)
|
119
|
+
activesupport (>= 3.0)
|
120
|
+
railties (>= 3.0)
|
121
|
+
rspec (~> 2.10.0)
|
122
|
+
rubyzip (0.9.9)
|
123
|
+
selenium-webdriver (2.24.0)
|
124
|
+
childprocess (>= 0.2.5)
|
125
|
+
libwebsocket (~> 0.1.3)
|
126
|
+
multi_json (~> 1.0)
|
127
|
+
rubyzip
|
128
|
+
sprockets (2.1.3)
|
129
|
+
hike (~> 1.2)
|
130
|
+
rack (~> 1.0)
|
131
|
+
tilt (~> 1.1, != 1.3.0)
|
132
|
+
sqlite3 (1.3.6-x86-mingw32)
|
133
|
+
thor (0.15.4)
|
134
|
+
tilt (1.3.3)
|
135
|
+
treetop (1.4.10)
|
136
|
+
polyglot
|
137
|
+
polyglot (>= 0.3.1)
|
138
|
+
tzinfo (0.3.33)
|
139
|
+
xpath (0.1.4)
|
140
|
+
nokogiri (~> 1.3)
|
141
|
+
|
142
|
+
PLATFORMS
|
143
|
+
x86-mingw32
|
144
|
+
|
145
|
+
DEPENDENCIES
|
146
|
+
capybara-webkit
|
147
|
+
cucumber-rails
|
148
|
+
database_cleaner
|
149
|
+
dummy_gem!
|
150
|
+
jquery-rails
|
151
|
+
rspec
|
152
|
+
rspec-rails
|
153
|
+
sqlite3
|
data/LICENSE
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
The license stated herein is a copy of the BSD License (modified on July 1999).
|
3
|
+
The AUTHOR mentionned below refers to the list of people involved in the
|
4
|
+
creation and modification of any file included in the delivered package.
|
5
|
+
This list is found in the file named AUTHORS.
|
6
|
+
The AUTHORS and LICENSE files have to be included in any release of software
|
7
|
+
embedding source code of this package, or using it as a derivative software.
|
8
|
+
|
9
|
+
Copyright (c) 2012 Muriel Salvan (muriel@x-aeon.com)
|
10
|
+
|
11
|
+
Redistribution and use in source and binary forms, with or without
|
12
|
+
modification, are permitted provided that the following conditions are met:
|
13
|
+
|
14
|
+
1. Redistributions of source code must retain the above copyright notice,
|
15
|
+
this list of conditions and the following disclaimer.
|
16
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
17
|
+
this list of conditions and the following disclaimer in the documentation
|
18
|
+
and/or other materials provided with the distribution.
|
19
|
+
3. The name of the author may not be used to endorse or promote products
|
20
|
+
derived from this software without specific prior written permission.
|
21
|
+
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
23
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
24
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
25
|
+
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
26
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
27
|
+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
28
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
29
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
30
|
+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
31
|
+
OF SUCH DAMAGE.
|
data/README
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
= Rails-Ajax
|
2
|
+
|
3
|
+
Add Ajax capabilities to Rails websites with history, bookmarking...
|
4
|
+
|
5
|
+
== Where is the documentation ?
|
6
|
+
|
7
|
+
Check the website at http://rails-ajax.sourceforge.net
|
8
|
+
|
9
|
+
== Who wrote it ?
|
10
|
+
|
11
|
+
Check the AUTHORS[link:AUTHORS.html] file.
|
12
|
+
|
13
|
+
== What is the license ?
|
14
|
+
|
15
|
+
You can find out in the LICENSE[link:LICENSE.html] file.
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'RailsAjax'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
Bundler::GemHelper.install_tasks
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
|
30
|
+
task :test do |t|
|
31
|
+
load("#{File.dirname(__FILE__)}/test/run.rb")
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
task :default => :test
|
data/ReleaseInfo
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
window.JSON||(window.JSON={}),function(){function f(a){return a<10?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c<f;c+=1)h[c]=str(c,i)||"null";return e=h.length===0?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]",gap=g,e}if(rep&&typeof rep=="object"){f=rep.length;for(c=0;c<f;c+=1)d=rep[c],typeof d=="string"&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e))}else for(d in i)Object.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));return e=h.length===0?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}",gap=g,e}}"use strict",typeof Date.prototype.toJSON!="function"&&(Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()});var JSON=window.JSON,cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;typeof JSON.stringify!="function"&&(JSON.stringify=function(a,b,c){var d;gap="",indent="";if(typeof c=="number")for(d=0;d<c;d+=1)indent+=" ";else typeof c=="string"&&(indent=c);rep=b;if(!b||typeof b=="function"||typeof b=="object"&&typeof b.length=="number")return str("",{"":a});throw new Error("JSON.stringify")}),typeof JSON.parse!="function"&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&typeof e=="object")for(c in e)Object.hasOwnProperty.call(e,c)&&(d=walk(e,c),d!==undefined?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),typeof reviver=="function"?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(),function(a,b){"use strict";var c=a.History=a.History||{},d=a.jQuery;if(typeof c.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");c.Adapter={bind:function(a,b,c){d(a).bind(b,c)},trigger:function(a,b,c){d(a).trigger(b,c)},extractEventData:function(a,c,d){var e=c&&c.originalEvent&&c.originalEvent[a]||d&&d[a]||b;return e},onDomLoad:function(a){d(a)}},typeof c.init!="undefined"&&c.init()}(window),function(a,b){"use strict";var c=a.document,d=a.setTimeout||d,e=a.clearTimeout||e,f=a.setInterval||f,g=a.History=a.History||{};if(typeof g.initHtml4!="undefined")throw new Error("History.js HTML4 Support has already been loaded...");g.initHtml4=function(){if(typeof g.initHtml4.initialized!="undefined")return!1;g.initHtml4.initialized=!0,g.enabled=!0,g.savedHashes=[],g.isLastHash=function(a){var b=g.getHashByIndex(),c;return c=a===b,c},g.saveHash=function(a){return g.isLastHash(a)?!1:(g.savedHashes.push(a),!0)},g.getHashByIndex=function(a){var b=null;return typeof a=="undefined"?b=g.savedHashes[g.savedHashes.length-1]:a<0?b=g.savedHashes[g.savedHashes.length+a]:b=g.savedHashes[a],b},g.discardedHashes={},g.discardedStates={},g.discardState=function(a,b,c){var d=g.getHashByState(a),e;return e={discardedState:a,backState:c,forwardState:b},g.discardedStates[d]=e,!0},g.discardHash=function(a,b,c){var d={discardedHash:a,backState:c,forwardState:b};return g.discardedHashes[a]=d,!0},g.discardedState=function(a){var b=g.getHashByState(a),c;return c=g.discardedStates[b]||!1,c},g.discardedHash=function(a){var b=g.discardedHashes[a]||!1;return b},g.recycleState=function(a){var b=g.getHashByState(a);return g.discardedState(a)&&delete g.discardedStates[b],!0},g.emulated.hashChange&&(g.hashChangeInit=function(){g.checkerFunction=null;var b="",d,e,h,i;return g.isInternetExplorer()?(d="historyjs-iframe",e=c.createElement("iframe"),e.setAttribute("id",d),e.style.display="none",c.body.appendChild(e),e.contentWindow.document.open(),e.contentWindow.document.close(),h="",i=!1,g.checkerFunction=function(){if(i)return!1;i=!0;var c=g.getHash()||"",d=g.unescapeHash(e.contentWindow.document.location.hash)||"";return c!==b?(b=c,d!==c&&(h=d=c,e.contentWindow.document.open(),e.contentWindow.document.close(),e.contentWindow.document.location.hash=g.escapeHash(c)),g.Adapter.trigger(a,"hashchange")):d!==h&&(h=d,g.setHash(d,!1)),i=!1,!0}):g.checkerFunction=function(){var c=g.getHash();return c!==b&&(b=c,g.Adapter.trigger(a,"hashchange")),!0},g.intervalList.push(f(g.checkerFunction,g.options.hashChangeInterval)),!0},g.Adapter.onDomLoad(g.hashChangeInit)),g.emulated.pushState&&(g.onHashChange=function(b){var d=b&&b.newURL||c.location.href,e=g.getHashByUrl(d),f=null,h=null,i=null,j;return g.isLastHash(e)?(g.busy(!1),!1):(g.doubleCheckComplete(),g.saveHash(e),e&&g.isTraditionalAnchor(e)?(g.Adapter.trigger(a,"anchorchange"),g.busy(!1),!1):(f=g.extractState(g.getFullUrl(e||c.location.href,!1),!0),g.isLastSavedState(f)?(g.busy(!1),!1):(h=g.getHashByState(f),j=g.discardedState(f),j?(g.getHashByIndex(-2)===g.getHashByState(j.forwardState)?g.back(!1):g.forward(!1),!1):(g.pushState(f.data,f.title,f.url,!1),!0))))},g.Adapter.bind(a,"hashchange",g.onHashChange),g.pushState=function(b,d,e,f){if(g.getHashByUrl(e))throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==!1&&g.busy())return g.pushQueue({scope:g,callback:g.pushState,args:arguments,queue:f}),!1;g.busy(!0);var h=g.createStateObject(b,d,e),i=g.getHashByState(h),j=g.getState(!1),k=g.getHashByState(j),l=g.getHash();return g.storeState(h),g.expectedStateId=h.id,g.recycleState(h),g.setTitle(h),i===k?(g.busy(!1),!1):i!==l&&i!==g.getShortUrl(c.location.href)?(g.setHash(i,!1),!1):(g.saveState(h),g.Adapter.trigger(a,"statechange"),g.busy(!1),!0)},g.replaceState=function(a,b,c,d){if(g.getHashByUrl(c))throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(d!==!1&&g.busy())return g.pushQueue({scope:g,callback:g.replaceState,args:arguments,queue:d}),!1;g.busy(!0);var e=g.createStateObject(a,b,c),f=g.getState(!1),h=g.getStateByIndex(-2);return g.discardState(f,e,h),g.pushState(e.data,e.title,e.url,!1),!0}),g.emulated.pushState&&g.getHash()&&!g.emulated.hashChange&&g.Adapter.onDomLoad(function(){g.Adapter.trigger(a,"hashchange")})},typeof g.init!="undefined"&&g.init()}(window),function(a,b){"use strict";var c=a.console||b,d=a.document,e=a.navigator,f=a.sessionStorage||!1,g=a.setTimeout,h=a.clearTimeout,i=a.setInterval,j=a.clearInterval,k=a.JSON,l=a.alert,m=a.History=a.History||{},n=a.history;k.stringify=k.stringify||k.encode,k.parse=k.parse||k.decode;if(typeof m.init!="undefined")throw new Error("History.js Core has already been loaded...");m.init=function(){return typeof m.Adapter=="undefined"?!1:(typeof m.initCore!="undefined"&&m.initCore(),typeof m.initHtml4!="undefined"&&m.initHtml4(),!0)},m.initCore=function(){if(typeof m.initCore.initialized!="undefined")return!1;m.initCore.initialized=!0,m.options=m.options||{},m.options.hashChangeInterval=m.options.hashChangeInterval||100,m.options.safariPollInterval=m.options.safariPollInterval||500,m.options.doubleCheckInterval=m.options.doubleCheckInterval||500,m.options.storeInterval=m.options.storeInterval||1e3,m.options.busyDelay=m.options.busyDelay||250,m.options.debug=m.options.debug||!1,m.options.initialTitle=m.options.initialTitle||d.title,m.intervalList=[],m.clearAllIntervals=function(){var a,b=m.intervalList;if(typeof b!="undefined"&&b!==null){for(a=0;a<b.length;a++)j(b[a]);m.intervalList=null}},m.debug=function(){(m.options.debug||!1)&&m.log.apply(m,arguments)},m.log=function(){var a=typeof c!="undefined"&&typeof c.log!="undefined"&&typeof c.log.apply!="undefined",b=d.getElementById("log"),e,f,g,h,i;a?(h=Array.prototype.slice.call(arguments),e=h.shift(),typeof c.debug!="undefined"?c.debug.apply(c,[e,h]):c.log.apply(c,[e,h])):e="\n"+arguments[0]+"\n";for(f=1,g=arguments.length;f<g;++f){i=arguments[f];if(typeof i=="object"&&typeof k!="undefined")try{i=k.stringify(i)}catch(j){}e+="\n"+i+"\n"}return b?(b.value+=e+"\n-----\n",b.scrollTop=b.scrollHeight-b.clientHeight):a||l(e),!0},m.getInternetExplorerMajorVersion=function(){var a=m.getInternetExplorerMajorVersion.cached=typeof m.getInternetExplorerMajorVersion.cached!="undefined"?m.getInternetExplorerMajorVersion.cached:function(){var a=3,b=d.createElement("div"),c=b.getElementsByTagName("i");while((b.innerHTML="<!--[if gt IE "+ ++a+"]><i></i><![endif]-->")&&c[0]);return a>4?a:!1}();return a},m.isInternetExplorer=function(){var a=m.isInternetExplorer.cached=typeof m.isInternetExplorer.cached!="undefined"?m.isInternetExplorer.cached:Boolean(m.getInternetExplorerMajorVersion());return a},m.emulated={pushState:!Boolean(a.history&&a.history.pushState&&a.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)),hashChange:Boolean(!("onhashchange"in a||"onhashchange"in d)||m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8)},m.enabled=!m.emulated.pushState,m.bugs={setHash:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),safariPoll:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),ieDoubleCheck:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<7)},m.isEmptyObject=function(a){for(var b in a)return!1;return!0},m.cloneObject=function(a){var b,c;return a?(b=k.stringify(a),c=k.parse(b)):c={},c},m.getRootUrl=function(){var a=d.location.protocol+"//"+(d.location.hostname||d.location.host);if(d.location.port||!1)a+=":"+d.location.port;return a+="/",a},m.getBaseHref=function(){var a=d.getElementsByTagName("base"),b=null,c="";return a.length===1&&(b=a[0],c=b.href.replace(/[^\/]+$/,"")),c=c.replace(/\/+$/,""),c&&(c+="/"),c},m.getBaseUrl=function(){var a=m.getBaseHref()||m.getBasePageUrl()||m.getRootUrl();return a},m.getPageUrl=function(){var a=m.getState(!1,!1),b=(a||{}).url||d.location.href,c;return c=b.replace(/\/+$/,"").replace(/[^\/]+$/,function(a,b,c){return/\./.test(a)?a:a+"/"}),c},m.getBasePageUrl=function(){var a=d.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,function(a,b,c){return/[^\/]$/.test(a)?"":a}).replace(/\/+$/,"")+"/";return a},m.getFullUrl=function(a,b){var c=a,d=a.substring(0,1);return b=typeof b=="undefined"?!0:b,/[a-z]+\:\/\//.test(a)||(d==="/"?c=m.getRootUrl()+a.replace(/^\/+/,""):d==="#"?c=m.getPageUrl().replace(/#.*/,"")+a:d==="?"?c=m.getPageUrl().replace(/[\?#].*/,"")+a:b?c=m.getBaseUrl()+a.replace(/^(\.\/)+/,""):c=m.getBasePageUrl()+a.replace(/^(\.\/)+/,"")),c.replace(/\#$/,"")},m.getShortUrl=function(a){var b=a,c=m.getBaseUrl(),d=m.getRootUrl();return m.emulated.pushState&&(b=b.replace(c,"")),b=b.replace(d,"/"),m.isTraditionalAnchor(b)&&(b="./"+b),b=b.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),b},m.store={},m.idToState=m.idToState||{},m.stateToId=m.stateToId||{},m.urlToId=m.urlToId||{},m.storedStates=m.storedStates||[],m.savedStates=m.savedStates||[],m.normalizeStore=function(){m.store.idToState=m.store.idToState||{},m.store.urlToId=m.store.urlToId||{},m.store.stateToId=m.store.stateToId||{}},m.getState=function(a,b){typeof a=="undefined"&&(a=!0),typeof b=="undefined"&&(b=!0);var c=m.getLastSavedState();return!c&&b&&(c=m.createStateObject()),a&&(c=m.cloneObject(c),c.url=c.cleanUrl||c.url),c},m.getIdByState=function(a){var b=m.extractId(a.url),c;if(!b){c=m.getStateString(a);if(typeof m.stateToId[c]!="undefined")b=m.stateToId[c];else if(typeof m.store.stateToId[c]!="undefined")b=m.store.stateToId[c];else{for(;;){b=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof m.idToState[b]=="undefined"&&typeof m.store.idToState[b]=="undefined")break}m.stateToId[c]=b,m.idToState[b]=a}}return b},m.normalizeState=function(a){var b,c;if(!a||typeof a!="object")a={};if(typeof a.normalized!="undefined")return a;if(!a.data||typeof a.data!="object")a.data={};b={},b.normalized=!0,b.title=a.title||"",b.url=m.getFullUrl(m.unescapeString(a.url||d.location.href)),b.hash=m.getShortUrl(b.url),b.data=m.cloneObject(a.data),b.id=m.getIdByState(b),b.cleanUrl=b.url.replace(/\??\&_suid.*/,""),b.url=b.cleanUrl,c=!m.isEmptyObject(b.data);if(b.title||c)b.hash=m.getShortUrl(b.url).replace(/\??\&_suid.*/,""),/\?/.test(b.hash)||(b.hash+="?"),b.hash+="&_suid="+b.id;return b.hashedUrl=m.getFullUrl(b.hash),(m.emulated.pushState||m.bugs.safariPoll)&&m.hasUrlDuplicate(b)&&(b.url=b.hashedUrl),b},m.createStateObject=function(a,b,c){var d={data:a,title:b,url:c};return d=m.normalizeState(d),d},m.getStateById=function(a){a=String(a);var c=m.idToState[a]||m.store.idToState[a]||b;return c},m.getStateString=function(a){var b,c,d;return b=m.normalizeState(a),c={data:b.data,title:a.title,url:a.url},d=k.stringify(c),d},m.getStateId=function(a){var b,c;return b=m.normalizeState(a),c=b.id,c},m.getHashByState=function(a){var b,c;return b=m.normalizeState(a),c=b.hash,c},m.extractId=function(a){var b,c,d;return c=/(.*)\&_suid=([0-9]+)$/.exec(a),d=c?c[1]||a:a,b=c?String(c[2]||""):"",b||!1},m.isTraditionalAnchor=function(a){var b=!/[\/\?\.]/.test(a);return b},m.extractState=function(a,b){var c=null,d,e;return b=b||!1,d=m.extractId(a),d&&(c=m.getStateById(d)),c||(e=m.getFullUrl(a),d=m.getIdByUrl(e)||!1,d&&(c=m.getStateById(d)),!c&&b&&!m.isTraditionalAnchor(a)&&(c=m.createStateObject(null,null,e))),c},m.getIdByUrl=function(a){var c=m.urlToId[a]||m.store.urlToId[a]||b;return c},m.getLastSavedState=function(){return m.savedStates[m.savedStates.length-1]||b},m.getLastStoredState=function(){return m.storedStates[m.storedStates.length-1]||b},m.hasUrlDuplicate=function(a){var b=!1,c;return c=m.extractState(a.url),b=c&&c.id!==a.id,b},m.storeState=function(a){return m.urlToId[a.url]=a.id,m.storedStates.push(m.cloneObject(a)),a},m.isLastSavedState=function(a){var b=!1,c,d,e;return m.savedStates.length&&(c=a.id,d=m.getLastSavedState(),e=d.id,b=c===e),b},m.saveState=function(a){return m.isLastSavedState(a)?!1:(m.savedStates.push(m.cloneObject(a)),!0)},m.getStateByIndex=function(a){var b=null;return typeof a=="undefined"?b=m.savedStates[m.savedStates.length-1]:a<0?b=m.savedStates[m.savedStates.length+a]:b=m.savedStates[a],b},m.getHash=function(){var a=m.unescapeHash(d.location.hash);return a},m.unescapeString=function(b){var c=b,d;for(;;){d=a.unescape(c);if(d===c)break;c=d}return c},m.unescapeHash=function(a){var b=m.normalizeHash(a);return b=m.unescapeString(b),b},m.normalizeHash=function(a){var b=a.replace(/[^#]*#/,"").replace(/#.*/,"");return b},m.setHash=function(a,b){var c,e,f;return b!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.setHash,args:arguments,queue:b}),!1):(c=m.escapeHash(a),m.busy(!0),e=m.extractState(a,!0),e&&!m.emulated.pushState?m.pushState(e.data,e.title,e.url,!1):d.location.hash!==c&&(m.bugs.setHash?(f=m.getPageUrl(),m.pushState(null,null,f+"#"+c,!1)):d.location.hash=c),m)},m.escapeHash=function(b){var c=m.normalizeHash(b);return c=a.escape(c),m.bugs.hashEscape||(c=c.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),c},m.getHashByUrl=function(a){var b=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return b=m.unescapeHash(b),b},m.setTitle=function(a){var b=a.title,c;b||(c=m.getStateByIndex(0),c&&c.url===a.url&&(b=c.title||m.options.initialTitle));try{d.getElementsByTagName("title")[0].innerHTML=b.replace("<","<").replace(">",">").replace(" & "," & ")}catch(e){}return d.title=b,m},m.queues=[],m.busy=function(a){typeof a!="undefined"?m.busy.flag=a:typeof m.busy.flag=="undefined"&&(m.busy.flag=!1);if(!m.busy.flag){h(m.busy.timeout);var b=function(){var a,c,d;if(m.busy.flag)return;for(a=m.queues.length-1;a>=0;--a){c=m.queues[a];if(c.length===0)continue;d=c.shift(),m.fireQueueItem(d),m.busy.timeout=g(b,m.options.busyDelay)}};m.busy.timeout=g(b,m.options.busyDelay)}return m.busy.flag},m.busy.flag=!1,m.fireQueueItem=function(a){return a.callback.apply(a.scope||m,a.args||[])},m.pushQueue=function(a){return m.queues[a.queue||0]=m.queues[a.queue||0]||[],m.queues[a.queue||0].push(a),m},m.queue=function(a,b){return typeof a=="function"&&(a={callback:a}),typeof b!="undefined"&&(a.queue=b),m.busy()?m.pushQueue(a):m.fireQueueItem(a),m},m.clearQueue=function(){return m.busy.flag=!1,m.queues=[],m},m.stateChanged=!1,m.doubleChecker=!1,m.doubleCheckComplete=function(){return m.stateChanged=!0,m.doubleCheckClear(),m},m.doubleCheckClear=function(){return m.doubleChecker&&(h(m.doubleChecker),m.doubleChecker=!1),m},m.doubleCheck=function(a){return m.stateChanged=!1,m.doubleCheckClear(),m.bugs.ieDoubleCheck&&(m.doubleChecker=g(function(){return m.doubleCheckClear(),m.stateChanged||a(),!0},m.options.doubleCheckInterval)),m},m.safariStatePoll=function(){var b=m.extractState(d.location.href),c;if(!m.isLastSavedState(b))c=b;else return;return c||(c=m.createStateObject()),m.Adapter.trigger(a,"popstate"),m},m.back=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.back,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.back(!1)}),n.go(-1),!0)},m.forward=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.forward,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.forward(!1)}),n.go(1),!0)},m.go=function(a,b){var c;if(a>0)for(c=1;c<=a;++c)m.forward(b);else{if(!(a<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(c=-1;c>=a;--c)m.back(b)}return m};if(m.emulated.pushState){var o=function(){};m.pushState=m.pushState||o,m.replaceState=m.replaceState||o}else m.onPopState=function(b,c){var e=!1,f=!1,g,h;return m.doubleCheckComplete(),g=m.getHash(),g?(h=m.extractState(g||d.location.href,!0),h?m.replaceState(h.data,h.title,h.url,!1):(m.Adapter.trigger(a,"anchorchange"),m.busy(!1)),m.expectedStateId=!1,!1):(e=m.Adapter.extractEventData("state",b,c)||!1,e?f=m.getStateById(e):m.expectedStateId?f=m.getStateById(m.expectedStateId):f=m.extractState(d.location.href),f||(f=m.createStateObject(null,null,d.location.href)),m.expectedStateId=!1,m.isLastSavedState(f)?(m.busy(!1),!1):(m.storeState(f),m.saveState(f),m.setTitle(f),m.Adapter.trigger(a,"statechange"),m.busy(!1),!0))},m.Adapter.bind(a,"popstate",m.onPopState),m.pushState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.pushState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.pushState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0},m.replaceState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.replaceState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.replaceState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0};if(f){try{m.store=k.parse(f.getItem("History.store"))||{}}catch(p){m.store={}}m.normalizeStore()}else m.store={},m.normalizeStore();m.Adapter.bind(a,"beforeunload",m.clearAllIntervals),m.Adapter.bind(a,"unload",m.clearAllIntervals),m.saveState(m.storeState(m.extractState(d.location.href,!0))),f&&(m.onUnload=function(){var a,b;try{a=k.parse(f.getItem("History.store"))||{}}catch(c){a={}}a.idToState=a.idToState||{},a.urlToId=a.urlToId||{},a.stateToId=a.stateToId||{};for(b in m.idToState){if(!m.idToState.hasOwnProperty(b))continue;a.idToState[b]=m.idToState[b]}for(b in m.urlToId){if(!m.urlToId.hasOwnProperty(b))continue;a.urlToId[b]=m.urlToId[b]}for(b in m.stateToId){if(!m.stateToId.hasOwnProperty(b))continue;a.stateToId[b]=m.stateToId[b]}m.store=a,m.normalizeStore(),f.setItem("History.store",k.stringify(a))},m.intervalList.push(i(m.onUnload,m.options.storeInterval)),m.Adapter.bind(a,"beforeunload",m.onUnload),m.Adapter.bind(a,"unload",m.onUnload));if(!m.emulated.pushState){m.bugs.safariPoll&&m.intervalList.push(i(m.safariStatePoll,m.options.safariPollInterval));if(e.vendor==="Apple Computer, Inc."||(e.appCodeName||"")==="Mozilla")m.Adapter.bind(a,"hashchange",function(){m.Adapter.trigger(a,"popstate")}),m.getHash()&&m.Adapter.onDomLoad(function(){m.Adapter.trigger(a,"hashchange")})}},m.init()}(window)
|
@@ -0,0 +1,256 @@
|
|
1
|
+
//--
|
2
|
+
// Copyright (c) 2012 Muriel Salvan (muriel@x-aeon.com)
|
3
|
+
// Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
//++
|
5
|
+
|
6
|
+
<% if (RailsAjax.config.Enabled) %>
|
7
|
+
|
8
|
+
// Encapsulate everything in a nice namespace
|
9
|
+
var railsAjax = {
|
10
|
+
|
11
|
+
// Initialization, to be called just once when the DOM is ready
|
12
|
+
init: function() {
|
13
|
+
try {
|
14
|
+
// Register bindings to every Rails remote element
|
15
|
+
railsAjax.attachAjaxToElements('*[data-remote=true]');
|
16
|
+
var lRootURL = History.getRootUrl();
|
17
|
+
jQuery(window).bind('statechange', function() {
|
18
|
+
try {
|
19
|
+
var lState = History.getState();
|
20
|
+
<%= 'alert(\'[RailsAjax] History statechange triggered #\' + lState.data.id + \' via \' + lState.data.type + \' to \' + lState.url.replace(lRootURL, \'/\') + \' (anchor: \' + lState.data.anchor + \')\');' if (RailsAjax.config.DebugAlerts) %>
|
21
|
+
jQuery.ajax({
|
22
|
+
// TODO (History.js): Remove the anchor attribute when History.js handles anchors correctly.
|
23
|
+
anchor: lState.data.anchor,
|
24
|
+
// Get back all parameters set by Rails' jquery-ujs
|
25
|
+
type: lState.data.type,
|
26
|
+
data: lState.data.data,
|
27
|
+
dataType: lState.data.dataType,
|
28
|
+
crossDomain: lState.data.crossDomain,
|
29
|
+
// Set the URL to query
|
30
|
+
url: lState.url.replace(lRootURL, '/'),
|
31
|
+
// And the callbacks
|
32
|
+
// TODO (History.js): Remove the beforeSend callback when anchors will be handled correctly by History.js
|
33
|
+
beforeSend: function(ioXHR, iSettings) {
|
34
|
+
// Remember the anchor used
|
35
|
+
ioXHR.anchor = iSettings.anchor;
|
36
|
+
},
|
37
|
+
success: function(iData, iStatus, iXHR) {
|
38
|
+
railsAjax.ajaxSuccess(iXHR, iData);
|
39
|
+
},
|
40
|
+
error: function(iXHR, iStatus, iError) {
|
41
|
+
railsAjax.ajaxError(iXHR, iError);
|
42
|
+
}
|
43
|
+
});
|
44
|
+
} catch (iError) {
|
45
|
+
alert('[RailsAjax] Exception in statechange callback: ' + iError.name + ' - ' + iError.message);
|
46
|
+
}
|
47
|
+
});
|
48
|
+
} catch (iError) {
|
49
|
+
alert('[RailsAjax] Exception during railsAjax initialization: ' + iError.name + ' - ' + iError.message);
|
50
|
+
}
|
51
|
+
},
|
52
|
+
|
53
|
+
// Attach Ajax delegations to elements needing them
|
54
|
+
//
|
55
|
+
// Parameters::
|
56
|
+
// * *iCSSSelector* (_String_): CSS selector of elements needing attachment
|
57
|
+
attachAjaxToElements: function(iCSSSelector) {
|
58
|
+
try {
|
59
|
+
<%= 'alert(\'[RailsAjax] Attach Ajax bindings to elements \' + iCSSSelector + \' (\' + jQuery(iCSSSelector).length + \' elements)\');' if (RailsAjax.config.DebugAlerts) %>
|
60
|
+
jQuery(document)
|
61
|
+
.delegate(iCSSSelector, 'ajax:beforeSend', function(iEvent, ioXHR, iSettings) {
|
62
|
+
try {
|
63
|
+
var lThis = jQuery(this);
|
64
|
+
var lURL = ((lThis.is('a')) ? lThis.attr('href') : lThis.attr('action'));
|
65
|
+
<%= 'alert(\'[RailsAjax] Ajax before send. URL=\' + lURL + \' Method=\' + iSettings.type + \' Data=\' + iSettings.data);' if (RailsAjax.config.DebugAlerts) %>
|
66
|
+
var lContinue = true;
|
67
|
+
if (railsAjax.beforeSend != undefined) {
|
68
|
+
try {
|
69
|
+
lContinue = (railsAjax.beforeSend(ioXHR, iSettings) != false);
|
70
|
+
} catch (iUserError) {
|
71
|
+
alert('[RailsAjax] Exception in user callback railsAjax.beforeSend: ' + iUserError.name + ' - ' + iUserError.message);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
<%= 'alert(\'[RailsAjax] Continue on the Ajax load ? \' + lContinue);' if (RailsAjax.config.DebugAlerts) %>
|
75
|
+
if (lContinue) {
|
76
|
+
railsAjax.pushNewState(lURL,
|
77
|
+
{
|
78
|
+
// Replicate the whole Rails' jquery-ujs parameters, as we will need to pass them to the new ajax options object created during onstatechange event.
|
79
|
+
type: iSettings.type,
|
80
|
+
data: iSettings.data,
|
81
|
+
dataType: iSettings.dataType,
|
82
|
+
crossDomain: iSettings.crossDomain
|
83
|
+
},
|
84
|
+
false
|
85
|
+
);
|
86
|
+
}
|
87
|
+
// Cancel AJAX processing right now.
|
88
|
+
// It will be taken care of by the changestate event.
|
89
|
+
return false;
|
90
|
+
} catch (iError) {
|
91
|
+
alert('[RailsAjax] Exception while ajax:beforeSend: ' + iError.name + ' - ' + iError.message);
|
92
|
+
}
|
93
|
+
})
|
94
|
+
} catch (iError) {
|
95
|
+
alert('[RailsAjax] Exception while binding Ajax events to elements ' + iCSSSelector + ': ' + iError.name + ' - ' + iError.message);
|
96
|
+
}
|
97
|
+
},
|
98
|
+
|
99
|
+
// Callback called when Ajax call is successfull
|
100
|
+
//
|
101
|
+
// Parameters::
|
102
|
+
// * *iXHR* (_Object_): The XHR object responsible for the Ajax call
|
103
|
+
// * *iData* (_String_): The received data
|
104
|
+
ajaxSuccess: function(iXHR, iData) {
|
105
|
+
try {
|
106
|
+
<%= 'alert(\'[RailsAjax] Ajax success. Loading data: \' + iData);' if (RailsAjax.config.DebugAlerts) %>
|
107
|
+
|
108
|
+
// 1. Change the window's title if needed
|
109
|
+
if ('page_title' in iData) {
|
110
|
+
document.title = iData.page_title;
|
111
|
+
}
|
112
|
+
|
113
|
+
// 2. Replace HTML data, and execute scripts in the same time
|
114
|
+
jQuery.each(iData.div_contents, function(iCSSSelector, iContent) {
|
115
|
+
// This replaces HTML content and also executes scripts (even document.ready ones)
|
116
|
+
jQuery(iCSSSelector).html(iContent);
|
117
|
+
});
|
118
|
+
|
119
|
+
// 3. Scroll to anchor if needed
|
120
|
+
if (iXHR.anchor) {
|
121
|
+
railsAjax.scrollToAnchor(iXHR.anchor);
|
122
|
+
}
|
123
|
+
|
124
|
+
// 4. For Firefox only, workaround a bug by setting the Favicon
|
125
|
+
if (jQuery.browser.mozilla) {
|
126
|
+
railsAjax.setFavicon();
|
127
|
+
}
|
128
|
+
|
129
|
+
// 5. Execute scripts that were added
|
130
|
+
if ('js_to_execute' in iData) {
|
131
|
+
jQuery.each(iData.js_to_execute, function(iIdx, iJS) {
|
132
|
+
<%= 'alert(\'[RailsAjax] Execute script #\' + iIdx + \':\\n\' + iJS);' if (RailsAjax.config.DebugAlerts) %>
|
133
|
+
try {
|
134
|
+
eval(iJS);
|
135
|
+
} catch (iError) {
|
136
|
+
alert('[RailsAjax] Exception while executing Ajax script: ' + iError.name + ' - ' + iError.message + '\nScript:\n' + iJS);
|
137
|
+
}
|
138
|
+
});
|
139
|
+
}
|
140
|
+
|
141
|
+
// 6. Call user callbacks
|
142
|
+
if (railsAjax.success != undefined) {
|
143
|
+
try {
|
144
|
+
railsAjax.success(iXHR, iData);
|
145
|
+
} catch (iUserError) {
|
146
|
+
alert('[RailsAjax] Exception in user callback railsAjax.success: ' + iUserError.name + ' - ' + iUserError.message);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
if (railsAjax.complete != undefined) {
|
150
|
+
try {
|
151
|
+
railsAjax.complete(iXHR);
|
152
|
+
} catch (iUserError) {
|
153
|
+
alert('[RailsAjax] Exception in user callback railsAjax.complete: ' + iUserError.name + ' - ' + iUserError.message);
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
// 7. Handle redirects
|
158
|
+
if ('redirect_to' in iData) {
|
159
|
+
railsAjax.pushNewState(iData.redirect_to, {}, true);
|
160
|
+
}
|
161
|
+
|
162
|
+
} catch (iError) {
|
163
|
+
alert('[RailsAjax] Exception while Ajax success callback: ' + iError.name + ' - ' + iError.message);
|
164
|
+
}
|
165
|
+
},
|
166
|
+
|
167
|
+
// Callback called when Ajax call has failed
|
168
|
+
//
|
169
|
+
// Parameters::
|
170
|
+
// * *iXHR* (_Object_): The xhr object
|
171
|
+
// * *iError* (_Object_): The error
|
172
|
+
ajaxError: function(iXHR, iError) {
|
173
|
+
if (railsAjax.error != undefined) {
|
174
|
+
try {
|
175
|
+
railsAjax.error(iXHR, iError);
|
176
|
+
} catch (iUserError) {
|
177
|
+
alert('[RailsAjax] Exception in user callback railsAjax.error: ' + iUserError.name + ' - ' + iUserError.message);
|
178
|
+
}
|
179
|
+
}
|
180
|
+
if (railsAjax.complete != undefined) {
|
181
|
+
try {
|
182
|
+
railsAjax.complete(iXHR);
|
183
|
+
} catch (iUserError) {
|
184
|
+
alert('[RailsAjax] Exception in user callback railsAjax.complete: ' + iUserError.name + ' - ' + iUserError.message);
|
185
|
+
}
|
186
|
+
}
|
187
|
+
},
|
188
|
+
|
189
|
+
// Used to identify states in debugging logs
|
190
|
+
<%= 'gStateID: 0,' if (RailsAjax.config.DebugAlerts) %>
|
191
|
+
|
192
|
+
// Push a new History state
|
193
|
+
//
|
194
|
+
// Parameters::
|
195
|
+
// * *iURL* (_String_): The URL to be pushed
|
196
|
+
// * *iData* (_Object_): The state object to store with it
|
197
|
+
// * *iReplaceState* (_Boolean_): Do we replace the current state ?
|
198
|
+
pushNewState: function(iURL, iData, iReplaceState) {
|
199
|
+
try {
|
200
|
+
// Remove the hash if it is present, as otherwise anchorchange is triggered and statechange ignored.
|
201
|
+
// We don't want to handle anchorchange callback as it is unable to get the real History state correctly.
|
202
|
+
// TODO (History.js): Correct bug https://github.com/balupton/history.js/issues/42 and https://github.com/balupton/history.js/issues/173, then remove this special hash and anchor treatment
|
203
|
+
var lSplittedURL = iURL.split('#');
|
204
|
+
var lState = jQuery.extend(
|
205
|
+
{
|
206
|
+
// Used to identify states in debugging logs
|
207
|
+
<%= 'id: railsAjax.gStateID,' if (RailsAjax.config.DebugAlerts) %>
|
208
|
+
anchor: lSplittedURL[1]
|
209
|
+
},
|
210
|
+
iData
|
211
|
+
);
|
212
|
+
if (iReplaceState) {
|
213
|
+
History.replaceState(lState, null, lSplittedURL[0]);
|
214
|
+
} else {
|
215
|
+
History.pushState(lState, null, lSplittedURL[0]);
|
216
|
+
}
|
217
|
+
<%= 'railsAjax.gStateID = railsAjax.gStateID + 1;' if (RailsAjax.config.DebugAlerts) %>
|
218
|
+
} catch (iError) {
|
219
|
+
alert('[RailsAjax] Exception in pushNewState: ' + iError.name + ' - ' + iError.message);
|
220
|
+
}
|
221
|
+
},
|
222
|
+
|
223
|
+
// Scroll the web page to display a given anchor.
|
224
|
+
// An anchor is either a div id, or a named "a"
|
225
|
+
//
|
226
|
+
// Parameters::
|
227
|
+
// * *iAnchor* (_String_): Anchor name
|
228
|
+
scrollToAnchor: function(iAnchor) {
|
229
|
+
var lDivElement = jQuery('div#' + iAnchor)[0]
|
230
|
+
if (lDivElement != undefined) {
|
231
|
+
lDivElement.scrollIntoView(true);
|
232
|
+
} else {
|
233
|
+
var lLstElements = window.document.getElementsByName(iAnchor);
|
234
|
+
if (lLstElements.length > 0) {
|
235
|
+
lLstElements[0].scrollIntoView(true);
|
236
|
+
} else {
|
237
|
+
alert('[RailsAjax] No anchor named ' + iAnchor);
|
238
|
+
}
|
239
|
+
}
|
240
|
+
},
|
241
|
+
|
242
|
+
// Reload the favicon.
|
243
|
+
// This is needed to workaround a Firefox bug: http://kilianvalkhof.com/2010/javascript/the-case-of-the-disappearing-favicon/
|
244
|
+
setFavicon: function() {
|
245
|
+
var link = jQuery('link[type="image/x-icon"]').remove().attr('href');
|
246
|
+
jQuery('<link href="'+ link +'" rel="shortcut icon" type="image/x-icon" />').appendTo('head');
|
247
|
+
}
|
248
|
+
|
249
|
+
};
|
250
|
+
|
251
|
+
// Initialize everything once the DOM is loaded and ready
|
252
|
+
jQuery(document).ready(function(){
|
253
|
+
railsAjax.init();
|
254
|
+
});
|
255
|
+
|
256
|
+
<% end %>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<% if (RailsAjax.config.Enabled) %>
|
2
|
+
|
3
|
+
// Define callbacks used with asynchronous Ajax answers:
|
4
|
+
// railsAjax.beforeSend => railsAjax.success/railsAjax.error => railsAjax.complete
|
5
|
+
// There is no need to declare them if there is no use for them.
|
6
|
+
|
7
|
+
// Callback called before executing an Ajax call.
|
8
|
+
// This callback can return false to cancel the Ajax call.
|
9
|
+
//
|
10
|
+
// Parameters::
|
11
|
+
// * *ioXHR* (_Object_): The XHR object responsible for the Ajax call (can be modified if needed)
|
12
|
+
// * *iSettings* (_Object_): Settings used for the Ajax call
|
13
|
+
// Return::
|
14
|
+
// * _Boolean_: Do we validate the Ajax call ?
|
15
|
+
railsAjax.beforeSend = function(ioXHR, iSettings) {
|
16
|
+
//alert('Going to issue a RailsAjax call');
|
17
|
+
return true;
|
18
|
+
}
|
19
|
+
|
20
|
+
// Callback called when Ajax call is successfull
|
21
|
+
//
|
22
|
+
// Parameters::
|
23
|
+
// * *iXHR* (_Object_): The XHR object responsible for the Ajax call
|
24
|
+
// * *iData* (_String_): The received data
|
25
|
+
railsAjax.success = function(iXHR, iData) {
|
26
|
+
//alert('Successful RailsAjax call');
|
27
|
+
};
|
28
|
+
|
29
|
+
// Callback called when Ajax call has failed
|
30
|
+
//
|
31
|
+
// Parameters::
|
32
|
+
// * *iXHR* (_Object_): The xhr object
|
33
|
+
// * *iError* (_Object_): The error
|
34
|
+
railsAjax.error = function(iXHR, iError) {
|
35
|
+
alert('RailsAjax call failed with error ' + iXHR.status + ' (' + iXHR.statusText + '): ' + iError.name + ' - ' + iError.message);
|
36
|
+
}
|
37
|
+
|
38
|
+
// Callback called when Ajax call is completed (either successful or in error)
|
39
|
+
//
|
40
|
+
// Parameters::
|
41
|
+
// * *iXHR* (_Object_): The xhr object
|
42
|
+
railsAjax.complete = function(iXHR) {
|
43
|
+
//alert('RailsAjax call complete');
|
44
|
+
}
|
45
|
+
|
46
|
+
<% end %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# RailsAjax configuration
|
2
|
+
RailsAjax::configure do
|
3
|
+
|
4
|
+
# Enable or disable RailsAjax.
|
5
|
+
# If disabled, RailsAjax methods will be useless, and corresponding JavaScript will be removed.
|
6
|
+
# When changing this switch, you have to:
|
7
|
+
# * Precompile your assets in production mode
|
8
|
+
# * Restart your server
|
9
|
+
enable true
|
10
|
+
|
11
|
+
# Set the default main container that will receive the result of Ajax requests.
|
12
|
+
# This container will get what is rendered by default when render is called.
|
13
|
+
main_container 'body'
|
14
|
+
|
15
|
+
# Set the containers that will receive Rails' flash messages.
|
16
|
+
# Use these if those containers are part of your layout and will not be refreshed by each Ajax call. In this case RailsAjax will still refresh them.
|
17
|
+
# If not set for a given flash message type, you have to return the corresponding flash yourself in each Ajax's response.
|
18
|
+
flash_containers(
|
19
|
+
:notice => '#FlashNotice',
|
20
|
+
:error => '#FlashError',
|
21
|
+
:alert => '#FlashAlert'
|
22
|
+
)
|
23
|
+
|
24
|
+
# Activate debugging alerts in the JS code.
|
25
|
+
# This will pop plenty of JS dialogs at each stage of RailsAjax calls, useful to better debug what is going wrong.
|
26
|
+
# When changing this switch, you have to:
|
27
|
+
# * Precompile your assets in production mode
|
28
|
+
# * Restart your server
|
29
|
+
debug_alerts false
|
30
|
+
|
31
|
+
end
|
data/lib/rails-ajax.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module RailsAjax
|
7
|
+
|
8
|
+
# Give the root directory of the RailsAjax installation
|
9
|
+
#
|
10
|
+
# Return::
|
11
|
+
# * _String_: RailsAjax root directory
|
12
|
+
def self.root
|
13
|
+
return File.expand_path("#{File.dirname(__FILE__)}/..")
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'rails-ajax/railtie'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
# Alias standard methods, and add new ones to adapt them to AJAX calls
|
7
|
+
module ActionController
|
8
|
+
|
9
|
+
class Base
|
10
|
+
|
11
|
+
include RailsAjax::Controller
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module ActionView
|
7
|
+
|
8
|
+
class Base
|
9
|
+
|
10
|
+
include RailsAjax::UrlHelper
|
11
|
+
include RailsAjax::FormTagHelper
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module RailsAjax
|
7
|
+
|
8
|
+
# Class used to configure and store the configuration of RailsAjax
|
9
|
+
class Configuration
|
10
|
+
|
11
|
+
# Indicate if RailsAjax is enabled
|
12
|
+
#
|
13
|
+
# _Boolean_
|
14
|
+
attr_reader :Enabled
|
15
|
+
|
16
|
+
# The main container
|
17
|
+
#
|
18
|
+
# _String_
|
19
|
+
attr_reader :MainContainer
|
20
|
+
|
21
|
+
# The flash containers
|
22
|
+
#
|
23
|
+
# <em>map< Symbol, String ></em>
|
24
|
+
attr_reader :FlashContainers
|
25
|
+
|
26
|
+
# Debug alerts ?
|
27
|
+
#
|
28
|
+
# _Boolean_
|
29
|
+
attr_reader :DebugAlerts
|
30
|
+
|
31
|
+
# Constructor
|
32
|
+
def initialize
|
33
|
+
# Set default values here
|
34
|
+
@Enabled = true
|
35
|
+
@MainContainer = 'body'
|
36
|
+
@FlashContainers = {}
|
37
|
+
@DebugAlerts = false
|
38
|
+
end
|
39
|
+
|
40
|
+
# Do we activate RailsAjax ?
|
41
|
+
#
|
42
|
+
# Parameters::
|
43
|
+
# * *iSwitch* (_Boolean_): Do we activate RailsAjax ?
|
44
|
+
def enable(iSwitch)
|
45
|
+
@Enabled = iSwitch
|
46
|
+
end
|
47
|
+
|
48
|
+
# Define the main container
|
49
|
+
#
|
50
|
+
# Parameters::
|
51
|
+
# * *iSelector* (_String_): Selector used to identify the container
|
52
|
+
def main_container(iSelector)
|
53
|
+
@MainContainer = iSelector
|
54
|
+
end
|
55
|
+
|
56
|
+
# Define the flash containers
|
57
|
+
#
|
58
|
+
# Parameters::
|
59
|
+
# * *iMapSelectors* (<em>map<Symbol,String></em>): The map of selectors, per flash message type (:alert, :notice...)
|
60
|
+
def flash_containers(iMapSelectors)
|
61
|
+
@FlashContainers.merge!(iMapSelectors)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Do we activate debugging alerts ?
|
65
|
+
#
|
66
|
+
# Parameters::
|
67
|
+
# * *iSwitch* (_Boolean_): Do we activate debugging alerts ?
|
68
|
+
def debug_alerts(iSwitch)
|
69
|
+
@DebugAlerts = iSwitch
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module RailsAjax
|
7
|
+
|
8
|
+
# Module defining new methods that will be part of every controller
|
9
|
+
module Controller
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
# Render
|
14
|
+
# Adapt to AJAX calls, by returning the following JSON object that will be interpreted by client side JavaScript.
|
15
|
+
def render(*iArgs, &iBlock)
|
16
|
+
if (RailsAjax.config.Enabled)
|
17
|
+
lArgs = _normalize_args(*iArgs, &iBlock)
|
18
|
+
if ((request.xhr?) and
|
19
|
+
(!lArgs.has_key?(:partial)) and
|
20
|
+
(!lArgs.has_key?(:layout)))
|
21
|
+
logger.debug "[RailsAjax] render: iArgs=#{iArgs.inspect} iBlock?#{iBlock != nil} flash=#{flash.inspect} | Normalized arguments: #{lArgs.inspect}"
|
22
|
+
|
23
|
+
# If we have a redirection, use redirect_to
|
24
|
+
if (lArgs[:location] == nil)
|
25
|
+
# Complete arguments if needed
|
26
|
+
# We don't want a special layout for Ajax requests: this was asked using AJAX for a page to be displayed in the main content
|
27
|
+
lArgs[:layout] = false
|
28
|
+
|
29
|
+
# Render
|
30
|
+
lMainPage = nil
|
31
|
+
if (iBlock == nil)
|
32
|
+
lMainPage = render_to_string(lArgs)
|
33
|
+
else
|
34
|
+
lMainPage = render_to_string(lArgs) do
|
35
|
+
iBlock.call
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Send JSON result
|
40
|
+
# Use 'application/json'
|
41
|
+
self.content_type = 'application/json'
|
42
|
+
self.response_body = get_json_response(
|
43
|
+
:css_to_refresh => {
|
44
|
+
RailsAjax::config.MainContainer => lMainPage
|
45
|
+
}
|
46
|
+
).to_json
|
47
|
+
elsif (lArgs[:status] == nil)
|
48
|
+
redirect_to lArgs[:location]
|
49
|
+
else
|
50
|
+
redirect_to lArgs[:location], lArgs[:status]
|
51
|
+
end
|
52
|
+
|
53
|
+
elsif (iBlock == nil)
|
54
|
+
super(*iArgs)
|
55
|
+
else
|
56
|
+
super(*iArgs) do
|
57
|
+
iBlock.call
|
58
|
+
end
|
59
|
+
end
|
60
|
+
elsif (iBlock == nil)
|
61
|
+
super(*iArgs)
|
62
|
+
else
|
63
|
+
super(*iArgs) do
|
64
|
+
iBlock.call
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
# Render a redirection
|
71
|
+
# Adapt to AJAX calls
|
72
|
+
def redirect_to(iOptions = {}, iResponseStatus = {})
|
73
|
+
if (RailsAjax.config.Enabled and request.xhr?)
|
74
|
+
logger.debug "[RailsAjax] redirect_to: iOptions=#{iOptions.inspect} iResponseStatus=#{iResponseStatus.inspect}"
|
75
|
+
# Use 'application/json'
|
76
|
+
self.content_type = 'application/json'
|
77
|
+
self.response_body = get_json_response(
|
78
|
+
:redirect_to => url_for(iOptions)
|
79
|
+
).to_json
|
80
|
+
else
|
81
|
+
super(iOptions, iResponseStatus)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
# Mark given DOM elements (selected using a CSS selector) to be refreshed with a partial's content
|
88
|
+
#
|
89
|
+
# Parameters::
|
90
|
+
# * *iCSSSelector* (_String_): The CSS selector to be used to refresh elements
|
91
|
+
# * *iPartialName* (_String_): Name of the partial to be used to refresh these elements
|
92
|
+
def refresh_dom_with_partial(iCSSSelector, iPartialName)
|
93
|
+
if RailsAjax.config.Enabled
|
94
|
+
logger.debug "[RailsAjax] Mark partial #{iPartialName} to be refreshed in #{iCSSSelector}"
|
95
|
+
if (defined?(@PartialsToRefresh) == nil)
|
96
|
+
@PartialsToRefresh = {}
|
97
|
+
end
|
98
|
+
@PartialsToRefresh[iCSSSelector] = iPartialName
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Add a Javascript to be executed just after the Ajax call
|
103
|
+
# This is used to execute special Ajax handling that is not needed in case the same request is made without Ajax
|
104
|
+
#
|
105
|
+
# Parameters::
|
106
|
+
# * *iJS* (_String_): Javascript to be executed
|
107
|
+
def execute_javascript(iJS)
|
108
|
+
if RailsAjax.config.Enabled
|
109
|
+
logger.debug "[RailsAjax] Add javascript to be executed: #{iJS[0..255]}"
|
110
|
+
if (defined?(@JSToExecute) == nil)
|
111
|
+
@JSToExecute = []
|
112
|
+
end
|
113
|
+
@JSToExecute << iJS
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# Get the JSON object that will be sent to an Ajax request.
|
120
|
+
# Include the partials marked to be refreshed.
|
121
|
+
# Include Javascripts to be executed
|
122
|
+
# Structure of the JSON object:
|
123
|
+
# * *:div_contents* (<em>map<String,String></em>): The content of DOM elements to be replaced, indexed by CSS selector.
|
124
|
+
# * *:page_title* (_String_): The new page title
|
125
|
+
# * *:redirect_to* (_String_): Page to be redirected to
|
126
|
+
# * *:js_to_execute* (<em>list<String></em>): Javascripts to be executed
|
127
|
+
#
|
128
|
+
# Parameters::
|
129
|
+
# * *iOptions* (<em>map<Symbol,Object></em>): Options [optional = {}]
|
130
|
+
# * *:css_to_refresh* (<em>map<String,String></em>): List of CSS to be refreshed, along with their HTML code [optional = {}]
|
131
|
+
# * *:redirect_to* (_String_): URL to redirect to [optional = nil]
|
132
|
+
# Return::
|
133
|
+
# * <em>map<Object,Object></em>: The corresponding JSON data
|
134
|
+
def get_json_response(iOptions = {})
|
135
|
+
rJSON = {}
|
136
|
+
|
137
|
+
lDivContents = iOptions[:css_to_refresh] || {}
|
138
|
+
if (defined?(@PartialsToRefresh) != nil)
|
139
|
+
@PartialsToRefresh.each do |iCSSSelector, iPartialName|
|
140
|
+
lDivContents[iCSSSelector] = render_to_string(:partial => iPartialName)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
RailsAjax::config.FlashContainers.each do |iSymFlashType, iSelector|
|
144
|
+
lDivContents[iSelector] = flash[iSymFlashType]
|
145
|
+
end
|
146
|
+
rJSON[:js_to_execute] = @JSToExecute if (defined?(@JSToExecute) != nil)
|
147
|
+
rJSON[:div_contents] = lDivContents
|
148
|
+
rJSON[:redirect_to] = iOptions[:redirect_to] if (iOptions[:redirect_to] != nil)
|
149
|
+
|
150
|
+
return rJSON
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module RailsAjax
|
7
|
+
|
8
|
+
# Module defining methods to include in ActionView::Helpers::FormTagHelper
|
9
|
+
module FormTagHelper
|
10
|
+
|
11
|
+
# Replaces form_tag with an Ajax updated version
|
12
|
+
def form_tag(url_for_options = {}, options = {}, &block)
|
13
|
+
if (RailsAjax.config.Enabled and
|
14
|
+
(options[:target] == nil))
|
15
|
+
if block_given?
|
16
|
+
return super(url_for_options, options.merge({:remote => true})) do
|
17
|
+
block.call
|
18
|
+
end
|
19
|
+
else
|
20
|
+
return super(url_for_options, options.merge({:remote => true}))
|
21
|
+
end
|
22
|
+
elsif block_given?
|
23
|
+
return super(url_for_options, options) do
|
24
|
+
block.call
|
25
|
+
end
|
26
|
+
else
|
27
|
+
return super(url_for_options, options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module RailsAjax
|
7
|
+
|
8
|
+
# The configuration
|
9
|
+
# <em>RailsAjax::Configuration</em>
|
10
|
+
@@Configuration = RailsAjax::Configuration.new
|
11
|
+
|
12
|
+
# Give access to the configuration
|
13
|
+
#
|
14
|
+
# Return::
|
15
|
+
# * <em>RailsAjax::Configuration</em>: The RailsAjax configuration
|
16
|
+
def self.config
|
17
|
+
return @@Configuration
|
18
|
+
end
|
19
|
+
|
20
|
+
# Configure RailsAjax
|
21
|
+
#
|
22
|
+
# Parameters::
|
23
|
+
# * *iProcConfig* (_CodeBlock_): Block called that will contain all configuration directives
|
24
|
+
def self.configure(&iProcConfig)
|
25
|
+
@@Configuration.instance_eval(&iProcConfig)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module RailsAjax
|
7
|
+
|
8
|
+
# Class defining how Rails-Ajax is plugged into Rails
|
9
|
+
class Railtie < Rails::Railtie
|
10
|
+
|
11
|
+
# Define Rake tasks
|
12
|
+
rake_tasks do
|
13
|
+
load "#{RailsAjax.root}/tasks/rails-ajax_tasks.rake"
|
14
|
+
end
|
15
|
+
|
16
|
+
initializer :'rails-ajax.initialize' do |ioApp|
|
17
|
+
# Require all files
|
18
|
+
require 'rails-ajax/configuration'
|
19
|
+
require 'rails-ajax/rails-ajax'
|
20
|
+
require 'rails-ajax/controller'
|
21
|
+
require 'rails-ajax/form_tag_helper'
|
22
|
+
require 'rails-ajax/url_helper'
|
23
|
+
require 'rails-ajax/action_controller/base'
|
24
|
+
require 'rails-ajax/action_view/base'
|
25
|
+
# Add a new assets path for javascript
|
26
|
+
ioApp.config.assets.paths << "#{RailsAjax.root}/assets/javascripts"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module RailsAjax
|
7
|
+
|
8
|
+
# Module defining methods to include in ActionView::Helpers::FormHelper
|
9
|
+
module UrlHelper
|
10
|
+
|
11
|
+
# Adapt link_to method to handle Ajax queries automatically
|
12
|
+
def link_to(*args, &block)
|
13
|
+
if (RailsAjax.config.Enabled)
|
14
|
+
lName = args.first
|
15
|
+
lOptions = args.second || {}
|
16
|
+
lHTMLOptions = args.third || {}
|
17
|
+
if (lHTMLOptions[:target] == nil)
|
18
|
+
if block_given?
|
19
|
+
return super(lName, lOptions, lHTMLOptions.merge({:remote => true})) do
|
20
|
+
block.call
|
21
|
+
end
|
22
|
+
else
|
23
|
+
return super(lName, lOptions, lHTMLOptions.merge({:remote => true}))
|
24
|
+
end
|
25
|
+
elsif block_given?
|
26
|
+
# It is specified to open the link in another frame. Don't use AJAX.
|
27
|
+
return super(*args) do
|
28
|
+
block.call
|
29
|
+
end
|
30
|
+
else
|
31
|
+
return super(*args)
|
32
|
+
end
|
33
|
+
elsif block_given?
|
34
|
+
return super(*args) do
|
35
|
+
block.call
|
36
|
+
end
|
37
|
+
else
|
38
|
+
return super(*args)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (Muriel@X-Aeon.com)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
namespace :'rails-ajax' do
|
7
|
+
|
8
|
+
# Copy a file if it does not exist from RailsAjax root path /gen to Rails root path
|
9
|
+
#
|
10
|
+
# Parameters::
|
11
|
+
# * *iFileName* (_String_): The file name
|
12
|
+
def copy_file_unless_exists(iFileName)
|
13
|
+
lDstFileName = File.join(Rails.root, iFileName)
|
14
|
+
if (File.exist?(lDstFileName))
|
15
|
+
puts "File #{lDstFileName} already exists. Will not overwrite."
|
16
|
+
else
|
17
|
+
puts "Creating file #{lDstFileName}."
|
18
|
+
FileUtils.mkdir_p(File.dirname(lDstFileName))
|
19
|
+
FileUtils.cp(File.join("#{RailsAjax.root}/gen", iFileName), lDstFileName)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Install required Rails Ajax files. Existing files will not be overwritten."
|
24
|
+
task :install do
|
25
|
+
copy_file_unless_exists('app/assets/javascripts/RailsAjax-Config.js.erb')
|
26
|
+
copy_file_unless_exists('config/initializers/rails-ajax-config.rb')
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails-ajax
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.20120706
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Muriel Salvan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-06 00:00:00.000000000Z
|
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: 2.3.1
|
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: 2.3.1
|
30
|
+
description: Add Ajax capabilities to Rails websites, with minimal code changes. Supports
|
31
|
+
history, bookmarking, partial refreshes, Rails flashes, user callbacks, scripts
|
32
|
+
execution, redirections. Built upon Rails-UJS and jQuery.
|
33
|
+
email: muriel@x-aeon.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- assets/javascripts/jquery.history.js
|
39
|
+
- assets/javascripts/jquery.rails-ajax.js.erb
|
40
|
+
- AUTHORS
|
41
|
+
- ChangeLog
|
42
|
+
- Credits
|
43
|
+
- Gemfile
|
44
|
+
- Gemfile.lock
|
45
|
+
- gen/app/assets/javascripts/RailsAjax-Config.js.erb
|
46
|
+
- gen/config/initializers/rails-ajax-config.rb
|
47
|
+
- lib/rails-ajax/action_controller/base.rb
|
48
|
+
- lib/rails-ajax/action_view/base.rb
|
49
|
+
- lib/rails-ajax/configuration.rb
|
50
|
+
- lib/rails-ajax/controller.rb
|
51
|
+
- lib/rails-ajax/form_tag_helper.rb
|
52
|
+
- lib/rails-ajax/rails-ajax.rb
|
53
|
+
- lib/rails-ajax/railtie.rb
|
54
|
+
- lib/rails-ajax/url_helper.rb
|
55
|
+
- lib/rails-ajax.rb
|
56
|
+
- LICENSE
|
57
|
+
- Rakefile
|
58
|
+
- README
|
59
|
+
- ReleaseInfo
|
60
|
+
- tasks/rails-ajax_tasks.rake
|
61
|
+
homepage: http://rails-ajax.sourceforge.net
|
62
|
+
licenses: []
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project: rails-ajax
|
81
|
+
rubygems_version: 1.8.20
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: Add Ajax capabilities to Rails websites with history, bookmarking, partial
|
85
|
+
refreshes, Rails flashes, user callbacks, scripts execution, redirections.
|
86
|
+
test_files: []
|