parlement 0.8 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/CHANGES +22 -0
  2. data/Rakefile +2 -2
  3. data/app/controllers/account_controller.rb +20 -7
  4. data/app/controllers/application.rb +17 -4
  5. data/app/controllers/elt_controller.rb +1 -10
  6. data/app/controllers/person_controller.rb +1 -1
  7. data/app/helpers/elt_helper.rb +14 -0
  8. data/app/models/elt.rb +2 -0
  9. data/app/models/mail.rb +6 -5
  10. data/app/models/person.rb +5 -0
  11. data/app/views/account/_login.rhtml +52 -48
  12. data/app/views/account/_show.rhtml +13 -12
  13. data/app/views/elt/_choice.rhtml +11 -2
  14. data/app/views/elt/_elt.rhtml +38 -50
  15. data/app/views/elt/new.rhtml +8 -8
  16. data/app/views/elt/show.rhtml +21 -12
  17. data/app/views/layouts/top.rhtml +1 -0
  18. data/app/views/person/_listElts.rhtml +47 -26
  19. data/app/views/person/show.rhtml +8 -18
  20. data/config/environment.rb +6 -3
  21. data/db/ROOT/fr.txt +34 -31
  22. data/db/ROOT/parlement/test.txt +6 -4
  23. data/db/development_structure.sql +18 -20
  24. data/public/engine_files/login_engine/stylesheets/login_engine.css +81 -0
  25. data/public/images/ParlementLogo_fr.png +0 -0
  26. data/public/images/comments.gif +0 -0
  27. data/public/images/vote_minus.png +0 -0
  28. data/public/images/vote_plus.png +0 -0
  29. data/public/images/vote_plus_minus.svg +79 -0
  30. data/public/images/write.png +0 -0
  31. data/public/images/write.svg +70 -0
  32. data/public/javascripts/mybehaviour.js +3 -4
  33. data/public/stylesheets/default.css +449 -0
  34. data/public/stylesheets/live_tree.css +62 -0
  35. data/public/stylesheets/scaffold.css +74 -0
  36. data/script/about +3 -0
  37. data/script/benchmarker +19 -0
  38. data/script/breakpointer +3 -0
  39. data/script/console +3 -0
  40. data/script/create_db +7 -0
  41. data/script/destroy +3 -0
  42. data/script/generate +3 -0
  43. data/script/plugin +3 -0
  44. data/script/profiler +34 -0
  45. data/script/runner +3 -0
  46. data/script/server +3 -0
  47. data/test/unit/elt_test.rb +11 -0
  48. data/test/unit/mail_test.rb +29 -0
  49. metadata +27 -40
  50. data/test/fixtures/attachments.yml +0 -13
  51. data/test/fixtures/choices.yml +0 -13
  52. data/test/fixtures/elts.yml +0 -36
  53. data/test/fixtures/img.png +0 -0
  54. data/test/fixtures/mail/avatar +0 -249
  55. data/test/fixtures/mail/mail_ruby +0 -39
  56. data/test/fixtures/mail/mail_rubyChild +0 -30
  57. data/test/fixtures/mail/mail_rubyChild2 +0 -30
  58. data/test/fixtures/mail/mail_rubyWithAttachment +0 -7932
  59. data/test/fixtures/mail/mail_rubyWithSubject +0 -27
  60. data/test/fixtures/mails.yml +0 -13
  61. data/test/fixtures/people.yml +0 -68
  62. data/test/fixtures/subscribers.yml +0 -14
  63. data/test/fixtures/users.yml +0 -41
  64. data/test/functional/account_controller_test.rb +0 -317
  65. data/test/functional/elt_controller_test.rb +0 -87
  66. data/test/functional/person_controller_test.rb +0 -18
  67. data/test/functional/subscriber_controller_test.rb +0 -128
  68. data/test/mocks/test/time.rb +0 -17
  69. data/test/mocks/test/user_notify.rb +0 -16
  70. data/test/test_helper.rb +0 -72
data/CHANGES CHANGED
@@ -1,5 +1,27 @@
1
1
  - parlement changelog
2
2
 
