Commit dab589514d270bc3e01ca1dc19e46f7d3cbe34d0

Authored by Carlos Purificação
Committed by Alexandre Barbosa
1 parent 27f11bf7

Fixing html_safe for noosfero core

Signed-off-by: Alexandre Barbosa <alexandreab@live.com>
Signed-off-by: Arthur Jahn <stutrzbecher@gmail.com>
Signed-off-by: David Carlos <ddavidcarlos1392@gmail.com>
Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com>
Signed-off-by: Victor Costa <vfcosta@gmail.com>
Showing 106 changed files with 327 additions and 277 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 106 files displayed.

app/controllers/my_profile/cms_controller.rb
... ... @@ -108,7 +108,7 @@ class CmsController &lt; MyProfileController
108 108 end
109 109  
110 110 def new
111   - # FIXME this method should share some logic wirh edit !!!
  111 + # FIXME this method should share some logic with edit !!!
112 112  
113 113 @success_back_to = params[:success_back_to]
114 114 # user must choose an article type first
... ... @@ -365,7 +365,7 @@ class CmsController &lt; MyProfileController
365 365 def search
366 366 query = params[:q]
367 367 results = find_by_contents(:uploaded_files, profile, profile.files.published, query)[:results]
368   - render :text => article_list_to_json(results), :content_type => 'application/json'
  368 + render :text => article_list_to_json(results).html_safe, :content_type => 'application/json'
369 369 end
370 370  
371 371 def search_article_privacy_exceptions
... ...
app/controllers/my_profile/profile_editor_controller.rb
... ... @@ -29,6 +29,7 @@ class ProfileEditorController &lt; MyProfileController
29 29 Image.transaction do
30 30 begin
31 31 @plugins.dispatch(:profile_editor_transaction_extras)
  32 + # TODO: This is unsafe! Add sanitizer
32 33 @profile_data.update!(params[:profile_data])
33 34 redirect_to :action => 'index', :profile => profile.identifier
34 35 rescue Exception => ex
... ...
app/helpers/action_tracker_helper.rb
... ... @@ -15,12 +15,12 @@ module ActionTrackerHelper
15 15 end
16 16  
17 17 def join_community_description ta
18   - n_('has joined 1 community:<br />%{name}', 'has joined %{num} communities:<br />%{name}', ta.get_resource_name.size) % {
  18 + n_('has joined 1 community:<br />%{name}'.html_safe, 'has joined %{num} communities:<br />%{name}'.html_safe, ta.get_resource_name.size) % {
19 19 num: ta.get_resource_name.size,
20 20 name: ta.collect_group_with_index(:resource_name) do |n,i|
21   - link_to image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")),
  21 + link = link_to image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")),
22 22 ta.get_resource_url[i], title: n
23   - end.join
  23 + end.join.html_safe
24 24 }
25 25 end
26 26  
... ...
app/helpers/application_helper.rb
... ... @@ -99,7 +99,6 @@ module ApplicationHelper
99 99 #
100 100 # TODO: implement correcly the 'Help' button click
101 101 def help(content = nil, link_name = nil, options = {}, &block)
102   -
103 102 link_name ||= _('Help')
104 103  
105 104 @help_message_id ||= 1
... ... @@ -122,7 +121,7 @@ module ApplicationHelper
122 121 button = link_to_function(content_tag('span', link_name), "Element.show('#{help_id}')", options )
123 122 close_button = content_tag("div", link_to_function(_("Close"), "Element.hide('#{help_id}')", :class => 'close_help_button'))
124 123  
125   - text = content_tag('div', button + content_tag('div', content_tag('div', content) + close_button, :class => 'help_message', :id => help_id, :style => 'display: none;'), :class => 'help_box')
  124 + text = content_tag('div', button + content_tag('div', content_tag('div', content.html_safe) + close_button, :class => 'help_message', :id => help_id, :style => 'display: none;'), :class => 'help_box')
126 125  
127 126 unless block.nil?
128 127 concat(text)
... ... @@ -362,8 +361,8 @@ module ApplicationHelper
362 361 def popover_menu(title,menu_title,links,html_options={})
363 362 html_options[:class] = "" unless html_options[:class]
364 363 html_options[:class] << " menu-submenu-trigger"
365   - html_options[:onclick] = "toggleSubmenu(this, '#{menu_title}', #{CGI::escapeHTML(links.to_json)}); return false"
366 364  
  365 + html_options[:onclick] = "toggleSubmenu(this, '#{menu_title}', #{CGI::escapeHTML(links.to_json)}); return false".html_safe
367 366 link_to(content_tag(:span, title), '#', html_options)
368 367 end
369 368  
... ... @@ -473,9 +472,9 @@ module ApplicationHelper
473 472 map(&:role)
474 473 names = []
475 474 roles.each do |role|
476   - names << content_tag('span', role.name, :style => "color: #{role_color(role, resource.environment.id)}")
  475 + names << content_tag('span', role.name, :style => "color: #{role_color(role, resource.environment.id)}").html_safe
477 476 end
478   - names.join(', ')
  477 + safe_join(names, ', ')
479 478 end
480 479  
481 480 def role_color(role, env_id)
... ... @@ -911,7 +910,8 @@ module ApplicationHelper
911 910 end
912 911  
913 912 def admin_link
914   - user.is_admin?(environment) ? link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', environment.admin_url, :title => _("Configure the environment"), :class => 'admin-link') : ''
  913 + admin_icon = '<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>'
  914 + user.is_admin?(environment) ? link_to(admin_icon.html_safe, environment.admin_url, :title => _("Configure the environment"), :class => 'admin-link') : ''
915 915 end
916 916  
917 917 def usermenu_logged_in
... ... @@ -920,23 +920,39 @@ module ApplicationHelper
920 920 if count > 0
921 921 pending_tasks_count = link_to(count.to_s, user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks"))
922 922 end
  923 + user_identifier = "<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>"
  924 + welcome_link = link_to(user_identifier.html_safe, user.public_profile_url, :id => "homepage-link", :title => _('Go to your homepage'))
  925 + welcome_span = _("<span class='welcome'>Welcome,</span> %s") % welcome_link.html_safe
  926 + ctrl_panel_icon = '<i class="icon-menu-ctrl-panel"></i>'
  927 + ctrl_panel_section = '<strong>' + ctrl_panel_icon + _('Control panel') + '</strong>'
  928 + ctrl_panel_link = link_to(ctrl_panel_section.html_safe, user.admin_url, :class => 'ctrl-panel', :title => _("Configure your personal account and content"))
  929 + logout_icon = '<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>'
  930 + logout_link = link_to(logout_icon.html_safe, { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system"))
  931 + join_result = safe_join(
  932 + [welcome_span.html_safe, render_environment_features(:usermenu).html_safe, admin_link.html_safe,
  933 + manage_enterprises.html_safe, manage_communities.html_safe, ctrl_panel_link.html_safe,
  934 + pending_tasks_count.html_safe, logout_link.html_safe], "")
  935 + join_result
  936 + end
923 937  
924   - (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.url, :id => "homepage-link", :title => _('Go to your homepage'))) +
925   - render_environment_features(:usermenu) +
926   - admin_link +
927   - manage_enterprises +
928   - manage_communities +
929   - link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', user.admin_url, :class => 'ctrl-panel', :title => _("Configure your personal account and content")) +
930   - pending_tasks_count +
931   - link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system"))
  938 + def usermenu_notlogged_in
  939 + login_str = '<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>'
  940 + ret = _("<span class='login'>%s</span>") % modal_inline_link_to(login_str.html_safe, login_url, '#inlineLoginBox', :id => 'link_login')
  941 + return ret.html_safe
932 942 end
933 943  
  944 + def usermenu_signup
  945 + signup_str = '<strong>' + _('Sign up') + '</strong>'
  946 + ret = _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to(signup_str.html_safe, :controller => 'account', :action => 'signup')
  947 + return ret.html_safe
  948 +
  949 + end
934 950 def limited_text_area(object_name, method, limit, text_area_id, options = {})
935   - content_tag(:div, [
  951 + content_tag(:div, safe_join([
936 952 text_area(object_name, method, { :id => text_area_id, :onkeyup => "limited_text_area('#{text_area_id}', #{limit})" }.merge(options)),
937 953 content_tag(:p, content_tag(:span, limit) + ' ' + _(' characters left'), :id => text_area_id + '_left'),
938 954 content_tag(:p, _('Limit of characters reached'), :id => text_area_id + '_limit', :style => 'display: none')
939   - ].join, :class => 'limited-text-area')
  955 + ]), :class => 'limited-text-area')
940 956 end
941 957  
942 958 def expandable_text_area(object_name, method, text_area_id, options = {})
... ... @@ -1032,8 +1048,8 @@ module ApplicationHelper
1032 1048 end
1033 1049  
1034 1050 def render_tabs(tabs)
1035   - titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
1036   - contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
  1051 + titles = tabs.inject(''.html_safe){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
  1052 + contents = tabs.inject(''.html_safe){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
1037 1053  
1038 1054 content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs')
1039 1055 end
... ... @@ -1051,7 +1067,7 @@ module ApplicationHelper
1051 1067 def expirable_link_to(expired, content, url, options = {})
1052 1068 if expired
1053 1069 options[:class] = (options[:class] || '') + ' disabled'
1054   - content_tag('a', '&nbsp;'+content_tag('span', content), options)
  1070 + content_tag('a', '&nbsp;'.html_safe+content_tag('span', content), options)
1055 1071 else
1056 1072 if options[:modal]
1057 1073 options.delete(:modal)
... ... @@ -1084,7 +1100,7 @@ module ApplicationHelper
1084 1100  
1085 1101 radios = templates.map do |template|
1086 1102 content_tag('li', labelled_radio_button(link_to(template.name, template.url, :target => '_blank'), "#{field_name}[template_id]", template.id, environment.is_default_template?(template)))
1087   - end.join("\n")
  1103 + end.join("\n").html_safe
1088 1104  
1089 1105 content_tag('div', content_tag('label', _('Profile organization'), :for => 'template-options', :class => 'formlabel') +
1090 1106 content_tag('p', _('Your profile will be created according to the selected template. Click on the options to view them.'), :style => 'margin: 5px 15px;padding: 0px 10px;') +
... ... @@ -1124,7 +1140,7 @@ module ApplicationHelper
1124 1140 content_tag(:div, :class => 'errorExplanation', :id => 'errorExplanation') do
1125 1141 content_tag(:h2, _('Errors while saving')) +
1126 1142 content_tag(:ul) do
1127   - errors.map { |err| content_tag(:li, err) }.join
  1143 + safe_join(errors.map { |err| content_tag(:li, err) })
1128 1144 end
1129 1145 end
1130 1146 end
... ... @@ -1234,6 +1250,7 @@ module ApplicationHelper
1234 1250 :href=>"#",
1235 1251 :title=>_("Exit full screen mode")
1236 1252 })
  1253 + content.html_safe
1237 1254 end
1238 1255  
1239 1256 end
... ...
app/helpers/block_helper.rb
... ... @@ -3,13 +3,13 @@ module BlockHelper
3 3 def block_title(title, subtitle=nil)
4 4 block_header = block_heading title
5 5 block_header += block_heading(subtitle, 'h4') if subtitle
6   - content_tag 'div', block_header, :class => 'block-header'
  6 + content_tag('div', block_header, :class => 'block-header').html_safe
7 7 end
8 8  
9 9 def block_heading(title, heading='h3')
10 10 tag_class = 'block-' + (heading == 'h3' ? 'title' : 'subtitle')
11 11 tag_class += ' empty' if title.empty?
12   - content_tag heading, content_tag('span', h(title)), :class => tag_class
  12 + content_tag heading, content_tag('span', h(title)), :class => tag_class.html_safe
13 13 end
14 14  
15 15 def highlights_block_config_image_fields(block, image={}, row_number=nil)
... ...
app/helpers/blog_helper.rb
... ... @@ -41,12 +41,12 @@ module BlogHelper
41 41 css_add << position
42 42 content << (content_tag 'div', id: "post-#{art.id}", class: css_add do
43 43 content_tag 'div', class: position + '-inner blog-post-inner' do
44   - display_post(art, conf[:format]).html_safe +
45   - '<br style="clear:both"/>'.html_safe
  44 + display_post(art, conf[:format]) +
  45 + '<br style="clear:both"/>'
46 46 end
47   - end)
  47 + end).html_safe
48 48 }
49   - content.join("\n<hr class='sep-posts'/>\n") + (pagination or '')
  49 + safe_join(content, "\n<hr class='sep-posts'/>\n") + (pagination or '').html_safe
50 50 end
51 51  
52 52 def display_post(article, format = 'full')
... ... @@ -61,7 +61,8 @@ module BlogHelper
61 61 else
62 62 '<div class="post-pic" style="background-image:url('+img+')"></div>'
63 63 end
64   - end.to_s + title + html
  64 + end.to_s.html_safe +
  65 + title.html_safe + html
65 66 end
66 67  
67 68 def display_compact_format(article)
... ...
app/helpers/box_organizer_helper.rb
... ... @@ -38,7 +38,7 @@ module BoxOrganizerHelper
38 38 content_tag(:ul,
39 39 images_path.map do |preview|
40 40 content_tag(:li, image_tag(preview, height: '240', alt: ''))
41   - end.join("\n")
  41 + end.join("\n").html_safe
42 42 )
43 43 end
44 44  
... ...
app/helpers/boxes_helper.rb
... ... @@ -44,7 +44,7 @@ module BoxesHelper
44 44  
45 45 def display_boxes(holder, main_content)
46 46 boxes = holder.boxes.with_position.first(boxes_limit(holder))
47   - content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n")
  47 + content = safe_join(boxes.reverse.map { |item| display_box(item, main_content) }, "\n")
48 48 content = main_content if (content.blank?)
49 49  
50 50 content_tag('div', content, :class => 'boxes', :id => 'boxes' )
... ... @@ -54,7 +54,7 @@ module BoxesHelper
54 54 if holder.respond_to?(element)
55 55 content_tag('div', holder.send(element), options)
56 56 else
57   - ''
  57 + ''.html_safe
58 58 end
59 59 end
60 60  
... ... @@ -70,9 +70,10 @@ module BoxesHelper
70 70  
71 71 def display_box_content(box, main_content)
72 72 context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params, :user => user, :controller => controller }
73   - box_decorator.select_blocks(box, box.blocks.includes(:box), context).map do |item|
  73 + blocks = box_decorator.select_blocks(box, box.blocks.includes(:box), context).map do |item|
74 74 display_block item, main_content
75   - end.join("\n") + box_decorator.block_target(box)
  75 + end
  76 + safe_join(blocks, "\n") + box_decorator.block_target(box)
76 77 end
77 78  
78 79 def select_blocks box, arr, context
... ... @@ -136,17 +137,18 @@ module BoxesHelper
136 137  
137 138 result = filter_html(result, block)
138 139  
139   - content_tag('div',
140   - box_decorator.block_target(block.box, block) +
141   - content_tag('div',
142   - content_tag('div',
143   - content_tag('div',
144   - result + footer_content + box_decorator.block_edit_buttons(block),
145   - :class => 'block-inner-2'),
146   - :class => 'block-inner-1'),
147   - options),
148   - :class => 'block-outer') +
149   - box_decorator.block_handle(block)
  140 + join_result = safe_join([result, footer_content, box_decorator.block_edit_buttons(block)])
  141 + content_tag_inner_1 = content_tag('div', join_result, :class => 'block-inner-2')
  142 +
  143 + content_tag_inner_2 = content_tag('div', content_tag_inner_1, :class => 'block-inner-1')
  144 + content_tag_inner_3 = content_tag('div', content_tag_inner_2, options)
  145 + content_tag_inner_4 = box_decorator.block_target(block.box, block) + content_tag_inner_3
  146 + c = content_tag('div', content_tag_inner_4, :class => 'block-outer')
  147 + box_decorator_result = box_decorator.block_handle(block)
  148 + result_final = safe_join([c, box_decorator_result], "")
  149 +
  150 +
  151 + return result_final
150 152 end
151 153  
152 154 def wrap_main_content(content)
... ... @@ -156,17 +158,17 @@ module BoxesHelper
156 158 def extract_block_content(content)
157 159 case content
158 160 when Hash
159   - content_tag('iframe', '', :src => url_for(content))
  161 + content_tag('iframe', ''.html_safe, :src => url_for(content))
160 162 when String
161 163 if content.split("\n").size == 1 and content =~ /^https?:\/\//
162   - content_tag('iframe', '', :src => content)
  164 + content_tag('iframe', ''.html_safe, :src => content)
163 165 else
164 166 content
165 167 end
166 168 when Proc
167 169 self.instance_eval(&content)
168 170 when NilClass
169   - ''
  171 + ''.html_safe
170 172 else
171 173 raise "Unsupported content for block (#{content.class})"
172 174 end
... ... @@ -175,14 +177,14 @@ module BoxesHelper
175 177 module DontMoveBlocks
176 178 # does nothing
177 179 def self.block_target(box, block = nil)
178   - ''
  180 + ''.html_safe
179 181 end
180 182 # does nothing
181 183 def self.block_handle(block)
182   - ''
  184 + ''.html_safe
183 185 end
184 186 def self.block_edit_buttons(block)
185   - ''
  187 + ''.html_safe
186 188 end
187 189 def self.select_blocks box, arr, context
188 190 arr = arr.select{ |block| block.visible? context }
... ... @@ -229,9 +231,9 @@ module BoxesHelper
229 231 # makes the given block draggable so it can be moved away.
230 232 def block_handle(block)
231 233 return "" unless movable?(block)
232   - icon = "<div><div>#{display_icon(block.class)}</div><span>#{_(block.class.pretty_name)}</span></div>"
  234 + icon = "<div><div>#{display_icon(block.class)}</div><span>#{_(block.class.pretty_name)}</span></div>".html_safe
233 235 block_draggable("block-#{block.id}",
234   - :helper => "function() {return cloneDraggableBlock($(this), '#{icon}')}")
  236 + :helper => "function() {return cloneDraggableBlock($(this), '#{icon}')}".html_safe)
