Commit d4faecd1b9164c86146c2a5ea235c2540ceeab46
1 parent
509aeab0
Exists in
master
and in
27 other branches
rails3: development + packaging updates
Some specific points: - ./script/quick-start not works from start to end on a clean Debian wheezy system - Gemfile: remove checking for programs since the Gemfile is not really the right place to do this - Gemfile.lock: lock gem versions against Debian wheezy. This assumes package versions in Debian wheezy + some backported packages available at http://people.debian.org/~terceiro/noosfero-wheezy-backports/ - db:data:minimal: add an explicit contact email to the new environment. This fixes a long standing issue: when installing Noosfero on a brand new system, exim MTA will choke on a malformed sender address, and abort the entire installation. - added a simple Vagrantfile for development purposes Pending: - provide proper backports for packages and drop the temporary http://people.debian.org/~terceiro/noosfero-wheezy-backports/
Showing
23 changed files
with
1005 additions
and
81 deletions
Show diff stats
Gemfile
... | ... | @@ -3,11 +3,18 @@ gem 'rails' |
3 | 3 | gem 'fast_gettext' |
4 | 4 | gem 'acts-as-taggable-on' |
5 | 5 | gem 'prototype-rails' |
6 | -gem 'prototype_legacy_helper', '0.0.0', :git => 'http://git.github.com/rails/prototype_legacy_helper.git' | |
6 | +gem 'prototype_legacy_helper', '0.0.0', :path => 'vendor/prototype_legacy_helper' | |
7 | 7 | gem 'rails_autolink' |
8 | 8 | gem 'pg' |
9 | - | |
10 | -# TODO needs a rebuild diff-lcs wrt wheezy | |
9 | +gem 'rmagick' | |
10 | +gem 'RedCloth' | |
11 | +gem 'will_paginate' | |
12 | +gem 'ruby-feedparser' | |
13 | +gem 'daemons' | |
14 | +gem 'thin' | |
15 | +gem 'hpricot' | |
16 | +gem 'nokogiri' | |
17 | +gem 'rake', :require => false | |
11 | 18 | |
12 | 19 | # FIXME list here all actual dependencies (i.e. the ones in debian/control), |
13 | 20 | # with their GEM names (not the Debian package names) |
... | ... | @@ -35,12 +42,3 @@ Dir.glob(File.join('config', 'plugins', '*')).each do |plugin| |
35 | 42 | plugin_gemfile = File.join(plugin, 'Gemfile') |
36 | 43 | eval File.read(plugin_gemfile) if File.exists?(plugin_gemfile) |
37 | 44 | end |
38 | - | |
39 | -def program(name) | |
40 | - unless system("which #{name} > /dev/null") | |
41 | - puts "W: Program #{name} is needed, but was not found in your PATH" | |
42 | - end | |
43 | -end | |
44 | - | |
45 | -program 'java' | |
46 | -program 'firefox' | ... | ... |
Gemfile.lock
1 | -GIT | |
2 | - remote: http://git.github.com/rails/prototype_legacy_helper.git | |
3 | - revision: a2cd95c3e3c1a4f7a9566efdab5ce59c886cb05f | |
1 | +PATH | |
2 | + remote: vendor/prototype_legacy_helper | |
4 | 3 | specs: |
5 | 4 | prototype_legacy_helper (0.0.0) |
6 | 5 | |
7 | 6 | GEM |
8 | 7 | remote: https://rubygems.org/ |
9 | 8 | specs: |
9 | + RedCloth (4.2.9) | |
10 | 10 | actionmailer (3.2.6) |
11 | 11 | actionpack (= 3.2.6) |
12 | 12 | mail (~> 2.4.4) |
... | ... | @@ -34,49 +34,51 @@ GEM |
34 | 34 | activesupport (3.2.6) |
35 | 35 | i18n (~> 0.6) |
36 | 36 | multi_json (~> 1.0) |
37 | - acts-as-taggable-on (3.0.1) | |
37 | + acts-as-taggable-on (3.0.2) | |
38 | 38 | rails (>= 3, < 5) |
39 | 39 | arel (3.0.2) |
40 | 40 | builder (3.0.0) |
41 | - capybara (2.2.1) | |
41 | + capybara (2.1.0) | |
42 | 42 | mime-types (>= 1.16) |
43 | 43 | nokogiri (>= 1.3.3) |
44 | 44 | rack (>= 1.0.0) |
45 | 45 | rack-test (>= 0.5.4) |
46 | 46 | xpath (~> 2.0) |
47 | - childprocess (0.4.0) | |
48 | - ffi (~> 1.0, >= 1.0.11) | |
49 | - cucumber (1.3.2) | |
47 | + childprocess (0.3.3) | |
48 | + ffi (~> 1.0.6) | |
49 | + cucumber (1.0.6) | |
50 | 50 | builder (>= 2.1.2) |
51 | - diff-lcs (>= 1.1.3) | |
52 | - gherkin (~> 2.12.0) | |
53 | - multi_json (~> 1.3) | |
54 | - cucumber-rails (1.4.0) | |
55 | - capybara (>= 1.1.2) | |
56 | - cucumber (>= 1.2.0) | |
51 | + diff-lcs (>= 1.1.2) | |
52 | + gherkin (~> 2.4.18) | |
53 | + json (>= 1.4.6) | |
54 | + term-ansicolor (>= 1.0.6) | |
55 | + cucumber-rails (1.0.6) | |
56 | + capybara (>= 1.1.1) | |
57 | + cucumber (>= 1.0.6) | |
57 | 58 | nokogiri (>= 1.5.0) |
58 | - rails (>= 3.0.0) | |
59 | + daemons (1.1.5) | |
59 | 60 | dalli (2.7.0) |
60 | 61 | database_cleaner (1.2.0) |
61 | - diff-lcs (1.2.5) | |
62 | + diff-lcs (1.1.3) | |
62 | 63 | erubis (2.7.0) |
64 | + eventmachine (0.12.11) | |
63 | 65 | fast_gettext (0.6.8) |
64 | - ffi (1.9.3) | |
65 | - gherkin (2.12.2) | |
66 | - multi_json (~> 1.3) | |
66 | + ffi (1.0.11) | |
67 | + gherkin (2.4.21) | |
68 | + json (>= 1.4.6) | |
67 | 69 | hike (1.2.1) |
70 | + hpricot (0.8.6) | |
68 | 71 | i18n (0.6.0) |
69 | 72 | journey (1.0.3) |
73 | + json (1.7.3) | |
70 | 74 | mail (2.4.4) |
71 | 75 | i18n (>= 0.4.0) |
72 | 76 | mime-types (~> 1.16) |
73 | 77 | treetop (~> 1.4.8) |
74 | 78 | mime-types (1.19) |
75 | - mini_portile (0.5.2) | |
76 | 79 | multi_json (1.3.6) |
77 | - nokogiri (1.6.1) | |
78 | - mini_portile (~> 0.5.0) | |
79 | - pg (0.17.1) | |
80 | + nokogiri (1.5.5) | |
81 | + pg (0.13.2) | |
80 | 82 | polyglot (0.3.3) |
81 | 83 | prototype-rails (3.2.1) |
82 | 84 | rails (~> 3.2) |
... | ... | @@ -106,23 +108,22 @@ GEM |
106 | 108 | thor (>= 0.14.6, < 2.0) |
107 | 109 | rake (0.9.2.2) |
108 | 110 | rdoc (3.9.4) |
109 | - rspec (2.14.1) | |
110 | - rspec-core (~> 2.14.0) | |
111 | - rspec-expectations (~> 2.14.0) | |
112 | - rspec-mocks (~> 2.14.0) | |
113 | - rspec-core (2.14.7) | |
114 | - rspec-expectations (2.14.5) | |
115 | - diff-lcs (>= 1.1.3, < 2.0) | |
116 | - rspec-mocks (2.14.5) | |
117 | - rspec-rails (2.14.1) | |
111 | + rmagick (2.13.1) | |
112 | + rspec (2.10.0) | |
113 | + rspec-core (~> 2.10.0) | |
114 | + rspec-expectations (~> 2.10.0) | |
115 | + rspec-mocks (~> 2.10.0) | |
116 | + rspec-core (2.10.1) | |
117 | + rspec-expectations (2.10.0) | |
118 | + diff-lcs (~> 1.1.3) | |
119 | + rspec-mocks (2.10.1) | |
120 | + rspec-rails (2.10.1) | |
118 | 121 | actionpack (>= 3.0) |
119 | - activemodel (>= 3.0) | |
120 | 122 | activesupport (>= 3.0) |
121 | 123 | railties (>= 3.0) |
122 | - rspec-core (~> 2.14.0) | |
123 | - rspec-expectations (~> 2.14.0) | |
124 | - rspec-mocks (~> 2.14.0) | |
125 | - rubyzip (1.1.0) | |
124 | + rspec (~> 2.10.0) | |
125 | + ruby-feedparser (0.7) | |
126 | + rubyzip (1.1.2) | |
126 | 127 | selenium-webdriver (2.39.0) |
127 | 128 | childprocess (>= 0.2.5) |
128 | 129 | multi_json (~> 1.0) |
... | ... | @@ -133,6 +134,11 @@ GEM |
133 | 134 | multi_json (~> 1.0) |
134 | 135 | rack (~> 1.0) |
135 | 136 | tilt (~> 1.1, != 1.3.0) |
137 | + term-ansicolor (1.0.7) | |
138 | + thin (1.3.1) | |
139 | + daemons (>= 1.0.9) | |
140 | + eventmachine (>= 0.12.6) | |
141 | + rack (>= 1.0.0) | |
136 | 142 | thor (0.15.3) |
137 | 143 | tilt (1.3.3) |
138 | 144 | treetop (1.4.10) |
... | ... | @@ -140,6 +146,7 @@ GEM |
140 | 146 | polyglot (>= 0.3.1) |
141 | 147 | tzinfo (0.3.33) |
142 | 148 | websocket (1.0.7) |
149 | + will_paginate (3.0.3) | |
143 | 150 | xpath (2.0.0) |
144 | 151 | nokogiri (~> 1.3) |
145 | 152 | |
... | ... | @@ -147,19 +154,27 @@ PLATFORMS |
147 | 154 | ruby |
148 | 155 | |
149 | 156 | DEPENDENCIES |
157 | + RedCloth | |
150 | 158 | acts-as-taggable-on |
151 | 159 | capybara |
152 | 160 | cucumber |
153 | 161 | cucumber-rails |
162 | + daemons | |
154 | 163 | dalli |
155 | 164 | database_cleaner |
156 | 165 | fast_gettext |
166 | + hpricot | |
167 | + nokogiri | |
157 | 168 | pg |
158 | 169 | prototype-rails |
159 | 170 | prototype_legacy_helper (= 0.0.0)! |
160 | 171 | rails |
161 | 172 | rails_autolink |
162 | 173 | rake |
174 | + rmagick | |
163 | 175 | rspec |
164 | 176 | rspec-rails |
177 | + ruby-feedparser | |
165 | 178 | selenium-webdriver |
179 | + thin | |
180 | + will_paginate | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +# -*- mode: ruby -*- | |
2 | +# vi: set ft=ruby : | |
3 | + | |
4 | +VAGRANTFILE_API_VERSION = "2" | |
5 | +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| | |
6 | + config.vm.box = "debian-wheezy" | |
7 | + config.vm.network :forwarded_port, host: 3000, guest: 3000 | |
8 | + config.vm.provision :shell do |shell| | |
9 | + shell.inline = 'su vagrant -c /vagrant/script/vagrant' | |
10 | + end | |
11 | +end | ... | ... |
config/initializers/01_load_config.rb
debian/control
... | ... | @@ -10,9 +10,19 @@ Build-Depends: |
10 | 10 | ruby-sqlite3, |
11 | 11 | rake, |
12 | 12 | rails3 (>= 3.2.6-1~), |
13 | + ruby-rspec, | |
14 | + ruby-rspec-rails, | |
13 | 15 | ruby-will-paginate, |
16 | + cucumber, | |
17 | + ruby-cucumber-rails, | |
18 | + ruby-capybara, | |
19 | + ruby-database-cleaner, | |
20 | + ruby-selenium-webdriver, | |
21 | + ruby-tidy, | |
22 | + ruby-mocha, | |
23 | + imagemagick, | |
24 | + xvfb, | |
14 | 25 | tango-icon-theme, |
15 | - rcov | |
16 | 26 | Standards-Version: 3.8.4 |
17 | 27 | Homepage: http://noosfero.org/ |
18 | 28 | Vcs-Git: git://git.colivre.coop.br/noosfero.git |
... | ... | @@ -25,8 +35,8 @@ Depends: |
25 | 35 | ruby, |
26 | 36 | ruby1.9.3, |
27 | 37 | rake, |
38 | + ruby-dalli, | |
28 | 39 | ruby-fast-gettext, |
29 | - ruby-sqlite3, | |
30 | 40 | ruby-pg, |
31 | 41 | ruby-rmagick, |
32 | 42 | ruby-redcloth, |
... | ... | @@ -34,12 +44,15 @@ Depends: |
34 | 44 | iso-codes, |
35 | 45 | ruby-feedparser, |
36 | 46 | ruby-daemons, |
37 | - rcov, | |
38 | 47 | thin, |
39 | 48 | tango-icon-theme, |
40 | 49 | ruby-hpricot, |
41 | 50 | ruby-nokogiri, |
51 | + ruby-acts-as-taggable-on, | |
52 | + ruby-prototype-rails, | |
53 | + ruby-rails-autolink, | |
42 | 54 | memcached, |
55 | + ruby-memcache-client, | |
43 | 56 | debconf, |
44 | 57 | dbconfig-common, |
45 | 58 | adduser, | ... | ... |
debian/noosfero.dirs
debian/noosfero.install
... | ... | @@ -5,18 +5,20 @@ lib usr/share/noosfero |
5 | 5 | script usr/share/noosfero |
6 | 6 | util usr/share/noosfero |
7 | 7 | Rakefile usr/share/noosfero |
8 | -vendor/cardmagic-contacts-f66219e6589ccaf3ab9e3574fdd41225d0dd5073 usr/share/noosfero/vendor | |
9 | -vendor/gdata-1.1.1 usr/share/noosfero/vendor | |
10 | -vendor/plugins usr/share/noosfero/vendor | |
11 | -vendor/terceiro-fast_gettext-fe7bb09e30f7b1b5876a3b7a18fe8a254c6f59cb usr/share/noosfero/vendor | |
12 | -vendor/ezcrypto-0.7.2 usr/share/noosfero/vendor | |
8 | +vendor usr/share/noosfero | |
13 | 9 | |
10 | +Gemfile usr/share/noosfero | |
11 | +Gemfile.lock usr/share/noosfero | |
12 | +debian/bundle/config usr/share/noosfero/.bundle | |
13 | + | |
14 | +config/application.rb usr/share/noosfero/config | |
14 | 15 | config/boot.rb usr/share/noosfero/config |
15 | 16 | config/environment.rb usr/share/noosfero/config |
16 | 17 | config/environments usr/share/noosfero/config |
17 | 18 | config/initializers usr/share/noosfero/config |
18 | 19 | config/routes.rb usr/share/noosfero/config |
19 | 20 | config/locales usr/share/noosfero/config |
21 | +config.ru usr/share/noosfero | |
20 | 22 | |
21 | 23 | plugins usr/share/noosfero |
22 | 24 | ... | ... |
gitignore.example
lib/tasks/data.rake
1 | 1 | namespace :db do |
2 | 2 | namespace :data do |
3 | 3 | task :minimal do |
4 | - sh 'rails', 'runner', "Environment.create!(:name => 'Noosfero', :is_default => true)" | |
4 | + sh 'rails', 'runner', "Environment.create!(:name => 'Noosfero', :contact_email => 'noosfero@localhost.localdomain', :is_default => true)" | |
5 | 5 | unless ENV['NOOSFERO_DOMAIN'].blank? |
6 | 6 | sh 'rails', 'runner', "Environment.default.domains << Domain.new(:name => ENV['NOOSFERO_DOMAIN'])" |
7 | 7 | end | ... | ... |
lib/tasks/doc.rake
... | ... | @@ -41,8 +41,8 @@ namespace :noosfero do |
41 | 41 | toc_sections.each do |toc| |
42 | 42 | section_topics = Dir.glob(File.dirname(toc) + '/*.textile').map {|item| item.sub('.textile', '.en.xhtml') }.reject {|item| ['index.en.xhtml', 'toc.en.xhtml' ].include?(File.basename(item))} |
43 | 43 | file toc => section_topics do |t| |
44 | - require 'app/models/doc_item' | |
45 | - require 'app/models/doc_topic' | |
44 | + require './app/models/doc_item' | |
45 | + require './app/models/doc_topic' | |
46 | 46 | begin |
47 | 47 | File.open(toc, 'w') do |output_file| |
48 | 48 | section = File.basename(File.dirname(toc)) |
... | ... | @@ -67,8 +67,9 @@ namespace :noosfero do |
67 | 67 | |
68 | 68 | top_level_toc = 'doc/noosfero/toc.en.xhtml' |
69 | 69 | file top_level_toc => index_sections do |
70 | - require 'app/models/doc_item' | |
71 | - require 'app/models/doc_topic' | |
70 | + $LOAD_PATH << '.' | |
71 | + require './app/models/doc_item' | |
72 | + require './app/models/doc_topic' | |
72 | 73 | begin |
73 | 74 | File.open(top_level_toc, 'w') do |output_file| |
74 | 75 | output_file.puts "<!-- THIS FILE IS AUTOGENERATED. DO NOT EDIT -->" | ... | ... |
lib/tasks/gettext.rake
... | ... | @@ -6,7 +6,7 @@ makemo_stamp = 'tmp/makemo.stamp' |
6 | 6 | desc "Create mo-files for L10n" |
7 | 7 | task :makemo => makemo_stamp |
8 | 8 | file makemo_stamp => Dir.glob('po/*/noosfero.po') do |
9 | - ruby '-rconfig/boot -e \'require "gettext"; require "gettext/utils"; GetText.create_mofiles(true, "po", "locale")\' 2>/dev/null' | |
9 | + ruby '-I. -rconfig/boot -e \'require "gettext"; require "gettext/utils"; GetText.create_mofiles(true, "po", "locale")\'' | |
10 | 10 | Rake::Task['symlinkmo'].invoke |
11 | 11 | FileUtils.mkdir_p 'tmp' |
12 | 12 | FileUtils.touch makemo_stamp | ... | ... |
lib/tasks/multitenancy.rake
... | ... | @@ -19,7 +19,7 @@ end |
19 | 19 | namespace :db do |
20 | 20 | |
21 | 21 | task :migrate_other_environments => :environment do |
22 | - envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_#{RAILS_ENV}$/) } | |
22 | + envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_#{Rails.env}$/) } | |
23 | 23 | envs.each do |e| |
24 | 24 | puts "*** Migrating #{e}" if Rake.application.options.trace |
25 | 25 | system "rake db:migrate RAILS_ENV=#{e}" | ... | ... |
po/eo/noosfero-doc.po
... | ... | @@ -7,12 +7,12 @@ msgid "" |
7 | 7 | msgstr "" |
8 | 8 | "Project-Id-Version: PACKAGE VERSION\n" |
9 | 9 | "POT-Creation-Date: 2013-12-10 15:48-0300\n" |
10 | -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | |
10 | +"PO-Revision-Date: 2014-03-23 17:11-0300\n" | |
11 | 11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
12 | 12 | "Language-Team: LANGUAGE <LL@li.org>\n" |
13 | 13 | "Language: eo\n" |
14 | 14 | "MIME-Version: 1.0\n" |
15 | -"Content-Type: text/plain; charset=CHARSET\n" | |
15 | +"Content-Type: text/plain; charset=UTF-8\n" | |
16 | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | 17 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" |
18 | 18 | ... | ... |
po/es/noosfero-doc.po
... | ... | @@ -7,14 +7,14 @@ msgid "" |
7 | 7 | msgstr "" |
8 | 8 | "Project-Id-Version: PACKAGE VERSION\n" |
9 | 9 | "POT-Creation-Date: 2013-12-10 15:48-0300\n" |
10 | -"PO-Revision-Date: 2012-10-04 13:01-0600\n" | |
10 | +"PO-Revision-Date: 2014-03-23 17:11-0300\n" | |
11 | 11 | "Last-Translator: Luis David Aguilar Carlos <ludwig9003@gmail.com>, Freddy " |
12 | 12 | "Martn Hernndez Facio <fmhf14@gmail.com>, Pedro Alonzo Ramrez Tovar <pedro." |
13 | 13 | "alonzo709@gmail.com>\n" |
14 | 14 | "Language-Team: Spanish <LL@li.org>\n" |
15 | 15 | "Language: \n" |
16 | 16 | "MIME-Version: 1.0\n" |
17 | -"Content-Type: text/plain; charset=CHARSET\n" | |
17 | +"Content-Type: text/plain; charset=UTF-8\n" | |
18 | 18 | "Content-Transfer-Encoding: ENCODING\n" |
19 | 19 | |
20 | 20 | # type: Content of: <h1> | ... | ... |
po/it/noosfero-doc.po
... | ... | @@ -8,12 +8,12 @@ msgid "" |
8 | 8 | msgstr "" |
9 | 9 | "Project-Id-Version: noosfero 0.36.6\n" |
10 | 10 | "POT-Creation-Date: 2013-12-10 15:48-0300\n" |
11 | -"PO-Revision-Date: 2012-06-05 10:32-0300\n" | |
11 | +"PO-Revision-Date: 2014-03-23 17:10-0300\n" | |
12 | 12 | "Last-Translator: Daniela Feitosa <danielafeitosa@colivre.coop.br>\n" |
13 | 13 | "Language-Team: LANGUAGE TEAM <LL@li.org>\n" |
14 | 14 | "Language: \n" |
15 | 15 | "MIME-Version: 1.0\n" |
16 | -"Content-Type: text/plain; charset=CHARSET\n" | |
16 | +"Content-Type: text/plain; charset=UTF-8\n" | |
17 | 17 | "Content-Transfer-Encoding: 8bit\n" |
18 | 18 | |
19 | 19 | #. type: Content of: <h1> | ... | ... |
po/noosfero-doc.pot
... | ... | @@ -13,7 +13,7 @@ msgstr "" |
13 | 13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
14 | 14 | "Language: \n" |
15 | 15 | "MIME-Version: 1.0\n" |
16 | -"Content-Type: text/plain; charset=CHARSET\n" | |
16 | +"Content-Type: text/plain; charset=UTF-8\n" | |
17 | 17 | "Content-Transfer-Encoding: 8bit\n" |
18 | 18 | |
19 | 19 | #. type: Content of: <h1> | ... | ... |
script/install-dependencies/debian-wheezy.sh
1 | -# needed to run noosfero | |
2 | -runtime_dependencies=$(sed -e '/^\s*#/d; 1,/^Depends:/d; /^Recommends:/,$ d; s/([^)]*)//g; s/,\s*/\n/g' debian/control | grep -v 'memcached\|debconf\|dbconfig-common\|postgresql\|misc:Depends\|adduser\|mail-transport-agent') | |
3 | -run sudo apt-get -y install $runtime_dependencies | |
4 | -sudo apt-get -y install iceweasel || sudo apt-get -y install firefox | |
1 | +# FIXME upload to a more official repository and sign with an existing key | |
2 | +if [ ! -e /etc/apt/sources.list.d/noosfero.list ]; then | |
3 | + sudo tee /etc/apt/sources.list.d/noosfero.list <<EOF | |
4 | +deb http://people.debian.org/~terceiro/noosfero-wheezy-backports/ ./ | |
5 | +EOF | |
6 | + sudo apt-key add - <<EOF | |
7 | +-----BEGIN PGP PUBLIC KEY BLOCK----- | |
8 | +Version: GnuPG v1 | |
5 | 9 | |
6 | -# needed for development | |
7 | -run sudo apt-get -y install ruby-tidy ruby-mocha imagemagick po4a xvfb libxml2-dev libxslt1-dev | |
10 | +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 | |
120 | +y/cBuQY= | |
121 | +=oYoG | |
122 | +-----END PGP PUBLIC KEY BLOCK----- | |
123 | +EOF | |
124 | + run sudo apt-get update | |
125 | +fi | |
8 | 126 | |
9 | -sudo apt-get -y install bundler apt-file | |
10 | -sudo apt-file update | |
127 | +run sudo apt-get -y install dctrl-tools | |
11 | 128 | |
12 | -run ./script/debundler | |
129 | +# needed to run noosfero | |
130 | +packages=$(grep-dctrl -n -s Build-Depends,Depends,Recommends -S -X noosfero debian/control | sed -e 's/([^)]*)//g; s/,\s*/\n/g' | grep -v 'memcached\|debconf\|dbconfig-common\|misc:Depends\|adduser\|mail-transport-agent') | |
131 | +run sudo apt-get -y install $packages | |
132 | +sudo apt-get -y install iceweasel || sudo apt-get -y install firefox | |
13 | 133 | |
14 | 134 | run bundle --local | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +#!/bin/sh | |
2 | + | |
3 | +set -e | |
4 | +sudo apt-get install netcat-traditional | |
5 | + | |
6 | +# apt-cacher-ng running on the host | |
7 | +# 10.0.2.2 = host ip on virtualbox/qemu | |
8 | +# 192.168..122.1 = host ip on default libvirt bridge | |
9 | +for ip in 10.0.2.2 192.168.122.1; do | |
10 | + if nc -z -w 1 $ip 3142; then | |
11 | + echo "Acquire::http::Proxy \"http://$ip:3142\";" | sudo tee /etc/apt/apt.conf.d/01proxy | |
12 | + fi | |
13 | +done | |
14 | + | |
15 | +cd /vagrant | |
16 | +./script/quick-start | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +# Prototype Legacy Helper | |
2 | + | |
3 | +This plugin adds support for `form_remote_tag`, etc from Rails 2 to Rails 3. | |
4 | + | |
5 | +## Installation | |
6 | + | |
7 | +Either add the following to your `Gemfile` and run `bundle`: | |
8 | + | |
9 | + gem 'prototype_legacy_helper', '0.0.0', :git => 'git://github.com/rails/prototype_legacy_helper.git' | |
10 | + | |
11 | +or run the following command to vendor the plugin within your app: | |
12 | + | |
13 | + rails plugin install git://github.com/rails/prototype_legacy_helper.git | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +require 'prototype_legacy_helper' | ... | ... |
vendor/prototype_legacy_helper/lib/prototype_legacy_helper.rb
0 → 100644
... | ... | @@ -0,0 +1,432 @@ |
1 | +module PrototypeHelper | |
2 | + # Creates a button with an onclick event which calls a remote action | |
3 | + # via XMLHttpRequest | |
4 | + # The options for specifying the target with :url | |
5 | + # and defining callbacks is the same as link_to_remote. | |
6 | + def button_to_remote(name, options = {}, html_options = {}) | |
7 | + button_to_function(name, remote_function(options), html_options) | |
8 | + end | |
9 | + | |
10 | + # Returns a button input tag with the element name of +name+ and a value (i.e., display text) of +value+ | |
11 | + # that will submit form using XMLHttpRequest in the background instead of a regular POST request that | |
12 | + # reloads the page. | |
13 | + # | |
14 | + # # Create a button that submits to the create action | |
15 | + # # | |
16 | + # # Generates: <input name="create_btn" onclick="new Ajax.Request('/testing/create', | |
17 | + # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)}); | |
18 | + # # return false;" type="button" value="Create" /> | |
19 | + # <%= submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %> | |
20 | + # | |
21 | + # # Submit to the remote action update and update the DIV succeed or fail based | |
22 | + # # on the success or failure of the request | |
23 | + # # | |
24 | + # # Generates: <input name="update_btn" onclick="new Ajax.Updater({success:'succeed',failure:'fail'}, | |
25 | + # # '/testing/update', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)}); | |
26 | + # # return false;" type="button" value="Update" /> | |
27 | + # <%= submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' }, | |
28 | + # :update => { :success => "succeed", :failure => "fail" } | |
29 | + # | |
30 | + # <tt>options</tt> argument is the same as in form_remote_tag. | |
31 | + def submit_to_remote(name, value, options = {}) | |
32 | + options[:with] ||= 'Form.serialize(this.form)' | |
33 | + | |
34 | + html_options = options.delete(:html) || {} | |
35 | + html_options[:name] = name | |
36 | + | |
37 | + button_to_remote(value, options, html_options) | |
38 | + end | |
39 | + | |
40 | + # Returns a link to a remote action defined by <tt>options[:url]</tt> | |
41 | + # (using the url_for format) that's called in the background using | |
42 | + # XMLHttpRequest. The result of that request can then be inserted into a | |
43 | + # DOM object whose id can be specified with <tt>options[:update]</tt>. | |
44 | + # Usually, the result would be a partial prepared by the controller with | |
45 | + # render :partial. | |
46 | + # | |
47 | + # Examples: | |
48 | + # # Generates: <a href="#" onclick="new Ajax.Updater('posts', '/blog/destroy/3', {asynchronous:true, evalScripts:true}); | |
49 | + # # return false;">Delete this post</a> | |
50 | + # link_to_remote "Delete this post", :update => "posts", | |
51 | + # :url => { :action => "destroy", :id => post.id } | |
52 | + # | |
53 | + # # Generates: <a href="#" onclick="new Ajax.Updater('emails', '/mail/list_emails', {asynchronous:true, evalScripts:true}); | |
54 | + # # return false;"><img alt="Refresh" src="/images/refresh.png?" /></a> | |
55 | + # link_to_remote(image_tag("refresh"), :update => "emails", | |
56 | + # :url => { :action => "list_emails" }) | |
57 | + # | |
58 | + # You can override the generated HTML options by specifying a hash in | |
59 | + # <tt>options[:html]</tt>. | |
60 | + # | |
61 | + # link_to_remote "Delete this post", :update => "posts", | |
62 | + # :url => post_url(@post), :method => :delete, | |
63 | + # :html => { :class => "destructive" } | |
64 | + # | |
65 | + # You can also specify a hash for <tt>options[:update]</tt> to allow for | |
66 | + # easy redirection of output to an other DOM element if a server-side | |
67 | + # error occurs: | |
68 | + # | |
69 | + # Example: | |
70 | + # # Generates: <a href="#" onclick="new Ajax.Updater({success:'posts',failure:'error'}, '/blog/destroy/5', | |
71 | + # # {asynchronous:true, evalScripts:true}); return false;">Delete this post</a> | |
72 | + # link_to_remote "Delete this post", | |
73 | + # :url => { :action => "destroy", :id => post.id }, | |
74 | + # :update => { :success => "posts", :failure => "error" } | |
75 | + # | |
76 | + # Optionally, you can use the <tt>options[:position]</tt> parameter to | |
77 | + # influence how the target DOM element is updated. It must be one of | |
78 | + # <tt>:before</tt>, <tt>:top</tt>, <tt>:bottom</tt>, or <tt>:after</tt>. | |
79 | + # | |
80 | + # The method used is by default POST. You can also specify GET or you | |
81 | + # can simulate PUT or DELETE over POST. All specified with <tt>options[:method]</tt> | |
82 | + # | |
83 | + # Example: | |
84 | + # # Generates: <a href="#" onclick="new Ajax.Request('/person/4', {asynchronous:true, evalScripts:true, method:'delete'}); | |
85 | + # # return false;">Destroy</a> | |
86 | + # link_to_remote "Destroy", :url => person_url(:id => person), :method => :delete | |
87 | + # | |
88 | + # By default, these remote requests are processed asynchronous during | |
89 | + # which various JavaScript callbacks can be triggered (for progress | |
90 | + # indicators and the likes). All callbacks get access to the | |
91 | + # <tt>request</tt> object, which holds the underlying XMLHttpRequest. | |
92 | + # | |
93 | + # To access the server response, use <tt>request.responseText</tt>, to | |
94 | + # find out the HTTP status, use <tt>request.status</tt>. | |
95 | + # | |
96 | + # Example: | |
97 | + # # Generates: <a href="#" onclick="new Ajax.Request('/words/undo?n=33', {asynchronous:true, evalScripts:true, | |
98 | + # # onComplete:function(request){undoRequestCompleted(request)}}); return false;">hello</a> | |
99 | + # word = 'hello' | |
100 | + # link_to_remote word, | |
101 | + # :url => { :action => "undo", :n => word_counter }, | |
102 | + # :complete => "undoRequestCompleted(request)" | |
103 | + # | |
104 | + # The callbacks that may be specified are (in order): | |
105 | + # | |
106 | + # <tt>:loading</tt>:: Called when the remote document is being | |
107 | + # loaded with data by the browser. | |
108 | + # <tt>:loaded</tt>:: Called when the browser has finished loading | |
109 | + # the remote document. | |
110 | + # <tt>:interactive</tt>:: Called when the user can interact with the | |
111 | + # remote document, even though it has not | |
112 | + # finished loading. | |
113 | + # <tt>:success</tt>:: Called when the XMLHttpRequest is completed, | |
114 | + # and the HTTP status code is in the 2XX range. | |
115 | + # <tt>:failure</tt>:: Called when the XMLHttpRequest is completed, | |
116 | + # and the HTTP status code is not in the 2XX | |
117 | + # range. | |
118 | + # <tt>:complete</tt>:: Called when the XMLHttpRequest is complete | |
119 | + # (fires after success/failure if they are | |
120 | + # present). | |
121 | + # | |
122 | + # You can further refine <tt>:success</tt> and <tt>:failure</tt> by | |
123 | + # adding additional callbacks for specific status codes. | |
124 | + # | |
125 | + # Example: | |
126 | + # # Generates: <a href="#" onclick="new Ajax.Request('/testing/action', {asynchronous:true, evalScripts:true, | |
127 | + # # on404:function(request){alert('Not found...? Wrong URL...?')}, | |
128 | + # # onFailure:function(request){alert('HTTP Error ' + request.status + '!')}}); return false;">hello</a> | |
129 | + # link_to_remote word, | |
130 | + # :url => { :action => "action" }, | |
131 | + # 404 => "alert('Not found...? Wrong URL...?')", | |
132 | + # :failure => "alert('HTTP Error ' + request.status + '!')" | |
133 | + # | |
134 | + # A status code callback overrides the success/failure handlers if | |
135 | + # present. | |
136 | + # | |
137 | + # If you for some reason or another need synchronous processing (that'll | |
138 | + # block the browser while the request is happening), you can specify | |
139 | + # <tt>options[:type] = :synchronous</tt>. | |
140 | + # | |
141 | + # You can customize further browser side call logic by passing in | |
142 | + # JavaScript code snippets via some optional parameters. In their order | |
143 | + # of use these are: | |
144 | + # | |
145 | + # <tt>:confirm</tt>:: Adds confirmation dialog. | |
146 | + # <tt>:condition</tt>:: Perform remote request conditionally | |
147 | + # by this expression. Use this to | |
148 | + # describe browser-side conditions when | |
149 | + # request should not be initiated. | |
150 | + # <tt>:before</tt>:: Called before request is initiated. | |
151 | + # <tt>:after</tt>:: Called immediately after request was | |
152 | + # initiated and before <tt>:loading</tt>. | |
153 | + # <tt>:submit</tt>:: Specifies the DOM element ID that's used | |
154 | + # as the parent of the form elements. By | |
155 | + # default this is the current form, but | |
156 | + # it could just as well be the ID of a | |
157 | + # table row or any other DOM element. | |
158 | + # <tt>:with</tt>:: A JavaScript expression specifying | |
159 | + # the parameters for the XMLHttpRequest. | |
160 | + # Any expressions should return a valid | |
161 | + # URL query string. | |
162 | + # | |
163 | + # Example: | |
164 | + # | |
165 | + # :with => "'name=' + $('name').value" | |
166 | + # | |
167 | + # You can generate a link that uses AJAX in the general case, while | |
168 | + # degrading gracefully to plain link behavior in the absence of | |
169 | + # JavaScript by setting <tt>html_options[:href]</tt> to an alternate URL. | |
170 | + # Note the extra curly braces around the <tt>options</tt> hash separate | |
171 | + # it as the second parameter from <tt>html_options</tt>, the third. | |
172 | + # | |
173 | + # Example: | |
174 | + # link_to_remote "Delete this post", | |
175 | + # { :update => "posts", :url => { :action => "destroy", :id => post.id } }, | |
176 | + # :href => url_for(:action => "destroy", :id => post.id) | |
177 | + def link_to_remote(name, options = {}, html_options = nil) | |
178 | + link_to_function(name, remote_function(options), html_options || options.delete(:html)) | |
179 | + end | |
180 | + | |
181 | + # Returns a form tag that will submit using XMLHttpRequest in the | |
182 | + # background instead of the regular reloading POST arrangement. Even | |
183 | + # though it's using JavaScript to serialize the form elements, the form | |
184 | + # submission will work just like a regular submission as viewed by the | |
185 | + # receiving side (all elements available in <tt>params</tt>). The options for | |
186 | + # specifying the target with <tt>:url</tt> and defining callbacks is the same as | |
187 | + # +link_to_remote+. | |
188 | + # | |
189 | + # A "fall-through" target for browsers that doesn't do JavaScript can be | |
190 | + # specified with the <tt>:action</tt>/<tt>:method</tt> options on <tt>:html</tt>. | |
191 | + # | |
192 | + # Example: | |
193 | + # # Generates: | |
194 | + # # <form action="/some/place" method="post" onsubmit="new Ajax.Request('', | |
195 | + # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;"> | |
196 | + # form_remote_tag :html => { :action => | |
197 | + # url_for(:controller => "some", :action => "place") } | |
198 | + # | |
199 | + # The Hash passed to the <tt>:html</tt> key is equivalent to the options (2nd) | |
200 | + # argument in the FormTagHelper.form_tag method. | |
201 | + # | |
202 | + # By default the fall-through action is the same as the one specified in | |
203 | + # the <tt>:url</tt> (and the default method is <tt>:post</tt>). | |
204 | + # | |
205 | + # form_remote_tag also takes a block, like form_tag: | |
206 | + # # Generates: | |
207 | + # # <form action="/" method="post" onsubmit="new Ajax.Request('/', | |
208 | + # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); | |
209 | + # # return false;"> <div><input name="commit" type="submit" value="Save" /></div> | |
210 | + # # </form> | |
211 | + # <% form_remote_tag :url => '/posts' do -%> | |
212 | + # <div><%= submit_tag 'Save' %></div> | |
213 | + # <% end -%> | |
214 | + def form_remote_tag(options = {}, &block) | |
215 | + options[:form] = true | |
216 | + | |
217 | + options[:html] ||= {} | |
218 | + options[:html][:onsubmit] = | |
219 | + (options[:html][:onsubmit] ? options[:html][:onsubmit] + "; " : "") + | |
220 | + "#{remote_function(options)}; return false;" | |
221 | + | |
222 | + form_tag(options[:html].delete(:action) || url_for(options[:url]), options[:html], &block) | |
223 | + end | |
224 | + | |
225 | + # Creates a form that will submit using XMLHttpRequest in the background | |
226 | + # instead of the regular reloading POST arrangement and a scope around a | |
227 | + # specific resource that is used as a base for questioning about | |
228 | + # values for the fields. | |
229 | + # | |
230 | + # === Resource | |
231 | + # | |
232 | + # Example: | |
233 | + # <% remote_form_for(@post) do |f| %> | |
234 | + # ... | |
235 | + # <% end %> | |
236 | + # | |
237 | + # This will expand to be the same as: | |
238 | + # | |
239 | + # <% remote_form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %> | |
240 | + # ... | |
241 | + # <% end %> | |
242 | + # | |
243 | + # === Nested Resource | |
244 | + # | |
245 | + # Example: | |
246 | + # <% remote_form_for([@post, @comment]) do |f| %> | |
247 | + # ... | |
248 | + # <% end %> | |
249 | + # | |
250 | + # This will expand to be the same as: | |
251 | + # | |
252 | + # <% remote_form_for :comment, @comment, :url => post_comment_path(@post, @comment), :html => { :method => :put, :class => "edit_comment", :id => "edit_comment_45" } do |f| %> | |
253 | + # ... | |
254 | + # <% end %> | |
255 | + # | |
256 | + # If you don't need to attach a form to a resource, then check out form_remote_tag. | |
257 | + # | |
258 | + # See FormHelper#form_for for additional semantics. | |
259 | + def remote_form_for(record_or_name_or_array, *args, &proc) | |
260 | + options = args.extract_options! | |
261 | + | |
262 | + case record_or_name_or_array | |
263 | + when String, Symbol | |
264 | + object_name = record_or_name_or_array | |
265 | + when Array | |
266 | + object = record_or_name_or_array.last | |
267 | + object_name = ActiveModel::Naming.singular(object) | |
268 | + apply_form_for_options!(record_or_name_or_array, options) | |
269 | + args.unshift object | |
270 | + else | |
271 | + object = record_or_name_or_array | |
272 | + object_name = ActiveModel::Naming.singular(record_or_name_or_array) | |
273 | + apply_form_for_options!(object, options) | |
274 | + args.unshift object | |
275 | + end | |
276 | + | |
277 | + form_remote_tag options do | |
278 | + fields_for object_name, *(args << options), &proc | |
279 | + end | |
280 | + end | |
281 | + alias_method :form_remote_for, :remote_form_for | |
282 | + | |
283 | + # Returns '<tt>eval(request.responseText)</tt>' which is the JavaScript function | |
284 | + # that +form_remote_tag+ can call in <tt>:complete</tt> to evaluate a multiple | |
285 | + # update return document using +update_element_function+ calls. | |
286 | + def evaluate_remote_response | |
287 | + "eval(request.responseText)" | |
288 | + end | |
289 | + | |
290 | + # Observes the field with the DOM ID specified by +field_id+ and calls a | |
291 | + # callback when its contents have changed. The default callback is an | |
292 | + # Ajax call. By default the value of the observed field is sent as a | |
293 | + # parameter with the Ajax call. | |
294 | + # | |
295 | + # Example: | |
296 | + # # Generates: new Form.Element.Observer('suggest', 0.25, function(element, value) {new Ajax.Updater('suggest', | |
297 | + # # '/testing/find_suggestion', {asynchronous:true, evalScripts:true, parameters:'q=' + value})}) | |
298 | + # <%= observe_field :suggest, :url => { :action => :find_suggestion }, | |
299 | + # :frequency => 0.25, | |
300 | + # :update => :suggest, | |
301 | + # :with => 'q' | |
302 | + # %> | |
303 | + # | |
304 | + # Required +options+ are either of: | |
305 | + # <tt>:url</tt>:: +url_for+-style options for the action to call | |
306 | + # when the field has changed. | |
307 | + # <tt>:function</tt>:: Instead of making a remote call to a URL, you | |
308 | + # can specify javascript code to be called instead. | |
309 | + # Note that the value of this option is used as the | |
310 | + # *body* of the javascript function, a function definition | |
311 | + # with parameters named element and value will be generated for you | |
312 | + # for example: | |
313 | + # observe_field("glass", :frequency => 1, :function => "alert('Element changed')") | |
314 | + # will generate: | |
315 | + # new Form.Element.Observer('glass', 1, function(element, value) {alert('Element changed')}) | |
316 | + # The element parameter is the DOM element being observed, and the value is its value at the | |
317 | + # time the observer is triggered. | |
318 | + # | |
319 | + # Additional options are: | |
320 | + # <tt>:frequency</tt>:: The frequency (in seconds) at which changes to | |
321 | + # this field will be detected. Not setting this | |
322 | + # option at all or to a value equal to or less than | |
323 | + # zero will use event based observation instead of | |
324 | + # time based observation. | |
325 | + # <tt>:update</tt>:: Specifies the DOM ID of the element whose | |
326 | + # innerHTML should be updated with the | |
327 | + # XMLHttpRequest response text. | |
328 | + # <tt>:with</tt>:: A JavaScript expression specifying the parameters | |
329 | + # for the XMLHttpRequest. The default is to send the | |
330 | + # key and value of the observed field. Any custom | |
331 | + # expressions should return a valid URL query string. | |
332 | + # The value of the field is stored in the JavaScript | |
333 | + # variable +value+. | |
334 | + # | |
335 | + # Examples | |
336 | + # | |
337 | + # :with => "'my_custom_key=' + value" | |
338 | + # :with => "'person[name]=' + prompt('New name')" | |
339 | + # :with => "Form.Element.serialize('other-field')" | |
340 | + # | |
341 | + # Finally | |
342 | + # :with => 'name' | |
343 | + # is shorthand for | |
344 | + # :with => "'name=' + value" | |
345 | + # This essentially just changes the key of the parameter. | |
346 | + # | |
347 | + # Additionally, you may specify any of the options documented in the | |
348 | + # <em>Common options</em> section at the top of this document. | |
349 | + # | |
350 | + # Example: | |
351 | + # | |
352 | + # # Sends params: {:title => 'Title of the book'} when the book_title input | |
353 | + # # field is changed. | |
354 | + # observe_field 'book_title', | |
355 | + # :url => 'http://example.com/books/edit/1', | |
356 | + # :with => 'title' | |
357 | + # | |
358 | + # | |
359 | + def observe_field(field_id, options = {}) | |
360 | + if options[:frequency] && options[:frequency] > 0 | |
361 | + build_observer('Form.Element.Observer', field_id, options) | |
362 | + else | |
363 | + build_observer('Form.Element.EventObserver', field_id, options) | |
364 | + end | |
365 | + end | |
366 | + | |
367 | + # Observes the form with the DOM ID specified by +form_id+ and calls a | |
368 | + # callback when its contents have changed. The default callback is an | |
369 | + # Ajax call. By default all fields of the observed field are sent as | |
370 | + # parameters with the Ajax call. | |
371 | + # | |
372 | + # The +options+ for +observe_form+ are the same as the options for | |
373 | + # +observe_field+. The JavaScript variable +value+ available to the | |
374 | + # <tt>:with</tt> option is set to the serialized form by default. | |
375 | + def observe_form(form_id, options = {}) | |
376 | + if options[:frequency] | |
377 | + build_observer('Form.Observer', form_id, options) | |
378 | + else | |
379 | + build_observer('Form.EventObserver', form_id, options) | |
380 | + end | |
381 | + end | |
382 | + | |
383 | + # Periodically calls the specified url (<tt>options[:url]</tt>) every | |
384 | + # <tt>options[:frequency]</tt> seconds (default is 10). Usually used to | |
385 | + # update a specified div (<tt>options[:update]</tt>) with the results | |
386 | + # of the remote call. The options for specifying the target with <tt>:url</tt> | |
387 | + # and defining callbacks is the same as link_to_remote. | |
388 | + # Examples: | |
389 | + # # Call get_averages and put its results in 'avg' every 10 seconds | |
390 | + # # Generates: | |
391 | + # # new PeriodicalExecuter(function() {new Ajax.Updater('avg', '/grades/get_averages', | |
392 | + # # {asynchronous:true, evalScripts:true})}, 10) | |
393 | + # periodically_call_remote(:url => { :action => 'get_averages' }, :update => 'avg') | |
394 | + # | |
395 | + # # Call invoice every 10 seconds with the id of the customer | |
396 | + # # If it succeeds, update the invoice DIV; if it fails, update the error DIV | |
397 | + # # Generates: | |
398 | + # # new PeriodicalExecuter(function() {new Ajax.Updater({success:'invoice',failure:'error'}, | |
399 | + # # '/testing/invoice/16', {asynchronous:true, evalScripts:true})}, 10) | |
400 | + # periodically_call_remote(:url => { :action => 'invoice', :id => customer.id }, | |
401 | + # :update => { :success => "invoice", :failure => "error" } | |
402 | + # | |
403 | + # # Call update every 20 seconds and update the new_block DIV | |
404 | + # # Generates: | |
405 | + # # new PeriodicalExecuter(function() {new Ajax.Updater('news_block', 'update', {asynchronous:true, evalScripts:true})}, 20) | |
406 | + # periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block') | |
407 | + # | |
408 | + def periodically_call_remote(options = {}) | |
409 | + frequency = options[:frequency] || 10 # every ten seconds by default | |
410 | + code = "new PeriodicalExecuter(function() {#{remote_function(options)}}, #{frequency})" | |
411 | + javascript_tag(code) | |
412 | + end | |
413 | + | |
414 | + protected | |
415 | + def build_observer(klass, name, options = {}) | |
416 | + if options[:with] && (options[:with] !~ /[\{=(.]/) | |
417 | + options[:with] = "'#{options[:with]}=' + encodeURIComponent(value)" | |
418 | + else | |
419 | + options[:with] ||= 'value' unless options[:function] | |
420 | + end | |
421 | + | |
422 | + callback = options[:function] || remote_function(options) | |
423 | + javascript = "new #{klass}('#{name}', " | |
424 | + javascript << "#{options[:frequency]}, " if options[:frequency] | |
425 | + javascript << "function(element, value) {" | |
426 | + javascript << "#{callback}}" | |
427 | + javascript << ")" | |
428 | + javascript_tag(javascript) | |
429 | + end | |
430 | +end | |
431 | + | |
432 | +ActionController::Base.helper PrototypeHelper | ... | ... |
vendor/prototype_legacy_helper/test/test_prototype_helper.rb
0 → 100644
... | ... | @@ -0,0 +1,297 @@ |
1 | +if ENV['RAILS_ROOT'] | |
2 | + environment = File.expand_path('vendor/gems/environment', ENV['RAILS_ROOT']) | |
3 | + require environment if File.exist?("#{environment}.rb") | |
4 | +end | |
5 | + | |
6 | +$:.unshift File.expand_path('../../lib', __FILE__) | |
7 | + | |
8 | +require 'test/unit' | |
9 | +require 'action_view' | |
10 | +require 'action_controller' | |
11 | +require 'active_model' | |
12 | +require 'prototype_helper' | |
13 | + | |
14 | +class Bunny < Struct.new(:Bunny, :id) | |
15 | +end | |
16 | + | |
17 | +class Author | |
18 | + extend ActiveModel::Naming | |
19 | + | |
20 | + attr_reader :id | |
21 | + def save; @id = 1 end | |
22 | + def new_record?; @id.nil? end | |
23 | + def name | |
24 | + @id.nil? ? 'new author' : "author ##{@id}" | |
25 | + end | |
26 | +end | |
27 | + | |
28 | +class Article | |
29 | + extend ActiveModel::Naming | |
30 | + | |
31 | + attr_reader :id | |
32 | + attr_reader :author_id | |
33 | + def save; @id = 1; @author_id = 1 end | |
34 | + def new_record?; @id.nil? end | |
35 | + def name | |
36 | + @id.nil? ? 'new article' : "article ##{@id}" | |
37 | + end | |
38 | +end | |
39 | + | |
40 | +class Author::Nested < Author; end | |
41 | + | |
42 | +class PrototypeHelperTest < ActionView::TestCase | |
43 | + attr_accessor :formats, :output_buffer, :template_format | |
44 | + | |
45 | + def _evaluate_assigns_and_ivars() end | |
46 | + | |
47 | + def reset_formats(format) | |
48 | + @format = format | |
49 | + end | |
50 | + | |
51 | + def setup | |
52 | + @record = @author = Author.new | |
53 | + @article = Article.new | |
54 | + super | |
55 | + @template = self | |
56 | + @controller = Class.new do | |
57 | + def url_for(options) | |
58 | + if options.is_a?(String) | |
59 | + options | |
60 | + else | |
61 | + url = "http://www.example.com/" | |
62 | + url << options[:action].to_s if options and options[:action] | |
63 | + url << "?a=#{options[:a]}" if options && options[:a] | |
64 | + url << "&b=#{options[:b]}" if options && options[:a] && options[:b] | |
65 | + url | |
66 | + end | |
67 | + end | |
68 | + end.new | |
69 | + end | |
70 | + | |
71 | + | |
72 | + def test_observe_form | |
73 | + assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {new Ajax.Request('http://www.example.com/cart_changed', {asynchronous:true, evalScripts:true, parameters:value})})\n//]]>\n</script>), | |
74 | + observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" }) | |
75 | + end | |
76 | + | |
77 | + def test_observe_form_using_function_for_callback | |
78 | + assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {alert('Form changed')})\n//]]>\n</script>), | |
79 | + observe_form("cart", :frequency => 2, :function => "alert('Form changed')") | |
80 | + end | |
81 | + | |
82 | + def test_observe_field | |
83 | + assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/reorder_if_empty', {asynchronous:true, evalScripts:true, parameters:value})})\n//]]>\n</script>), | |
84 | + observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" }) | |
85 | + end | |
86 | + | |
87 | + def test_observe_field_using_with_option | |
88 | + expected = %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/check_value', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(value)})})\n//]]>\n</script>) | |
89 | + assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => 'id') | |
90 | + assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => "'id=' + encodeURIComponent(value)") | |
91 | + end | |
92 | + | |
93 | + def test_observe_field_using_json_in_with_option | |
94 | + expected = %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/check_value', {asynchronous:true, evalScripts:true, parameters:{'id':value}})})\n//]]>\n</script>) | |
95 | + assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => "{'id':value}") | |
96 | + end | |
97 | + | |
98 | + def test_observe_field_using_function_for_callback | |
99 | + assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {alert('Element changed')})\n//]]>\n</script>), | |
100 | + observe_field("glass", :frequency => 5.minutes, :function => "alert('Element changed')") | |
101 | + end | |
102 | + | |
103 | + def test_observe_field_without_frequency | |
104 | + assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.EventObserver('glass', function(element, value) {new Ajax.Request('http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:value})})\n//]]>\n</script>), | |
105 | + observe_field("glass") | |
106 | + end | |
107 | + | |
108 | + | |
109 | + def test_periodically_call_remote | |
110 | + assert_dom_equal %(<script type="text/javascript">\n//<![CDATA[\nnew PeriodicalExecuter(function() {new Ajax.Updater('schremser_bier', 'http://www.example.com/mehr_bier', {asynchronous:true, evalScripts:true})}, 10)\n//]]>\n</script>), | |
111 | + periodically_call_remote(:update => "schremser_bier", :url => { :action => "mehr_bier" }) | |
112 | + end | |
113 | + | |
114 | + def test_periodically_call_remote_with_frequency | |
115 | + assert_dom_equal( | |
116 | + "<script type=\"text/javascript\">\n//<![CDATA[\nnew PeriodicalExecuter(function() {new Ajax.Request('http://www.example.com/', {asynchronous:true, evalScripts:true})}, 2)\n//]]>\n</script>", | |
117 | + periodically_call_remote(:frequency => 2) | |
118 | + ) | |
119 | + end | |
120 | + | |
121 | + | |
122 | + def test_form_remote_tag | |
123 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">), | |
124 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) | |
125 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">), | |
126 | + form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast }) | |
127 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">), | |
128 | + form_remote_tag(:update => { :failure => "glass_of_water" }, :url => { :action => :fast }) | |
129 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer',failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">), | |
130 | + form_remote_tag(:update => { :success => 'glass_of_beer', :failure => "glass_of_water" }, :url => { :action => :fast }) | |
131 | + end | |
132 | + | |
133 | + def test_form_remote_tag_with_method | |
134 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>), | |
135 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :html => { :method => :put }) | |
136 | + end | |
137 | + | |
138 | + def test_form_remote_tag_with_block_in_erb | |
139 | + __in_erb_template = '' | |
140 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { concat "Hello world!" } | |
141 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">Hello world!</form>), output_buffer | |
142 | + end | |
143 | + | |
144 | + def test_on_callbacks | |
145 | + callbacks = [:uninitialized, :loading, :loaded, :interactive, :complete, :success, :failure] | |
146 | + callbacks.each do |callback| | |
147 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">), | |
148 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") | |
149 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">), | |
150 | + form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();") | |
151 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({failure:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">), | |
152 | + form_remote_tag(:update => { :failure => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();") | |
153 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer',failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">), | |
154 | + form_remote_tag(:update => { :success => "glass_of_beer", :failure => "glass_of_water" }, :url => { :action => :fast }, callback=>"monkeys();") | |
155 | + end | |
156 | + | |
157 | + #HTTP status codes 200 up to 599 have callbacks | |
158 | + #these should work | |
159 | + 100.upto(599) do |callback| | |
160 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">), | |
161 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") | |
162 | + end | |
163 | + | |
164 | + #test 200 and 404 | |
165 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on200:function(request){monkeys();}, on404:function(request){bananas();}, parameters:Form.serialize(this)}); return false;">), | |
166 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, 200=>"monkeys();", 404=>"bananas();") | |
167 | + | |
168 | + #these shouldn't | |
169 | + 1.upto(99) do |callback| | |
170 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">), | |
171 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") | |
172 | + end | |
173 | + 600.upto(999) do |callback| | |
174 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">), | |
175 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") | |
176 | + end | |
177 | + | |
178 | + #test ultimate combo | |
179 | + assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on200:function(request){monkeys();}, on404:function(request){bananas();}, onComplete:function(request){c();}, onFailure:function(request){f();}, onLoading:function(request){c1()}, onSuccess:function(request){s()}, parameters:Form.serialize(this)}); return false;\">), | |
180 | + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :loading => "c1()", :success => "s()", :failure => "f();", :complete => "c();", 200=>"monkeys();", 404=>"bananas();") | |
181 | + end | |
182 | + | |
183 | + def test_remote_form_for_with_record_identification_with_new_record | |
184 | + remote_form_for(@record, {:html => { :id => 'create-author' }}) {} | |
185 | + | |
186 | + expected = %(<form action='#{authors_path}' onsubmit="new Ajax.Request('#{authors_path}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_author' id='create-author' method='post'></form>) | |
187 | + assert_dom_equal expected, output_buffer | |
188 | + end | |
189 | + | |
190 | + def test_remote_form_for_with_record_identification_without_html_options | |
191 | + remote_form_for(@record) {} | |
192 | + | |
193 | + expected = %(<form action='#{authors_path}' onsubmit="new Ajax.Request('#{authors_path}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_author' method='post' id='new_author'></form>) | |
194 | + assert_dom_equal expected, output_buffer | |
195 | + end | |
196 | + | |
197 | + def test_remote_form_for_with_record_identification_with_existing_record | |
198 | + @record.save | |
199 | + remote_form_for(@record) {} | |
200 | + | |
201 | + expected = %(<form action='#{author_path(@record)}' id='edit_author_1' method='post' onsubmit="new Ajax.Request('#{author_path(@record)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='edit_author'><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div></form>) | |
202 | + assert_dom_equal expected, output_buffer | |
203 | + end | |
204 | + | |
205 | + def test_remote_form_for_with_new_object_in_list | |
206 | + remote_form_for([@author, @article]) {} | |
207 | + | |
208 | + expected = %(<form action='#{author_articles_path(@author)}' onsubmit="new Ajax.Request('#{author_articles_path(@author)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_article' method='post' id='new_article'></form>) | |
209 | + assert_dom_equal expected, output_buffer | |
210 | + end | |
211 | + | |
212 | + def test_remote_form_for_with_existing_object_in_list | |
213 | + @author.save | |
214 | + @article.save | |
215 | + remote_form_for([@author, @article]) {} | |
216 | + | |
217 | + expected = %(<form action='#{author_article_path(@author, @article)}' id='edit_article_1' method='post' onsubmit="new Ajax.Request('#{author_article_path(@author, @article)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='edit_article'><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div></form>) | |
218 | + assert_dom_equal expected, output_buffer | |
219 | + end | |
220 | + | |
221 | + | |
222 | + def test_button_to_remote | |
223 | + assert_dom_equal %(<input class=\"fine\" type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true});\" />), | |
224 | + button_to_remote("Remote outpost", { :url => { :action => "whatnot" }}, { :class => "fine" }) | |
225 | + assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.reponseText)}});\" />), | |
226 | + button_to_remote("Remote outpost", :complete => "alert(request.reponseText)", :url => { :action => "whatnot" }) | |
227 | + assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.reponseText)}});\" />), | |
228 | + button_to_remote("Remote outpost", :success => "alert(request.reponseText)", :url => { :action => "whatnot" }) | |
229 | + assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.reponseText)}});\" />), | |
230 | + button_to_remote("Remote outpost", :failure => "alert(request.reponseText)", :url => { :action => "whatnot" }) | |
231 | + assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot?a=10&b=20', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.reponseText)}});\" />), | |
232 | + button_to_remote("Remote outpost", :failure => "alert(request.reponseText)", :url => { :action => "whatnot", :a => '10', :b => '20' }) | |
233 | + end | |
234 | + | |
235 | + def test_submit_to_remote | |
236 | + assert_dom_equal %(<input name=\"More beer!\" onclick=\"new Ajax.Updater('empty_bottle', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});\" type=\"button\" value=\"1000000\" />), | |
237 | + submit_to_remote("More beer!", 1_000_000, :update => "empty_bottle") | |
238 | + end | |
239 | + | |
240 | + | |
241 | + def test_link_to_remote | |
242 | + assert_dom_equal %(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outauthor</a>), | |
243 | + link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }}, { :class => "fine" }) | |
244 | + assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>), | |
245 | + link_to_remote("Remote outauthor", :complete => "alert(request.responseText)", :url => { :action => "whatnot" }) | |
246 | + assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>), | |
247 | + link_to_remote("Remote outauthor", :success => "alert(request.responseText)", :url => { :action => "whatnot" }) | |
248 | + assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>), | |
249 | + link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot" }) | |
250 | + assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot?a=10&b=20', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>), | |
251 | + link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot", :a => '10', :b => '20' }) | |
252 | + assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:false, evalScripts:true}); return false;\">Remote outauthor</a>), | |
253 | + link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :type => :synchronous) | |
254 | + assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, insertion:'bottom'}); return false;\">Remote outauthor</a>), | |
255 | + link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :position => :bottom) | |
256 | + end | |
257 | + | |
258 | + def test_link_to_remote_html_options | |
259 | + assert_dom_equal %(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outauthor</a>), | |
260 | + link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }, :html => { :class => "fine" } }) | |
261 | + end | |
262 | + | |
263 | + def test_link_to_remote_url_quote_escaping | |
264 | + assert_dom_equal %(<a href="#" onclick="new Ajax.Request('http://www.example.com/whatnot\\\'s', {asynchronous:true, evalScripts:true}); return false;">Remote</a>), | |
265 | + link_to_remote("Remote", { :url => { :action => "whatnot's" } }) | |
266 | + end | |
267 | + | |
268 | + protected | |
269 | + def request_forgery_protection_token | |
270 | + nil | |
271 | + end | |
272 | + | |
273 | + def protect_against_forgery? | |
274 | + false | |
275 | + end | |
276 | + | |
277 | + def create_generator | |
278 | + block = Proc.new { |*args| yield *args if block_given? } | |
279 | + JavaScriptGenerator.new self, &block | |
280 | + end | |
281 | + | |
282 | + def author_path(record) | |
283 | + "/authors/#{record.id}" | |
284 | + end | |
285 | + | |
286 | + def authors_path | |
287 | + "/authors" | |
288 | + end | |
289 | + | |
290 | + def author_articles_path(author) | |
291 | + "/authors/#{author.id}/articles" | |
292 | + end | |
293 | + | |
294 | + def author_article_path(author, article) | |
295 | + "/authors/#{author.id}/articles/#{article.id}" | |
296 | + end | |
297 | +end | ... | ... |