3
+ == Version 0.9
4
+
5
+ Improved look, particularly the voting and writing part. Long posts and lists
6
+ now truncated. Permanent login. Positioned elements. Search form (though
7
+ google).
8
+
9
+ * now asking to choose a pseudo
10
+ * focus now on the login box
11
+ * anonymous mails can also be received
12
+ * correcting personal page
13
+ * choices now on the right bottom side of elements
14
+ * elements can now be positioned
15
+ * new elements are directly placed under their parent
16
+ * long posts and lists only display their n first paragraphs or items
17
+ * google search form
18
+ * position text is hidden
19
+ * the >> link now more closely associated associated to the choices
20
+ * images for vote and write
21
+ * anonymous users now have a hidden subscription link
22
+ * login is permanent over browser sessions
23
+ * some font encoding corrections in mails
24
+
3
25
  == Version 0.8
4
26
 
5
27
  Users can now filter elements according to an acceptation's threshold
data/Rakefile CHANGED
@@ -35,8 +35,8 @@ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
35
35
  PKG_FILES = FileList[
36
36
  '[A-Z]*', 'app/**/*', 'components/**/*', 'config/**/*', 'db/**/*',
37
37
  'lib/**/*', 'public/*.*', 'public/dynamic/*', 'public/images/*',
38
- 'public/engine_files/*', 'public/javascripts/*', 'script/stylesheets/*',
39
- 'test/**/*', 'vendor/**/*'
38
+ 'public/engine_files/*', 'public/engine_files/**/*', 'public/javascripts/*',
39
+ 'public/stylesheets/*', 'script/*', 'script/**/*' 'test/**/*', 'vendor/**/*'
40
40
  ].exclude(/\b(svn|tmp|attachment)\b|~$/)
41
41
 
42
42
  spec = Gem::Specification.new do |s|
@@ -7,14 +7,16 @@ class AccountController < UserController
7
7
 
8
8
  def login
9
9
  # Cleaning up
10
- session[:person] = session[:user] = nil
10
+ session[:person] = @person = session[:user] = @user = nil
11
+ cookies.delete :person_name
12
+ cookies.delete :salted_password
11
13
 
12
14
  login = @params[:person][:name]
13
15
  email = @params[:person][:email]
14
16
  password = @params[:user][:password]
15
17
 
16
18
  @person = Person.find_by_name(login)
17
- @user = User.find_by_login(login) if @person
19
+ @user = @person.user if @person
18
20
 
19
21
  # First we eventually create a new pseudo
20
22
  if not @person
@@ -112,14 +114,23 @@ class AccountController < UserController
112
114
  end
113
115
  end
114
116
 
115
- render :partial => 'show', :locals => {
116
- :divId => params[:divId], :choices => getAllVotes }
117
- end
117
+ # Record cookies for re authentication
118
+ if session[:person]
119
+ cookies[:person_name] = session[:person].name
120
+ cookies[:salted_password] = @user.salted_password if @user
121
+ end
118
122
 
123
+ render :partial => 'show',
124
+ :locals => { :divId => params[:divId], :choices => getAllVotes },
125
+ :status => (session[:person] ? 200 : 403)
126
+ end
119
127
 
120
128
  def logout
121
- session[:person] = @person = nil
122
- session[:user] = @user = nil
129
+ # Cleaning up
130
+ session[:person] = @person = session[:user] = @user = nil
131
+ cookies.delete :person_name
132
+ cookies.delete :salted_password
133
+
123
134
  render :partial => 'show', :locals => {
124
135
  :divId => params[:divId], :choices => getAllVotes }
125
136
  end
@@ -148,6 +159,8 @@ class AccountController < UserController
148
159
  end
149
160
 
150
161
  def setAvatar
162
+ return render(:text => "Not logged in", :status => 403) \
163
+ unless session[:person]
151
164
  logger.info "Setting up an avatar for person #{session[:person].name}"
152
165
 
153
166
  @elt = Elt.find_by_id 'people'
@@ -8,21 +8,34 @@ class ApplicationController < ActionController::Base
8
8
  model :user
9
9
 
10
10
  before_filter :set_charset
11
+ before_filter :set_login_from_cookie
11
12
  after_filter :fix_unicode_for_safari
12
13
  after_filter OutputCompressionFilter
13
14
 
14
15
  # automatically and transparently fixes utf-8 bug
15
16
  # with Safari when using xmlhttp
16
- def fix_unicode_for_safari
17
- if @headers["Content-Type"] == "text/html; charset=utf-8" and
17
+ def fix_unicode_for_safari
18
+ if @headers["Content-Type"] == "text/html; charset=utf-8" and
18
19
  @request.env['HTTP_USER_AGENT'].to_s.include? 'AppleWebKit' then
