Commit 4153a58121485658d5f814fc9fa54d6c969b5c77
Exists in
staging
and in
4 other branches
Merge branch 'rails3' into rails3_stable
Showing
15 changed files
with
122 additions
and
121 deletions
Show diff stats
app/controllers/my_profile/profile_editor_controller.rb
| ... | ... | @@ -15,20 +15,14 @@ class ProfileEditorController < MyProfileController |
| 15 | 15 | @possible_domains = profile.possible_domains |
| 16 | 16 | if request.post? |
| 17 | 17 | params[:profile_data][:fields_privacy] ||= {} if profile.person? && params[:profile_data].is_a?(Hash) |
| 18 | - begin | |
| 19 | - Profile.transaction do | |
| 20 | - Image.transaction do | |
| 21 | - if profile.update_attributes!(params[:profile_data]) | |
| 22 | - redirect_to :action => 'index', :profile => profile.identifier | |
| 23 | - end | |
| 18 | + Profile.transaction do | |
| 19 | + Image.transaction do | |
| 20 | + if @profile_data.update_attributes(params[:profile_data]) | |
| 21 | + redirect_to :action => 'index', :profile => profile.identifier | |
| 22 | + else | |
| 23 | + profile.identifier = params[:profile] if profile.identifier.blank? | |
| 24 | 24 | end |
| 25 | - end | |
| 26 | - rescue Exception => ex | |
| 27 | - if profile.identifier.blank? | |
| 28 | - profile.identifier = params[:profile] | |
| 29 | - end | |
| 30 | - session[:notice] = _('Cannot update profile') | |
| 31 | - logger.error ex.to_s | |
| 25 | + end | |
| 32 | 26 | end |
| 33 | 27 | end |
| 34 | 28 | end | ... | ... |
app/models/person.rb
| ... | ... | @@ -157,11 +157,6 @@ class Person < Profile |
| 157 | 157 | |
| 158 | 158 | validates_multiparameter_assignments |
| 159 | 159 | |
| 160 | - validates_each :birth_date do |record,attr,value| | |
| 161 | - date_str = record.birth_date_before_type_cast | |
| 162 | - record.errors.add(attr) if value.blank? && !date_str.blank? | |
| 163 | - end | |
| 164 | - | |
| 165 | 160 | def self.fields |
| 166 | 161 | FIELDS |
| 167 | 162 | end | ... | ... |
app/models/profile.rb
| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | # which by default is the one returned by Environment:default. |
| 4 | 4 | class Profile < ActiveRecord::Base |
| 5 | 5 | |
| 6 | - attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n | |
| 6 | + attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time | |
| 7 | 7 | |
| 8 | 8 | # use for internationalizable human type names in search facets |
| 9 | 9 | # reimplement on subclasses | ... | ... |
app/views/layouts/_javascript.html.erb
| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | 'jquery.noconflict.js', 'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorbox', |
| 4 | 4 | 'jquery-ui-1.10.4/js/jquery-ui-1.10.4.min', 'jquery.scrollTo', 'jquery.form.js', 'jquery-validation/jquery.validate', |
| 5 | 5 | 'jquery.cookie', 'jquery.ba-bbq.min.js', 'reflection', 'jquery.tokeninput', |
| 6 | -'add-and-join', 'report-abuse', 'catalog', 'manage-products', | |
| 6 | +'add-and-join', 'report-abuse', 'catalog', 'manage-products', 'autogrow', | |
| 7 | 7 | 'jquery-timepicker-addon/dist/jquery-ui-timepicker-addon', 'application.js', 'rails.js', :cache => 'cache/application' %> |
| 8 | 8 | |
| 9 | 9 | <% language = FastGettext.locale %> | ... | ... |
app/views/profile/_profile_wall.html.erb
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | <div id='leave_scrap'> |
| 3 | 3 | <%= flash[:error] %> |
| 4 | 4 | <%= form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''", :complete => "jQuery('#leave_scrap_form').removeClass('loading').find('*').attr('disabled', false)", :loading => "jQuery('#leave_scrap_form').addClass('loading').find('*').attr('disabled', true)", :html => {:id => 'leave_scrap_form' } do %> |
| 5 | - <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %> | |
| 5 | + <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2, :class => 'autogrow' %> | |
| 6 | 6 | <%= submit_button :new, _('Share') %> |
| 7 | 7 | <% end %> |
| 8 | 8 | </div> | ... | ... |
app/views/profile_editor/_person_form.html.erb
| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | <%= optional_field(@person, 'jabber_id', f.text_field(:jabber_id, :rel => _('Jabber'))) %> |
| 17 | 17 | <%= optional_field(@person, 'personal_website', f.text_field(:personal_website, :rel => _('Personal website'))) %> |
| 18 | 18 | <%= optional_field(@person, 'sex', f.radio_group(:profile_data, :sex, [ ['male',_('Male')], ['female',_('Female')] ])) %> |
| 19 | -<%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %> | |
| 19 | +<%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), date_field('profile_data[birth_date]', @profile_data. birth_date, '%Y-%m-%d', {:change_month => true, :change_year => true, :year_range => '-100:-5', :date_format => 'yy-mm-dd'}, {:id => 'profile_data_birth_date'}))) %> | |
| 20 | 20 | <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> |
| 21 | 21 | <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> |
| 22 | 22 | <%= optional_field(@person, 'state', f.text_field(:state, :id => 'state_field', :rel => _('State'))) %> | ... | ... |
config/environments/development.rb
etc/init.d/noosfero
| ... | ... | @@ -54,10 +54,10 @@ fi |
| 54 | 54 | ###################### |
| 55 | 55 | |
| 56 | 56 | main_script() { |
| 57 | - cd $NOOSFERO_DIR | |
| 58 | 57 | if [ "$NOOSFERO_USER" != "$USER" ]; then |
| 59 | - su $NOOSFERO_USER -l -c "./script/production $1" | |
| 58 | + su $NOOSFERO_USER -l -c "cd $NOOSFERO_DIR && ./script/production $1" | |
| 60 | 59 | else |
| 60 | + cd $NOOSFERO_DIR | |
| 61 | 61 | ./script/production $1 |
| 62 | 62 | fi |
| 63 | 63 | } | ... | ... |
etc/noosfero/varnish-accept-language.vcl
| ... | ... | @@ -186,7 +186,7 @@ sub vcl_recv { |
| 186 | 186 | |
| 187 | 187 | sub vcl_fetch { |
| 188 | 188 | if (beresp.http.Vary) { |
| 189 | - set beresp.http.Vary = beresp.http.Vary ", X-Varnish-Accept-Language"; | |
| 189 | + set beresp.http.Vary = beresp.http.Vary + ", X-Varnish-Accept-Language"; | |
| 190 | 190 | } else { |
| 191 | 191 | set beresp.http.Vary = "X-Varnish-Accept-Language"; |
| 192 | 192 | } | ... | ... |
etc/noosfero/varnish-noosfero.vcl
| ... | ... | @@ -45,7 +45,7 @@ sub vcl_error { |
| 45 | 45 | <div id='wrap'> |
| 46 | 46 | <div id='header'> |
| 47 | 47 | <div id='logo'> </div> |
| 48 | - <div id='details'><b>"} obj.status "</b> - " obj.response {"</div> | |
| 48 | + <div id='details'><b>"} + obj.status + "</b> - " + obj.response + {"</div> | |
| 49 | 49 | </div> |
| 50 | 50 | |
| 51 | 51 | <div id='de' style='display: none' class='message'> | ... | ... |
features/edit_profile.feature
| ... | ... | @@ -6,30 +6,6 @@ Feature: edit profile |
| 6 | 6 | | joao | |
| 7 | 7 | Given I am logged in as "joao" |
| 8 | 8 | |
| 9 | - Scenario: Warn about invalid birth date when active | |
| 10 | - Given the following person fields are active fields | |
| 11 | - | display_name | | |
| 12 | - | birth_date | | |
| 13 | - When I go to joao's control panel | |
| 14 | - And I follow "Edit Profile" | |
| 15 | - And I select "November" from "profile_data_birth_date_2i" | |
| 16 | - And I select "15" from "profile_data_birth_date_3i" | |
| 17 | - And I press "Save" | |
| 18 | - Then I should see "Birth date is invalid" | |
| 19 | - And I should not see "Birth date can't be blank" | |
| 20 | - | |
| 21 | - Scenario: Warn about invalid birth date when required | |
| 22 | - Given the following person fields are required fields | |
| 23 | - | display_name | | |
| 24 | - | birth_date | | |
| 25 | - When I go to joao's control panel | |
| 26 | - And I follow "Edit Profile" | |
| 27 | - And I select "November" from "profile_data_birth_date_2i" | |
| 28 | - And I select "15" from "profile_data_birth_date_3i" | |
| 29 | - And I press "Save" | |
| 30 | - Then I should see "Birth date is invalid" | |
| 31 | - And I should not see "Birth date can't be blank" | |
| 32 | - | |
| 33 | 9 | Scenario: Not warn if birth date is valid when active |
| 34 | 10 | Given the following person fields are active fields |
| 35 | 11 | | display_name | | ... | ... |
lib/tasks/release.rake
| ... | ... | @@ -41,7 +41,7 @@ namespace :noosfero do |
| 41 | 41 | end |
| 42 | 42 | |
| 43 | 43 | def version |
| 44 | - require_dependency 'noosfero' | |
| 44 | + require 'noosfero' | |
| 45 | 45 | Noosfero::VERSION |
| 46 | 46 | end |
| 47 | 47 | |
| ... | ... | @@ -130,42 +130,6 @@ EOF |
| 130 | 130 | choice |
| 131 | 131 | end |
| 132 | 132 | |
| 133 | - desc 'sets the new version on apropriate files' | |
| 134 | - task :set_version, :release_kind do |t, args| | |
| 135 | - next if File.exist?("tmp/pending-release") | |
| 136 | - release_kind = args[:release_kind] || 'stable' | |
| 137 | - | |
| 138 | - if release_kind == 'test' | |
| 139 | - version_question = "Release candidate of which version" | |
| 140 | - distribution = 'squeeze-test' | |
| 141 | - else | |
| 142 | - version_question = "Version that is being released" | |
| 143 | - distribution = 'unstable' | |
| 144 | - end | |
| 145 | - | |
| 146 | - version_name = new_version = ask(version_question) | |
| 147 | - | |
| 148 | - if release_kind == 'test' | |
| 149 | - rc_version = ask('RC version', Time.now.strftime('%Y%m%d%H%M%S')) | |
| 150 | - version_name += "~rc#{rc_version}" | |
| 151 | - end | |
| 152 | - release_message = ask("Release message") | |
| 153 | - | |
| 154 | - sh 'git checkout debian/changelog lib/noosfero.rb' | |
| 155 | - sh "sed -i \"s/VERSION = '[^']*'/VERSION = '#{version_name}'/\" lib/noosfero.rb" | |
| 156 | - sh "dch --newversion #{version_name} --distribution #{distribution} --force-distribution '#{release_message}'" | |
| 157 | - | |
| 158 | - sh 'git diff debian/changelog lib/noosfero.rb' | |
| 159 | - if confirm("Commit version bump to #{version_name} on #{distribution} distribution") | |
| 160 | - sh 'git add debian/changelog lib/noosfero.rb' | |
| 161 | - sh "git commit -m 'Bumping version #{version_name}'" | |
| 162 | - sh "touch tmp/pending-release" | |
| 163 | - else | |
| 164 | - sh 'git checkout debian/changelog lib/noosfero.rb' | |
| 165 | - abort 'Version update not confirmed. Reverting changes and exiting...' | |
| 166 | - end | |
| 167 | - end | |
| 168 | - | |
| 169 | 133 | desc "uploads the packages to the repository" |
| 170 | 134 | task :upload_packages, :release_kind do |t, args| |
| 171 | 135 | release_kind = args[:release_kind] || 'stable' |
| ... | ... | @@ -177,9 +141,13 @@ EOF |
| 177 | 141 | next if File.exist?("tmp/pending-release") |
| 178 | 142 | release_kind = args[:release_kind] || 'stable' |
| 179 | 143 | |
| 180 | - if release_kind == 'test' | |
| 144 | + if release_kind =~ /test/ | |
| 181 | 145 | version_question = "Release candidate of which version: " |
| 182 | - distribution = 'squeeze-test' | |
| 146 | + if release_kind == 'squeeze-test' | |
| 147 | + distribution = 'squeeze-test' | |
| 148 | + elsif release_kind == 'wheezy-test' | |
| 149 | + distribution = 'wheezy-test' | |
| 150 | + end | |
| 183 | 151 | else |
| 184 | 152 | version_question = "Version that is being released: " |
| 185 | 153 | distribution = 'unstable' |
| ... | ... | @@ -187,7 +155,7 @@ EOF |
| 187 | 155 | |
| 188 | 156 | version_name = new_version = ask(version_question) |
| 189 | 157 | |
| 190 | - if release_kind == 'test' | |
| 158 | + if release_kind =~ /test/ | |
| 191 | 159 | timestamp = Time.now.strftime('%Y%m%d%H%M%S') |
| 192 | 160 | version_name += "~rc#{timestamp}" |
| 193 | 161 | end |
| ... | ... | @@ -208,12 +176,6 @@ EOF |
| 208 | 176 | end |
| 209 | 177 | end |
| 210 | 178 | |
| 211 | - desc "uploads the packages to the repository" | |
| 212 | - task :upload_packages, :release_kind do |t, args| | |
| 213 | - release_kind = args[:release_kind] || 'stable' | |
| 214 | - sh "dput --unchecked #{release_kind} #{Dir['pkg/*.changes'].first}" | |
| 215 | - end | |
| 216 | - | |
| 217 | 179 | desc 'prepares a release tarball' |
| 218 | 180 | task :release, :release_kind do |t, args| |
| 219 | 181 | release_kind = args[:release_kind] || 'stable' |
| ... | ... | @@ -283,5 +245,5 @@ EOF |
| 283 | 245 | sh 'apt-ftparchive release . > Release' |
| 284 | 246 | end |
| 285 | 247 | end |
| 286 | - | |
| 248 | + | |
| 287 | 249 | end | ... | ... |
public/javascripts/application.js
| ... | ... | @@ -683,7 +683,6 @@ function hide_and_show(hide_elements, show_elements) { |
| 683 | 683 | |
| 684 | 684 | function limited_text_area(textid, limit) { |
| 685 | 685 | var text = jQuery('#' + textid).val(); |
| 686 | - grow_text_area(textid); | |
| 687 | 686 | var textlength = text.length; |
| 688 | 687 | jQuery('#' + textid + '_left span').html(limit - textlength); |
| 689 | 688 | if (textlength > limit) { |
| ... | ... | @@ -698,14 +697,9 @@ function limited_text_area(textid, limit) { |
| 698 | 697 | } |
| 699 | 698 | } |
| 700 | 699 | |
| 701 | -function grow_text_area(textid) { | |
| 702 | - var height = jQuery('#' + textid).attr('scrollHeight'); | |
| 703 | - if (jQuery.browser.webkit) { | |
| 704 | - height -= parseInt(jQuery('#' + textid).css('padding-top')) + | |
| 705 | - parseInt(jQuery('#' + textid).css('padding-bottom')); | |
| 706 | - } | |
| 707 | - jQuery('#' + textid).css('height', height + 'px'); | |
| 708 | -} | |
| 700 | +jQuery(function($) { | |
| 701 | + $('.autogrow').autogrow(); | |
| 702 | +}); | |
| 709 | 703 | |
| 710 | 704 | jQuery(function($) { |
| 711 | 705 | $('a').each(function() { | ... | ... |
| ... | ... | @@ -0,0 +1,93 @@ |
| 1 | +;(function($){ | |
| 2 | + //pass in just the context as a $(obj) or a settings JS object | |
| 3 | + $.fn.autogrow = function(opts) { | |
| 4 | + var that = $(this).css({overflow: 'hidden', resize: 'none'}) //prevent scrollies | |
| 5 | + , selector = that.selector | |
| 6 | + , defaults = { | |
| 7 | + context: $(document) //what to wire events to | |
| 8 | + , animate: true //if you want the size change to animate | |
| 9 | + , speed: 200 //speed of animation | |
| 10 | + , fixMinHeight: true //if you don't want the box to shrink below its initial size | |
| 11 | + , cloneClass: 'autogrowclone' //helper CSS class for clone if you need to add special rules | |
| 12 | + , onInitialize: false //resizes the textareas when the plugin is initialized | |
| 13 | + } | |
| 14 | + ; | |
| 15 | + opts = $.isPlainObject(opts) ? opts : {context: opts ? opts : $(document)}; | |
| 16 | + opts = $.extend({}, defaults, opts); | |
| 17 | + that.each(function(i, elem){ | |
| 18 | + var min, clone; | |
| 19 | + elem = $(elem); | |
| 20 | + //if the element is "invisible", we get an incorrect height value | |
| 21 | + //to get correct value, clone and append to the body. | |
| 22 | + if (elem.is(':visible') || parseInt(elem.css('height'), 10) > 0) { | |
| 23 | + min = parseInt(elem.css('height'), 10) || elem.innerHeight(); | |
| 24 | + } else { | |
| 25 | + clone = elem.clone() | |
| 26 | + .addClass(opts.cloneClass) | |
| 27 | + .val(elem.val()) | |
| 28 | + .css({ | |
| 29 | + position: 'absolute' | |
| 30 | + , visibility: 'hidden' | |
| 31 | + , display: 'block' | |
| 32 | + }) | |
| 33 | + ; | |
| 34 | + $('body').append(clone); | |
| 35 | + min = clone.innerHeight(); | |
| 36 | + clone.remove(); | |
| 37 | + } | |
| 38 | + if (opts.fixMinHeight) { | |
| 39 | + elem.data('autogrow-start-height', min); //set min height | |
| 40 | + } | |
| 41 | + elem.css('height', min); | |
| 42 | + | |
| 43 | + if (opts.onInitialize) { | |
| 44 | + resize.call(elem); | |
| 45 | + } | |
| 46 | + }); | |
| 47 | + opts.context | |
| 48 | + .on('keyup paste', selector, resize) | |
| 49 | + ; | |
| 50 | + | |
| 51 | + function resize (e){ | |
| 52 | + var box = $(this) | |
| 53 | + , oldHeight = box.innerHeight() | |
| 54 | + , newHeight = this.scrollHeight | |
| 55 | + , minHeight = box.data('autogrow-start-height') || 0 | |
| 56 | + , clone | |
| 57 | + ; | |
| 58 | + if (oldHeight < newHeight) { //user is typing | |
| 59 | + this.scrollTop = 0; //try to reduce the top of the content hiding for a second | |
| 60 | + opts.animate ? box.stop().animate({height: newHeight}, opts.speed) : box.innerHeight(newHeight); | |
| 61 | + } else if (!e || e.which == 8 || e.which == 46 || (e.ctrlKey && e.which == 88)) { //user is deleting, backspacing, or cutting | |
| 62 | + if (oldHeight > minHeight) { //shrink! | |
| 63 | + //this cloning part is not particularly necessary. however, it helps with animation | |
| 64 | + //since the only way to cleanly calculate where to shrink the box to is to incrementally | |
| 65 | + //reduce the height of the box until the $.innerHeight() and the scrollHeight differ. | |
| 66 | + //doing this on an exact clone to figure out the height first and then applying it to the | |
| 67 | + //actual box makes it look cleaner to the user | |
| 68 | + clone = box.clone() | |
| 69 | + .addClass(opts.cloneClass) //add clone class for extra css rules | |
| 70 | + .css({position: 'absolute', zIndex:-10}) //make "invisible" | |
| 71 | + .val(box.val()) //populate with content for consistent measuring | |
| 72 | + ; | |
| 73 | + box.after(clone); //append as close to the box as possible for best CSS matching for clone | |
| 74 | + do { //reduce height until they don't match | |
| 75 | + newHeight = clone[0].scrollHeight - 1; | |
| 76 | + clone.innerHeight(newHeight); | |
| 77 | + } while (newHeight === clone[0].scrollHeight); | |
| 78 | + newHeight++; //adding one back eliminates a wiggle on deletion | |
| 79 | + clone.remove(); | |
| 80 | + box.focus(); // Fix issue with Chrome losing focus from the textarea. | |
| 81 | + | |
| 82 | + //if user selects all and deletes or holds down delete til beginning | |
| 83 | + //user could get here and shrink whole box | |
| 84 | + newHeight < minHeight && (newHeight = minHeight); | |
| 85 | + oldHeight > newHeight && opts.animate ? box.stop().animate({height: newHeight}, opts.speed) : box.innerHeight(newHeight); | |
| 86 | + } else { //just set to the minHeight | |
| 87 | + box.innerHeight(minHeight); | |
| 88 | + } | |
| 89 | + } | |
| 90 | + } | |
| 91 | + return that; | |
| 92 | + } | |
| 93 | +})(jQuery); | ... | ... |
test/unit/person_test.rb
| ... | ... | @@ -1152,21 +1152,6 @@ class PersonTest < ActiveSupport::TestCase |
| 1152 | 1152 | assert_includes Person.more_active, profile |
| 1153 | 1153 | end |
| 1154 | 1154 | |
| 1155 | - should 'handle multiparameter attribute exception on birth date field' do | |
| 1156 | - assert_nothing_raised ActiveRecord::MultiparameterAssignmentErrors do | |
| 1157 | - p = Person.new( | |
| 1158 | - :name => 'birthday', :identifier => 'birthday', | |
| 1159 | - 'birth_date(1i)' => '', 'birth_date(2i)' => '6', 'birth_date(3i)' => '16' | |
| 1160 | - ) | |
| 1161 | - end | |
| 1162 | - end | |
| 1163 | - | |
| 1164 | - should 'not accept an empty year on birth date' do | |
| 1165 | - p = Person.new(:birth_date => "1115") | |
| 1166 | - p.valid? | |
| 1167 | - assert p.errors[:birth_date.to_s].present? | |
| 1168 | - end | |
| 1169 | - | |
| 1170 | 1155 | should 'associate report with the correct complaint' do |
| 1171 | 1156 | p1 = create_user('user1').person |
| 1172 | 1157 | p2 = create_user('user2').person | ... | ... |