235 237 end
236 238  
237 239 def block_draggable(element_id, options={})
... ... @@ -302,7 +304,7 @@ module BoxesHelper
302 304 buttons << modal_inline_icon(:embed, _('Embed code'), {}, "#embed-code-box-#{block.id}") << html
303 305 end
304 306  
305   - content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar')
  307 + content_tag('div', buttons.join("\n").html_safe + tag('br', :style => 'clear: left'), :class => 'button-bar')
306 308 end
307 309  
308 310 def current_blocks
... ...
app/helpers/buttons_helper.rb
... ... @@ -15,9 +15,9 @@ module ButtonsHelper
15 15 end
16 16 the_title = html_options[:title] || label
17 17 if html_options[:disabled]
18   - content_tag('a', '&nbsp;'+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title))
  18 + content_tag('a', '&nbsp;'.html_safe+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title))
19 19 else
20   - link_to('&nbsp;'+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title))
  20 + link_to('&nbsp;'.html_safe+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title))
21 21 end
22 22 end
23 23  
... ...
app/helpers/catalog_helper.rb
... ... @@ -19,18 +19,18 @@ module CatalogHelper
19 19 ancestors = category.ancestors.map { |c| link_to(c.name, {:controller => :catalog, :action => 'index', :level => c.id}) }.reverse
20 20 current_level = content_tag('strong', category.name)
21 21 all_items = [start] + ancestors + [current_level]
22   - content_tag('div', all_items.join(' &rarr; '), :id => 'breadcrumb')
  22 + content_tag('div', safe_join(all_items, ' &rarr; '), :id => 'breadcrumb')
23 23 end
24 24  
25 25 def category_link(category)
26 26 count = profile.products.from_category(category).count
27 27 name = truncate(category.name, :length => 22 - count.to_s.size)
28 28 link = link_to(name, {:controller => 'catalog', :action => 'index', :level => category.id}, :title => category.name)
29   - content_tag('div', "#{link} <span class=\"count\">#{count}</span>") if count > 0
  29 + content_tag('div', "#{link} <span class=\"count\">#{count}</span>".html_safe) if count > 0
30 30 end
31 31  
32 32 def category_with_sub_list(category)
33   - content_tag 'li', "#{category_link(category)}\n#{sub_category_list(category)}"
  33 + content_tag 'li', "#{category_link(category)}\n#{sub_category_list(category)}".html_safe
34 34 end
35 35  
36 36 def sub_category_list(category)
... ... @@ -39,7 +39,7 @@ module CatalogHelper
39 39 cat_link = category_link sub_category
40 40 sub_categories << content_tag('li', cat_link) unless cat_link.nil?
41 41 end
42   - content_tag('ul', sub_categories.join) if sub_categories.size > 0
  42 + content_tag('ul', sub_categories.join.html_safe) if sub_categories.size > 0
43 43 end
44 44  
45 45 end
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -7,7 +7,8 @@ module ContentViewerHelper
7 7 def display_number_of_comments(n)
8 8 base_str = "<span class='comment-count hide'>#{n}</span>"
9 9 amount_str = n == 0 ? _('no comments yet') : (n == 1 ? _('One comment') : _('%s comments') % n)
10   - base_str + "<span class='comment-count-write-out'>#{amount_str}</span>"
  10 + base_str += "<span class='comment-count-write-out'>#{amount_str}</span>"
  11 + base_str.html_safe
11 12 end
12 13  
13 14 def number_of_comments(article)
... ... @@ -19,11 +20,11 @@ module ContentViewerHelper
19 20 title = content_tag('h1', h(title), :class => 'title')
20 21 if article.belongs_to_blog? || article.belongs_to_forum?
21 22 unless args[:no_link]
22   - title = content_tag('h1', link_to(article.name, article.url), :class => 'title')
  23 + title = content_tag('h1', link_to(article.name, url_for(article.url)), :class => 'title')
23 24 end
24 25 comments = ''
25 26 unless args[:no_comments] || !article.accept_comments
26   - comments = (" - %s") % link_to_comments(article)
  27 + comments = (" - %s").html_safe % link_to_comments(article)
