Commit 30560212d346829cc52ebdc98037c18a2b95014b

Authored by Antonio Terceiro
1 parent 6b634fbb

Support running Noosfero as a /subdirectory

- Remove absolute URL's from stylesheets and javascripts
- Handle prefix in LinkListBlock
- add Noosfero.root method as a central data source

The application server needs to be started with the
RAILS_RELATIVE_URL_ROOT environment variable set to the desired prefix.

In development, this can be tested with

  # assuming /social prefix
  $ RAILS_RELATIVE_URL_ROOT=/social thin --prefix /social start

For production, see INSTALL.md
@@ -186,8 +186,8 @@ Apache instalation @@ -186,8 +186,8 @@ Apache instalation
186 186
187 # apt-get install apache2 187 # apt-get install apache2
188 188
189 -Apache configuration  
190 --------------------- 189 +Configuration - noosfero at /
  190 +-----------------------------
191 191
192 First you have to enable the following some apache modules: 192 First you have to enable the following some apache modules:
193 193
@@ -257,6 +257,62 @@ Now restart your apache server (as root): @@ -257,6 +257,62 @@ Now restart your apache server (as root):
257 257
258 # invoke-rc.d apache2 restart 258 # invoke-rc.d apache2 restart
259 259
  260 +Configuration - noosfero at a /subdirectory
  261 +-------------------------------------------
  262 +
  263 +This section describes how to configure noosfero at a subdirectory, what is
  264 +specially useful when you want Noosfero to share a domain name with other
  265 +applications. For example you can host noosfero at yourdomain.com/social, a
  266 +webmail application at yourdomain.com/webmail, and have a static HTML website
  267 +at yourdomain.com/.
  268 +
  269 +**NOTE:** Some plugins might not work well with this setting. Before deploying
  270 +this setting, make sure you test that everything you need works properly with
  271 +it.
  272 +
  273 +The configuration is similar to the main configuration instructions, except for
  274 +the following points. In the description below, replace '/subdirectory' with
  275 +the actual subdirectory you want.
  276 +
  277 +1) add a `prefix: /subdirectory` line to your thin configuration file (thin.yml).
  278 +
  279 +1.1) remember to restart the noosfero application server whenever you make
  280 +changes to that configuration file.
  281 +
  282 + # service noosfero restart
  283 +
  284 +2) add a line saying `export RAILS_RELATIVE_URL_ROOT=/subdirectory` to
  285 +/etc/default/noosfero (you can create it with just this line if it does not
  286 +exist already).
  287 +
  288 +3) You should add the following apache configuration to an existing virtual
  289 +host (plus the `<Proxy balancer://noosfero>` section as displayed above):
  290 +
  291 +```
  292 +Alias /subdirectory /path/to/noosfero/public
  293 +<Directory "/path/to/noosfero/public">
  294 + Options FollowSymLinks
  295 + AllowOverride None
  296 + Order Allow,Deny
  297 + Allow from all
  298 +
  299 + Include /path/to/noosfero/etc/noosfero/apache/cache.conf
  300 +
  301 + RewriteEngine On
  302 + RewriteBase /subdirectory
  303 + # Rewrite index to check for static index.html
  304 + RewriteRule ^$ index.html [QSA]
  305 + # Rewrite to check for Rails cached page
  306 + RewriteRule ^([^.]+)$ $1.html [QSA]
  307 + RewriteCond %{REQUEST_FILENAME} !-f
  308 + RewriteRule ^(.*)$ http://localhost:3000%{REQUEST_URI} [P,QSA,L]
  309 +</Directory>
  310 +```
  311 +
  312 +3.1) remember to reload the apache server whenever any apache configuration
  313 +file changes.
  314 +
  315 + # sudo service apache2 reload
260 316
261 Enabling exception notifications 317 Enabling exception notifications
262 ================================ 318 ================================
app/models/environment.rb
@@ -660,6 +660,7 @@ class Environment &lt; ActiveRecord::Base @@ -660,6 +660,7 @@ class Environment &lt; ActiveRecord::Base
660 url = 'http://' 660 url = 'http://'
661 url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname) 661 url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname)
662 url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port) 662 url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port)
  663 + url << Noosfero.root('')
663 url 664 url
664 end 665 end
665 666
app/models/link_list_block.rb
@@ -78,8 +78,13 @@ class LinkListBlock &lt; Block @@ -78,8 +78,13 @@ class LinkListBlock &lt; Block
78 address 78 address
79 end 79 end
80 if add !~ /^[a-z]+:\/\// && add !~ /^\// 80 if add !~ /^[a-z]+:\/\// && add !~ /^\//
81 - 'http://' + add 81 + '//' + add
82 else 82 else
  83 + if root = Noosfero.root
  84 + if !add.starts_with?(root)
  85 + add = root + add
  86 + end
  87 + end