19
20
  @response.body = @response.body.gsub(/([^\x00-\xa0])/u) { |s| "&#x%x;" % $1.unpack('U')[0] }
20
- end
21
- end
21
+ end
22
+ end
22
23
 
23
24
  def set_charset
24
25
  #@headers["Content-Type"] = "text/html; charset=iso-8859-15"
25
26
  @headers["Content-Type"] = "text/html; charset=utf-8"
26
27
  end
28
+
29
+ def set_login_from_cookie
30
+ unless session[:person]
31
+ if (person = Person.find_by_name(cookies[:person_name])) and \
32
+ ((!person.user and !cookies[:salted_password]) \
33
+ or (person.user \
34
+ and person.user.salted_password == cookies[:salted_password]))
35
+ session[:person] = person
36
+ session[:user] = person.user
37
+ end
38
+ end
39
+ end
27
40
  end
28
41
 
@@ -15,13 +15,8 @@ class EltController < ApplicationController
15
15
  @elt = Elt.find(params[:id])
16
16
  @title = @elt.subject
17
17
  @title += " (parlement)" if !@title.downcase.include? "parlement"
18
- if request.env['REQUEST_URI'].match '.dyndns'
19
- headers["Status"] = "301 Moved Permanently"
20
- redirect_to request.env['REQUEST_URI'].gsub(/.dyndns/, '')
21
- end
22
18
  render :layout => 'top'
23
19
 
24
- # TODO
25
20
  rescue ActiveRecord::RecordNotFound => e
26
21
  flash[:error] = "Element '#{params[:id]}' does not exist"
27
22
  headers["Status"] = "301 Moved Permanently"
@@ -67,10 +62,6 @@ class EltController < ApplicationController
67
62
  end
68
63
  end
69
64
 
70
- def preview
71
- render :inline => format(params[:elt][:body])
72
- end
73
-
74
65
  def create
75
66
  @elt = Elt.new(params[:elt])
76
67
  @elt.person = @session[:person]
@@ -82,7 +73,7 @@ class EltController < ApplicationController
82
73
  headers["Status"] = "404 Post considered as spam"
83
74
  render :controller => 'elt', :action => 'new', :status => 404
84
75
  elsif params[:submit] == "preview" or (@elt.publish and @elt.parent.add_child(@elt)) then
85
- headers["Status"] = "201 Created"
76
+ #headers["Status"] = "201 Created"
86
77
  render :partial => '/elt/elt', :locals => { :elt => @elt, :eltTop => false }
87
78
  else
88
79
  flash[:notice] = 'Error'
@@ -15,7 +15,7 @@ class PersonController < ApplicationController
15
15
  end
16
16
 
17
17
  def list
18
- @person = Person.find(params[:id]) if @person == nil
18
+ @person = Person.find(params[:id]) unless @person
19
19
  render :partial => '/person/listElts', :locals => { :person => @person }
20
20
  end
21
21
  end
@@ -11,6 +11,7 @@ module EltHelper
11
11
  # 1. numbered list
12
12
  # chat log lines become list elements
13
13
  # short lines to which are added a break
14
+ # positions have a special treatment in the view
14
15
  text = auto_link data \
15
16
  .gsub(/^\b(.*:)$(\n)^>\s/, '\\1<br/>\\2\\2> ') \
16
17
  .gsub(/^Yahoo! Groups Links$(\n{2}^<*.*$\s.*$)*/, '') \
@@ -20,8 +21,19 @@ module EltHelper
20
21
  .gsub(/^\d+[\.-]\s+/, '# ') \
21
22
  .gsub(/^(\d\d:\d\d\s)/, '* \\1') \
22
23
  .gsub(/^\b(.{2,50})$(\n)\b/, '\\1<br/>\\2') \
24
+ .gsub(/\n*^\b(position:\s*(\d*(\.\d+)?))\s*$\n*/, ' <span class="position">\1</span>') \
23
25
  if data != nil
24
26
 