27 28 end
28 29 date_format = show_with_right_format_date article
29 30 title << content_tag('span',
... ...
app/helpers/display_helper.rb
... ... @@ -53,18 +53,19 @@ module DisplayHelper
53 53 end
54 54  
55 55 def txt2html(txt)
56   - txt.strip.
  56 + ret = txt.strip.
57 57 gsub( /\s*\n\s*\n\s*/, "\r<p/>\r" ).
58 58 gsub( /\s*\n\s*/, "\n<br/>\n" ).
59 59 gsub( /\r/, "\n" ).
60 60 gsub( /(^|\s)(www\.[^\s]+|https?:\/\/[^\s]+)/ ) do
61 61 pre_char, href = $1, $2
62 62 href = 'http://'+href if ! href.match /^https?:/
63   - content = href.gsub(/^https?:\/\//, '').scan(/.{1,4}/).join('&#x200B;')
  63 + content = safe_join(href.gsub(/^https?:\/\//, '').scan(/.{1,4}/), '&#x200B;'.html_safe)
64 64 pre_char +
65 65 content_tag(:a, content, :href => href, :target => '_blank',
66   - :rel => 'nofolow', :onclick => "return confirm('%s')" %
  66 + :rel => 'nofolow', :onclick => "return confirm('%s')".html_safe %
67 67 _('Are you sure you want to visit this web site?'))
68 68 end
  69 + ret.html_safe
69 70 end
70 71 end
... ...
app/helpers/events_helper.rb
1 1 module EventsHelper
2 2  
3 3 include DatesHelper
  4 + include ActionView::Helpers::OutputSafetyHelper
  5 +
4 6 def list_events(date, events)
5 7 title = _('Events for %s') % show_date_month(date)
  8 + user_events = events.select { |item| item.display_to?(user) }
  9 + events_for_month = safe_join(user_events.map {|item| display_event_in_listing(item)}, '')
6 10 content_tag('h2', title) +
7 11 content_tag('div',
8 12 (events.any? ?
9   - content_tag('table', events.select { |item| item.display_to?(user) }.map {|item| display_event_in_listing(item)}.join('')) :
10   - content_tag('em', _('No events for this month'), :class => 'no-events')
  13 + content_tag('table', events_for_month) :
  14 + content_tag('em', _('No events for this month'), :class => 'no-events')
11 15 ), :id => 'agenda-items'
12 16 )
13 17 end
... ...
app/helpers/forms_helper.rb
... ... @@ -101,7 +101,7 @@ module FormsHelper
101 101  
102 102 def required_fields_message
103 103 content_tag('p', content_tag('span',
104   - _("The <label class='pseudoformlabel'>highlighted</label> fields are mandatory."),
  104 + _("The <label class='pseudoformlabel'>highlighted</label> fields are mandatory.").html_safe,
105 105 :class => 'required-field'
106 106 ))
107 107 end
... ... @@ -112,10 +112,11 @@ module FormsHelper
112 112 options_for_select = container.inject([]) do |options, element|
113 113 text, value = option_text_and_value(element)
114 114 selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
115   - options << %(<option title="#{html_escape(text.to_s)}" value="#{html_escape(value.to_s)}"#{selected_attribute}>#{html_escape(text.to_s)}</option>)
  115 + opt = %(<option title="#{html_escape(text.to_s)}" value="#{html_escape(value.to_s)}"#{selected_attribute}>#{html_escape(text.to_s)}</option>)
  116 + options << opt.html_safe
116 117 end
117 118  
118   - options_for_select.join("\n")
  119 + safe_join(options_for_select, "\n")
119 120 end
120 121  
121 122 def balanced_table(items, per_row=3)
... ... @@ -248,8 +249,8 @@ module FormsHelper
248 249 def date_range_field(from_name, to_name, from_value, to_value, datepicker_options = {}, html_options = {})
249 250 from_id = html_options[:from_id] || 'datepicker-from-date'
250 251 to_id = html_options[:to_id] || 'datepicker-to-date'
251   - return _('From') +' '+ date_field(from_name, from_value, datepicker_options, html_options.merge({:id => from_id})) +
252   - ' ' + _('until') +' '+ date_field(to_name, to_value, datepicker_options, html_options.merge({:id => to_id}))
  252 + return (_('From') +' '+ date_field(from_name, from_value, datepicker_options, html_options.merge({:id => from_id})) +
  253 + ' ' + _('until') +' '+ date_field(to_name, to_value, datepicker_options, html_options.merge({:id => to_id}))).html_safe
253 254 end
254 255  
255 256 def select_folder(label_text, field_id, collection, default_value=nil, html_options = {}, js_options = {})
... ...
app/helpers/forum_helper.rb
... ... @@ -35,7 +35,7 @@ module ForumHelper
35 35 :id => "post-#{art.id}"
36 36 )
37 37 }
38   - content_tag('table', content.join) + (pagination or '')
  38 + content_tag('table', safe_join(content, "")) + (pagination or '').html_safe
39 39 end
40 40  
41 41 def last_topic_update(article)
... ...
app/helpers/language_helper.rb
... ... @@ -40,7 +40,7 @@ module LanguageHelper
40 40 else
41 41 link_to(name, params.merge(:lang => code), :rel => 'nofollow')
42 42 end
43   - end.join(separator)
  43 + end.join(separator).html_safe
44 44 content_tag('div', languages, :id => 'language-chooser', :help => _('The language you choose here is the language used for options, buttons, etc. It does not affect the language of the content created by other users.'))
45 45 end
46 46 end
... ...
app/helpers/layout_helper.rb
... ... @@ -40,7 +40,8 @@ module LayoutHelper
40 40  
41 41 output += templete_javascript_ng.to_s
42 42  
43   - output
  43 + # This output should be safe!
  44 + output.html_safe
44 45 end
45 46  
46 47 def noosfero_stylesheets
... ... @@ -64,7 +65,9 @@ module LayoutHelper
64 65 output << stylesheet_link_tag(global_css_pub)
65 66 end
66 67 output << stylesheet_link_tag(theme_stylesheet_path)
67   - output.join "\n"
  68 +
  69 + # This output should be safe!
  70 + output.join("\n").html_safe
68 71 end
69 72  
70 73 def noosfero_layout_features
... ...
app/helpers/manage_products_helper.rb
... ... @@ -38,10 +38,11 @@ module ManageProductsHelper
38 38 end
39 39  
40 40 def options_for_select_categories(categories, selected = nil)
41   - categories.sort_by{|cat| cat.name.transliterate}.map do |category|
42   - selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '')
43   - "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{category.name + (category.leaf? ? '': ' &raquo;')}</option>"
44   - end.join("\n")
  41 + safe_join(categories.sort_by{ |cat|
  42 + cat.name.transliterate}.map do |category|
  43 + selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '')
  44 + "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{category.name + (category.leaf? ? '': ' &raquo;')}</option>".html_safe
  45 + end, "\n")
45 46 end
46 47  
47 48 def build_selects_for_ancestors(ancestors, current_category)
... ... @@ -76,10 +77,13 @@ module ManageProductsHelper
76 77  
77 78 def categories_container(categories_selection_html, hierarchy_html = '')
78 79 content_tag 'div',
79   - render('categories_autocomplete') +
80   - hidden_field_tag('selected_category_id') +
81   - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +
82   - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper'),
  80 + safe_join(
  81 + [
  82 + render('categories_autocomplete'),
  83 + hidden_field_tag('selected_category_id'),
  84 + content_tag('div', hierarchy_html, :id => 'hierarchy_navigation'),
  85 + content_tag('div', categories_selection_html, :id => 'categories_container_wrapper')
  86 + ], ''),
83 87 :id => 'categories-container'
84 88 end
85 89  
... ...
app/helpers/profile_editor_helper.rb
... ... @@ -129,7 +129,11 @@ module ProfileEditorHelper
129 129 else
130 130 domains = environment.domains
131 131 end
132   - labelled_form_field(_('Preferred domain name:'), select(object, :preferred_domain_id, domains.map {|item| [item.name, item.id]}, :prompt => '&lt;' + _('Select domain') + '&gt;'))
  132 + select_domain_prompt = '&lt;'.html_safe + _('Select domain').html_safe + '&gt;'.html_safe
  133 + select_field = select(object, :preferred_domain_id, domains.map {
  134 + |item| [item.name, item.id]}, :prompt => select_domain_prompt.html_safe)
  135 +
  136 + labelled_form_field(_('Preferred domain name:'), select_field)
133 137 end
134 138  
135 139 def control_panel(&block)
... ...
app/helpers/profile_image_helper.rb
... ... @@ -131,7 +131,7 @@ module ProfileImageHelper
131 131 links = links_for_balloon(profile)
132 132 content_tag('div', content_tag(tag,
133 133 (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ?
134   - popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "") +
  134 + popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "").html_safe +
135 135 link_to(
136 136 content_tag( 'span', profile_image( profile, size ), :class => img_class ) +
137 137 content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) +
... ... @@ -139,7 +139,7 @@ module ProfileImageHelper
139 139 profile.url,
140 140 :class => 'profile_link url',
141 141 :help => _('Click on this icon to go to the <b>%s</b>\'s home page') % profile.name,
142   - :title => profile.name ),
  142 + :title => profile.name ).html_safe,
143 143 :class => 'vcard'), :class => 'common-profile-list-block')
144 144 end
145 145 end
... ...
app/helpers/search_helper.rb
... ... @@ -124,10 +124,10 @@ module SearchHelper
124 124 def filters(asset)
125 125 return if !asset
126 126 klass = asset_class(asset)
127   - content_tag('div', klass::SEARCH_FILTERS.map do |name, options|
  127 + content_tag('div', safe_join(klass::SEARCH_FILTERS.map do |name, options|
128 128 default = klass.respond_to?("default_search_#{name}") ? klass.send("default_search_#{name}".to_s) : nil
129 129 select_filter(name, options, default)
130   - end.join("\n"), :id => 'search-filters')
  130 + end, "\n"), :id => 'search-filters')
131 131 end
132 132  
133 133 def assets_menu(selected)
... ... @@ -137,11 +137,11 @@ module SearchHelper
137 137 # menu.
138 138 assets.delete(:events)
139 139 content_tag('ul',
140   - assets.map do |asset|
  140 + safe_join(assets.map do |asset|
141 141 options = {}
142 142 options.merge!(:class => 'selected') if selected.to_s == asset.to_s
143 143 content_tag('li', asset_link(asset), options)
144   - end.join("\n"),
  144 + end, "\n"),
145 145 :id => 'assets-menu')
146 146 end
147 147  
... ...
app/helpers/tags_helper.rb
... ... @@ -58,7 +58,7 @@ module TagsHelper
58 58  
59 59 if options[:show_count]
60 60 display_count = options[:show_count] ? "<small><sup>(#{count})</sup></small>" : ""
61   - link_to tag + display_count, destination, :style => style
  61 + link_to (tag + display_count).html_safe, destination, :style => style
62 62 else
63 63 link_to h(tag) , destination, :style => style,
64 64 :title => n_( 'one item', '%d items', count ) % count
... ...
app/helpers/tinymce_helper.rb
... ... @@ -7,7 +7,7 @@ module TinymceHelper
7 7 output += javascript_include_tag 'tinymce/js/tinymce/jquery.tinymce.min.js'
8 8 output += javascript_include_tag 'tinymce.js'
9 9 output += include_macro_js_files.to_s
10   - output
  10 + output.html_safe
11 11 end
12 12  
13 13 def tinymce_init_js options = {}
... ... @@ -37,7 +37,7 @@ module TinymceHelper
37 37 #cleanup non tinymce options
38 38 options = options.except :mode
39 39  
40   - "noosfero.tinymce.init(#{options.to_json})"
  40 + "noosfero.tinymce.init(#{options.to_json})".html_safe
41 41 end
42 42  
43 43 def menubar mode
... ...
app/models/approve_article.rb
... ... @@ -86,7 +86,7 @@ class ApproveArticle &lt; Task
86 86  
87 87 def information
88 88 if article
89   - {:message => _('%{requestor} wants to publish the article: %{linked_subject}.')}
  89 + {:message => _('%{requestor} wants to publish the article: %{linked_subject}.').html_safe}
90 90 else
91 91 {:message => _("The article was removed.")}
92 92 end
... ...
app/models/create_community.rb
... ... @@ -60,9 +60,9 @@ class CreateCommunity &lt; Task
60 60  
61 61 def information
62 62 if description.blank?
63   - { :message => _('%{requestor} wants to create community %{subject} with no description.') }
  63 + { :message => _('%{requestor} wants to create community %{subject} with no description.').html_safe }
64 64 else
65   - { :message => _('%{requestor} wants to create community %{subject} with this description:<p><em>%{description}</em></p>'),
  65 + { :message => _('%{requestor} wants to create community %{subject} with this description:<p><em>%{description}</em></p>').html_safe,
66 66 :variables => {:description => description} }
67 67 end
68 68 end
... ...
app/models/create_enterprise.rb
... ... @@ -163,7 +163,7 @@ class CreateEnterprise &lt; Task
163 163 end
164 164  
165 165 def information
166   - {:message => _('%{requestor} wants to create enterprise %{subject}.')}
  166 + {:message => _('%{requestor} wants to create enterprise %{subject}.').html_safe}
167 167 end
168 168  
169 169 def reject_details
... ...
app/models/doc_item.rb
... ... @@ -17,7 +17,7 @@ class DocItem
17 17 else
18 18 match
19 19 end
20   - end
  20 + end.html_safe
21 21 end
22 22  
23 23 private
... ...
app/models/environment.rb
... ... @@ -729,7 +729,7 @@ class Environment &lt; ActiveRecord::Base
729 729 url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname)
730 730 url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port)
731 731 url << Noosfero.root('')
732   - url
  732 + url.html_safe
733 733 end
734 734  
735 735 def to_s
... ...
app/models/invite_friend.rb
... ... @@ -13,7 +13,7 @@ class InviteFriend &lt; Invitation
13 13 end
14 14  
15 15 def information
16   - {:message => _('%{requestor} wants to be your friend.')}
  16 + {:message => _('%{requestor} wants to be your friend.').html_safe}