83 add 88 add
84 end 89 end
85 end 90 end
@@ -96,4 +101,5 @@ class LinkListBlock &lt; Block @@ -96,4 +101,5 @@ class LinkListBlock &lt; Block
96 sanitizer = HTML::WhiteListSanitizer.new 101 sanitizer = HTML::WhiteListSanitizer.new
97 sanitizer.sanitize(text) 102 sanitizer.sanitize(text)
98 end 103 end
  104 +
99 end 105 end
app/views/layouts/application-ng.html.erb
@@ -19,6 +19,9 @@ @@ -19,6 +19,9 @@
19 <meta property="og:site_name" content="<%= profile ? profile.name : @environment.name %>"> 19 <meta property="og:site_name" content="<%= profile ? profile.name : @environment.name %>">
20 <meta property="og:description" content="<%= @page ? truncate(strip_tags(@page.body.to_s), :length => 200) : @environment.name %>"> 20 <meta property="og:description" content="<%= @page ? truncate(strip_tags(@page.body.to_s), :length => 200) : @environment.name %>">
21 21
  22 + <!-- site root -->
  23 + <meta property="noosfero:root" content="<%= Noosfero.root %>"/>
  24 +
22 <% if @page %> 25 <% if @page %>
23 <meta property="article:published_time" content="<%= show_date(@page.published_at) %>"> 26 <meta property="article:published_time" content="<%= show_date(@page.published_at) %>">
24 <% @page.body_images_paths.each do |img| %> 27 <% @page.body_images_paths.each do |img| %>
lib/noosfero.rb
@@ -3,6 +3,10 @@ @@ -3,6 +3,10 @@
3 require 'fast_gettext' 3 require 'fast_gettext'
4 module Noosfero 4 module Noosfero
5 5
  6 + def self.root(default = nil)
  7 + ENV.fetch('RAILS_RELATIVE_URL_ROOT', default)
  8 + end
  9 +