27
+ # Only show the n first paragraphs
28
+ text.gsub!(/((?:(\n)(?:^.+$\n)*){#{NB_PARAGRAPH_TO_DISPLAY}})((?:.|\n)*)/,
29
+ '\1\2<a class="readMore" href="#" onclick="Element.hide(this); Element.removeClassName(this.parentNode.nextSibling, \'tooLarge\'); return false;">Read more...</a>\2<div class="tooLarge">\2\3\2</div>') \
30
+ if data and text.strip =~ /((?:(\n)(?:^.+$\n)*){#{NB_PARAGRAPH_TO_DISPLAY+2}})/
31
+
32
+ # Only show the n*2 first list items
33
+ text.gsub!(/((?:^\*\s+.+$\n){#{NB_PARAGRAPH_TO_DISPLAY*2}})((?:.|\n)*)(\n)/,
34
+ '\1\3\3* <a class="readMore" href="#" onclick="Element.hide(this.parentNode.parentNode); Element.removeClassName(this.parentNode.parentNode.nextSibling.nextSibling, \'tooLarge\'); return false;">Read more...</a>\3\3<div class="tooLarge">\3\3\2</div>') \
35
+ if data and text.strip =~ /(?:(?:^\*\s+.+$\n){#{NB_PARAGRAPH_TO_DISPLAY*2+2}})/
36
+
25
37
  #hard_breaks = true
26
38
  textiled = text.blank? ? "" : RedCloth.new(text)
27
39
  begin
@@ -35,6 +47,8 @@ module EltHelper
35
47
  # Remove any leading and finishing <p> </p> as they are not required
36
48
  if textiled[0..2] == "<p>" then textiled = textiled[3..-1] end
37
49
  if textiled[-4..-1] == "</p>" then textiled = textiled[0..-5] end
50
+ # Here to push away the choice span
51
+ textiled += " "+"&#160;"*22
38
52
  end
39
53
 
40
54
  textiled
data/app/models/elt.rb CHANGED
@@ -56,6 +56,8 @@ class Elt < ActiveRecord::Base
56
56
 
57
57
  build_mail(:elt => self) unless mail
58
58
  mail.publish
59
+
60
+ self.position = Regexp.last_match(1) if body =~ /^\s*position:\s*(\d+(\.\d+)?)(\s|$)/
59
61
  save!
60
62
 
61
63
  parent.vote Regexp.last_match(1), person if body =~ /^\s*(-1|0|\+1)(\s|$)/
data/app/models/mail.rb CHANGED
@@ -98,7 +98,8 @@ class Mail < ActiveRecord::Base
98
98
  || Person.find_by_name(unquote(mail.friendly_from)) \
99
99
  || elt.build_person(:id => unquote(mail.friendly_from).gsub(/\s/, '_'),
100
100
  :name => unquote(mail.friendly_from),
101
- :email => mail.from.first)
101
+ :email => mail.from.first) \
102
+ if not mail.from.first.match(/#{ANONYMOUS_POSTER}@#{ActionMailer::Base.server_settings[:domain]}/)
102
103
 
103
104
  self.mail_parents = mail.references
104
105
  self.message = mail.message_id
@@ -183,9 +184,9 @@ class Mail < ActiveRecord::Base
183
184
 
184
185
  private
185
186
 
186
- # This is to make sure we only have utf-8, no iso-8859
187
+ # This is to make sure we only have text, no iso-8859 or utf-8 encoding
187
188
  def unquote(text)
188
- text.gsub(/\=\?.*?\?\=/) { |m| TMail::Unquoter.unquote_and_convert_to m, 'utf-8' }
189
+ text.gsub(/\=\?(.*)\?(Q|q)\?.*?\?\=/) { |m| TMail::Unquoter.unquote_and_convert_to m, Regexp.last_match(1) }
189
190
  end
190
191
 
191
192
  # Get and store the attachments
@@ -210,9 +211,9 @@ class Mail < ActiveRecord::Base
210
211
  # Here to correct a null character which can occur in some mails
211
212
  # It looks like ==0 or ^@ !!!
212
213
  # Otherwise the elt can not be saved in the db :(
213
- elt.body += Iconv.new(charset, 'utf-8').iconv(attachment.body).gsub(/\0/, '')
214
+ elt.body += Iconv.new(charset, 'iso-8859-1').iconv(attachment.body).gsub(/\0/, '')
214
215
  else
215
- elt.body += Iconv.new(charset, 'utf-8').iconv(attachment.body)
216
+ elt.body += Iconv.new(charset, 'iso-8859-1').iconv(attachment.body)
216
217
  end
217
218
  else
218
219
  # Here too have to remove any eventual null character!
data/app/models/person.rb CHANGED
@@ -14,5 +14,10 @@ class Person < ActiveRecord::Base
14
14
  has_and_belongs_to_many :subscribed_elts,
15
15
  :class_name => "Elt",
16
16
  :join_table => "subscribers"
17
+
18
+ # Convenience method, because User is as it was from the salted login plugin
19
+ def user
20
+ return User.find_by_login(name)
21
+ end
17
22
  end
18
23
 
@@ -7,55 +7,59 @@
7
7
  <%= hidden_field 'elt', 'id' if @elt %>
8
8
  <input type="hidden" id="divId" name="divId" value="<%= divId %>"/>
9
9
 
10
- <div class="login">
11
- <label for="person_name">Pseudo:
12
- <%= text_field "person", "name", :size => 10 %>
10
+ <div class="login">Please, choose a pseudo</div>
11
+
12
+ <label for="person_name">Pseudo:
13
+ <%= text_field "person", "name", :size => 10 %>
14
+ <script type="text/javascript">Form.focusFirstElement(document.forms[0]);</script>
15
+ </label>
16
+
17
+ <%= link_to_function('<span class="icon">&gt;&gt;</span>',
18
+ "Element.toggle(this);" \
19
+ +visual_effect(:Grow, 'user_password_'+divId.to_s) \
20
+ +"Form.focusFirstElement(document.forms[0])") %>
21
+
22
+ <span style="display: none;" id="user_password_<%= divId %>">
23
+ <br/>
24
+ <label for="user_password">Password:
25
+ <%= password_field "user", "password", :size => 10 %>
13
26
  </label>
14
27
 
15
- <%= link_to_function('+',
16
- "Element.show(this);"+visual_effect(:Grow, 'user_password_'+divId.to_s),
17
- :class => "subscribeLink") %>
18
-
19
- <span style="display: none;" id="user_password_<%= divId %>">
20
- <br/>
21
- <label for="user_password">Password:
22
- <%= password_field "user", "password", :size => 10 %>
23
- </label>
24
-
25
- <%= link_to_function('email? &gt;',
26
- "Element.toggle(this);"+visual_effect(:Grow, 'person_email_'+divId.to_s),
27
- :class => "subscribeLink") %>
28
- </span>
29
-
30
- <span style="display: none;" id="person_email_<%= divId %>">
31
- <br/>
32
- <label for="person_email">Email (or check key):</label>
33
- <%= text_field "person", "email", :size => 20 %>
34
- </span>
35
-
36
- <%= submit_tag 'Ok' %>
37
-
38
- <%= render :partial => '/help',
39
- :locals => { :divId => 'login'+divId.to_s, :content => '
40
- <p>You can propose an element with</p>
41
- <ul>
42
- <li>no pseudo</li>
43
- <li>an unprotected pseudo</li>
44
- <li>a password protected pseudo (click on "+")</li>
45
- <li>a password protected and email verified pseudo</li>
46
- </ul>
47
- <p>
48
- The last method is the only secure way to protect a nickname on
49
- <strong>this</strong> server.
50
- </p>
51
- <p>
52
- If a nick is not protected and verified, anybody else can protect it for
53
- themselves if they at least supply a password <em>and</em> an email.
54
- </p>
55
- <p>
56
- A login must contain [3..40] characters, a password [5..40].
57
- </p>
58
- ' } %>
59
- </div>
28
+ <%= link_to_function('<span class="icon">&gt;&gt;</span>',
29
+ "Element.toggle(this);" \
30
+ +visual_effect(:Grow, 'person_email_'+divId.to_s) \
31
+ +"Form.focusFirstElement(document.forms[0])") %>
32
+ </span>
33
+
34
+ <span style="display: none;" id="person_email_<%= divId %>">
35
+ <br/>
36
+ <label for="person_email">Email (or check key):</label>
37
+ <%= text_field "person", "email", :size => 20 %>
38
+ </span>
39
+
40
+ <%= submit_tag 'OK' %>
41
+
42
+ <%= render :partial => '/help',
43
+ :locals => { :divId => 'login'+divId.to_s, :content => '
44
+ <p>You can participate with:</p>
45
+ <ul>
46
+ <li>no pseudo</li>
47
+ <li>an unprotected pseudo</li>
48
+ <li>a password protected pseudo (click on "<span class="icon">&gt;&gt;</span>")</li>
49
+ <li>a password protected and email verified pseudo</li>
50
+ </ul>
51
+ <p>
52
+ The last method is the only secure way to protect a nickname on
53
+ <strong>this</strong> server.
54
+ </p>
55
+ <p>
56
+ If a pseudo is not protected <strong>and</strong> verified, anybody
57
+ else can protect it for themselves if they at least supply a password
58
+ <em>and</em> an email.
59
+ </p>
60
+ <p>
61
+ A login must contain [3..40] characters, a password [5..40].
62
+ </p>
63
+ ' } %>
60
64
  <%= end_form_tag %>
61
65
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  <% if choices ||= false %>
9
9
  <!-- Here are updated all choices, watch out, javascript! -->
10
- <div class="choicesToUpdate" title="choicesToUpdate">
10
+ <span class="choicesToUpdate" title="choicesToUpdate">
11
11
  <%= choices.size %>
12
12
  <script language="JavaScript">
13
13
  var choices_to_update = {
@@ -15,7 +15,7 @@
15
15
  };
16
16
  updateChoices(choices_to_update);
17
17
  </script>
18
- </div>
18
+ </span>
19
19
  <% end %>
20
20
 
21
21
  <% if @person = session[:person] %>
@@ -28,32 +28,33 @@
28
28
  { :href => url_for(:controller => 'account', :action => 'logout') }) %>
29
29
  </span>
30
30
 
31
- <% if session[:person].name and session[:person].name != '' %>
32
- <span class="author">
33
- &lt;<%= link_to session[:person].name,
34
- :controller => 'person',
35
- :action => 'show',
36
- :id => session[:person] %>&gt;
37
- </span>
38
- <% end %>
31
+ <span class="author">
32
+ &lt;<%= link_to session[:person].name,
33
+ :controller => 'person',
34
+ :action => 'show',
35
+ :id => session[:person] %>&gt;
36
+ </span>
39
37
 
40
38
  <div>
41
39
  <%= image_tag (@person.image ? @person.image : "/javascripts/blank.gif"),
42
- :id => "person_avatar", :class => "avatar" %>
40
+ :id => "person_avatar", :class => "avatar" %>
43
41
  </div>
44
42
 
45
43
  <%= form_tag( { :controller => "account", :action => "setAvatar"},
46
44
  :multipart => true, :target => "avatar", :class => "setAvatar") %>
47
45
  <label>
48
46
  Avatar:
49
- <%= file_field "person", "image", :onchange => "submit()" %>
47
+ <%= file_field "person", "image", :onchange => "submit()", :size => "18" %>
50
48
  </label>
51
49
  <%= submit_tag 'Ok' %>
52
50
  <%= end_form_tag %>
53
51
 
54
52
  <iframe id="avatar" name="avatar" style="display: none"></iframe>
53
+
54
+ <script language="JavaScript">Element.show($('subscription'));</script>
55
55
  <% else %>
56
56
 
57
57
  <%= render :partial => '/account/login', :locals => { :divId => divId } %>
58
+ <script language="JavaScript">Element.hide($('subscription'));</script>
58
59
  <% end %>
59
60
 
@@ -5,7 +5,7 @@ result = elt.result
5
5
 
6
6
  <label class="con <%= choice and choice.value == -1 ? "selected" : "" %>"
7
7
  title="-1" for="choice_<%= elt.id %>_con">
8
- V
8
+ <%= image_tag 'vote_minus' %>
9
9
  <%= radio_button_tag "choice[value]", "-1",
10
10
  (choice and choice.value == -1),
11
11
  :id => "choice_#{elt.id}_con",
@@ -22,7 +22,7 @@ result = elt.result
22
22
 
23
23
  <label class="pro <%= choice and choice.value == 1 ? "selected" : "" %>"
24
24
  title="+1" for="choice_<%= elt.id %>_pro">
25
- Λ
25
+ <%= image_tag 'vote_plus' %>
26
26
  <%= radio_button_tag "choice[value]", "+1",
27
27
  (choice and choice.value == +1),
28
28
  :id => "choice_#{elt.id}_pro",
@@ -31,3 +31,12 @@ result = elt.result
31
31
 
32
32
  <%= submit_tag 'Vote!' %>
33
33
 
34
+ <span class="eltQuickAdd" id="eltQuickAdd_<%= elt.id %>" title="<%= elt.created_on %>">
35
+ <%= link_to_remote(image_tag('write'),
36
+ { :update => 'eltNew_'+elt.id.to_s,
37
+ :url => { :controller => 'elt', :action => 'new', :id => elt },
38
+ :loaded => visual_effect(:BlindDown, 'eltNew_'+elt.id.to_s)+
39
+ visual_effect(:BlindDown, 'eltSubsClose_'+elt.id.to_s) },
40
+ { :href => url_for(:controller => 'elt', :action => 'new', :id => @elt)}) %>
41
+ </span>
42
+