17 17 end
18 18  
19 19 def accept_details
... ... @@ -25,7 +25,7 @@ class InviteFriend &lt; Invitation
25 25 end
26 26  
27 27 def target_notification_description
28   - _('%{requestor} wants to be your friend.') % {:requestor => requestor.name}
  28 + (_('%{requestor} wants to be your friend.') % {:requestor => requestor.name}).html_safe
29 29 end
30 30  
31 31 def permission
... ...
app/models/invite_member.rb
... ... @@ -25,7 +25,7 @@ class InviteMember &lt; Invitation
25 25 end
26 26  
27 27 def information
28   - {:message => _('%{requestor} invited you to join %{linked_subject}.')}
  28 + {:message => _('%{requestor} invited you to join %{linked_subject}.').html_safe}
29 29 end
30 30  
31 31 def url
... ... @@ -37,7 +37,7 @@ class InviteMember &lt; Invitation
37 37 end
38 38  
39 39 def target_notification_description
40   - _('%{requestor} invited you to join %{community}.') % {:requestor => requestor.name, :community => community.name}
  40 + (_('%{requestor} invited you to join %{community}.') % {:requestor => requestor.name, :community => community.name}).html_safe
41 41 end
42 42  
43 43 def target_notification_message
... ...
app/models/profile.rb
... ... @@ -646,7 +646,7 @@ class Profile &lt; ActiveRecord::Base
646 646 url << url_options[:host]
647 647 url << ':' << url_options[:port].to_s if url_options.key?(:port)
648 648 url << Noosfero.root('')
649   - url
  649 + url.html_safe