6 def self.pattern_for_controllers_in_directory(dir) 10 def self.pattern_for_controllers_in_directory(dir)
7 disjunction = controllers_in_directory(dir).join('|') 11 disjunction = controllers_in_directory(dir).join('|')
8 pattern = disjunction.blank? ? '' : ('(' + disjunction + ')') 12 pattern = disjunction.blank? ? '' : ('(' + disjunction + ')')
public/designs/icons/tango/style.css
@@ -106,7 +106,7 @@ @@ -106,7 +106,7 @@
106 .icon-activate-user { background-image: url(Tango/16x16/emblems/emblem-system.png) } 106 .icon-activate-user { background-image: url(Tango/16x16/emblems/emblem-system.png) }
107 .icon-deactivate-user { background-image: url(Tango/16x16/emblems/emblem-unreadable.png) } 107 .icon-deactivate-user { background-image: url(Tango/16x16/emblems/emblem-unreadable.png) }
108 .icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) } 108 .icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) }
109 -.icon-reset-admin-role { background-image: url(/images/icons-app/person-icon.png) } 109 +.icon-reset-admin-role { background-image: url(../../../images/icons-app/person-icon.png) }
110 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) } 110 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) }
111 111
112 /******************LARGE ICONS********************/ 112 /******************LARGE ICONS********************/
public/designs/templates/leftbar/stylesheets/style.css
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 } 41 }
42 42
43 .profile-activity-article-forum .profile-activity-lead { 43 .profile-activity-article-forum .profile-activity-lead {
44 - background: url(/images/forum-activity-bg-onecol.png); 44 + background: url(../../../../images/forum-activity-bg-onecol.png);
45 width: 489px; 45 width: 489px;
46 } 46 }
47 47
public/designs/templates/rightbar/stylesheets/style.css
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 } 41 }
42 42
43 .profile-activity-article-forum .profile-activity-lead { 43 .profile-activity-article-forum .profile-activity-lead {
44 - background: url(/images/forum-activity-bg-onecol.png); 44 + background: url(../../../..//images/forum-activity-bg-onecol.png);
45 width: 489px; 45 width: 489px;
46 } 46 }
47 47
public/designs/themes/base/style.css
@@ -257,7 +257,7 @@ body, th, td, input { @@ -257,7 +257,7 @@ body, th, td, input {
257 } 257 }
258 258
259 #navigation .menu-submenu-trigger { 259 #navigation .menu-submenu-trigger {
260 - background: #eee url(/images/down-arrow.png) center center no-repeat; 260 + background: #eee url(../../../images/down-arrow.png) center center no-repeat;
261 border: 0px; 261 border: 0px;
262 height: 8px; 262 height: 8px;
263 width: 124px; 263 width: 124px;
@@ -1220,28 +1220,28 @@ hr.pre-posts, hr.sep-posts { @@ -1220,28 +1220,28 @@ hr.pre-posts, hr.sep-posts {
1220 } 1220 }
1221 1221
1222 .comment-from-owner .comment-wrapper-1 { 1222 .comment-from-owner .comment-wrapper-1 {
1223 - background: #fbf7b5 url(/images/comment-owner-bg-N.png) repeat-x; 1223 + background: #fbf7b5 url(../../../images/comment-owner-bg-N.png) repeat-x;
1224 } 1224 }
1225 .comment-from-owner .comment-wrapper-2 { 1225 .comment-from-owner .comment-wrapper-2 {
1226 - background: url(/images/comment-owner-bg-S.png) 0% 100% repeat-x; 1226 + background: url(../../../images/comment-owner-bg-S.png) 0% 100% repeat-x;
1227 } 1227 }
1228 .comment-from-owner .comment-wrapper-3 { 1228 .comment-from-owner .comment-wrapper-3 {
1229 - background: url(/images/comment-owner-bg-L.png) 100% 0% repeat-y; 1229 + background: url(../../../images/comment-owner-bg-L.png) 100% 0% repeat-y;
1230 } 1230 }
1231 .comment-from-owner .comment-wrapper-4 { 1231 .comment-from-owner .comment-wrapper-4 {
1232 - background: url(/images/comment-owner-bg-O.png) 0% 0% repeat-y; 1232 + background: url(../../../images/comment-owner-bg-O.png) 0% 0% repeat-y;
1233 } 1233 }
1234 .comment-from-owner .comment-wrapper-5 { 1234 .comment-from-owner .comment-wrapper-5 {
1235 - background: url(/images/comment-owner-bg-SL.png) 100% 100% no-repeat; 1235 + background: url(../../../images/comment-owner-bg-SL.png) 100% 100% no-repeat;
1236 } 1236 }
1237 .comment-from-owner .comment-wrapper-6 { 1237 .comment-from-owner .comment-wrapper-6 {
1238 - background: url(/images/comment-owner-bg-SO.png) 0% 100% no-repeat; 1238 + background: url(../../../images/comment-owner-bg-SO.png) 0% 100% no-repeat;
1239 } 1239 }
1240 .comment-from-owner .comment-wrapper-7 { 1240 .comment-from-owner .comment-wrapper-7 {
1241 - background: url(/images/comment-owner-bg-NL.png) 100% 0% no-repeat; 1241 + background: url(../../../images/comment-owner-bg-NL.png) 100% 0% no-repeat;
1242 } 1242 }
1243 .comment-from-owner .comment-wrapper-8 { 1243 .comment-from-owner .comment-wrapper-8 {
1244 - background: url(/images/comment-owner-bg-NO.png) 0% 0% no-repeat; 1244 + background: url(../../../images/comment-owner-bg-NO.png) 0% 0% no-repeat;
1245 } 1245 }
1246 1246
1247 .comment-created-at { 1247 .comment-created-at {
public/javascripts/application.js
@@ -5,6 +5,14 @@ function noosfero_init() { @@ -5,6 +5,14 @@ function noosfero_init() {
5 // focus_first_field(); it is moving the page view when de form is down. 5 // focus_first_field(); it is moving the page view when de form is down.
6 } 6 }
7 7
  8 +var __noosfero_root = null;
  9 +function noosfero_root() {
  10 + if (__noosfero_root == null) {
  11 + __noosfero_root = jQuery('meta[property="noosfero:root"]').attr("content") || '';
  12 + }
  13 + return __noosfero_root;
  14 +}
  15 +
8 /* If applicable, find the first field in which the user can type and move the 16 /* If applicable, find the first field in which the user can type and move the
9 * keyboard focus to it. 17 * keyboard focus to it.
10 * 18 *
@@ -167,7 +175,7 @@ function loading_done(element_id) { @@ -167,7 +175,7 @@ function loading_done(element_id) {
167 jQuery(element_id).removeClass('small-loading-dark'); 175 jQuery(element_id).removeClass('small-loading-dark');
168 } 176 }
169 function open_loading(message) { 177 function open_loading(message) {
170 - jQuery('body').prepend("<div id='overlay_loading' class='ui-widget-overlay' style='display: none'/><div id='overlay_loading_modal' style='display: none'><p>"+message+"</p><img src='/images/loading-dark.gif'/></div>"); 178 + jQuery('body').prepend("<div id='overlay_loading' class='ui-widget-overlay' style='display: none'/><div id='overlay_loading_modal' style='display: none'><p>"+message+"</p><img src='" + noosfero_root() + "/images/loading-dark.gif'/></div>");
171 jQuery('#overlay_loading').show(); 179 jQuery('#overlay_loading').show();
172 jQuery('#overlay_loading_modal').center(); 180 jQuery('#overlay_loading_modal').center();
173 jQuery('#overlay_loading_modal').fadeIn('slow'); 181 jQuery('#overlay_loading_modal').fadeIn('slow');
@@ -515,11 +523,12 @@ jQuery(function($) { @@ -515,11 +523,12 @@ jQuery(function($) {
515 } 523 }
516 }); 524 });
517 525
518 - $.getJSON('/account/user_data', function userDataCallBack(data) { 526 + var user_data = noosfero_root() + '/account/user_data';
  527 + $.getJSON(user_data, function userDataCallBack(data) {
519 if (data.login) { 528 if (data.login) {
520 // logged in 529 // logged in
521 if (data.chat_enabled) { 530 if (data.chat_enabled) {
522 - setInterval(function(){ $.getJSON('/account/user_data', chatOnlineUsersDataCallBack)}, 10000); 531 + setInterval(function(){ $.getJSON(user_data, chatOnlineUsersDataCallBack)}, 10000);
523 } 532 }
524 $('head').append('<meta content="authenticity_token" name="csrf-param" />'); 533 $('head').append('<meta content="authenticity_token" name="csrf-param" />');
525 $('head').append('<meta content="'+$.cookie("_noosfero_.XSRF-TOKEN")+'" name="csrf-token" />'); 534 $('head').append('<meta content="'+$.cookie("_noosfero_.XSRF-TOKEN")+'" name="csrf-token" />');
@@ -600,7 +609,7 @@ function display_notice(message) { @@ -600,7 +609,7 @@ function display_notice(message) {
600 609
601 function open_chat_window(self_link, anchor) { 610 function open_chat_window(self_link, anchor) {
602 anchor = anchor || '#'; 611 anchor = anchor || '#';
603 - var noosfero_chat_window = window.open('/chat' + anchor,'noosfero_chat','width=900,height=500'); 612 + var noosfero_chat_window = window.open(noosfero_root() + '/chat' + anchor,'noosfero_chat','width=900,height=500');
604 noosfero_chat_window.focus(); 613 noosfero_chat_window.focus();
605 return false; 614 return false;
606 } 615 }
public/javascripts/lightbox.js
@@ -221,7 +221,7 @@ function addLightboxMarkup() { @@ -221,7 +221,7 @@ function addLightboxMarkup() {
221 lb.id = 'lightbox'; 221 lb.id = 'lightbox';
222 lb.className = 'loading'; 222 lb.className = 'loading';
223 lb.innerHTML = '<div id="lbLoadMessage">' + 223 lb.innerHTML = '<div id="lbLoadMessage">' +
224 - '<img src="/images/loading.gif"/>' + 224 + '<img src="' + noosfero_root() + '/images/2loading.gif"/>' +
225 '</div>'; 225 '</div>';
226 bod.appendChild(overlay); 226 bod.appendChild(overlay);
227 bod.appendChild(lb); 227 bod.appendChild(lb);
public/javascripts/thickbox.js
@@ -13,7 +13,7 @@ var tb_pathToImage = &quot;/images/loading.gif&quot;; @@ -13,7 +13,7 @@ var tb_pathToImage = &quot;/images/loading.gif&quot;;
13 jQuery(document).ready(function(){ 13 jQuery(document).ready(function(){
14 tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox 14 tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox
15 imgLoader = new Image();// preload image 15 imgLoader = new Image();// preload image
16 - imgLoader.src = tb_pathToImage; 16 + imgLoader.src = noosfero_root() + tb_pathToImage;
17 }); 17 });
18 18
19 //add thickbox to href & area elements that have a class of .thickbox 19 //add thickbox to href & area elements that have a class of .thickbox
public/stylesheets/application.css
@@ -1047,7 +1047,7 @@ code input { @@ -1047,7 +1047,7 @@ code input {
1047 width: 100%; 1047 width: 100%;
1048 height: 16px; 1048 height: 16px;
1049 text-align: left; 1049 text-align: left;
1050 - background: transparent url(/images/black-alpha-pixel.png); 1050 + background: transparent url(../images/black-alpha-pixel.png);
1051 border-bottom: 1px solid #333; 1051 border-bottom: 1px solid #333;
1052 text-decoration: none; 1052 text-decoration: none;
1053 } 1053 }
@@ -1065,7 +1065,7 @@ code input { @@ -1065,7 +1065,7 @@ code input {
1065 padding-left: 16px; 1065 padding-left: 16px;
1066 border-bottom: 1px solid #eee; 1066 border-bottom: 1px solid #eee;
1067 display: block; 1067 display: block;
1068 - background: transparent url(/images/zoom.png) left center no-repeat; 1068 + background: transparent url(../images/zoom.png) left center no-repeat;
1069 color: #fff; 1069 color: #fff;
1070 } 1070 }
1071 #article pre { 1071 #article pre {
@@ -1257,7 +1257,7 @@ a.comment-picture { @@ -1257,7 +1257,7 @@ a.comment-picture {
1257 background: transparent; 1257 background: transparent;
1258 } 1258 }
1259 .comment-replies .comment-from-owner.comment-content { 1259 .comment-replies .comment-from-owner.comment-content {
1260 - background: transparent url(/images/comment-reply-owner-bg.png) left bottom repeat-x; 1260 + background: transparent url(../images/comment-reply-owner-bg.png) left bottom repeat-x;
1261 } 1261 }
1262 .comment-replies .comment-user-status { 1262 .comment-replies .comment-user-status {
1263 top: 15px; 1263 top: 15px;
@@ -1318,7 +1318,7 @@ a.comment-picture { @@ -1318,7 +1318,7 @@ a.comment-picture {
1318 border: 1px solid #808080; 1318 border: 1px solid #808080;
1319 padding: 0; 1319 padding: 0;
1320 margin-bottom: 10px; 1320 margin-bottom: 10px;
1321 - background: transparent url(/images/black-alpha-pixel-5.png) left top repeat; 1321 + background: transparent url(../images/black-alpha-pixel-5.png) left top repeat;
1322 -moz-border-radius: 5px; 1322 -moz-border-radius: 5px;
1323 -webkit-border-radius: 5px; 1323 -webkit-border-radius: 5px;
1324 border-radius: 5px; 1324 border-radius: 5px;
@@ -1527,7 +1527,7 @@ div.article-body p img { @@ -1527,7 +1527,7 @@ div.article-body p img {
1527 /* NOT PUBLISHED BLOG POSTS */ 1527 /* NOT PUBLISHED BLOG POSTS */
1528 1528
1529 .blog-post.not-published { 1529 .blog-post.not-published {
1530 - background: url(/images/hachure.png); 1530 + background: url(../images/hachure.png);
1531 opacity: 0.25; 1531 opacity: 0.25;
1532 filter: alpha(opacity=25); 1532 filter: alpha(opacity=25);
1533 zoom: 1; 1533 zoom: 1;
@@ -1623,7 +1623,7 @@ body.noosfero a.button.with-text.icon-none, body.noosfero input.button.with-text @@ -1623,7 +1623,7 @@ body.noosfero a.button.with-text.icon-none, body.noosfero input.button.with-text
1623 padding-left: 2px; 1623 padding-left: 2px;
1624 } 1624 }
1625 a.disabled{ 1625 a.disabled{
1626 - filter: url(/filters.svg#grayscale); /* Firefox 3.5+ */ 1626 + filter: url(../filters.svg#grayscale); /* Firefox 3.5+ */
1627 filter: gray; /* IE6-9 */ 1627 filter: gray; /* IE6-9 */
1628 -webkit-filter: grayscale(1); /* Google Chrome & Safari 6+ */ 1628 -webkit-filter: grayscale(1); /* Google Chrome & Safari 6+ */
1629 cursor: default; 1629 cursor: default;
@@ -1699,7 +1699,7 @@ a.button.disabled, input.disabled { @@ -1699,7 +1699,7 @@ a.button.disabled, input.disabled {
1699 display: none; 1699 display: none;
1700 } 1700 }
1701 .invisible-block { 1701 .invisible-block {
1702 - background: url(/images/hachure.png); 1702 + background: url(../images/hachure.png);
1703 opacity: 0.25; 1703 opacity: 0.25;
1704 } 1704 }
1705 .msie .invisible-block { 1705 .msie .invisible-block {
@@ -1914,7 +1914,7 @@ a.button.disabled, input.disabled { @@ -1914,7 +1914,7 @@ a.button.disabled, input.disabled {
1914 width: 97%; 1914 width: 97%;
1915 } 1915 }
1916 .link-list-row:hover { 1916 .link-list-row:hover {
1917 - background: #ddd url(/images/drag-and-drop.png) no-repeat; 1917 + background: #ddd url(../images/drag-and-drop.png) no-repeat;
1918 background-position: 98% 15px; 1918 background-position: 98% 15px;
1919 } 1919 }
1920 .link-list-row li { 1920 .link-list-row li {
@@ -2007,7 +2007,7 @@ a.button.disabled, input.disabled { @@ -2007,7 +2007,7 @@ a.button.disabled, input.disabled {
2007 } 2007 }
2008 #content .comment-header .comment-actions-reply { 2008 #content .comment-header .comment-actions-reply {
2009 float: right; 2009 float: right;
2010 - background-image: url(/designs/icons/tango/Tango/16x16/actions/go-jump.png); 2010 + background-image: url(../designs/icons/tango/Tango/16x16/actions/go-jump.png);
2011 height: 12px; 2011 height: 12px;
2012 } 2012 }
2013 #content .comment-header ul { 2013 #content .comment-header ul {
@@ -2104,13 +2104,13 @@ a.button.disabled, input.disabled { @@ -2104,13 +2104,13 @@ a.button.disabled, input.disabled {
2104 height: 15px; 2104 height: 15px;
2105 } 2105 }
2106 .common-profile-list-block .sex-male { 2106 .common-profile-list-block .sex-male {
2107 - background: url(/images/icons-app/ico-male.png); 2107 + background: url(../images/icons-app/ico-male.png);
2108 } 2108 }
2109 .common-profile-list-block .sex-female { 2109 .common-profile-list-block .sex-female {
2110 - background: url(/images/icons-app/ico-female.png); 2110 + background: url(../images/icons-app/ico-female.png);
2111 } 2111 }
2112 .common-profile-list-block .sex-undef { 2112 .common-profile-list-block .sex-undef {
2113 - background: url(/images/icons-app/ico-sex-undef.png); 2113 + background: url(../images/icons-app/ico-sex-undef.png);
2114 } 2114 }
2115 .msie6 .common-profile-list-block .sex-male { 2115 .msie6 .common-profile-list-block .sex-male {
2116 background: none; 2116 background: none;
@@ -2357,13 +2357,13 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation @@ -2357,13 +2357,13 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation
2357 height: 15px; 2357 height: 15px;
2358 } 2358 }
2359 .profile-info-picture .sex-male { 2359 .profile-info-picture .sex-male {
2360 - background: url(/images/icons-app/ico-male.png); 2360 + background: url(../images/icons-app/ico-male.png);
2361 } 2361 }
2362 .profile-info-picture .sex-female { 2362 .profile-info-picture .sex-female {
2363 - background: url(/images/icons-app/ico-female.png); 2363 + background: url(../images/icons-app/ico-female.png);
2364 } 2364 }
2365 .profile-info-picture .sex-undef { 2365 .profile-info-picture .sex-undef {
2366 - background: url(/images/icons-app/ico-sex-undef.png); 2366 + background: url(../images/icons-app/ico-sex-undef.png);
2367 } 2367 }
2368 .msie6 .profile-info-picture .sex-male { 2368 .msie6 .profile-info-picture .sex-male {
2369 background: none; 2369 background: none;
@@ -2805,7 +2805,7 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation @@ -2805,7 +2805,7 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation
2805 font-size: 0.70em; 2805 font-size: 0.70em;
2806 color: white; 2806 color: white;
2807 font-weight: bold; 2807 font-weight: bold;
2808 - background: url(/images/catalog-expanders.png) no-repeat; 2808 + background: url(../images/catalog-expanders.png) no-repeat;
2809 display: block; 2809 display: block;
2810 line-height: 15px; 2810 line-height: 15px;
2811 background-position: left 100%; 2811 background-position: left 100%;
@@ -3844,7 +3844,7 @@ h1#agenda-title { @@ -3844,7 +3844,7 @@ h1#agenda-title {
3844 bottom: 5px; 3844 bottom: 5px;
3845 position: absolute; 3845 position: absolute;
3846 display: block; 3846 display: block;
3847 - background: transparent url(/images/loading-dark.gif) center center no-repeat; 3847 + background: transparent url(../images/loading-dark.gif) center center no-repeat;
3848 } 3848 }
3849 /* hide the close x on the loading screen */ 3849 /* hide the close x on the loading screen */
3850 .controller-invite .ui-dialog-titlebar-close { 3850 .controller-invite .ui-dialog-titlebar-close {
@@ -3860,7 +3860,7 @@ h1#agenda-title { @@ -3860,7 +3860,7 @@ h1#agenda-title {
3860 border: 1px solid #AABB88; 3860 border: 1px solid #AABB88;
3861 -moz-border-radius: 5px; 3861 -moz-border-radius: 5px;
3862 -webkit-border-radius: 5px; 3862 -webkit-border-radius: 5px;
3863 - background: url(/images/ccc.gif); /* image ccc.gif from http://www.wannabegirl.org/translucent */ 3863 + background: url(../images/ccc.gif); /* image ccc.gif from http://www.wannabegirl.org/translucent */
3864 padding: 10px 30px 20px 30px; 3864 padding: 10px 30px 20px 30px;
3865 } 3865 }
3866 #categories_container_wrapper { 3866 #categories_container_wrapper {
@@ -3869,7 +3869,7 @@ h1#agenda-title { @@ -3869,7 +3869,7 @@ h1#agenda-title {
3869 padding: 5px; 3869 padding: 5px;
3870 -moz-border-radius: 3px; 3870 -moz-border-radius: 3px;
3871 -webkit-border-radius: 3px; 3871 -webkit-border-radius: 3px;
3872 - background: url(/images/fff.gif); /* image fff.gif from http://www.wannabegirl.org/translucent */ 3872 + background: url(../images/fff.gif); /* image fff.gif from http://www.wannabegirl.org/translucent */
3873 border: 1px solid #CCC; 3873 border: 1px solid #CCC;
3874 border-bottom: 0; 3874 border-bottom: 0;
3875 position: relative; 3875 position: relative;
@@ -4668,7 +4668,7 @@ h1#agenda-title { @@ -4668,7 +4668,7 @@ h1#agenda-title {
4668 position: absolute; 4668 position: absolute;
4669 bottom: 0; 4669 bottom: 0;
4670 z-index: 2; 4670 z-index: 2;
4671 - background: transparent url(/images/black-alpha-pixel.png); 4671 + background: transparent url(../images/black-alpha-pixel.png);
4672 color: #fff; 4672 color: #fff;
4673 text-decoration: none; 4673 text-decoration: none;
4674 display: block; 4674 display: block;
@@ -4750,10 +4750,10 @@ h1#agenda-title { @@ -4750,10 +4750,10 @@ h1#agenda-title {
4750 display: none; 4750 display: none;
4751 } 4751 }
4752 .featured-product-prev { 4752 .featured-product-prev {
4753 - background-image: url(/designs/icons/tango/Tango/16x16/actions/go-previous.png); 4753 + background-image: url(../designs/icons/tango/Tango/16x16/actions/go-previous.png);
4754 } 4754 }
4755 .featured-product-next { 4755 .featured-product-next {
4756 - background-image: url(/designs/icons/tango/Tango/16x16/actions/go-next.png); 4756 + background-image: url(../designs/icons/tango/Tango/16x16/actions/go-next.png);
4757 } 4757 }
4758 .featured-products-block-container { 4758 .featured-products-block-container {
4759 width: 92%; 4759 width: 92%;
@@ -4882,14 +4882,14 @@ h1#agenda-title { @@ -4882,14 +4882,14 @@ h1#agenda-title {
4882 top: -1px; 4882 top: -1px;
4883 left: -3px; 4883 left: -3px;
4884 overflow: hidden; 4884 overflow: hidden;
4885 - background: #efefef url(/images/top-arrow.png) center center no-repeat; 4885 + background: #efefef url(../images/top-arrow.png) center center no-repeat;
4886 border: 1px solid #ccc; 4886 border: 1px solid #ccc;
4887 z-index: 2; 4887 z-index: 2;
4888 -moz-border-radius: 5px; 4888 -moz-border-radius: 5px;
4889 -webkit-border-radius: 5px; 4889 -webkit-border-radius: 5px;
4890 } 4890 }
4891 .common-profile-list-block .vcard .menu-submenu-trigger:hover, .menu-submenu-trigger:hover, .comment-actions .vcard .menu-submenu-trigger:hover { 4891 .common-profile-list-block .vcard .menu-submenu-trigger:hover, .menu-submenu-trigger:hover, .comment-actions .vcard .menu-submenu-trigger:hover {
4892 - background: #fff url(/images/top-arrow.png) center center no-repeat; 4892 + background: #fff url(../images/top-arrow.png) center center no-repeat;
4893 border: 1px solid #ccc; 4893 border: 1px solid #ccc;
4894 } 4894 }
4895 .menu-submenu-trigger span { 4895 .menu-submenu-trigger span {
@@ -4916,17 +4916,17 @@ h1#agenda-title { @@ -4916,17 +4916,17 @@ h1#agenda-title {
4916 right: -44px; 4916 right: -44px;
4917 } 4917 }
4918 .menu-submenu-footer { 4918 .menu-submenu-footer {
4919 - background: transparent url(/images/balloon-footer.png) center center no-repeat; 4919 + background: transparent url(../images/balloon-footer.png) center center no-repeat;
4920 height: 29px; 4920 height: 29px;
4921 margin: 0; 4921 margin: 0;
4922 } 4922 }
4923 .menu-submenu-header { 4923 .menu-submenu-header {
4924 - background: transparent url(/images/balloon-header.png) center center no-repeat; 4924 + background: transparent url(../images/balloon-header.png) center center no-repeat;
4925 height: 17px; 4925 height: 17px;
4926 margin: 0; 4926 margin: 0;
4927 } 4927 }
4928 .menu-submenu-content { 4928 .menu-submenu-content {
4929 - background: transparent url(/images/balloon-middle.png) top left repeat-y; 4929 + background: transparent url(../images/balloon-middle.png) top left repeat-y;
4930 margin: 0; 4930 margin: 0;
4931 padding: 0; 4931 padding: 0;
4932 width: 100%; 4932 width: 100%;
@@ -5034,7 +5034,7 @@ h1#agenda-title { @@ -5034,7 +5034,7 @@ h1#agenda-title {
5034 height: 25px; 5034 height: 25px;
5035 width: 100%; 5035 width: 100%;
5036 position: absolute; 5036 position: absolute;
5037 - background: #ccc url(/images/icons-app/chat-22x22.png) 2px 2px no-repeat; 5037 + background: #ccc url(../images/icons-app/chat-22x22.png) 2px 2px no-repeat;
5038 } 5038 }
5039 #title-bar .title { 5039 #title-bar .title {
5040 margin: 0; 5040 margin: 0;
@@ -5280,7 +5280,7 @@ h1#agenda-title { @@ -5280,7 +5280,7 @@ h1#agenda-title {
5280 padding-left: 60px; 5280 padding-left: 60px;
5281 float: none; 5281 float: none;
5282 overflow: hidden; 5282 overflow: hidden;
5283 - background: transparent url(/images/forum-activity-bg.png) left center no-repeat; 5283 + background: transparent url(../images/forum-activity-bg.png) left center no-repeat;
5284 } 5284 }
5285 5285
5286 .profile-activity-article-forum .see-forum { 5286 .profile-activity-article-forum .see-forum {
@@ -5288,7 +5288,7 @@ h1#agenda-title { @@ -5288,7 +5288,7 @@ h1#agenda-title {
5288 } 5288 }
5289 5289
5290 .profile-activity-article-forum .see-forum a { 5290 .profile-activity-article-forum .see-forum a {
5291 - background: transparent url(/images/forum-activity-icon.png) left center no-repeat; 5291 + background: transparent url(../images/forum-activity-icon.png) left center no-repeat;
5292 padding-left: 30px; 5292 padding-left: 30px;
5293 font-weight: bold; 5293 font-weight: bold;
5294 color: #dadada !important; 5294 color: #dadada !important;
@@ -6263,7 +6263,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6263,7 +6263,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6263 6263
6264 #signup-form .invalid { 6264 #signup-form .invalid {
6265 border-color: #7f0000; 6265 border-color: #7f0000;
6266 - background-image: url(/images/passwords_nomatch.png); 6266 + background-image: url(../images/passwords_nomatch.png);
6267 box-shadow: 0 0 7px red; 6267 box-shadow: 0 0 7px red;
6268 } 6268 }
6269 6269
@@ -6277,7 +6277,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6277,7 +6277,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6277 6277
6278 #signup-form .checking { 6278 #signup-form .checking {
6279 border-color: #4A4A4A; 6279 border-color: #4A4A4A;
6280 - background-image: url(/images/login_checking.png); 6280 + background-image: url(../images/login_checking.png);
6281 } 6281 }
6282 6282
6283 #signup-form span.checking { 6283 #signup-form span.checking {
@@ -6290,7 +6290,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6290,7 +6290,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6290 6290
6291 #signup-form .validated { 6291 #signup-form .validated {
6292 border-color: #005000; 6292 border-color: #005000;
6293 - background-image: url(/images/passwords_match.png); 6293 + background-image: url(../images/passwords_match.png);
6294 } 6294 }
6295 6295
6296 #signup-form span.validated { 6296 #signup-form span.validated {
@@ -6348,7 +6348,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6348,7 +6348,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6348 padding: 5px 10px 45px 10px; 6348 padding: 5px 10px 45px 10px;
6349 margin: 0; 6349 margin: 0;
6350 line-height: 1.5em; 6350 line-height: 1.5em;
6351 - background: transparent url(/images/gray-balloon.png) bottom center no-repeat; 6351 + background: transparent url(../images/gray-balloon.png) bottom center no-repeat;
6352 position: absolute; 6352 position: absolute;
6353 z-index: 2; 6353 z-index: 2;
6354 right: -150px; 6354 right: -150px;
@@ -6410,7 +6410,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6410,7 +6410,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6410 #content #signup-form .submit { 6410 #content #signup-form .submit {
6411 border: 0; 6411 border: 0;
6412 padding: 8px 36px 12px; 6412 padding: 8px 36px 12px;
6413 - background: transparent url(/images/gray-bg.png) left center repeat-x; 6413 + background: transparent url(../images/gray-bg.png) left center repeat-x;
6414 font-size: 17px; 6414 font-size: 17px;
6415 color: #FFF; 6415 color: #FFF;
6416 text-align: center; 6416 text-align: center;
public/stylesheets/filters.svg 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../filters.svg
0 \ No newline at end of file 2 \ No newline at end of file
public/stylesheets/iepngfix/iepngfix.css
1 -img { behavior: url(/stylesheets/iepngfix/iepngfix.htc) } 1 +img { behavior: url(iepngfix.htc) }
test/unit/link_list_block_test.rb
@@ -65,6 +65,18 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase @@ -65,6 +65,18 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase
65 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/address'} 65 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/address'}
66 end 66 end
67 67
  68 + should 'handle /prefix if not already added' do
  69 + Noosfero.stubs(:root).returns('/prefix')
  70 + l = LinkListBlock.new(:links => [{:name => "foo", :address => '/bar'}] )
  71 + assert_tag_in_string l.content, :tag => 'a', :attributes => { :href => '/prefix/bar' }
  72 + end
  73 +
  74 + should 'not add /prefix if already there' do
  75 + Noosfero.stubs(:root).returns('/prefix')
  76 + l = LinkListBlock.new(:links => [{:name => "foo", :address => '/prefix/bar'}] )
  77 + assert_tag_in_string l.content, :tag => 'a', :attributes => { :href => '/prefix/bar' }
  78 + end
  79 +
68 should 'display options for icons' do 80 should 'display options for icons' do
69 l = LinkListBlock.new 81 l = LinkListBlock.new
70 l.icons_options.each do |option| 82 l.icons_options.each do |option|
@@ -92,8 +104,8 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase @@ -92,8 +104,8 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase
92 assert_no_tag_in_string l.link_html(l.links.first), :attributes => { :onclick => /.*/ } 104 assert_no_tag_in_string l.link_html(l.links.first), :attributes => { :onclick => /.*/ }
93 end 105 end
94 106
95 - should 'add http in front of incomplete external links' do  
96 - {'/local/link' => '/local/link', 'http://example.org' => 'http://example.org', 'example.org' => 'http://example.org'}.each do |input, output| 107 + should 'add protocol in front of incomplete external links' do
  108 + {'/local/link' => '/local/link', 'http://example.org' => 'http://example.org', 'example.org' => '//example.org'}.each do |input, output|
97 l = LinkListBlock.new(:links => [{:name => 'categ', :address => input}]) 109 l = LinkListBlock.new(:links => [{:name => 'categ', :address => input}])
98 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => output} 110 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => output}
99 end 111 end