650 650 end
651 651  
652 652 private :generate_url, :url_options
... ...
app/models/suggest_article.rb
... ... @@ -65,7 +65,7 @@ class SuggestArticle &lt; Task
65 65  
66 66 def information
67 67 variables = requestor.blank? ? {:requestor => sender} : {}
68   - { :message => _('%{requestor} suggested the publication of the article: %{subject}.'),
  68 + { :message => _('%{requestor} suggested the publication of the article: %{subject}.').html_safe,
69 69 :variables => variables }
70 70 end
71 71  
... ... @@ -78,7 +78,7 @@ class SuggestArticle &lt; Task
78 78 end
79 79  
80 80 def target_notification_description
81   - _('%{requestor} suggested the publication of the article: %{article}.') %
  81 + _('%{requestor} suggested the publication of the article: %{article}.').html_safe %
82 82 {:requestor => sender, :article => article_name}
83 83 end
84 84  
... ...
app/views/account/_signup_form.html.erb
... ... @@ -107,7 +107,7 @@
107 107 <%= render :partial => 'profile_editor/person_form', :locals => {:f => f} %>
108 108 <% end %>
109 109  
110   - <%= @plugins.dispatch(:signup_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
  110 + <%= safe_join(@plugins.dispatch(:signup_extra_contents).collect { |content| instance_eval(&content) }, "") %>
111 111  
112 112 <%= template_options(:people, 'profile_data') %>
113 113  
... ...
app/views/account/activate_enterprise.html.erb
... ... @@ -14,7 +14,7 @@
14 14 <div id="enterprise-activation-create-user-form" style="display: none">
15 15 <h3><%= _('Personal signup form') %></h3>
16 16 <%= render :partial => 'signup_form', :locals => { :hidden_atention => true } %>
17   - <p><%= message = _('<b>Warning</b>: this form is for your personal information, not of your enterprise. So you will have a personal account that can manage your enterprise.') %></p>
  17 + <p><%= message = _('<b>Warning</b>: this form is for your personal information, not of your enterprise. So you will have a personal account that can manage your enterprise.').html_safe %></p>
18 18 </div>
19 19  
20 20 <div id="enterprise-activation-login-form" style="display: none">
... ...
app/views/account/invalid_change_password_code.html.erb
1 1 <h1><%= _("Invalid change password code") %></h1>
2 2  
3 3 <p>
4   -<%= _('The code you are using for password change is not valid. Please try to request password change using the <a href="%s">"I forgot my password"</a> functionality.') % url_for(:action => 'forgot_password') %>
  4 +<%= _('The code you are using for password change is not valid. Please try to request password change using the <a href="%s">"I forgot my password"</a> functionality.') % url_for(:action => 'forgot_password').html_safe %>
5 5 </p>
... ...
app/views/account/login.html.erb
... ... @@ -20,7 +20,7 @@
20 20 </label>
21 21 </div>
22 22  
23   - <%= @plugins.dispatch(:login_extra_contents).collect { |content| instance_exec(&content) }.join("") %>
  23 + <%= safe_join(@plugins.dispatch(:login_extra_contents).collect { |content| instance_exec(&content) }, "") %>
24 24  
25 25 <% button_bar do %>
26 26 <%= submit_button( 'login', _('Log in') )%>
... ...
app/views/account/login_block.html.erb
... ... @@ -15,7 +15,7 @@
15 15  
16 16 <%= f.password_field :password %>
17 17  
18   - <%= @plugins.dispatch(:login_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
  18 + <%= safe_join(@plugins.dispatch(:login_extra_contents).collect { |content| instance_eval(&content) }, "") %>
19 19  
20 20 <% button_bar do %>
21 21 <%= submit_button( 'login', _('Log in') )%>
... ...
app/views/account/new_password_ok.html.erb
... ... @@ -5,5 +5,5 @@
5 5 </p>
6 6  
7 7 <p>
8   -<%= _("You can <a href='%s'>login</a> now.") % url_for(:action => 'login') %>
  8 +<%= _("You can <a href='%s'>login</a> now.").html_safe % url_for(:action => 'login') %>
9 9 </p>
... ...
app/views/blocks/blog_archives.html.erb
... ... @@ -6,7 +6,7 @@
6 6 <%= content_tag('li', content_tag('strong', "#{year.to_i} (#{count})")) %>
7 7 <ul class='<%= year.to_i %>-archive'>
8 8 <% block.blog.total_number_of_posts(:by_month, year).each do |month, count| %>
9   - <%= content_tag('li', link_to("#{month_name(month.to_i)} (#{count})", block.blog.url.merge(year: year.to_i, month: month.to_i))) %>
  9 + <%= content_tag('li', link_to("#{month_name(month.to_i)} (#{count})", url_for(block.blog.url.merge(year: year.to_i, month: month.to_i)).html_safe)) %>
10 10 <% end %>
11 11 </ul>
12 12 <% end %>
... ...
app/views/blocks/link_list.html.erb
... ... @@ -8,7 +8,7 @@
8 8 <%= block.sanitize_link(link_to(link[:name], block.expand_address(link[:address]),
9 9 :target => link[:target],
10 10 :class => (link[:icon] ? "icon-#{link[:icon]}" : ''),
11   - :title => link[:title])) %>
  11 + :title => link[:title])).html_safe %>
12 12 </li>
13 13 <% end %>
14 14 </ul>
... ...
app/views/blocks/login.html.erb
... ... @@ -3,7 +3,7 @@
3 3 <h2><%= _('Logged in as %s') % user.identifier %></h2>
4 4 <ul>
5 5 <li><%= _('User since %s/%s') % [user.created_at.month, user.created_at.year] %></li>
6   - <li><%= link_to _('Homepage'), user.public_profile_url %></li>
  6 + <li><%= link_to _('Homepage'), url_for(user.public_profile_url) %></li>
7 7 </ul>
8 8 <div class="user-actions">
9 9 <%= button(:'menu-logout', _('Logout'), :controller => 'account', :action => 'logout') %>
... ...
app/views/blocks/profile_list.html.erb
... ... @@ -10,8 +10,8 @@
10 10 <% if list.empty? %>
11 11 <div class='common-profile-list-block-none'><%= _('None') %></div>
12 12 <% else %>
13   - <ul><%= list %></ul>
  13 + <ul><%= list.html_safe %></ul>
14 14 <% end %>
15 15 </div>
16   -
  16 +
17 17 <br style='clear:both'/>
... ...
app/views/box_organizer/_article_block.html.erb
... ... @@ -9,7 +9,8 @@
9 9 first_text = articles[articles.find_index{|a| a.kind_of? TextArticle}||-1]
10 10 selected = @block.article || first_text
11 11 %>
12   - <%= select_tag(
  12 + <%=
  13 + select_tag(
13 14 'block[article_id]',
14 15 options_for_select_with_title(articles.map {|item| [item.path, item.id]}, selected.id),
15 16 :onchange => 'this.changedTo(this.value)'
... ...
app/views/catalog/index.html.erb
... ... @@ -35,7 +35,7 @@
35 35 <% else %>
36 36 <div class="no-image"><%= _('No image') %></div>
37 37 <% end %>
38   - <div class="catalog-item-extras"><%= extra_content.join("\n") %></div>
  38 + <div class="catalog-item-extras"><%= safe_join(extra_content, "\n") %></div>
39 39 </li>
40 40  
41 41 <li class="product-link"><%= link_to_product product %></li>
... ...
app/views/cms/_blog.html.erb
... ... @@ -35,7 +35,7 @@
35 35 <div id="article-formitem">
36 36 <%= labelled_form_field( _('Address'),
37 37 content_tag('code',
38   - url_for(@article.url).gsub(/#{@article.slug}$/, '') +
  38 + url_for(@article.url).gsub(/#{@article.slug}$/, '').html_safe +
39 39 text_field(:article, :slug, :onchange => "warn_value_change()", :size => 25)
40 40 ) +
41 41 content_tag('div',
... ...
app/views/cms/_textile_quick_reference.html.erb
... ... @@ -14,7 +14,7 @@
14 14 <p><%= _('Numbered lists:') %></p>
15 15 <pre># <%= _('first item') %>
16 16 # <%= _('second item') %></pre>
17   - <p><%= h(_('For code, use HTML tags <pre> and <code>, and indent the code inside them:')) %>
  17 + <p><%= h(_('For code, use HTML tags <pre> and <code>, and indent the code inside them:').html_safe) %>
18 18 </p>
19 19 <pre>
20 20 &lt;pre&gt;
... ... @@ -23,7 +23,7 @@
23 23 &lt;/code&gt;
24 24 &lt;/pre&gt;
25 25 </pre>
26   - <p><%= _('See also a more complete <a href="%s">Textile Reference</a>.') % 'http://redcloth.org/hobix.com/textile/' %></p>
  26 + <p><%= _('See also a more complete <a href="%s">Textile Reference</a>.').html_safe % 'http://redcloth.org/hobix.com/textile/' %></p>
27 27 </div>
28 28 </div>
29 29  
... ...
app/views/cms/edit.html.erb
... ... @@ -39,7 +39,7 @@
39 39  
40 40 <script>
41 41 jQuery('#article_tag_list').inputosaurus({
42   - autoCompleteSource: <%= "'/myprofile/#{profile.identifier}/cms/search_tags'," %>
  42 + autoCompleteSource: <%= "'/myprofile/#{profile.identifier}/cms/search_tags',".html_safe %>
43 43 activateFinalResult : true
44 44 })
45 45 </script>
... ...
app/views/cms/select_article_type.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <ul class="article-types">
6 6 <% for type in @article_types %>
7 7 <% action = type[:class].name == 'UploadedFile' ? {:action => 'upload_files'} : {:action => 'new', :type => type[:class].name} %>
8   - <%= content_tag('a', :href => url_for(action.merge(:parent_id => @parent_id, :back_to => @back_to))) do %>
  8 + <%= content_tag('a', :href => url_for(action.merge(:parent_id => @parent_id, :back_to => @back_to)).html_safe) do %>
9 9 <li class="<%= icon_for_new_article(type[:class]) %>" onmouseover="javascript: jQuery(this).addClass('mouseover')" onmouseout="jQuery(this).removeClass('mouseover')">
10 10 <strong><%= type[:short_description] %></strong>
11 11 <div class='description'><%= type[:description] %></div>
... ...
app/views/cms/upload_files.html.erb
... ... @@ -17,11 +17,11 @@
17 17 <h3><%= _("Select the files you want to upload (max size %s):") % UploadedFile.max_size.to_humanreadable %></h3>
18 18 <h4><%= _('Documents, Images, Videos, Audio') %></h4>
19 19  
20   -<h5><%= _('Uploading files to %s') % content_tag('code', @target) %></h5>
  20 +<h5><%= (_('Uploading files to %s') % content_tag('code', @target)).html_safe%></h5>
21 21  
22 22 <%= form_for('uploaded_file', :url => { :action => 'upload_files' }, :html => {:multipart => true}) do |f| %>
23 23  
24   - <%= @plugins.dispatch(:upload_files_extra_fields, params[:parent_id]).collect { |content| instance_exec(&content) }.join("") %>
  24 + <%= safe_join(@plugins.dispatch(:upload_files_extra_fields, params[:parent_id]).collect { |content| instance_exec(&content) }, "") %>
25 25  
26 26 <%= render :partial => 'upload_file_form', :locals => { :size => '45'} %>
27 27  
... ...
app/views/cms/view.html.erb
... ... @@ -17,7 +17,7 @@
17 17 <% button_bar(:style => 'margin-bottom: 1em;') do %>
18 18 <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %>
19 19  
20   - <%= modal_button('new', _('New content'), :action => 'new', :parent_id => parent_id, :cms => true) %>
  20 + <%= modal_button('new', _('New content'), url_for({:action => 'new', :parent_id => parent_id, :cms => true}).html_safe) %>
21 21 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor', :action => "index") %>
22 22 <% end %>
23 23  
... ... @@ -26,7 +26,7 @@
26 26 <strong><%= _('Current folder: ') %></strong>
27 27 <%= link_to profile.identifier, :action => 'index' %>
28 28 <% @article.hierarchy.each do |item| %>
29   - <%= " / " + ((item == @article) ? item.name.html_safe : link_to(item.slug, :id => item.id).html_safe) %>
  29 + <%= " / ".html_safe + ((item == @article) ? item.name.html_safe : link_to(item.slug, :id => item.id).html_safe) %>
30 30 <% end %>
31 31 </div>
32 32 <% end %>
... ... @@ -45,9 +45,9 @@
45 45 <tr>
46 46 <td>
47 47 <% if @article.parent %>
48   - <%= link_to '.. (' + _('parent folder') + ')', {:action => 'view', :id => @article.parent.id}, :class => 'icon-parent-folder' %>
  48 + <%= link_to '.. ('.html_safe + _('parent folder') + ')', {:action => 'view', :id => @article.parent.id}, :class => 'icon-parent-folder' %>
49 49 <% else %>
50   - <%= link_to '.. (' + _('parent folder') + ')', {:action => 'index'}, :class => 'icon-parent-folder' %>
  50 + <%= link_to '.. ('.html_safe + _('parent folder') + ')', {:action => 'index'}, :class => 'icon-parent-folder' %>
51 51 <% end %>
52 52 </td>
53 53 <td><%= Folder.short_description %></td>
... ...
app/views/comment/_comment.html.erb
... ... @@ -43,7 +43,7 @@
43 43 <p/>
44 44 <%= txt2html comment.body %>
45 45 </div>
46   - <%= @plugins.dispatch(:comment_extra_contents, local_assigns).collect { |content| instance_exec(&content) }.join("") %>
  46 + <%= safe_join(@plugins.dispatch(:comment_extra_contents, local_assigns).collect { |content| instance_exec(&content) }, "") %>
47 47 </div>
48 48  
49 49 <div class="comment_reply post_comment_box closed" id="comment_reply_to_<%= comment.id %>">
... ...
app/views/comment/_comment_form.html.erb
... ... @@ -85,7 +85,7 @@ function check_captcha(button, confirm_action) {
85 85 <%= hidden_field_tag(:view, params[:view])%>
86 86 <%= f.hidden_field(:reply_of_id) %>
87 87  
88   - <%= @plugins.dispatch(:comment_form_extra_contents, local_assigns.merge(:comment => @comment)).collect { |content| instance_exec(&content) }.join("") %>
  88 + <%= safe_join(@plugins.dispatch(:comment_form_extra_contents, local_assigns.merge(:comment => @comment)).collect { |content| instance_exec(&content) }, "") %>
89 89  
90 90 <% button_bar do %>
91 91 <%= submit_button('add', _('Post comment'), :onclick => "if(check_captcha(this)) { save_comment(this) } else { check_captcha(this, save_comment)};return false;") %>
... ...
app/views/content_viewer/_article_toolbar.html.erb
... ... @@ -26,7 +26,7 @@
26 26 <% content = _('Add translation') %>
27 27 <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %>
28 28 <% url = profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => parent_id, :type => @page.type, :article => { :translation_of_id => @page.native_translation.id })%>
29   - <%= expirable_button @page, :locale, content, url %>
  29 + <%= expirable_button @page, :locale, content, url_for(url).html_safe %>
30 30 <% end %>
31 31  
32 32 <% if !@page.archived? %>
... ... @@ -67,7 +67,7 @@
67 67 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div>
68 68 <% end %>
69 69 <%= button_without_text(:feed, _('RSS feed'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
70   - <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
  70 + <%= safe_join(@plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }) %>
71 71 <% if @page.archived? %>
72 72 <%= render :partial => 'cms/archived_warning', :locals => {:article => @page} %>
73 73 <% end %>
... ...
app/views/content_viewer/_publishing_info.html.erb
... ... @@ -7,7 +7,7 @@
7 7 </span>
8 8 <% unless @no_comments %>
9 9 <span class="comments">
10   - <%= (" - %s") % link_to_comments(@page)%>
  10 + <%= (" - %s").html_safe % link_to_comments(@page) %>
11 11 </span>
12 12 <% end %>
13 13  
... ...
app/views/content_viewer/event_page.html.erb
... ... @@ -35,7 +35,7 @@
35 35 </div>
36 36 <% end %>
37 37 <div class="event-content">
38   - <%= event.body %>
  38 + <%= raw event.body %>
39 39 </div>
40 40 <% end %>
41 41 </div>
... ...
app/views/content_viewer/versions_diff.html.erb
... ... @@ -2,9 +2,9 @@
2 2 <%= button(:back, _('Back to the versions'), {:action => 'article_versions'}) %>
3 3 </div>
4 4  
5   -<h1><%= _('Changes on "%s"') % @page.title %></h1>
  5 +<h1><%= _('Changes on "%s"').html_safe % @page.title %></h1>
6 6  
7   -<p> <%= _('Changes from %s &rarr; %s') % [show_time(@v1.updated_at), show_time(@v2.updated_at)] %> </p>
  7 +<p> <%= _('Changes from %s &rarr; %s').html_safe % [show_time(@v1.updated_at), show_time(@v2.updated_at)] %> </p>
8 8  
9 9 <% diffContent = Diffy::Diff.new(@v1.body, @v2.body, :context => 1) %>
10 10 <% if diffContent.to_s(:text).blank? %>
... ... @@ -12,5 +12,5 @@
12 12 <%= _('These versions range have no differences.')%>
13 13 </p>
14 14 <% else %>
15   - <%= diffContent.to_s(:html) %>
  15 + <%= diffContent.to_s(:html).html_safe %>
16 16 <% end %>
... ...
app/views/content_viewer/view_page.html.erb
... ... @@ -45,24 +45,24 @@
45 45 <% if ! @page.categories.empty? %>
46 46 <div id="article-cat">
47 47 <h4><%= _('Categories') %></h4>
48   - <%= @page.categories.map {|item| link_to_category(item, false) }.join(", ") %>
  48 + <%= safe_join(@page.categories.map {|item| link_to_category(item, false) }, ", ") %>
49 49 </div>
50 50 <% end %>
51 51  
52 52 <% if !@page.tags.empty? %>
53 53 <div id="article-tags">
54   - <%= _("This article's tags:") %>
55   - <%= @page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>
  54 + <%= _("This article's tags:").html_safe %>
  55 + <%= safe_join(@page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }, "\n") %>
56 56 </div>
57 57 <% end %>
58 58  
59 59 <%= display_source_info(@page) %>
60 60  
61   -<%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
  61 +<%= safe_join(@plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_exec(&content) }, "") %>
62 62  
63 63 <% if @page.accept_comments? || @comments_count > 0 %>
64 64 <div class="comments" id="comments_list">
65   - <h3 <%= 'class="no-comments-yet"' if @comments_count == 0 %>>
  65 + <h3 <%= 'class="no-comments-yet"'.html_safe if @comments_count == 0 %>>
66 66 <%= display_number_of_comments(@comments_count) %>
67 67 </h3>
68 68  
... ...
app/views/doc/_toc.html.erb
... ... @@ -5,5 +5,5 @@
5 5 <li><%= link_to text, link, :target => '_blank' %></li>
6 6 <% end %>
7 7 </ul>
8   - <%= @toc.text %>
  8 + <%= raw @toc.text %>
9 9 </div>
... ...
app/views/features/index.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <p>
6 6 <%= _('Here you can enable or disable several features of your environment. Each feature represents some funcionality that your environment can use if you enable it.
7 7  
8   -Check all the features you want to enable for your environment, uncheck all the ones you don\'t want, and use the <em>"Save changes" button</em> to confirm your changes.') %>
  8 +Check all the features you want to enable for your environment, uncheck all the ones you don\'t want, and use the <em>"Save changes" button</em> to confirm your changes.').html_safe %>
9 9 </p>
10 10  
11 11 <%= labelled_form_for(:environment, :url => {:action => 'update'}) do |f| %>
... ...
app/views/home/index.html.erb
... ... @@ -7,7 +7,7 @@
7 7 <div class='highlighted-news-item post-<%= index + 1 %>-inner'>
8 8 <h2><%= link_to(h(highlighted.title), highlighted.url, :class => 'post-title') %></h2>
9 9 <span class="post-date"><%= show_date(highlighted.published_at, true) %> </span>
10   - <div class='headline'><%= highlighted.lead %></div>
  10 + <div class='headline'><%= raw highlighted.lead %></div>
11 11 <p class='highlighted-news-read-more'>
12 12 <%= link_to(_('Read more'), highlighted.url) %>
13 13 </p>
... ... @@ -49,7 +49,7 @@
49 49 <% end %>
50 50 <% end %>
51 51 <% else %>
52   - <%= environment.description %>
  52 + <%= environment.description.html_safe %>
53 53 <% end %>
54 54  
55 55 <% if environment.enabled?('search_in_home') %>
... ...
app/views/invite/_select_address_book.html.erb
... ... @@ -3,12 +3,12 @@
3 3  
4 4 <%= form_tag do %>
5 5  
6   - <%= [
  6 + <%= safe_join([
7 7 radio_button_tag(:import_from, "manual", @import_from == "manual", :onclick => 'hide_invite_friend_login_password()') + content_tag('label', _('Manually (empty field)'), :for => "import_from_manual"),
8 8 radio_button_tag(:import_from, "gmail", @import_from == "gmail", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Gmail', :for => 'import_from_gmail'),
9 9 radio_button_tag(:import_from, "yahoo", @import_from == "yahoo", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Yahoo', :for => "import_from_yahoo"),
10 10 radio_button_tag(:import_from, "hotmail", @import_from == "hotmail", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Hotmail', :for => "import_from_hotmail")
11   - ].join("\n<br/>\n") %>
  11 + ], "\n<br/>\n".html_safe) %>
12 12  
13 13 <script type="text/javascript">
14 14 function hide_invite_friend_login_password() {
... ...
app/views/layouts/_user.html.erb
... ... @@ -7,22 +7,23 @@
7 7 </span>
8 8 <% else %>
9 9 <span class='not-logged-in'>
10   - <%= _("<span class='login'>%s</span>") % modal_inline_link_to('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, '#inlineLoginBox', :id => 'link_login') %>
11   - <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_exec(&content) }.join("") %>
  10 + <%= usermenu_notlogged_in %>
  11 + <% @plugins.dispatch(:alternative_authentication_link).collect do |content|%>
  12 + <%= instance_exec(&content) %>
  13 + <%end%>
12 14  
13   - <div id='inlineLoginBox' style='display: none;'>
14   - <%= render :file => 'account/login', :locals => { :is_popin => true } %>
15   - </div>
  15 + <div id='inlineLoginBox' style='display: none;'>
  16 + <%= render :file => 'account/login', :locals => { :is_popin => true } %>
  17 + </div>
16 18  
17   - <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>
18   - <%= _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to('<strong>' + _('Sign up') + '</strong>', :controller => 'account', :action => 'signup')%>
19   - <% end %>
20   -
21   - </span>
  19 + <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>
  20 + <%= usermenu_signup %>
  21 + <% end %>
  22 + </span>
22 23 <% end %>
23 24 <form action="/search/articles" id="top-search" class="search_form clean" method="get">
24 25 <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" />
25   - <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div>
  26 + <div><%=_('Press <strong>Enter</strong> to send the search query.').html_safe%></div>
26 27 <%= javascript_tag 'jQuery("#user form input").hint();' %>
27 28 </form>
28 29 </div><!-- end id="user" -->
... ...
app/views/layouts/application-ng.html.erb
1 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>" class="<%= h html_tag_classes %>">
3 3 <head>
4   - <title><%= h page_title %></title>
  4 + <title><%= h page_title.html_safe %></title>
5 5 <%= yield(:feeds) %>
6 6 <!--<meta http-equiv="refresh" content="1"/>-->
7 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
... ... @@ -20,24 +20,33 @@
20 20 <%# Add custom tags/styles/etc via content_for %>
21 21 <%= yield :head %>
22 22 <%=
23   - @plugins.dispatch(:head_ending).map do |content|
24   - if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end
25   - end.join("\n")
  23 + str = (@plugins.dispatch(:head_ending).map do |content|
  24 + if content.respond_to?(:call) then
  25 + instance_exec(&content).to_s
  26 + else
  27 + content.to_s
  28 + end
  29 + end)
  30 + safe_join(str, "\n")
26 31 %>
27 32  
28 33 <script type="text/javascript">
29   - DEFAULT_LOADING_MESSAGE = <%="'#{ _('loading...') }'" %>;
30   - noosfero.profile = <%= (@profile.identifier if @profile).to_json %>
  34 + DEFAULT_LOADING_MESSAGE = <%="'#{ _('loading...') }'".html_safe %>;
  35 + noosfero.profile = <%= (@profile.identifier if @profile).to_json.html_safe %>
31 36 </script>
32 37  
33 38 </head>
34 39 <body class="<%= h body_classes %>">
35 40 <a href="#content" id="link-go-content"><span><%= _("Go to the content") %></span></a>
36   -
37 41 <%=
38   - @plugins.dispatch(:body_beginning).map do |content|
39   - if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end
40   - end.join("\n")
  42 + str = (@plugins.dispatch(:body_beginning).map do |content|
  43 + if content.respond_to?(:call) then
  44 + instance_exec(&content).to_s
  45 + else
  46 + content.to_s
  47 + end
  48 + end)
  49 + safe_join(str, "\n")
41 50 %>
42 51 <div id="global-header">
43 52 <%= global_header %>
... ... @@ -75,9 +84,14 @@
75 84 <%= noosfero_layout_features %>
76 85 <%= addthis_javascript %>
77 86 <%=
78   - @plugins.dispatch(:body_ending).map do |content|
79   - if content.respond_to?(:call) then instance_exec(&content).html_safe else content.html_safe end
80   - end.join("\n")
  87 + str = (@plugins.dispatch(:body_ending).map do |content|
  88 + if content.respond_to?(:call) then
  89 + instance_exec(&content)
  90 + else
  91 + content
  92 + end
  93 + end)
  94 + safe_join(str, "\n")
81 95 %>
82 96 </body>
83 97 </html>
... ...
app/views/mailconf/index.html.erb
... ... @@ -16,7 +16,7 @@
16 16 <% if profile.user.enable_email %>
17 17 <h2><%= ('E-mail address') %></h2>
18 18 <ul>
19   - <%= profile.email_addresses.map{|i| content_tag('li', i)}.join("\n") %>
  19 + <%= safe_join(profile.email_addresses.map{|i| content_tag('li', i)}, "\n") %>
20 20 </ul>
21 21 <h2><%= _('Configuration') %></h2>
22 22 <ul>
... ... @@ -31,7 +31,7 @@
31 31 <% else %>
32 32  
33 33 <h2><%= _("Enable e-Mail account below:") %></h2>
34   - <ul><%= profile.email_addresses.map{|i| content_tag('li', i)}.join("\n") %></ul>
  34 + <ul><%= safe_join(profile.email_addresses.map{|i| content_tag('li', i)}, "\n") %></ul>
35 35 <blockquote><%= _("You'll be able to access a webmail from your user menu.") %></blockquote>
36 36 <% button_bar do %>
37 37 <%= button(:ok, _('Enable e-Mail'), { :action => 'enable' }, :method => 'post') %>
... ...
app/views/manage_products/show.html.erb
... ... @@ -14,7 +14,7 @@
14 14 </div>
15 15 <div id='product-extra-content'>
16 16 <% extra_content = @plugins.dispatch(:product_info_extras, @product).collect { |content| instance_exec(&content) } %>
17   - <%= extra_content.join("\n") %>
  17 + <%= safe_join(extra_content, "\n") %>
18 18 </div>
19 19 <div id='product-info'>
20 20 <%= render :partial => 'manage_products/display_info' %>
... ...
app/views/memberships/new_community.html.erb
... ... @@ -34,13 +34,13 @@
34 34 <div style='margin-bottom: 0.5em' id='community-join-before'>
35 35 <%= radio_button 'community', 'closed', 'true', :style => 'float: left' %>
36 36 <div style='margin-left: 30px'>
37   - <%= _('<strong>Before</strong> joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).') %>
  37 + <%= _('<strong>Before</strong> joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).').html_safe %>
38 38 </div>
39 39 </div>
40 40 <div id='community-join-after'>
41 41 <%= radio_button 'community', 'closed', 'false', :style => 'float: left' %>
42 42 <div style='margin-left: 30px'>
43   - <%= _('<strong>After</strong> joining this group (a moderator can always desactivate access for users later).') %>
  43 + <%= _('<strong>After</strong> joining this group (a moderator can always desactivate access for users later).').html_safe %>
44 44 </div>
45 45 </div>
46 46  
... ...
app/views/pending_task_notifier/notification.text.erb
... ... @@ -2,7 +2,7 @@
2 2  
3 3 <%= _("You have %d pending task(s).") % @tasks.size %>
4 4  
5   -<%= @tasks.map{|i| " * #{i.description}"}.join("\n") %>
  5 +<%= safe_join(@tasks.map{|i| " * #{i.description}"}, "\n") %>
6 6  
7 7 <%= _("Click in address below to process task(s):") %>
8 8  
... ... @@ -11,7 +11,7 @@
11 11 <% pending_tasks = @person.pending_tasks_for_organization(organization) %>
12 12 <%= _("%s has %d pending task(s).") % [organization.name, pending_tasks.size] %>
13 13  
14   -<%= pending_tasks.map{|i| " * #{i.information}"}.join("\n") %>
  14 +<%= safe_join(pending_tasks.map{|i| " * #{i.information}"}, "\n") %>
15 15  
16 16 <%= _("Click in address below to process task(s):") %>
17 17  
... ...
app/views/profile/content_tagged.html.erb
... ... @@ -20,6 +20,6 @@
20 20 <%= pagination_links @tagged, :param_name => 'npage' %>
21 21  
22 22 <div>
23   - <%= link_to _('See content tagged with "%s" in the entire site') % escaped_tag, :controller => 'search', :action => 'tag', :tag => @tag %>
  23 + <%= link_to (_('See content tagged with "%s" in the entire site') % escaped_tag).html_safe, :controller => 'search', :action => 'tag', :tag => @tag %>
24 24 </div>
25 25 <% end %>
... ...
app/views/profile/index.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <% else %>
6 6 <% unless profile.description.blank? %>
7 7 <div class='public-profile-description'>
8   - <%= profile.description %>
  8 + <%= raw profile.description %>
9 9 </div>
10 10 <% end %>
11 11 <div id='public-profile-search'>
... ...
app/views/profile_editor/_moderation.html.erb
... ... @@ -34,13 +34,13 @@
34 34 <div style='margin-bottom: 0.5em'>
35 35 <%= radio_button 'profile_data', 'closed', 'true', :style => 'float: left' %>
36 36 <div style='margin-left: 30px'>
37   - <%= _('<strong>Before</strong> joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).') %>
  37 + <%= _('<strong>Before</strong> joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).').html_safe %>
38 38 </div>
39 39 </div>
40 40 <div>
41 41 <%= radio_button 'profile_data', 'closed', 'false', :style => 'float: left' %>
42 42 <div style='margin-left: 30px'>
43   - <%= _('<strong>After</strong> joining this group (a moderator can always desactivate access for users later).') %>
  43 + <%= _('<strong>After</strong> joining this group (a moderator can always desactivate access for users later).').html_safe %>
44 44 </div>
45 45 </div>
46 46 <br>
... ... @@ -52,13 +52,13 @@
52 52 <div style='margin-bottom: 0.5em'>
53 53 <%= radio_button 'profile_data', 'moderated_articles', 'true', :style => 'float: left' %>
54 54 <div style='margin-left: 30px'>
55   - <%= _('<strong>Before</strong> being published in this group (a moderator has to accept the article in pending request before the article be listed as a article of this group).') %>
  55 + <%= _('<strong>Before</strong> being published in this group (a moderator has to accept the article in pending request before the article be listed as a article of this group).').html_safe %>
56 56 </div>
57 57 </div>
58 58 <div>
59 59 <%= radio_button 'profile_data', 'moderated_articles', 'false', :style => 'float: left' %>
60 60 <div style='margin-left: 30px'>
61   - <%= _('<strong>After</strong> being published in this group (a moderator can always remove publicated articles later).') %>
  61 + <%= _('<strong>After</strong> being published in this group (a moderator can always remove publicated articles later).').html_safe %>
62 62 </div>
63 63 </div>
64 64  
... ...
app/views/profile_editor/_organization.html.erb
... ... @@ -4,7 +4,7 @@
4 4  
5 5 <%= required f.text_field(:name) %>
6 6  
7   - <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }.join("") %>
  7 + <%= safe_join(@plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }, "") %>
8 8  
9 9 <% if @environment.enabled?('enable_organization_url_change') %>
10 10 <script type="text/javascript">
... ... @@ -41,7 +41,7 @@
41 41 <div id="profile-identifier-formitem">
42 42 <%= required labelled_form_field( _('Address'),
43 43 content_tag('code',
44   - url_for(profile.url).gsub(/#{profile.identifier}$/, '') +
  44 + url_for(profile.url).gsub(/#{profile.identifier}$/, '').html_safe +
45 45 text_field(:profile_data, :identifier, :onchange => "warn_value_change()", :size => 25)
46 46 ) +
47 47 content_tag('div',
... ...
app/views/profile_editor/_pending_tasks.html.erb
... ... @@ -4,7 +4,7 @@
4 4 <div class='pending-tasks'>
5 5 <h2><%= _('You have pending requests') %></h2>
6 6 <ul>
7   - <%= @pending_tasks.map {|task| content_tag('li', task_information(task))}.join %>
  7 + <%= safe_join(@pending_tasks.map {|task| content_tag('li', task_information(task))}) %>
8 8 </ul>
9 9 <%= button(:todo, _('Process requests'), :controller => 'tasks', :action => 'index') %>
10 10 </div>
... ...
app/views/profile_editor/_person.html.erb
... ... @@ -16,7 +16,7 @@
16 16 </div>
17 17 </div>
18 18  
19   - <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }.join("") %>
  19 + <%= safe_join(@plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }, "") %>
20 20  
21 21 <div class="formfieldline">
22 22 <%= label_tag("private_token", _("Private Token")) %>
... ...
app/views/profile_editor/edit.html.erb
... ... @@ -26,20 +26,20 @@
26 26  
27 27 <% if profile.person? %>
28 28 <div>
29   - <%= labelled_radio_button _('Public &mdash; show my contents to all internet users'), 'profile_data[public_profile]', true, @profile.public_profile? %>
  29 + <%= labelled_radio_button _('Public &mdash; show my contents to all internet users').html_safe, 'profile_data[public_profile]', true, @profile.public_profile? %>
30 30 </div>
31 31 <div>
32   - <%= labelled_radio_button _('Private &mdash; show my contents only to friends'), 'profile_data[public_profile]', false, !@profile.public_profile? %>
  32 + <%= labelled_radio_button _('Private &mdash; show my contents only to friends').html_safe, 'profile_data[public_profile]', false, !@profile.public_profile? %>
33 33 </div>
34 34 <% else %>
35 35 <div>
36   - <%= labelled_check_box _("Secret &mdash; hide the community and all its contents for non members and other people can't join this community unless they are invited to."), 'profile_data[secret]', true, profile.secret, :class => "profile-secret-box" %>
  36 + <%= labelled_check_box _("Secret &mdash; hide the community and all its contents for non members and other people can't join this community unless they are invited to.").html_safe, 'profile_data[secret]', true, profile.secret, :class => "profile-secret-box" %>
37 37 </div>
38 38 <div>
39   - <%= labelled_radio_button _('Public &mdash; show content of this group to all internet users'), 'profile_data[public_profile]', true, @profile.public_profile?, :class => "public-community-button" %>
  39 + <%= labelled_radio_button _('Public &mdash; show content of this group to all internet users').html_safe, 'profile_data[public_profile]', true, @profile.public_profile?, :class => "public-community-button" %>
40 40 </div>
41 41 <div>
42   - <%= labelled_radio_button _('Private &mdash; show content of this group only to members'), 'profile_data[public_profile]', false, !@profile.public_profile?, :class => "private-community-button" %>
  42 + <%= labelled_radio_button _('Private &mdash; show content of this group only to members').html_safe, 'profile_data[public_profile]', false, !@profile.public_profile?, :class => "private-community-button" %>
43 43 </div>
44 44 <% end %>
45 45  
... ... @@ -60,9 +60,9 @@
60 60 )%>
61 61  
62 62 <%=
63   - @plugins.dispatch(:profile_editor_extras).map do |content|
  63 + safe_join(@plugins.dispatch(:profile_editor_extras).map do |content|
64 64 content.kind_of?(Proc) ? self.instance_exec(&content) : content
65   - end.join("\n")
  65 + end, "\n")
66 66 %>
67 67  
68 68 <%= select_categories(:profile_data, _('Select the categories of your interest'), 2) %>
... ...
app/views/profile_members/_members_filter.erb
... ... @@ -7,7 +7,7 @@
7 7  
8 8 <p><%= _('Roles:') %> </p>
9 9 <% @data[:roles].each do |r| %>
10   - <%= labelled_check_box(r.name, 'filters[roles][]', r.id, @filters[:roles].include?(r.id.to_s), :add_hidden => false) %><br/>
  10 + <%= raw labelled_check_box(r.name, 'filters[roles][]', r.id, @filters[:roles].include?(r.id.to_s), :add_hidden => false) %><br/>
11 11 <% end %>
12 12 <p>
13 13 <%= submit_button(:search, _('Search')) %>
... ...
app/views/search/_article_last_change.html.erb
... ... @@ -2,7 +2,7 @@
2 2  
3 3 <div class="search-article-author-changes">
4 4 <% if article.last_changed_by and article.last_changed_by != article.profile %>
5   - <span><%= _('Updated by %{name} at %{date}') % {:name => link_to(article.last_changed_by.name, article.last_changed_by.url),
  5 + <span><%= _('Updated by %{name} at %{date}').html_safe % {:name => link_to(article.last_changed_by.name, article.last_changed_by.url),
6 6 :date => show_date(article.updated_at) } %></span>
7 7 <% else %>
8 8 <span><%= _('Last update: %s.') % show_date(article.updated_at) %></span>
... ...
app/views/search/_full_product.html.erb
1 1 <% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_exec(&content) } %>
2   -<% extra_properties = @plugins.dispatch(:asset_product_properties, product)%>
  2 +<% extra_properties = @plugins.dispatch(:asset_product_properties, product) %>
3 3  
4 4 <li class="search-product-item <%= 'highlighted' if product.highlighted? %>">
5 5  
... ... @@ -77,9 +77,9 @@
77 77  
78 78 <div style="clear: both"></div>
79 79  
80   - <%= extra_content.join('\n') %>
  80 + <%= safe_join(extra_content, '\n') %>
81 81 <% extra_properties.each do |property| %>
82   - <div><%= property[:name] + ': ' + instance_exec(&property[:content]) %></div>
  82 + <div><%= ''.html_safe + property[:name] + ': ' + instance_exec(&property[:content]) %></div>
83 83 <% end %>
84 84  
85 85 </li>
... ...
app/views/search/tag.html.erb
1 1 <h2>
2   - <%= _('Tagged with "%s"') % content_tag('code', @tag) %>
  2 + <%= _('Tagged with "%s"').html_safe % content_tag('code', @tag) %>
3 3 </h2>
4 4  
5 5 <% button_bar do %>
... ...
app/views/shared/_list_groups.html.erb
... ... @@ -6,9 +6,9 @@
6 6 </div>
7 7 <span class='profile-details'>
8 8 <strong><%= group.name %></strong><br/>
9   - <%= _('Role: %s') % rolename_for(profile, group) + '<br/>' if profile.role_assignments.find_by(resource_id: group.id) %>
  9 + <%= raw _('Role: %s') % rolename_for(profile, group) + '<br/>' if profile.role_assignments.find_by(resource_id: group.id) %>
10 10 <%= _('Type: %s') % _(group.class.identification) %> <br/>
11   - <%= _('Description: %s') % group.description + '<br/>' if group.community? %>
  11 + <%= raw _('Description: %s') % group.description + '<br/>' if group.community? %>
12 12 <%= _('Members: %s') % group.members_count.to_s %> <br/>
13 13 <%= _('Created at: %s') % show_date(group.created_at) unless group.enterprise? %> <br/>
14 14 <% button_bar do %>
... ...
app/views/tasks/_add_member_accept_details.html.erb
1 1 <%= content = _("Roles:")+"<br />"
2 2 roles = Profile::Roles.organization_member_roles(task.target.environment.id) + profile.custom_roles
3 3 roles.each do |role|
4   - content += labelled_check_box(role.name, "tasks[#{task.id}][task][roles][]", role.id, false)+"<br />"
  4 + content += labelled_check_box(role.name, "tasks[#{task.id}][task][roles][]", role.id, false) + "<br />".html_safe
5 5 end
6   -content_tag('p', content, :class => 'member-classify-suggestion')
  6 +content_tag('p', content.html_safe, :class => 'member-classify-suggestion').html_safe
7 7 %>
... ...
app/views/tasks/_task_icon.html.erb
... ... @@ -3,7 +3,7 @@
3 3 if icon_info[:type] == :profile_image
4 4 icon = profile_image(icon_info[:profile], :minor)
5 5 elsif icon_info[:type] == :defined_image
6   - icon = "<img src='#{icon_info[:src]}' alt='#{icon_info[:name]}' />"
  6 + icon = "<img src='#{icon_info[:src]}' alt='#{icon_info[:name]}' />".html_safe
7 7 end
8 8  
9 9 if icon_info[:url]
... ...
app/views/tasks/list_requested.html.erb
... ... @@ -3,7 +3,7 @@
3 3 <ul>
4 4 <% @tasks.each do |task| %>
5 5 <li>
6   - <strong><%= task.respond_to?(:title) ? link_to( task.title, :action => 'ticket_details', :id => task.id) : task.information %></strong><br/>
  6 + <strong><%= task.respond_to?(:title) ? link_to( task.title, :action => 'ticket_details', :id => task.id).html_safe : task.information %></strong><br/>
7 7 <small>
8 8 <%= _('Created:') + ' ' + show_date(task.created_at) %>
9 9 &nbsp; &#151; &nbsp;
... ...
config/initializers/html_safe.rb
... ... @@ -1,10 +0,0 @@
1   -#From: https://github.com/coletivoEITA/noosfero-ecosol/blob/57908cde4fe65dfe22298a8a7f6db5dba1e7cc75/config/initializers/html_safe.rb
2   -
3   -# Disable Rails html autoescaping. This is due to noosfero using too much helpers/models to output html.
4   -# It it would change too much code and make it hard to maintain.
5   -# FIXME THIS IS SO WRONG
6   -class Object
7   - def html_safe?
8   - true
9   - end
10   -end
lib/noosfero/plugin.rb
... ... @@ -611,7 +611,7 @@ class Noosfero::Plugin
611 611 end
612 612  
613 613 # -> Perform extra transactions related to profile in profile editor
614   - # returns = true in success or raise and exception if it could not update the data
  614 + # returns = true in success or raise an exception if it could not update the data
615 615 def profile_editor_transaction_extras
616 616 nil
617 617 end
... ...
plugins/breadcrumbs/lib/breadcrumbs_plugin/content_breadcrumbs_block.rb
... ... @@ -49,7 +49,7 @@ class BreadcrumbsPlugin::ContentBreadcrumbsBlock &lt; Block
49 49  
50 50 def content(args={})
51 51 block = self
52   - proc do
  52 + ret = (proc do
53 53 trail = block.trail(@page, @profile, params)
54 54 if !trail.empty?
55 55 separator = content_tag('span', ' > ', :class => 'separator')
... ... @@ -67,7 +67,8 @@ class BreadcrumbsPlugin::ContentBreadcrumbsBlock &lt; Block
67 67 else
68 68 ''
69 69 end
70   - end
  70 + end)
  71 + ret.html_safe
71 72 end
72 73  
73 74 def cacheable?
... ...
plugins/context_content/lib/context_content_plugin/context_content_block.rb
... ... @@ -86,7 +86,7 @@ class ContextContentPlugin::ContextContentBlock &lt; Block
86 86  
87 87 def content(args={})
88 88 block = self
89   - proc do
  89 + ret = proc do
90 90 contents = block.contents(@page)
91 91 parent_title = block.parent_title(contents)
92 92 if !contents.blank?
... ... @@ -95,6 +95,7 @@ class ContextContentPlugin::ContextContentBlock &lt; Block
95 95 ''
96 96 end
97 97 end
  98 + ret.html_safe
98 99 end
99 100  
100 101 def cacheable?
... ...
plugins/event/views/event_plugin/event_block_item.html.erb
... ... @@ -16,7 +16,7 @@
16 16 img_class = img.blank? ? 'no-img' : 'has-img'
17 17 %>
18 18 <%=
19   - link_to([
  19 + link_to(safe_join([
20 20 content_tag('time',
21 21 block.date_to_html(event.start_date),
22 22 :itemprop => 'startDate',
... ... @@ -33,7 +33,7 @@
33 33 :itemtype => 'http://schema.org/Place',
34 34 :itemprop => :location),
35 35 content_tag('span', time_left_str, :class => 'days-left ' + time_class)
36   - ].join("\n"),
  36 + ], "\n"),
37 37 (event.link.blank? ? event.url : event.link),
38 38 :class => 'ev-days-' + event.duration.to_s,
39 39 :itemprop => :url
... ...
plugins/profile_members_headlines/views/blocks/headlines.html.erb
... ... @@ -15,7 +15,7 @@
15 15 <%= show_date(headline.published_at) %>
16 16 </div>
17 17 <div class='tags'>
18   - <%= headline.tags.map { |t| link_to(t, :controller => 'profile', :profile => member.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>
  18 + <%= safe_join(headline.tags.map { |t| link_to(t, :controller => 'profile', :profile => member.identifier, :action => 'tags', :id => t.name ) }, "\n") %>
19 19 </div>
20 20 </div>
21 21 </div>
... ...
plugins/relevant_content/lib/relevant_content_plugin/relevant_content_block.rb
... ... @@ -83,7 +83,7 @@ class RelevantContentPlugin::RelevantContentBlock &lt; Block
83 83 end
84 84 end
85 85 end
86   - return content
  86 + return content.html_safe
87 87 end
88 88  
89 89 def timeout
... ...
public/designs/themes/base/footer.html.erb
... ... @@ -3,7 +3,7 @@
3 3 <%= link_to _('Manual'), '/doc', id: "link-to-doc", class: 'icon-help' %>
4 4 </div><!-- end id="footer-links" -->
5 5 <div id="copyright">
6   - <p><%= _('This social network uses <a href="http://noosfero.org/">Noosfero</a>, developed by %s and licensed under the <a href="http://www.gnu.org/licenses/agpl.html">GNU Affero General Public License</a> version 3 or any later version.') % link_to('Colivre', 'http://colivre.coop.br/') %></p>
  6 + <p><%= (_('This social network uses <a href="http://noosfero.org/">Noosfero</a>, developed by %s and licensed under the <a href="http://www.gnu.org/licenses/agpl.html">GNU Affero General Public License</a> version 3 or any later version.') % link_to('Colivre', 'http://colivre.coop.br/')).html_safe %></p>
7 7 </div><!-- end id="copyright" -->
8 8 <%= language_chooser(environment) %>
9 9 </div>
... ...
public/designs/themes/profile-base/footer.html.erb
1 1 <div id="footer-content">
2   - <p><%= _('This site uses <a href="http://noosfero.org/">Noosfero</a>, developed by %s and licensed under the <a href="http://www.gnu.org/licenses/agpl.html">GNU Affero General Public License</a> version 3 or any later version.') % link_to('Colivre', 'http://colivre.coop.br/') %></p>
  2 + <p><%= _('This site uses <a href="http://noosfero.org/">Noosfero</a>, developed by %s and licensed under the <a href="http://www.gnu.org/licenses/agpl.html">GNU Affero General Public License</a> version 3 or any later version.') % link_to('Colivre', 'http://colivre.coop.br/').html_safe %></p>
3 3 </div>
... ...
test/functional/account_controller_test.rb
... ... @@ -689,7 +689,7 @@ class AccountControllerTest &lt; ActionController::TestCase
689 689 should 'merge user data with extra stuff from plugins' do
690 690 class Plugin1 < Noosfero::Plugin
691 691 def user_data_extras
692   - {:foo => 'bar'}
  692 + {:foo => 'bar'.html_safe }
693 693 end
694 694 end
695 695  
... ... @@ -787,12 +787,12 @@ class AccountControllerTest &lt; ActionController::TestCase
787 787 should 'add extra content on signup forms from plugins' do
788 788 class Plugin1 < Noosfero::Plugin
789 789 def signup_extra_contents
790   - proc {"<strong>Plugin1 text</strong>"}
  790 + proc {"<strong>Plugin1 text</strong>".html_safe}
791 791 end
792 792 end
793 793 class Plugin2 < Noosfero::Plugin
794 794 def signup_extra_contents
795   - proc {"<strong>Plugin2 text</strong>"}
  795 + proc {"<strong>Plugin2 text</strong>".html_safe}
796 796 end
797 797 end
798 798 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ... @@ -909,12 +909,12 @@ class AccountControllerTest &lt; ActionController::TestCase
909 909 should 'add extra content on login form from plugins' do
910 910 class Plugin1 < Noosfero::Plugin
911 911 def login_extra_contents
912   - proc {"<strong>Plugin1 text</strong>"}
  912 + proc {"<strong>Plugin1 text</strong>".html_safe}
913 913 end
914 914 end
915 915 class Plugin2 < Noosfero::Plugin
916 916 def login_extra_contents
917   - proc {"<strong>Plugin2 text</strong>"}
  917 + proc {"<strong>Plugin2 text</strong>".html_safe}
918 918 end
919 919 end
920 920 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ...
test/functional/application_controller_test.rb
... ... @@ -375,7 +375,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
375 375 should 'include javascripts supplied by plugins' do
376 376 class Plugin1 < Noosfero::Plugin
377 377 def js_files
378   - ['js1.js']
  378 + ['js1.js'.html_safe]
379 379 end
380 380 end
381 381  
... ... @@ -384,7 +384,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
384 384  
385 385 class Plugin2 < Noosfero::Plugin
386 386 def js_files
387   - ['js2.js', 'js3.js']
  387 + ['js2.js'.html_safe, 'js3.js'.html_safe]
388 388 end
389 389 end
390 390  
... ... @@ -409,12 +409,12 @@ class ApplicationControllerTest &lt; ActionController::TestCase
409 409 should 'include content in the beginning of body supplied by plugins regardless it is a block or html code' do
410 410 class TestBodyBeginning1Plugin < Noosfero::Plugin
411 411 def body_beginning
412   - lambda {"<span id='plugin1'>This is [[plugin1]] speaking!</span>"}
  412 + lambda {"<span id='plugin1'>This is [[plugin1]] speaking!</span>".html_safe}
413 413 end
414 414 end
415 415 class TestBodyBeginning2Plugin < Noosfero::Plugin
416 416 def body_beginning
417   - "<span id='plugin2'>This is Plugin2 speaking!</span>"
  417 + "<span id='plugin2'>This is Plugin2 speaking!</span>".html_safe
418 418 end
419 419 end
420 420  
... ... @@ -432,12 +432,12 @@ class ApplicationControllerTest &lt; ActionController::TestCase
432 432  
433 433 class TestHeadEnding1Plugin < Noosfero::Plugin
434 434 def head_ending
435   - lambda {"<script>alert('This is [[plugin1]] speaking!')</script>"}
  435 + lambda {"<script>alert('This is [[plugin1]] speaking!')</script>".html_safe}
436 436 end
437 437 end
438 438 class TestHeadEnding2Plugin < Noosfero::Plugin
439 439 def head_ending
440   - "<style>This is Plugin2 speaking!</style>"
  440 + "<style>This is Plugin2 speaking!</style>".html_safe
441 441 end
442 442 end
443 443  
... ...
test/functional/catalog_controller_test.rb
... ... @@ -71,13 +71,13 @@ class CatalogControllerTest &lt; ActionController::TestCase
71 71 should 'include extra content supplied by plugins on catalog item extras' do
72 72 class Plugin1 < Noosfero::Plugin
73 73 def catalog_item_extras(product)
74   - proc {"<span id='plugin1'>This is Plugin1 speaking!</span>"}
  74 + proc {"<span id='plugin1'>This is Plugin1 speaking!</span>".html_safe}
75 75 end
76 76 end
77 77  
78 78 class Plugin2 < Noosfero::Plugin
79 79 def catalog_item_extras(product)
80   - proc {"<span id='plugin2'>This is Plugin2 speaking!</span>"}
  80 + proc {"<span id='plugin2'>This is Plugin2 speaking!</span>".html_safe}
81 81 end
82 82 end
83 83 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ...
test/functional/enterprise_registration_controller_test.rb
... ... @@ -191,13 +191,13 @@ class EnterpriseRegistrationControllerTest &lt; ActionController::TestCase
191 191 should 'include hidden fields supplied by plugins on enterprise registration' do
192 192 class Plugin1 < Noosfero::Plugin
193 193 def enterprise_registration_hidden_fields
194   - {'plugin1' => 'Plugin 1'}
  194 + {'plugin1' => 'Plugin 1'.html_safe}
195 195 end
196 196 end
197 197  
198 198 class Plugin2 < Noosfero::Plugin
199 199 def enterprise_registration_hidden_fields
200   - {'plugin2' => 'Plugin 2'}
  200 + {'plugin2' => 'Plugin 2'.html_safe}
201 201 end
202 202 end
203 203 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ...
test/functional/events_controller_test.rb
... ... @@ -13,7 +13,7 @@ class EventsControllerTest &lt; ActionController::TestCase
13 13  
14 14 get :events, :profile => profile.identifier
15 15  
16   - today = DateTime.now.strftime("%B %d, %Y")
  16 + today = DateTime.now.strftime("%B %d, %Y").html_safe
17 17 assert_tag :tag => 'div', :attributes => {:id => "agenda-items"},
18 18 :descendant => {:tag => 'h3', :content => "Events for #{today}"},
19 19 :descendant => {:tag => 'tr', :content => "Joao Birthday"},
... ...
test/functional/friends_controller_test.rb
... ... @@ -43,7 +43,7 @@ class FriendsControllerTest &lt; ActionController::TestCase
43 43  
44 44 should 'display find people button' do
45 45 get :index, :profile => 'testuser'
46   - assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/search/assets?asset=people' }
  46 + assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/search/assets?asset=people'.html_safe }
47 47 end
48 48  
49 49 should 'not display invite friends button if any plugin tells not to' do
... ...
test/functional/home_controller_test.rb
... ... @@ -88,12 +88,12 @@ class HomeControllerTest &lt; ActionController::TestCase
88 88 should 'provide a link to make the user authentication' do
89 89 class Plugin1 < Noosfero::Plugin
90 90 def alternative_authentication_link
91   - proc {"<a href='plugin1'>Plugin1 link</a>"}
  91 + proc {"<a href='plugin1'>Plugin1 link</a>".html_safe}
92 92 end
93 93 end
94 94 class Plugin2 < Noosfero::Plugin
95 95 def alternative_authentication_link
96   - proc {"<a href='plugin2'>Plugin2 link</a>"}
  96 + proc {"<a href='plugin2'>Plugin2 link</a>".html_safe}
97 97 end
98 98 end
99 99 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ... @@ -168,7 +168,7 @@ class HomeControllerTest &lt; ActionController::TestCase
168 168 should 'plugins add class to the <html>' do
169 169 class Plugin1 < Noosfero::Plugin
170 170 def html_tag_classes
171   - lambda { ['t1', 't2'] }
  171 + lambda { ['t1'.html_safe, 't2'.html_safe] }
172 172 end
173 173 end
174 174  
... ...
test/functional/manage_products_controller_test.rb
... ... @@ -429,12 +429,12 @@ class ManageProductsControllerTest &lt; ActionController::TestCase
429 429 should 'include extra content supplied by plugins on products info extras' do
430 430 class TestProductInfoExtras1Plugin < Noosfero::Plugin
431 431 def product_info_extras(p)
432   - proc {"<span id='plugin1'>This is Plugin1 speaking!</span>"}
  432 + proc {"<span id='plugin1'>This is Plugin1 speaking!</span>".html_safe}
433 433 end
434 434 end
435 435 class TestProductInfoExtras2Plugin < Noosfero::Plugin
436 436 def product_info_extras(p)
437   - proc { "<span id='plugin2'>This is Plugin2 speaking!</span>" }
  437 + proc { "<span id='plugin2'>This is Plugin2 speaking!</span>".html_safe }
438 438 end
439 439 end
440 440  
... ...
test/functional/profile_controller_test.rb
... ... @@ -125,7 +125,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
125 125 @profile.articles.create!(:name => 'testarticle', :tag_list => 'tag1')
126 126 get :content_tagged, :profile => @profile.identifier, :id => 'tag1'
127 127  
128   - assert_tag :tag => 'a', :attributes => { :href => '/tag/tag1' }, :content => 'See content tagged with "tag1" in the entire site'
  128 + assert_tag :tag => 'a', :attributes => { :href => '/tag/tag1' }, :content => 'See content tagged with "tag1" in the entire site'.html_safe
129 129 end
130 130  
131 131 should 'show a link to own control panel' do
... ... @@ -512,7 +512,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
512 512 should 'show description of orgarnization' do
513 513 login_as(@profile.identifier)
514 514 ent = fast_create(Enterprise)
515   - ent.description = 'Enterprise\'s description'
  515 + ent.description = "<span>Enterprise's description</span>"
516 516 ent.save
517 517 get :index, :profile => ent.identifier
518 518 assert_tag :tag => 'div', :attributes => { :class => 'public-profile-description' }, :content => /Enterprise\'s description/
... ... @@ -1236,13 +1236,13 @@ class ProfileControllerTest &lt; ActionController::TestCase
1236 1236 should 'display plugins tabs' do
1237 1237 class Plugin1 < Noosfero::Plugin
1238 1238 def profile_tabs
1239   - {:title => 'Plugin1 tab', :id => 'plugin1_tab', :content => proc { 'Content from plugin1.' }}
  1239 + {:title => 'Plugin1 tab', :id => 'plugin1_tab', :content => proc { 'Content from plugin1.'.html_safe }}
1240 1240 end
1241 1241 end
1242 1242  
1243 1243 class Plugin2 < Noosfero::Plugin
1244 1244 def profile_tabs
1245   - {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => proc { 'Content from plugin2.' }}
  1245 + {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => proc { 'Content from plugin2.'.html_safe }}
1246 1246 end
1247 1247 end
1248 1248 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
... ...